/* ===========================================================================
   Family Archive
   ---------------------------------------------------------------------------
   Design thesis: the interface has no color of its own. Every color on screen
   is borrowed from the photograph you are looking at -- the dominant color is
   measured at ingest and injected per card as --bloom, so the archive tints the
   UI rather than the other way round. Chrome stays in darkroom neutrals so the
   prints are the only saturated thing in the room.

   The one fixed accent is --imprint, the amber of a film date-stamp, used only
   at imprint scale in the mono face for metadata. It is a quotation, not a brand.

   Type is system-only by request: nothing loads from a third party, so opening
   the album leaks nothing to anyone but the family's own server.
   =========================================================================== */

:root {
  --ground: #0b0a09;
  --surface: #15120e;
  --surface-2: #1f1a14;
  --edge: #2c261e;
  --edge-bright: #453c30;
  --ink: #f4efe6;
  --ink-dim: #9b9084;
  --ink-faint: #6b6258;
  --imprint: #f0a63c;
  --danger: #e2664f;
  --hover-edge: #f600ff;      /* grid hover outline -- reads against any photo */

  --bloom: #6b6258;                 /* overridden inline, per photo */

  /* Georgia carries the display voice: it ships nearly everywhere, and its
     old-style figures give dates and counts a period feel a UI sans cannot. */
  --font-display: Georgia, 'Iowan Old Style', 'Palatino Linotype', 'Times New Roman', serif;
  --font-ui: system-ui, -apple-system, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
  --font-mono: ui-monospace, 'SF Mono', 'Cascadia Mono', 'Segoe UI Mono', Consolas, Menlo, monospace;

  --gap: 10px;
  --bar-h: 58px;
  --lb-top: 62px;
  --lb-bottom: 132px;
  --radius: 3px;                    /* prints have corners, not pills */
  --ease: cubic-bezier(.22, .61, .36, 1);
}

* { box-sizing: border-box; }
[hidden] { display: none !important; }

html, body {
  margin: 0;
  padding: 0;
  background: var(--ground);
  color: var(--ink);
  font-family: var(--font-ui);
  -webkit-font-smoothing: antialiased;
  overscroll-behavior-y: none;
}

body.no-scroll { overflow: hidden; }

a { color: inherit; }
a.btn, a.wordmark { text-decoration: none; }

:focus-visible {
  outline: 2px solid var(--imprint);
  outline-offset: 2px;
}

button {
  font: inherit;
  color: inherit;
  background: none;
  border: none;
  cursor: pointer;
}

/* --- the date-stamp imprint: the only fixed accent ------------------------ */
.imprint {
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: .10em;
  text-transform: uppercase;
  color: var(--imprint);
}
.imprint-dim { color: var(--ink-faint); }
.imprint-meas { text-transform: none; letter-spacing: .06em; }

/* =========================== top bar ====================================== */
.bar {
  position: sticky;
  top: 0;
  z-index: 40;
  height: var(--bar-h);
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 0 14px;
  background: color-mix(in srgb, var(--ground) 86%, transparent);
  backdrop-filter: blur(14px) saturate(1.3);
  border-bottom: 1px solid var(--edge);
}

.wordmark {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 16px;
  letter-spacing: .015em;
  white-space: nowrap;
  text-decoration: none;
}
.wordmark span { color: var(--ink-faint); font-weight: 500; }

.bar-spacer { flex: 1; }

.search {
  flex: 0 1 260px;
  min-width: 0;
  display: flex;
  align-items: center;
  gap: 8px;
  height: 34px;
  padding: 0 11px;
  background: var(--surface);
  border: 1px solid var(--edge);
  border-radius: var(--radius);
}
.search input {
  flex: 1;
  min-width: 0;
  background: none;
  border: none;
  color: var(--ink);
  font: inherit;
  font-size: 13px;
  outline: none;
}
.search input::placeholder { color: var(--ink-faint); }

.btn {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  height: 34px;
  padding: 0 13px;
  border: 1px solid var(--edge);
  border-radius: var(--radius);
  background: var(--surface);
  font-size: 13px;
  font-weight: 500;
  white-space: nowrap;
  transition: border-color .15s, background .15s;
}
.btn:hover { border-color: var(--edge-bright); background: var(--surface-2); }
.btn[aria-pressed="true"], .btn.is-on {
  border-color: var(--imprint);
  color: var(--imprint);
}
.btn-ghost { background: none; border-color: transparent; }
.btn-danger:hover { border-color: var(--danger); color: var(--danger); }
/* States the photo IS hidden, rather than offering to hide it. */
.btn-hidden-on {
  background: var(--danger);
  border-color: var(--danger);
  color: #fff;
  font-weight: 700;
}
.btn-hidden-on:hover { background: #ef7b64; border-color: #ef7b64; color: #fff; }

.bar-tools { display: flex; align-items: center; gap: 14px; }
.sheet-head { display: none; }
.sheet-links { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 12px; }
.sheet-links form { display: contents; }

.count {
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--ink-dim);
  white-space: nowrap;
}

/* =========================== layout ======================================= */
.shell { display: flex; align-items: flex-start; }

.rail {
  position: sticky;
  top: var(--bar-h);
  flex: 0 0 232px;
  height: calc(100vh - var(--bar-h));
  overflow-y: auto;
  padding: 18px 14px 60px;
  border-right: 1px solid var(--edge);
  scrollbar-width: thin;
}

.main { flex: 1; min-width: 0; padding: var(--gap); }

.facet { margin-bottom: 22px; }
.facet h3 {
  margin: 0 0 9px;
  font-family: var(--font-mono);
  font-size: 10px;
  font-weight: 400;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--ink-faint);
}

.opt {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  padding: 5px 7px;
  border-radius: var(--radius);
  font-size: 13px;
  text-align: left;
  color: var(--ink-dim);
  transition: background .12s, color .12s;
}
.opt:hover { background: var(--surface); color: var(--ink); }
.opt input[type="checkbox"] {
  flex: 0 0 auto;
  width: 15px;
  height: 15px;
  margin: 0;
  accent-color: var(--imprint);
  cursor: pointer;
}
.opt:has(input:checked) { background: var(--surface-2); color: var(--ink); }
.opt-label { flex: 1; }
.opt-n { font-family: var(--font-mono); font-size: 10px; color: var(--ink-faint); }

.rail-actions {
  position: sticky;
  top: 0;
  z-index: 2;
  display: flex;
  gap: 6px;
  padding: 4px 0 10px;
  margin-bottom: 12px;
  background: var(--ground);
  border-bottom: 1px solid var(--edge);
}
.rail-actions .btn { flex: 1; justify-content: center; }
.btn-apply {
  background: var(--surface);
  border-color: var(--edge);
  color: var(--ink-faint);
}
.btn-apply.is-dirty {
  background: var(--imprint);
  border-color: var(--imprint);
  color: #17120a;
  font-weight: 700;
}
.sheet .rail-actions { background: var(--surface); }

.facet-search {
  width: 100%;
  height: 34px;
  margin-bottom: 8px;
  padding: 0 11px;
  background: var(--ground);
  border: 1px solid var(--edge);
  border-radius: var(--radius);
  color: var(--ink);
  font: inherit;
  font-size: 13px;
  outline: none;
}
.facet-search:focus { border-color: var(--imprint); }
.facet-none { margin: 4px 2px 8px; font-size: 12.5px; color: var(--ink-faint); }

.taggroup { margin-bottom: 10px; }
.taggroup h4 {
  margin: 8px 0 4px;
  font-family: var(--font-mono);
  font-size: 9px;
  font-weight: 400;
  letter-spacing: .11em;
  text-transform: uppercase;
  color: var(--imprint);
  opacity: .75;
}

.facet-more {
  width: 100%;
  padding: 6px 7px;
  margin-top: 2px;
  border-radius: var(--radius);
  font-size: 12px;
  text-align: left;
  color: var(--ink-faint);
}
.facet-more:hover { color: var(--imprint); background: var(--surface); }

/* =========================== grid ========================================= */
/* Justified rows. Real aspect ratios are preserved because print size is the
   organising principle of this archive -- a 9x13 must not be squared off into
   looking like a 10x15. */
.grid { display: flex; flex-direction: column; gap: var(--gap); }
.row { display: flex; gap: var(--gap); }

.card {
  position: relative;
  container-type: inline-size;
  display: block;
  flex: 0 0 auto;
  padding: 0;
  border-radius: var(--radius);
  overflow: hidden;
  background-color: var(--bloom);
  background-size: cover;
  background-position: center;
  cursor: pointer;
  transform: translateZ(0);
  transition: transform .32s var(--ease), box-shadow .32s var(--ease);
  box-shadow: 0 1px 2px rgba(0,0,0,.5),
              0 14px 34px -16px color-mix(in srgb, var(--bloom) 70%, transparent);
}
.card img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0;
  transition: opacity .5s var(--ease);
}
.card img.loaded { opacity: 1; }
.card img.rotated {
  position: absolute;
  top: 50%;
  left: 50%;
  transform-origin: center;
  object-fit: cover;
}

@media (hover: hover) {
  .card:hover {
    transform: translateY(-3px);
    box-shadow: 0 2px 4px rgba(0,0,0,.55),
                0 26px 60px -18px color-mix(in srgb, var(--bloom) 95%, transparent);
  }
  .card:hover .card-meta { opacity: 1; }

  /* In edit mode the keyboard acts on whatever the cursor is over, so the card
     has to say plainly which one that is. A lift is too soft a signal when the
     next keystroke will turn the photo; drop it for a hard outline instead. */
  body.edit-mode .card:hover { transform: none; }
}

/* Driven by a class, not :hover, so it survives the relayout after a rotation.
   Outside the animation too -- a scaled outline would thin out mid-flight. */
body.edit-mode .card.is-hovered {
  transform: none;
  outline: 3px solid var(--hover-edge);
  outline-offset: -3px;
  box-shadow: 0 2px 4px rgba(0,0,0,.55),
              0 0 0 1px rgba(0,0,0,.6),
              0 18px 44px -16px color-mix(in srgb, var(--bloom) 80%, transparent);
}

.card-meta {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  display: flex;
  justify-content: space-between;
  gap: 8px;
  padding: 16px 9px 7px;
  /* No scrim -- the label carries its own shadow instead of dimming the photo. */
  opacity: 0;
  transition: opacity .2s;
  pointer-events: none;
  text-shadow: 0 1px 3px rgba(0,0,0,.95), 0 0 8px rgba(0,0,0,.7);
}

.badge-back {
  position: absolute;
  top: 7px; right: 7px;
  width: 20px; height: 20px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: rgba(10,9,8,.72);
  backdrop-filter: blur(4px);
  color: var(--imprint);
  font-family: var(--font-mono);
  font-size: 9px;
  font-weight: 700;
}

/* --- edit mode: correct a whole pile without opening each photo --------- */
.cardedit {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  z-index: 2;
  display: flex;
  align-items: center;
  /* Two children pushed apart: the arrow pair, then the colour marker. Absolute
     positioning let them overlap on narrow cards; this cannot. */
  justify-content: space-between;
  padding: 8px;
  /* No scrim: the buttons carry their own backdrop, and a gradient across the
     bottom of every card hid the part of the photo you are judging. */
}
.cardbtn {
  display: grid;
  place-items: center;
  width: 38px;
  height: 38px;
  padding: 0;
  border: 1px solid rgba(255,255,255,.34);
  border-radius: 50%;
  background: rgba(12,10,9,.72);
  color: var(--ink);
  backdrop-filter: blur(3px);
  transition: background .14s, border-color .14s, transform .14s;
}
.cardbtn:hover {
  background: rgba(12,10,9,.95);
  border-color: var(--imprint);
  color: var(--imprint);
  transform: translateY(-1px);
}
.cardbtn[disabled] { opacity: .5; }
.cardbtn svg { width: 22px; height: 22px; display: block; }
.cardedit-rot { display: flex; gap: 9px; }
.cardbtn-col { padding: 4px; }
.cardbtn-col svg { width: 24px; height: 24px; border-radius: 50%; }

/* Colour is shown as the thing itself: a full spectrum wheel. */
/* Small prints get small controls; a wallet-sized card is only ~126px wide and
   three full-size buttons simply do not fit. */
@container (max-width: 210px) {
  .cardbtn { width: 30px; height: 30px; }
  .cardbtn svg { width: 17px; height: 17px; }
  .cardbtn-col svg, .colorwheel { width: 19px; height: 19px; }
  .cardedit-rot { gap: 5px; }
  .cardedit { padding: 6px; }
}
@container (max-width: 150px) {
  .cardbtn { width: 25px; height: 25px; }
  .cardbtn svg { width: 14px; height: 14px; }
  .cardbtn-col svg, .colorwheel { width: 15px; height: 15px; }
  .cardedit-rot { gap: 3px; }
  .cardedit { padding: 4px; }
}

.colorwheel {
  display: block;
  width: 24px;
  height: 24px;
  border-radius: 50%;
  border: 1px solid rgba(255,255,255,.5);
  background: conic-gradient(#ff4d4d, #ffd24d, #6fe36f, #4dd2ff, #6a6aff, #e04dff, #ff4d4d);
}

/* On a phone the controls need to be reachable, not decorative. */
@media (max-width: 760px) {
  .cardbtn { width: 42px; height: 42px; }
  .cardbtn svg { width: 24px; height: 24px; }
  .cardedit-rot { gap: 11px; }
}

.card.is-sel { outline: 2px solid var(--imprint); outline-offset: -2px; }
/* A hidden photo stays in the owner's grid, dimmed and badged, so it can still
   be found and put back. Family members never receive it at all. */
.card.is-hidden-photo { opacity: .5; }
.card.is-hidden-photo:hover { opacity: .85; }
.badge-hidden {
  position: absolute;
  top: 7px; left: 7px;
  z-index: 3;
  display: grid;
  place-items: center;
  width: 24px; height: 24px;
  border-radius: 50%;
  background: var(--danger);
  color: #fff;
  box-shadow: 0 2px 6px rgba(0,0,0,.6);
}
.badge-hidden svg { width: 15px; height: 15px; display: block; }

.pager {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 10px;
  padding: 10px 2px;
}
#pager-bottom { padding-bottom: 40px; }
.pager-range {
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--ink-dim);
}
.pager-nav { display: flex; align-items: center; gap: 4px; flex-wrap: wrap; }
.pagebtn {
  min-width: 34px;
  height: 34px;
  padding: 0 9px;
  border: 1px solid var(--edge);
  border-radius: var(--radius);
  background: var(--surface);
  font-size: 13px;
  font-variant-numeric: tabular-nums;
}
.pagebtn:hover:not([disabled]) { border-color: var(--edge-bright); background: var(--surface-2); }
.pagebtn.is-current {
  background: var(--imprint);
  border-color: var(--imprint);
  color: #17120a;
  font-weight: 700;
}
.pagebtn[disabled] { opacity: .35; cursor: default; }
.pager-gap { color: var(--ink-faint); padding: 0 2px; }

@media (max-width: 560px) {
  .pager { justify-content: center; }
  .pager-range { width: 100%; text-align: center; }
  .pagebtn { min-width: 38px; height: 38px; }
}

.empty {
  padding: 90px 20px;
  text-align: center;
  color: var(--ink-faint);
}
.empty h2 {
  margin: 0 0 8px;
  font-family: var(--font-display);
  font-weight: 400;
  font-style: italic;
  font-size: 21px;
  color: var(--ink-dim);
}

/* =========================== lightbox ===================================== */
.lb {
  position: fixed;
  inset: 0;
  z-index: 100;
  display: none;
  background: var(--ground);
}
.lb.open { display: block; }

/* The ambient wash the archive is built around: a blurred, over-saturated copy
   of the photograph itself, so each image floods the screen with its own light.
   Two layers so navigation cross-fades instead of flickering. */
.ambient {
  position: absolute;
  inset: -12%;
  background-size: cover;
  background-position: center;
  filter: blur(70px) saturate(1.75);
  opacity: 0;
  transform: scale(1.12);
  transition: opacity .65s var(--ease);
  will-change: opacity;
}
.ambient.on { opacity: .52; }
.lb-vignette {
  position: absolute;
  inset: 0;
  background: radial-gradient(ellipse at 50% 45%,
              transparent 30%, rgba(6,5,5,.55) 78%, rgba(6,5,5,.88) 100%);
  pointer-events: none;
}

.lb-stage {
  position: absolute;
  inset: 0;
  cursor: grab;
  display: grid;
  place-items: center;
  padding: var(--lb-top) 14px var(--lb-bottom);
  touch-action: none;
}

/* the flip: turning the print over to read the back */
.flipper {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  transform-style: preserve-3d;
  transition: transform .72s var(--ease);
  max-width: 100%;
}
/* Pan, zoom and the flip are composed into one transform on .flipper by JS.
   Precedence matters: the long ease is the flip; button-driven zoom gets a short
   ease; a live gesture gets none at all, or each wheel tick animates against the
   next and the zoom stutters. */
.lb.zoomed .flipper { transition: transform .2s var(--ease); }
.lb.dragging .flipper { transition: none; }
.lb.zoomed .flipper, .lb.dragging .flipper { will-change: transform; }

.face {
  display: block;
  width: auto;
  height: auto;
  max-width: 100%;
  /* Percentages would resolve against an auto-height parent and be ignored. */
  max-height: calc(100vh - var(--lb-top) - var(--lb-bottom));
  max-height: calc(100dvh - var(--lb-top) - var(--lb-bottom));
  object-fit: contain;
  backface-visibility: hidden;
  -webkit-user-drag: none;
  user-select: none;
  transform-origin: center center;
  border-radius: 2px;
  box-shadow: 0 30px 80px -24px rgba(0,0,0,.9), 0 0 0 1px rgba(255,255,255,.05);
  transition: transform .2s var(--ease);
}
/* A quarter-turned element keeps its original layout box, so the height limit
   has to become the width limit or the picture paints outside the stage and looks
   misaligned once you zoom. */
.face.rot90 {
  max-width: calc(100vh - var(--lb-top) - var(--lb-bottom));
  max-width: calc(100dvh - var(--lb-top) - var(--lb-bottom));
  max-height: calc(100vw - 28px);
}
.lb.zoomed .lb-stage { cursor: grab; }
.lb.zoomed.dragging .lb-stage { cursor: grabbing; }
.face-back {
  position: absolute;
  inset: 0;
  margin: auto;
  transform: rotateY(180deg);
}

.lb-top {
  position: absolute;
  top: 0; left: 0; right: 0;
  z-index: 3;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 14px;
  background: linear-gradient(rgba(6,5,5,.72), transparent);
}
.lb-title { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.lb-counter {
  flex: 0 0 auto;
  padding: 5px 11px;
  border: 1px solid var(--edge-bright);
  border-radius: 99px;
  background: rgba(10,9,8,.7);
  font-family: var(--font-mono);
  font-size: 12px;
  letter-spacing: .04em;
  color: var(--ink);
}
.lb-size {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 15px;
  letter-spacing: .01em;
}

.lb-bottom {
  position: absolute;
  bottom: 0; left: 0; right: 0;
  z-index: 3;
  padding: 22px 14px 14px;
  background: linear-gradient(transparent, rgba(6,5,5,.8));
}
.lb-controls {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
  gap: 8px;
}

.nav-arrow {
  position: absolute;
  top: 50%;
  z-index: 3;
  width: 46px; height: 46px;
  margin-top: -23px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: rgba(10,9,8,.5);
  backdrop-filter: blur(6px);
  border: 1px solid var(--edge);
  font-size: 17px;
  transition: background .15s;
}
.nav-arrow:hover { background: rgba(10,9,8,.85); }
.nav-prev { left: 12px; }
.nav-next { right: 12px; }
@media (max-width: 760px) { .nav-arrow { display: none; } }

/* tags */
.end-panel {
  position: absolute;
  inset: 0;
  z-index: 6;
  display: grid;
  place-items: center;
  padding: 20px;
  background: rgba(6,5,5,.7);
}
.end-card {
  width: 100%;
  max-width: 340px;
  padding: 22px 20px 16px;
  text-align: center;
  background: var(--surface);
  border: 1px solid var(--edge-bright);
  border-radius: 10px;
  box-shadow: 0 30px 70px -20px rgba(0,0,0,.85);
}
.end-card h2 {
  margin: 0 0 6px;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 21px;
}
.end-card p { margin: 0 0 18px; font-size: 13.5px; color: var(--ink-dim); }
.end-actions { display: flex; flex-direction: column; gap: 8px; }
.end-actions .btn { justify-content: center; height: 40px; }
.end-dismiss {
  margin-top: 12px;
  font-size: 12.5px;
  color: var(--ink-faint);
}
.end-dismiss:hover { color: var(--imprint); }

.pin-box {
  position: fixed;
  z-index: 120;
  transform: translate(-50%, -130%);
}
.pin-box::after {
  content: '';
  position: absolute;
  left: 50%; bottom: -5px;
  width: 9px; height: 9px;
  margin-left: -4px;
  background: var(--surface-2);
  border-right: 1px solid var(--imprint);
  border-bottom: 1px solid var(--imprint);
  transform: rotate(45deg);
}
.pin-input {
  width: 190px;
  height: 36px;
  padding: 0 11px;
  background: var(--surface-2);
  border: 1px solid var(--imprint);
  border-radius: var(--radius);
  color: var(--ink);
  font: inherit;
  font-size: 14px;
  outline: none;
  box-shadow: 0 10px 26px -8px rgba(0,0,0,.8);
}

.modal-backdrop {
  position: fixed;
  inset: 0;
  z-index: 150;
  display: grid;
  place-items: center;
  padding: 16px;
  background: rgba(6,5,5,.45);
}
.modal {
  width: 100%;
  max-width: 370px;
  max-height: 88vh;
  max-height: 88dvh;
  overflow-y: auto;
  padding: 14px 16px;
  background: var(--surface);
  border: 1px solid var(--edge-bright);
  border-radius: 10px;
  box-shadow: 0 30px 70px -20px rgba(0,0,0,.85);
}
.modal h2 {
  margin: 0 0 10px;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 17px;
}
.fieldset { margin-bottom: 10px; }
.fieldset > h3 {
  margin: 0 0 4px;
  font-family: var(--font-mono);
  font-size: 10px;
  font-weight: 400;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--ink-faint);
}
.tagfield {
  display: block;
  width: 100%;
  height: 34px;                    /* mobile gets 44px back, further down */
  margin-bottom: 4px;
  padding: 0 10px;
  background: var(--ground);
  border: 1px solid var(--edge);
  border-radius: var(--radius);
  color: var(--ink);
  font: inherit;
  font-size: 14px;
  outline: none;
}
.tagfield:focus { border-color: var(--imprint); }
.addrow {
  padding: 3px 2px;
  font-size: 12px;
  color: var(--ink-faint);
}
.addrow:hover { color: var(--imprint); }
.modal-actions {
  position: sticky;
  bottom: -14px;
  display: flex;
  gap: 8px;
  padding: 10px 0 0;
  margin-top: 2px;
  background: var(--surface);
  border-top: 1px solid var(--edge);
}
.modal-actions .btn { flex: 1; justify-content: center; height: 36px; }
.modal-actions .btn-ok {
  background: var(--imprint);
  border-color: var(--imprint);
  color: #17120a;
  font-weight: 700;
}
.modal-actions .btn-ok:hover { background: #ffb955; border-color: #ffb955; }

@media (max-width: 560px) {
  .end-panel {
  position: absolute;
  inset: 0;
  z-index: 6;
  display: grid;
  place-items: center;
  padding: 20px;
  background: rgba(6,5,5,.7);
}
.end-card {
  width: 100%;
  max-width: 340px;
  padding: 22px 20px 16px;
  text-align: center;
  background: var(--surface);
  border: 1px solid var(--edge-bright);
  border-radius: 10px;
  box-shadow: 0 30px 70px -20px rgba(0,0,0,.85);
}
.end-card h2 {
  margin: 0 0 6px;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 21px;
}
.end-card p { margin: 0 0 18px; font-size: 13.5px; color: var(--ink-dim); }
.end-actions { display: flex; flex-direction: column; gap: 8px; }
.end-actions .btn { justify-content: center; height: 40px; }
.end-dismiss {
  margin-top: 12px;
  font-size: 12.5px;
  color: var(--ink-faint);
}
.end-dismiss:hover { color: var(--imprint); }

.pin-box {
  position: fixed;
  z-index: 120;
  transform: translate(-50%, -130%);
}
.pin-box::after {
  content: '';
  position: absolute;
  left: 50%; bottom: -5px;
  width: 9px; height: 9px;
  margin-left: -4px;
  background: var(--surface-2);
  border-right: 1px solid var(--imprint);
  border-bottom: 1px solid var(--imprint);
  transform: rotate(45deg);
}
.pin-input {
  width: 190px;
  height: 36px;
  padding: 0 11px;
  background: var(--surface-2);
  border: 1px solid var(--imprint);
  border-radius: var(--radius);
  color: var(--ink);
  font: inherit;
  font-size: 14px;
  outline: none;
  box-shadow: 0 10px 26px -8px rgba(0,0,0,.8);
}

.modal-backdrop { place-items: end center; padding: 0; }
  .modal {
    max-width: none;
    max-height: 92dvh;
    border-radius: 14px 14px 0 0;
    border-bottom: none;
  }
}

/* Show back earns color: 470 prints have writing on the reverse and it is the
   single most rewarding thing in the archive to discover. */
.btn-back-present {
  border-color: var(--imprint);
  color: var(--imprint);
  background: color-mix(in srgb, var(--imprint) 14%, transparent);
}
.btn-back-present:hover {
  background: color-mix(in srgb, var(--imprint) 26%, transparent);
  border-color: var(--imprint);
}
.btn-back-present[aria-pressed="true"] {
  background: var(--imprint);
  border-color: var(--imprint);
  color: #17120a;
  font-weight: 700;
}

/* Holds the front face and its pin layer together. It is one side of the 3D
   flip, so it keeps backface-visibility; pan and zoom live on .flipper. */
.facewrap {
  position: relative;
  display: block;
  max-width: 100%;
  backface-visibility: hidden;
}

/* --- pinned tags on the picture ---------------------------------------- */
.pinlayer {
  position: absolute;
  inset: 0;
  pointer-events: none;
  overflow: hidden;
}
.pin {
  position: absolute;
  transform: translate(-50%, -100%);
  pointer-events: auto;
  cursor: pointer;
  display: none;
  filter: drop-shadow(0 2px 4px rgba(0,0,0,.7));
}
.pins-on .pin { display: block; }
.pin-dot {
  width: 17px;
  height: 17px;
  border: 2px solid #17120a;
  border-radius: 50% 50% 50% 0;
  transform: rotate(-45deg);
  background: var(--imprint);
}
.pin-person .pin-dot { background: #6fd08c; }
.pin-place .pin-dot { background: #6bb6ff; }
.pin-label {
  position: absolute;
  left: 50%;
  bottom: 22px;
  transform: translateX(-50%);
  padding: 3px 8px;
  border-radius: 4px;
  background: rgba(10,9,8,.92);
  border: 1px solid var(--edge-bright);
  color: var(--ink);
  font-size: 12px;
  white-space: nowrap;
  opacity: 0;
  transition: opacity .14s;
  pointer-events: none;
}
.pin:hover .pin-label, .pin:focus-visible .pin-label { opacity: 1; }

.lb.tagging .lb-stage { cursor: crosshair; }
.lb.tagging .face { cursor: crosshair; }
.tag-hint {
  position: absolute;
  top: 64px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 4;
  padding: 6px 14px;
  border-radius: 99px;
  background: var(--imprint);
  color: #17120a;
  font-size: 12.5px;
  font-weight: 700;
}

/* --- autocomplete ------------------------------------------------------- */
.ac-wrap { position: relative; }
.ac-list {
  position: absolute;
  left: 0; right: 0; top: calc(100% - 4px);
  z-index: 5;
  max-height: 190px;
  overflow-y: auto;
  background: var(--surface-2);
  border: 1px solid var(--edge-bright);
  border-radius: var(--radius);
  box-shadow: 0 12px 28px -8px rgba(0,0,0,.7);
}
.ac-item {
  display: flex;
  justify-content: space-between;
  gap: 10px;
  width: 100%;
  padding: 9px 12px;
  text-align: left;
  font-size: 14px;
  background: none;
}
.ac-item:hover, .ac-item.is-active { background: var(--surface); color: var(--imprint); }
.ac-item .ac-n { font-family: var(--font-mono); font-size: 10px; color: var(--ink-faint); }

/* --- draggable dialog --------------------------------------------------- */
.modal-head {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: -14px -16px 10px;
  padding: 9px 16px;
  border-bottom: 1px solid var(--edge);
}
.modal-head h2 { margin: 0; flex: 1; }
@media (min-width: 561px) {
  .modal-head { cursor: grab; user-select: none; }
  .modal-head:active { cursor: grabbing; }
  .modal-backdrop.dragged { place-items: start; }
  .modal-backdrop.free { background: rgba(6,5,5,.35); pointer-events: none; }
  .modal-backdrop.free .modal { pointer-events: auto; }
}
.drag-hint {
  font-family: var(--font-mono);
  font-size: 9px;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--ink-faint);
}
@media (max-width: 560px) { .drag-hint { display: none; } }

.zoomgroup {
  display: inline-flex;
  align-items: center;
  border: 1px solid var(--edge);
  border-radius: var(--radius);
  background: var(--surface);
  overflow: hidden;
}
.zoomgroup .btn {
  border: none;
  border-radius: 0;
  background: none;
  padding: 0 11px;
  font-size: 15px;
  line-height: 1;
}
.zoomgroup .btn:hover { background: var(--surface-2); }
.zoom-level {
  min-width: 52px;
  padding: 0 4px;
  font-family: var(--font-mono);
  font-size: 11px;
  text-align: center;
  color: var(--ink-dim);
  border-left: 1px solid var(--edge);
  border-right: 1px solid var(--edge);
  height: 34px;
  line-height: 34px;
}
.zoom-level:hover { color: var(--imprint); }

/* --- tagging ---------------------------------------------------------- */
.backrow {
  display: flex;
  justify-content: center;
  margin-bottom: 10px;
}
.backrow .btn { height: 34px; padding: 0 18px; }
.backrow .btn[hidden] { display: none; }

.tagbar { display: flex; flex-direction: column; align-items: center; gap: 8px; margin-bottom: 12px; }

.taglist {
  display: flex;
  flex-wrap: nowrap;              /* one row, as asked; it scrolls if it overflows */
  align-items: center;
  gap: 6px;
  max-width: 100%;
  overflow-x: auto;
  scrollbar-width: none;
  padding-bottom: 2px;
}
.taglist::-webkit-scrollbar { display: none; }
.chip, .btn-addtag { flex: 0 0 auto; }
.btn-addtag {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  height: 30px;
  padding: 0 12px;
  border: 1px dashed var(--edge-bright);
  border-radius: 99px;
  background: rgba(10,9,8,.6);
  font-size: 12px;
  color: var(--ink-dim);
}
.btn-addtag:hover { border-style: solid; border-color: var(--imprint); color: var(--imprint); }
.chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px 9px;
  border: 1px solid var(--edge-bright);
  border-radius: 99px;
  background: rgba(10,9,8,.6);
  font-size: 12px;
}
.chip-x { color: var(--ink-faint); font-size: 13px; line-height: 1; }
.chip-x:hover { color: var(--danger); }
.chip-cat-person { border-color: color-mix(in srgb, var(--imprint) 55%, var(--edge)); }

/* The controls stay put while zoomed -- you need them most when you are in
   close on a face and want to flip, tag, or zoom back out. */
.lb-top, .lb-bottom, .nav-arrow { transition: opacity .25s; }

/* =========================== sheet (mobile filters) ======================= */
.sheet-backdrop {
  position: fixed; inset: 0; z-index: 60;
  background: rgba(6,5,5,.7);
  backdrop-filter: blur(3px);
  opacity: 0; pointer-events: none;
  transition: opacity .25s;
}
.sheet-backdrop.open { opacity: 1; pointer-events: auto; }

.sheet {
  position: fixed;
  left: 0; right: 0; bottom: 0;
  z-index: 61;
  max-height: 82vh;
  overflow-y: auto;
  padding: 8px 16px 30px;
  background: var(--surface);
  border-top: 1px solid var(--edge-bright);
  border-radius: 14px 14px 0 0;
  transform: translateY(101%);
  transition: transform .32s var(--ease);
}
.sheet.open { transform: translateY(0); }
.sheet-grab {
  width: 34px; height: 4px;
  margin: 6px auto 14px;
  border-radius: 99px;
  background: var(--edge-bright);
}

/* =========================== auth pages =================================== */
.auth-wrap {
  min-height: 100vh;
  display: grid;
  place-items: center;
  padding: 24px;
}
.auth-card {
  width: 100%;
  max-width: 350px;
  padding: 30px 26px 26px;
  background: var(--surface);
  border: 1px solid var(--edge);
  border-radius: 6px;
}
.auth-card h1 {
  margin: 0 0 4px;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 22px;
  letter-spacing: .01em;
}
.auth-sub { margin: 0 0 22px; font-size: 13px; color: var(--ink-dim); }
.field { margin-bottom: 13px; }
.field label {
  display: block;
  margin-bottom: 5px;
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--ink-faint);
}
.field input {
  width: 100%;
  height: 40px;
  padding: 0 12px;
  background: var(--ground);
  border: 1px solid var(--edge);
  border-radius: var(--radius);
  color: var(--ink);
  font: inherit;
  font-size: 14px;
  outline: none;
}
.field input:focus { border-color: var(--imprint); }
.btn-primary {
  width: 100%;
  height: 42px;
  margin-top: 8px;
  justify-content: center;
  background: var(--ink);
  border-color: var(--ink);
  color: var(--ground);
  font-weight: 700;
}
.btn-primary:hover { background: #fff; border-color: #fff; }
.alert {
  padding: 9px 11px;
  margin-bottom: 14px;
  border: 1px solid color-mix(in srgb, var(--danger) 50%, transparent);
  border-radius: var(--radius);
  background: color-mix(in srgb, var(--danger) 12%, transparent);
  font-size: 12.5px;
  color: #f0b5a8;
}

/* =========================== toast ======================================== */
.toast {
  position: fixed;
  left: 50%; bottom: 26px;
  z-index: 200;
  padding: 9px 16px;
  border: 1px solid var(--edge-bright);
  border-radius: 99px;
  background: var(--surface-2);
  font-size: 13px;
  transform: translate(-50%, 20px);
  opacity: 0;
  pointer-events: none;
  transition: opacity .25s, transform .25s var(--ease);
}
.toast.show { opacity: 1; transform: translate(-50%, 0); }

/* =========================== admin pages ================================== */
.page { max-width: 1100px; margin: 0 auto; padding: 26px 18px 70px; }
.page h1 {
  margin: 0 0 6px;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 25px;
  letter-spacing: .01em;
}
.page p.lede { margin: 0 0 26px; color: var(--ink-dim); font-size: 14px; max-width: 62ch; }

.cluster {
  display: flex;
  gap: 12px;
  flex-wrap: wrap;
  align-items: flex-start;
  padding: 14px;
  margin-bottom: 12px;
  background: var(--surface);
  border: 1px solid var(--edge);
  border-radius: 5px;
}
.cluster img { height: 132px; border-radius: 2px; display: block; }
.cluster figure { margin: 0; }
.cluster figcaption { margin-top: 6px; }

.table { width: 100%; border-collapse: collapse; font-size: 13px; }
.table th, .table td {
  padding: 9px 10px;
  text-align: left;
  border-bottom: 1px solid var(--edge);
}
.table th {
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--ink-faint);
  font-weight: 400;
}

/* =========================== responsive =================================== */
@media (max-width: 1023px) {
  /* On a phone the bar keeps only what a family member needs: where they are,
     how much is here, and the way in to filters. Everything else moves into the
     sheet, where it has room to be legible. */
  .rail { display: none; }
  .bar-tools { display: none; }
  .sheet-head { display: block; margin-bottom: 18px; }
  .sheet-head .search { flex-basis: auto; width: 100%; height: 40px; }
  #btn-filter { margin-left: auto; }

  /* Filter rows are checkboxes on a touch screen, so give them a real target.
     The desktop rail can stay compact; a thumb cannot. */
  .sheet .opt {
    min-height: 44px;
    padding: 8px 8px;
    font-size: 14.5px;
  }
  .sheet .opt input[type="checkbox"] { width: 20px; height: 20px; }
  .sheet .facet-search { height: 42px; font-size: 15px; }
  .sheet .facet h3 { margin-top: 14px; }
  .sheet .facet-more { min-height: 40px; font-size: 13.5px; }

  /* The dialog is compact on desktop; a thumb still needs room. */
  .modal .tagfield { height: 44px; font-size: 15px; margin-bottom: 6px; }
  .modal-actions .btn { height: 44px; }
  .pin-input { height: 44px; font-size: 15px; }
}
@media (max-width: 760px) {
  :root { --lb-bottom: 150px; }
}
@media (min-width: 1024px) {
  .sheet, .sheet-backdrop, #btn-filter { display: none; }
  :root { --gap: 12px; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important;
    transition-duration: .01ms !important;
  }
}
