/* Birta theme — single source of truth. Tune on /debug.
   Themes are named, not light/dark: :root is the straw library theme;
   named themes below opt in via data-theme (e.g. the viewer gallery). */
*, *::before, *::after { box-sizing: border-box; }

:root {
  --bg: #d6c9a4;
  --surface: #e2d8ba;
  --field: #faf7ee;
  --btn: #cabb8c;
  --btn-border: #9c8446;
  --text: #2a2620;
  --muted: #665f4b;
  --border: #c0b085;
  --accent: #b06a3d;
  --accent-hover: #995a30;
  --accent-contrast: #faf7ee;
  --danger: #a23b2f;
  --selection: #ccbb8f;
  --radius: 8px;
  --shadow: 0 1px 2px rgba(0,0,0,.05);
  /* Paper grain, two stacked SVG feTurbulence tiles laid behind the page for
     a brushed paper tooth. DON'T hand-edit the URIs — regenerate with
     `make gen-noise` (scripts/gen-noise.mjs).
     - --noise: 160px tile stretched into horizontal long-grain fibers
       (baseFrequency .018 across / .65 down), dark specks at ~.055 alpha.
     - --noise-fine: 257px unstretched fine-tooth tile (baseFrequency .77,
       ~.05 alpha) over the fibers, so they don't read as smoothly stretched;
       257 (~1.61x the fiber tile, and prime) is coprime to 160, so the
       combined pattern repeats only every ~41k px and tiling never shows. */
  --noise: url("data:image/svg+xml,%3Csvg%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%20width%3D%27160%27%20height%3D%27160%27%3E%3Cfilter%20id%3D%27n%27%3E%3CfeTurbulence%20type%3D%27fractalNoise%27%20baseFrequency%3D%270.018%200.65%27%20numOctaves%3D%273%27%20stitchTiles%3D%27stitch%27%20seed%3D%277%27%2F%3E%3CfeColorMatrix%20type%3D%27matrix%27%20values%3D%270%200%200%200%200%200%200%200%200%200%200%200%200%200%200%200%200%200%200.055%200%27%2F%3E%3C%2Ffilter%3E%3Crect%20width%3D%27160%27%20height%3D%27160%27%20filter%3D%27url(%23n)%27%2F%3E%3C%2Fsvg%3E");
  --noise-fine: url("data:image/svg+xml,%3Csvg%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%20width%3D%27257%27%20height%3D%27257%27%3E%3Cfilter%20id%3D%27n%27%3E%3CfeTurbulence%20type%3D%27fractalNoise%27%20baseFrequency%3D%270.77%27%20numOctaves%3D%272%27%20stitchTiles%3D%27stitch%27%20seed%3D%2711%27%2F%3E%3CfeColorMatrix%20type%3D%27matrix%27%20values%3D%270%200%200%200%200%200%200%200%200%200%200%200%200%200%200%200%200%200%200.05%200%27%2F%3E%3C%2Ffilter%3E%3Crect%20width%3D%27257%27%20height%3D%27257%27%20filter%3D%27url(%23n)%27%2F%3E%3C%2Fsvg%3E");
  --font-sans: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --font-serif: Georgia, "Times New Roman", serif;
  --font-mono: ui-monospace, SFMono-Regular, Menlo, monospace;
}

:root[data-theme="viewer"] {
  --bg: #14120f;
  --surface: #1e1b16;
  --field: #26221b;
  --btn: #2c281f;
  --btn-border: #4a4331;
  --text: #ece7dd;
  --muted: #a49a89;
  --border: #2c2820;
  --accent: #d08a54;
  --accent-hover: #e0985f;
  --accent-contrast: #14120f;
  --danger: #d06a5a;
  --selection: #3a2f24;
}

html { scrollbar-color: var(--border) transparent; }
body {
  margin: 0; padding: 1rem; line-height: 1.5;
  /* The paper-grain tiles (fine tooth over fibers) ride over the flat --bg;
     cards/panels are opaque and sit on top, so only the page ground shows
     the texture. */
  background-color: var(--bg); background-image: var(--noise-fine), var(--noise);
  color: var(--text);
  font-family: var(--font-sans);
}
h1 { font-size: 1.4rem; font-weight: 600; margin: 0 0 .5rem; }
h2 { font-size: 1.1rem; font-weight: 600; }
h3 { font-size: 1rem; font-weight: 600; }
a { color: var(--accent); text-decoration: none; }
a:hover { text-decoration: underline; }
::selection { background: var(--selection); }

/* form controls */
input[type="text"], input[type="password"], input[type="date"], select, textarea {
  background: var(--field); color: var(--text);
  border: 1px solid var(--border); border-radius: var(--radius);
  padding: .4rem .55rem; font: inherit;
}
:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
input[type="checkbox"], input[type="radio"] { accent-color: var(--accent); width: 1.05rem; height: 1.05rem; }

button, .btn {
  background: var(--btn); color: var(--text);
  border: 1px solid var(--btn-border); border-radius: var(--radius);
  padding: .4rem .7rem; font: inherit; cursor: pointer;
}
button:hover, .btn:hover { border-color: var(--text); }
.btn-primary { background: var(--accent); color: var(--accent-contrast); border-color: var(--accent); }
.btn-primary:hover { background: var(--accent-hover); border-color: var(--accent-hover); }
.btn-danger { background: transparent; color: var(--danger); border-color: var(--border); }
.btn-danger:hover { border-color: var(--danger); }
button:disabled, .btn:disabled { opacity: .5; cursor: default; }

/* scrollbars (WebKit/Chromium; Firefox uses scrollbar-color above) */
::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-thumb { background: var(--border); border-radius: 6px; }
::-webkit-scrollbar-track { background: transparent; }

/* shared components */
.bar { display: flex; gap: 1rem; align-items: center; flex-wrap: wrap; margin-bottom: .75rem; }
.bar .brand { font-weight: 700; font-size: 1.15rem; color: var(--text); }
.bar .brand:hover { text-decoration: none; }
.bar .nav { display: flex; gap: 1rem; align-items: center; }
.bar .nav a { color: var(--text); padding-bottom: 2px; border-bottom: 2px solid transparent; }
.bar .nav a:hover { text-decoration: none; border-bottom-color: var(--border); }
.bar .nav a.active { border-bottom-color: var(--accent); }
.bar .crumb { color: var(--muted); }
.bar-right { margin-left: auto; display: flex; gap: 1rem; align-items: center; }
.filter { display: flex; gap: .5rem; align-items: flex-end; flex-wrap: wrap; margin: .25rem 0 .75rem; }
.filter .field { display: flex; flex-direction: column; gap: .15rem; }
.filter .field-label { font-size: .7rem; text-transform: uppercase; letter-spacing: .05em; color: var(--muted); }
.filter .field-q { flex: 1; min-width: 16rem; position: relative; }
.groupsort { display: flex; flex-wrap: wrap; gap: .75rem; align-items: flex-end; }
.q-wrap { position: relative; display: block; width: 100%; }
.filter input.query, .q-mirror { padding: .4rem .55rem; border-radius: var(--radius); font: inherit; }
.filter input.query { width: 100%; position: relative; background: transparent; }
.filter input.query::placeholder { color: var(--muted); }
.q-wrap.q-live input.query { color: transparent; caret-color: var(--text); }
.q-wrap.q-live input.query::selection { background: color-mix(in srgb, var(--selection) 55%, transparent); }
.q-mirror { position: absolute; inset: 0; pointer-events: none; overflow: hidden; white-space: pre; border: 1px solid transparent; color: var(--text); background: var(--field); }
.q-mirror span { border-radius: 2px; }
.q-key { color: var(--accent); }
.q-conf { color: var(--muted); }
.q-colon, .q-op, .q-neg { color: var(--muted); font-weight: 600; }
.q-quoted { color: var(--text); background: color-mix(in srgb, var(--muted) 12%, transparent); }
.q-err { color: var(--danger); text-decoration: underline wavy; text-underline-offset: 3px; }
.q-paren { color: var(--muted); }
.q-paren.active { color: var(--accent); font-weight: 700; }
.q-d1 { background: color-mix(in srgb, var(--accent) 6%, transparent); }
.q-d2 { background: color-mix(in srgb, var(--accent) 11%, transparent); }
.q-d3 { background: color-mix(in srgb, var(--accent) 16%, transparent); }
.q-d4 { background: color-mix(in srgb, var(--accent) 21%, transparent); }
/* Overlay dropdown: floats below its input (positioned ancestor) instead of
   pushing the content underneath down the page. */
.q-suggest { position: absolute; top: calc(100% + .25rem); left: 0; right: 0; z-index: 20; padding: .4rem .6rem; max-width: 32rem; background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); box-shadow: var(--shadow); font-size: .85rem; }
.q-suggest-title { color: var(--muted); text-transform: uppercase; font-size: .7rem; letter-spacing: .05em; margin: .2rem 0; }
.q-suggest-row { font-family: var(--font-mono); padding: .1rem 0; cursor: pointer; }
.q-suggest-row.highlight { background: var(--selection); }
/* The lightbox tag box reuses the query panel's look, minus its pull-up
   margin (there's no mirror overlay above it) and width cap (the sidebar
   already constrains it). The info sidebar is always dark (fixed rgba
   ground, not themed — see .lb-info-panel), so the panel's colors are
   pinned dark to match: the straw theme's light --surface/--selection
   under the sidebar's inherited #eee text would be unreadable. */
.tag-suggest { max-width: none; background: rgba(30,28,24,.98); border-color: rgba(255,255,255,.14); }
.tag-suggest .q-suggest-title { color: #9aa; }
.tag-suggest .q-suggest-row.highlight { background: rgba(255,255,255,.12); }
.notice {
  background: var(--surface); border: 1px solid var(--border);
  border-left: 3px solid var(--accent); padding: .4rem .6rem;
  border-radius: var(--radius); margin: .25rem 0; color: var(--muted);
}
/* htmx marks the hx-indicator element (#results) while a swap request is
   in flight; the delay keeps fast responses from flickering. */
#results.htmx-request { opacity: .55; transition: opacity 150ms ease 100ms; }
/* selection panel: right-hand tray on wide screens, bottom sheet on narrow */
.layout { display: flex; gap: 1rem; align-items: flex-start; }
.results-main { flex: 1 1 auto; min-width: 0; }
.selpanel {
  flex: 0 0 260px; position: sticky; top: .5rem; z-index: 10;
  max-height: calc(100vh - 1rem); overflow-y: auto;
  display: flex; flex-direction: column; gap: .5rem;
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius); padding: .75rem; box-shadow: var(--shadow);
}
.selpanel[hidden] { display: none; }
.sel-head { margin: 0; }
.selpanel > form { display: flex; gap: .4rem; flex-wrap: wrap; margin: 0; }
.selpanel > form input[type="text"], .selpanel > form input[type="password"] { flex: 1 1 8rem; min-width: 0; }
.sel-actions { display: flex; gap: .4rem; flex-wrap: wrap; }
.sel-actions form { margin: 0; }
.sel-tray { display: grid; grid-template-columns: repeat(auto-fill, minmax(64px, 1fr)); gap: .4rem; }
.tray-item { position: relative; }
.tray-item img { width: 100%; height: 64px; object-fit: cover; border-radius: var(--radius); display: block; background: var(--bg); }
.tray-item form { position: absolute; top: 2px; right: 2px; margin: 0; }
.tray-x {
  border: none; border-radius: 999px; cursor: pointer;
  background: rgba(0,0,0,.55); color: #fff;
  font-size: .8rem; line-height: 1; padding: .15rem .35rem;
}
.sel-view { margin: 0; font-size: .9rem; }
@media (max-width: 50rem) {
  .layout { flex-direction: column; }
  .selpanel {
    position: sticky; bottom: 0; top: auto;
    flex: none; width: 100%; max-height: 45vh;
  }
  .sel-tray { display: flex; overflow-x: auto; }
  .tray-item { flex: 0 0 64px; }
}
.err { color: var(--danger); }
.auth { max-width: 22rem; margin: 4rem auto; padding: 1rem; }
.auth input, .auth button { width: 100%; margin: .3rem 0; padding: .5rem; }
.center { max-width: 30rem; margin: 5rem auto; padding: 1rem; text-align: center; color: var(--muted); }

/* admin catalog grid */
h2.day { font-size: 1rem; font-weight: 600; color: var(--muted); margin: 1rem 0 .35rem; }
.catalog-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(120px, 1fr)); gap: .5rem; }
.cell { position: relative; }
.cell img { width: 100%; height: 120px; object-fit: cover; border-radius: var(--radius); display: block; background: var(--surface); }
.cell.cursor { outline: 3px solid var(--accent); outline-offset: 2px; border-radius: var(--radius); }
.cell.missing img { opacity: .4; }
.album-grid .cell { cursor: grab; }
.album-grid.reordering { cursor: grabbing; user-select: none; }
/* the source cell keeps its grid slot but is hidden while its ghost floats */
.album-grid .cell.reorder-source { visibility: hidden; }
/* FLIP play step animates transform; reduced-motion snaps instantly */
.album-grid .cell.reorder-slide { transition: transform 160ms ease; }
@media (prefers-reduced-motion: reduce) {
  .album-grid .cell.reorder-slide { transition: none; }
}
/* floating clone that follows the cursor */
.album-drag-ghost {
  position: fixed;
  margin: 0;
  pointer-events: none;
  z-index: 1000;
  transform: scale(1.05);
  box-shadow: 0 8px 24px rgba(0, 0, 0, .35);
  opacity: .95;
}
.album-grid.reorder-error { outline: 2px solid var(--danger); outline-offset: 4px; }
.badge-tray {
  position: absolute; right: 4px; bottom: 4px; z-index: 1;
  display: flex; flex-direction: column; align-items: flex-end; gap: 2px;
}
.badge { background: var(--danger); color: #fff; font-size: .7rem; line-height: 1.4; padding: 1px 4px; border-radius: 3px; }
.badge.cropped, .badge.rotated { background: var(--accent); font-size: .85rem; line-height: 1; padding: 2px 4px; }
label.sel { position: absolute; top: 4px; right: 4px; z-index: 2; }
.pager { display: flex; gap: 1rem; margin: .5rem 0; }
.pager .disabled { color: var(--muted); opacity: .5; }

.cell .cell-x { position: absolute; top: 4px; right: 4px; z-index: 2; margin: 0; }
.cell .cell-x button {
  background: rgba(0, 0, 0, .55); color: #fff; border: 0; border-radius: 3px;
  width: 18px; height: 18px; line-height: 1; font-size: .8rem; cursor: pointer;
}
.album-excluded { margin-top: 1rem; }
.album-excluded .cell.excluded img { opacity: .5; }
.album-query { display: flex; gap: .4rem; align-items: center; margin: .25rem 0; }
.album-query input.query { flex: 1; }

/* albums table */
table { border-collapse: collapse; width: 100%; }
td, th { text-align: left; padding: .4rem; border-bottom: 1px solid var(--border); }
code { background: var(--surface); border: 1px solid var(--border); padding: 1px 4px; border-radius: 4px; font-family: var(--font-mono); }

/* per-photo view */
img.photo { max-width: 100%; max-height: 70vh; border-radius: var(--radius); display: block; }
.tags { display: flex; gap: .4rem; flex-wrap: wrap; align-items: center; margin: 1rem 0; }
.tag { display: inline-flex; gap: .3rem; align-items: center; background: var(--surface); border: 1px solid var(--border); border-radius: 999px; padding: .15rem .6rem; }
.tag a { color: var(--text); }
.tag button { border: none; background: none; color: var(--danger); cursor: pointer; font-size: 1rem; line-height: 1; padding: 0; }
form.add { display: flex; gap: .5rem; }

/* viewer gallery (uses the viewer theme via data-theme) */
.gallery { display: grid; grid-template-columns: repeat(auto-fill, minmax(160px, 1fr)); gap: .5rem; }
.gallery img { width: 100%; height: 160px; object-fit: cover; border-radius: var(--radius); cursor: pointer; display: block; background: var(--surface); }
#lb { position: fixed; inset: 0; background: rgba(0,0,0,.92); display: none; align-items: center; justify-content: center; padding: 1rem; }
#lb img { max-width: 100%; max-height: 100%; border-radius: var(--radius); }
#lb.open { display: flex; }

/* --- library selection (progressive enhancement; gated on body.js) --- */

body.js label.sel { opacity: 0; transition: opacity 130ms ease; }
body.js:not(.selecting) .cell:hover label.sel,
body.js:not(.selecting) .cell.selected label.sel { opacity: 1; }
@media (hover: none) { body.js label.sel { opacity: 1; } }

/* In select mode the brown hover wash (below) replaces the checkbox as the
   select affordance: hide the boxes and route every click to the cell. Touch
   devices have no hover to reveal the wash, so they keep tappable checkboxes. */
body.js.selecting label.sel { pointer-events: none; }
@media (hover: none) { body.js.selecting label.sel { pointer-events: auto; } }

.cell.selected img,
body.selecting .cell:hover:not(.selected) img { outline: 4px solid var(--accent); outline-offset: -4px; }
.cell.selected::after {
  content: ""; position: absolute; inset: 0; border-radius: var(--radius);
  background: var(--accent); opacity: .14; pointer-events: none;
}

/* Faint brown wash on unselected cells while a selection is active: fades in
   on hover to signal "click to select". Selected cells keep the stronger
   overlay + outline above, so hover (preview) and selected (committed) stay
   visually distinct. */
body.selecting .cell:not(.selected)::after {
  content: ""; position: absolute; inset: 0; border-radius: var(--radius);
  background: var(--accent); opacity: 0; pointer-events: none;
  transition: opacity 130ms ease;
}
body.selecting .cell:hover:not(.selected)::after { opacity: .08; }

.seltools { color: var(--muted); }
.seltools .selcount { color: var(--text); }

/* active row in the selections list */
tr.active td { background: var(--surface); }
.tag-active { color: var(--accent); border: 1px solid var(--accent); border-radius: 999px; padding: 0 .4rem; font-size: .75rem; }

@media (prefers-reduced-motion: reduce) {
  body.js label.sel { transition: none; }
  body.selecting .cell:not(.selected)::after { transition: none; }
}

/* --- library view icon + lightbox --- */
.cell-view {
  position: absolute; top: 4px; left: 4px; z-index: 1;
  border: none; border-radius: var(--radius); cursor: pointer;
  background: rgba(0,0,0,.55); color: #fff;
  font-size: .95rem; line-height: 1; padding: .15rem .4rem;
  opacity: 0; transition: opacity 130ms ease;
}
body:not(.js) .cell-view { display: none; }
body.selecting .cell:hover .cell-view { opacity: 1; }

.sel-bulk { display: flex; flex-wrap: wrap; gap: .4rem; align-items: center; margin: 0 0 .8rem; }
.sel-bulk form { display: inline; margin: 0; }
body:not(.js) .sel-jsonly { display: none; }

.lightbox {
  position: fixed; inset: 0; z-index: 50;
  display: flex; align-items: stretch;
  background: rgba(0,0,0,.9);
}
.lightbox[hidden] { display: none; }
.lb-stage {
  position: relative; flex: 1 1 auto; min-width: 0;
  display: flex; align-items: center; justify-content: center;
}
.lb-img { max-width: 92%; max-height: 92vh; border-radius: var(--radius); }
.lb-badge-tray {
  position: absolute; top: 1rem; left: 1rem; z-index: 2;
  display: flex; flex-direction: column; align-items: flex-start; gap: .35rem;
}
.lb-cropped-badge, .lb-rotated-badge {
  background: rgba(0,0,0,.6); color: #fff;
  font-size: .9rem; line-height: 1; padding: 3px 6px; border-radius: var(--radius);
}
.lb-cropped-badge[hidden], .lb-rotated-badge[hidden] { display: none; }
.lb-info-panel {
  display: none; flex: 0 0 20rem; max-width: 80vw;
  overflow-y: auto; padding: 3.5rem 1.4rem 1.25rem; /* top pad clears the close/info buttons */
  background: rgba(20,20,22,.96); color: #eee;
}
.lightbox.info-open .lb-info-panel { display: block; }
.lb-meta { margin: 0 0 1rem; }
.lb-meta div { display: flex; justify-content: space-between; gap: 1rem; padding: .3rem 0; border-bottom: 1px solid rgba(255,255,255,.08); }
.lb-meta dt { color: #9aa; font-size: .8rem; }
.lb-meta dd { margin: 0; text-align: right; word-break: break-word; }
.lb-tags { margin: .8rem 0 0; }
.lb-addtag { display: flex; gap: .4rem; position: relative; }
.lb-addtag input { flex: 1 1 auto; min-width: 0; }
.lb-info-panel.lb-error .lb-addtag input { border-color: #c0392b; }
.lb-autotags, .lb-location { margin: .8rem 0; }
.lb-tagrow {
  display: grid; grid-template-columns: auto 1fr; gap: .5rem;
  align-items: baseline; padding: .25rem .5rem; border-radius: var(--radius);
  font-size: .85rem;
  /* column flow: the optional .lb-conf / source smalls and the trailing
     .lb-acts append as implicit auto columns instead of wrapping into a
     2nd row under the default row flow. */
  grid-auto-flow: column;
}
.lb-tagrow:hover { background: rgba(255,255,255,.06); }
.lb-tagrow small { color: #9aa; font-size: .7rem; text-align: right; }
/* key column mirrors .lb-meta dt; value mirrors .lb-meta dd */
.lb-tagrow .lb-rowkey { font-size: .8rem; text-align: left; }
.lb-rowval { text-align: right; word-break: break-word; }
.lb-conf { color: var(--muted); }
.lb-acts { white-space: nowrap; }
.lb-acts button {
  border: none; background: none; cursor: pointer;
  font-size: .85rem; padding: 0 .25rem; line-height: 1;
}
.lb-act-promote { color: #8fc98f; }
.lb-act-dismiss { color: #c98f8f; }
.lb-acts button:hover { color: #fff; }
.lb-act-remove { color: #ccc; }
/* Approved rows read at a glance: green accent bar (inset shadow, not
   border-left, so approved rows don't shift horizontally) + faint wash;
   the ✓ toggle becomes a filled disc. Hover wash is stronger than the
   resting wash so row hover stays visible. */
.lb-tagrow.lb-approved { background: rgba(76,175,80,.12); box-shadow: inset 2px 0 0 #4caf50; }
.lb-tagrow.lb-approved:hover { background: rgba(76,175,80,.18); }
.lb-act-promote.lb-approved {
  background: #4caf50; color: #fff; font-weight: 700;
  border-radius: 50%; font-size: .7rem;
  display: inline-grid; place-items: center;
  width: 1.15rem; height: 1.15rem;
}
.lb-act-promote.lb-approved:hover { background: #3d8b40; color: #fff; }
/* Dismissed rows echo the approved treatment in red at half strength
   (wash .06 vs green .12, bar at 50% alpha vs solid) so they read as
   muted counterparts, not alarms. Inset shadow, not border-left, keeps
   rows from shifting horizontally. */
.lb-tagrow.lb-dismissed { background: rgba(198,40,40,.06); box-shadow: inset 2px 0 0 rgba(198,40,40,.5); }
.lb-tagrow.lb-dismissed:hover { background: rgba(198,40,40,.10); }
.lb-tagrow.lb-dismissed .lb-rowval { text-decoration: line-through; color: var(--muted); }
.lb-act-restore { color: #c98f8f; }
.lb-details .lb-meta { margin: 0 0 .5rem; }
.lb-group { margin: 1.25rem 0 .25rem; font-size: .72rem; text-transform: uppercase; letter-spacing: .06em; color: #8a8f98; }
.lb-details details.lb-overflow > summary {
  cursor: pointer; margin: 1.25rem 0 .25rem;
  font-size: .72rem; text-transform: uppercase; letter-spacing: .06em; color: #8a8f98;
}
.lb-details details.lb-overflow[open] > summary { margin-bottom: .25rem; }
.lb-details details.lb-overflow .lb-meta { margin: 0; }
.lb-details a { color: #cbd5e1; }
.lb-info-panel [data-qval] { cursor: pointer; }
.lb-info-panel .lb-filterable:hover { text-decoration: underline; text-underline-offset: 2px; }
.attr-menu { position: fixed; z-index: 60; background: #1c1f26; border: 1px solid rgba(255,255,255,.18); border-radius: var(--radius); box-shadow: 0 8px 28px rgba(0,0,0,.5); padding: .25rem; display: flex; flex-direction: column; min-width: 12rem; }
.attr-menu-item { text-align: left; background: none; border: none; color: #e6e8eb; font: inherit; padding: .4rem .6rem; border-radius: 4px; cursor: pointer; white-space: nowrap; }
.attr-menu-item:hover { background: rgba(255,255,255,.12); }
.lb-btn {
  position: absolute; border: none; cursor: pointer;
  background: rgba(0,0,0,.5); color: #fff;
  font-size: 1.6rem; line-height: 1; padding: .3rem .6rem; border-radius: var(--radius);
}
.lb-close { top: 1rem; right: 1rem; }
.lb-info { top: 1rem; right: 4rem; font-size: 1.2rem; }
.lb-crop { top: 1rem; right: 7rem; font-size: 1.2rem; }
.lb-rotate-left { top: 1rem; right: 10rem; font-size: 1.2rem; }
.lb-rotate-right { top: 1rem; right: 13rem; font-size: 1.2rem; }
.lb-delete, .lb-restore { top: 1rem; right: 16rem; font-size: 1.2rem; }
.lb-help { top: 1rem; right: 19rem; font-size: 1.2rem; font-weight: 700; }
.lb-prev { left: 1rem; top: 50%; transform: translateY(-50%); }
.lb-next { right: 1rem; top: 50%; transform: translateY(-50%); }
body.lb-open { overflow: hidden; }

.lb-help-panel {
  position: absolute; top: 3.75rem; right: 1rem; z-index: 4;
  max-width: min(24rem, 90vw);
  background: rgba(20,20,22,.96); color: #eee;
  border: 1px solid rgba(255,255,255,.14); border-radius: var(--radius);
  box-shadow: 0 8px 28px rgba(0,0,0,.5); padding: 1rem 1.25rem;
}
.lb-help-panel[hidden] { display: none; }
.lb-help-title { margin: 0 0 .7rem; font-size: .72rem; text-transform: uppercase; letter-spacing: .06em; color: #8a8f98; }
.lb-help-list { margin: 0; display: grid; gap: .45rem; }
.lb-help-list div { display: flex; justify-content: space-between; align-items: baseline; gap: 1.5rem; }
.lb-help-list dt { display: flex; gap: .3rem; margin: 0; }
.lb-help-list dd { margin: 0; color: #cbd5e1; font-size: .85rem; }
.lb-help-list kbd {
  background: rgba(255,255,255,.12); border: 1px solid rgba(255,255,255,.22);
  border-radius: 4px; padding: .05rem .4rem; min-width: 1.4rem; text-align: center;
  font-family: inherit; font-size: .8rem; line-height: 1.5;
}

/* The delete/restore confirmation reuses the help panel's dialog styling,
   recentered vertically. */
.lb-confirm-panel { top: 50%; transform: translateY(-50%); }

@media (max-width: 40rem) {
  .lightbox { flex-direction: column; }
  .lb-info-panel { flex: 0 0 auto; max-width: none; max-height: 45vh; padding-top: 1.25rem; }
}

@media (prefers-reduced-motion: reduce) {
  .cell-view { transition: none; }
}
.seltools.sel-error { outline: 2px solid var(--danger); }

.crop-overlay { position: absolute; inset: 0; z-index: 3; }
.lightbox.cropping .lb-info-panel,
.lightbox.cropping .lb-prev,
.lightbox.cropping .lb-next { display: none; }
.crop-box {
  position: absolute; box-sizing: border-box;
  border: 1px solid #fff; box-shadow: 0 0 0 100vmax rgba(0,0,0,.5);
  cursor: move; touch-action: none;
}
.crop-h {
  position: absolute; width: 12px; height: 12px; background: #fff;
  border-radius: 50%; touch-action: none;
}
.crop-h-nw { left: -6px; top: -6px; cursor: nwse-resize; }
.crop-h-n  { left: calc(50% - 6px); top: -6px; cursor: ns-resize; }
.crop-h-ne { right: -6px; top: -6px; cursor: nesw-resize; }
.crop-h-e  { right: -6px; top: calc(50% - 6px); cursor: ew-resize; }
.crop-h-se { right: -6px; bottom: -6px; cursor: nwse-resize; }
.crop-h-s  { left: calc(50% - 6px); bottom: -6px; cursor: ns-resize; }
.crop-h-sw { left: -6px; bottom: -6px; cursor: nesw-resize; }
.crop-h-w  { left: -6px; top: calc(50% - 6px); cursor: ew-resize; }
.crop-bar {
  position: absolute; left: 50%; bottom: 1rem; transform: translateX(-50%);
  display: flex; gap: .4rem; flex-wrap: wrap; justify-content: center;
  background: rgba(20,20,22,.9); padding: .5rem .7rem; border-radius: var(--radius);
}
.crop-ratio, .crop-action {
  border: none; cursor: pointer; border-radius: var(--radius);
  padding: .3rem .6rem; font-size: .85rem; background: rgba(255,255,255,.15); color: #fff;
}
.crop-save { background: var(--accent); }
.crop-uncrop, .crop-cancel { background: rgba(255,255,255,.15); }

/* Whole-query suggestion rows (Recent/Saved) can be long — keep them on one line. */
.q-suggest-row { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* Save-query star: JS-only affordance inside the query field. */
.q-star { display: none; }
body.js .q-star { display: block; position: absolute; top: 50%; right: .3rem; transform: translateY(-50%); border: 0; background: none; color: var(--muted); cursor: pointer; font-size: 1rem; line-height: 1; padding: 0 .15rem; }
body.js .q-star:disabled { opacity: .35; cursor: default; }
body.js .q-star.saved { color: var(--accent); }
body.js .q-wrap input.query { padding-right: 1.7rem; }
body.js .q-mirror { padding-right: 1.7rem; }
