/* Ad log home — magazine dispatch layout. Palette lives in tokens.css. */
@import url("tokens.css");
@import url("motion.css");

* { box-sizing: border-box; }

html {
  scroll-behavior: smooth;
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
}

body {
  margin: 0 auto;
  max-width: 1180px;
  padding: 20px 18px 72px;
  background:
    radial-gradient(1200px 500px at 10% -10%, rgba(154, 123, 79, 0.12), transparent 55%),
    radial-gradient(900px 420px at 100% 0%, rgba(40, 30, 20, 0.06), transparent 50%),
    var(--paper);
  color: var(--ink);
}

h1, h2 { font-family: var(--font-display); font-weight: 650; letter-spacing: -0.02em; }
h2 { font-size: 1.15rem; margin: 0 0 8px; }
.lede { color: var(--ink-soft); margin: 0; line-height: 1.45; }
.hint { font-size: 0.88rem; color: var(--ink-soft); }
a { color: #7a5530; }
code { font-size: 0.86em; }

/* —— Magazine hero —— */
#dispatch-hero {
  display: grid;
  grid-template-columns: minmax(0, 1.05fr) minmax(0, 0.95fr);
  gap: 28px;
  align-items: stretch;
  min-height: min(78vh, 720px);
  margin-bottom: 28px;
  animation: hero-in var(--dur-hero) var(--ease-out-expo) both;
}

@keyframes hero-in {
  from { opacity: 0; transform: translateY(14px); }
  to { opacity: 1; transform: none; }
}

.spread {
  position: relative;
  border-radius: 6px;
  overflow: hidden;
  isolation: isolate;
  min-height: 470px;
  background:
    radial-gradient(ellipse 80% 55% at 18% 12%, rgba(255, 248, 235, 0.55), transparent 55%),
    radial-gradient(ellipse 70% 50% at 88% 78%, rgba(90, 70, 40, 0.12), transparent 50%),
    linear-gradient(155deg, #ebe3d6 0%, #d8cebd 42%, #c9beab 100%);
  box-shadow:
    inset 0 0 0 1px rgba(255, 255, 255, 0.4),
    inset 0 -24px 40px rgba(28, 23, 18, 0.06),
    0 18px 40px rgba(28, 23, 18, 0.08);
}

/* Paper grain */
.spread::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  opacity: 0.28;
  background-image: var(--grain);
  mix-blend-mode: multiply;
}

/* Soft vignette + torn-edge feel via mask */
.spread::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 2;
  pointer-events: none;
  background:
    linear-gradient(180deg, rgba(255, 255, 255, 0.18), transparent 22%),
    linear-gradient(0deg, rgba(28, 23, 18, 0.1), transparent 28%),
    radial-gradient(circle at 50% 50%, transparent 55%, rgba(28, 23, 18, 0.08) 100%);
  box-shadow: inset 0 0 0 10px rgba(243, 238, 230, 0.35);
  opacity: 1;
}

/* Card height is derived from its width (fixed film proportions), while the
   slot offsets in JS are percentages of this box. Pinning the board to one
   aspect ratio keeps those two in agreement at any viewport height — otherwise
   a short window pushes the lower cards past the bottom edge. */
.spread-board {
  position: absolute;
  left: 4%;
  right: 4%;
  top: 50%;
  transform: translateY(-50%);
  aspect-ratio: 1 / 0.92;
  z-index: 3;
}

/* —— Polaroid cards ——
   Proportions follow real instant film: an 88 x 107 card with a square window
   and a deep bottom chin, which is where the caption is printed. Position, size
   and entrance offsets arrive as custom properties from the layout table in JS. */
.tile {
  --w: 44%;
  --x: 0%;
  --y: 0%;
  --tilt: 0deg;
  --from-x: 0px;
  --from-y: 26px;
  --from-rot: 0deg;
  --z: 1;
  position: absolute;
  left: var(--x);
  top: var(--y);
  width: var(--w);
  aspect-ratio: 88 / 107;
  z-index: var(--z);
  container-type: inline-size;
  /* Real cards are buttons, so the form's button padding has to be cleared. */
  padding: 0;
  border-radius: 3px;
  background:
    linear-gradient(178deg, #fffdf9 0%, #fbf7f0 62%, #f2ece1 100%);
  box-shadow:
    0 0 0 1px rgba(28, 23, 18, 0.08),
    0 1px 0 rgba(255, 255, 255, 0.9) inset,
    0 14px 30px rgba(28, 23, 18, 0.16),
    0 2px 6px rgba(28, 23, 18, 0.1);
  transform: rotate(var(--tilt));
  transition:
    transform var(--dur-med) var(--ease-out-soft),
    box-shadow var(--dur-med) var(--ease-out-soft);
  animation: polaroid-eject 0.95s var(--ease-out-expo) both;
  will-change: transform;
}

.tile:nth-child(1) { animation-delay: 0.05s; }
.tile:nth-child(2) { animation-delay: 0.15s; }
.tile:nth-child(3) { animation-delay: 0.25s; }
.tile:nth-child(4) { animation-delay: 0.35s; }
.tile:nth-child(5) { animation-delay: 0.45s; }
.tile:nth-child(6) { animation-delay: 0.55s; }

/* Static HTML seeds: hold still until the first real board paint from JS. */
.tile.is-seed {
  animation: none;
  opacity: 1;
}

/* Stage one: the card is pushed out of the camera and settles into the pile. */
@keyframes polaroid-eject {
  from {
    opacity: 0;
    transform:
      translate(var(--from-x), var(--from-y))
      scale(0.9)
      rotate(var(--from-rot));
  }
  60% { opacity: 1; }
  to {
    opacity: 1;
    transform: rotate(var(--tilt));
  }
}

.tile.is-clickable { cursor: zoom-in; }

.tile:hover,
.tile.is-clickable:focus-visible {
  z-index: 9;
  will-change: auto;
  transform: translateY(-10px) scale(1.045) rotate(0deg);
  box-shadow:
    0 0 0 1px rgba(28, 23, 18, 0.1),
    0 1px 0 rgba(255, 255, 255, 0.95) inset,
    0 26px 46px rgba(28, 23, 18, 0.26);
}

.tile.is-clickable:focus-visible {
  outline: 2px solid var(--bronze);
  outline-offset: 3px;
}

/* The print itself: square window, recessed slightly into the paper.
   Placed with absolute offsets rather than padding on the card, because a
   percentage padding resolves against the PARENT's width — which distorted the
   frame differently on the board and in the filmstrip. These percentages are
   Polaroid 600 geometry: an 88 x 107 card carrying a 79 x 79 print, with 4.5
   of border on three sides and 23.5 at the bottom. */
.tile-window {
  position: absolute;
  left: 5.11%;
  top: 4.21%;
  width: 89.77%;
  height: 73.83%;
  overflow: hidden;
  background: #e7e0d3;
  box-shadow:
    0 0 0 1px rgba(28, 23, 18, 0.1),
    0 1px 3px rgba(28, 23, 18, 0.16) inset;
}

.tile-media {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* Stage two: develop. The emulsion starts milky and low-contrast, then the
   image comes up. Timing is driven by the real media load, not a guess. */
.tile.has-media .tile-media {
  opacity: 0;
  filter: saturate(0.08) contrast(0.55) brightness(1.35) sepia(0.32);
  transform: scale(1.04);
  transition:
    opacity 0.5s var(--ease-out-soft),
    filter var(--dur-develop) var(--ease-develop) 0.15s,
    transform 1.2s var(--ease-out-expo);
}

.tile.has-media.is-ready .tile-media {
  opacity: 1;
  filter: none;
  transform: scale(1);
}

/* Milky chemical wash over the print while it develops. */
.tile-window::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 2;
  pointer-events: none;
  opacity: 0;
  background:
    radial-gradient(ellipse 120% 90% at 50% 40%, rgba(255, 253, 247, 0.95), rgba(233, 226, 213, 0.9));
  transition: opacity 1.3s var(--ease-develop);
}

.tile.has-media .tile-window::after,
.film-card .tile-window::after { opacity: 1; }
.tile.has-media.is-ready .tile-window::after,
.film-card.is-ready .tile-window::after { opacity: 0; }

.tile .ph,
.film-card .ph {
  position: absolute;
  inset: 0;
  z-index: 1;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  gap: 4cqw;
  padding: 7cqw;
  font-family: var(--font-display);
  font-size: 8.2cqw;
  line-height: 1.22;
  color: var(--ink-soft);
  transition: opacity 0.4s ease;
  background:
    repeating-linear-gradient(
      -14deg,
      transparent,
      transparent 9px,
      rgba(154, 123, 79, 0.06) 9px,
      rgba(154, 123, 79, 0.06) 10px
    ),
    linear-gradient(145deg, #f4eee4, #e2d7c6);
}

.tile.has-media.is-ready .ph,
.film-card.is-ready .ph {
  opacity: 0;
  pointer-events: none;
}

.tile .ph-mark,
.film-card .ph-mark {
  width: 16cqw;
  height: 16cqw;
  margin-bottom: auto;
  opacity: 0.4;
  background: currentColor;
  mask: no-repeat center / contain;
  -webkit-mask: no-repeat center / contain;
  mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='black' stroke-width='1.7' viewBox='0 0 24 24'%3E%3Crect x='4' y='5' width='16' height='14' rx='1.5'/%3E%3Ccircle cx='9' cy='10' r='1.4'/%3E%3Cpath d='M5.5 17l4.2-4.2a1.2 1.2 0 011.7 0L20 17'/%3E%3C/svg%3E");
  -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='black' stroke-width='1.7' viewBox='0 0 24 24'%3E%3Crect x='4' y='5' width='16' height='14' rx='1.5'/%3E%3Ccircle cx='9' cy='10' r='1.4'/%3E%3Cpath d='M5.5 17l4.2-4.2a1.2 1.2 0 011.7 0L20 17'/%3E%3C/svg%3E");
}

/* Caption printed on the chin: advertiser, then when it was logged. */
/* The wide bottom border of the frame, where a photographer would write. Pinned
   below the window rather than sized by height, so the caption never rides up
   over the print. */
.tile-chin {
  position: absolute;
  left: 6.5%;
  right: 6.5%;
  top: 79.5%;
  bottom: 3.5%;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 1cqw;
  overflow: hidden;
  font-family: var(--font-display);
  color: rgba(28, 23, 18, 0.72);
}

.tile-chin b {
  display: block;
  overflow: hidden;
  font-size: 9.8cqw;
  font-weight: 650;
  font-style: italic;
  line-height: 1.1;
  white-space: nowrap;
  text-overflow: ellipsis;
}

.tile-chin span {
  font-family: var(--font-body);
  font-size: 7.2cqw;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: rgba(28, 23, 18, 0.45);
}

.tile.is-video .tile-window::before {
  content: "";
  position: absolute;
  z-index: 3;
  width: 22cqw;
  height: 22cqw;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  border-radius: 50%;
  opacity: 0;
  background: rgba(250, 247, 242, 0.92);
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.2);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%231c1712'%3E%3Cpath d='M9 7.5v9l8-4.5-8-4.5z'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: 56% 50%;
  background-size: 55%;
  transition: opacity 0.4s ease 0.5s;
  pointer-events: none;
}

.tile.is-video.is-ready .tile-window::before { opacity: 1; }

/* A capture you just sent flies onto the board instead of appearing silently. */
.tile.just-landed {
  animation: polaroid-land 1.15s var(--ease-spring) both;
}

@keyframes polaroid-land {
  0% {
    opacity: 0;
    transform: translate(-14%, 46%) scale(1.3) rotate(-12deg);
  }
  55% { opacity: 1; }
  100% {
    opacity: 1;
    transform: rotate(var(--tilt));
  }
}

.spread-caption {
  position: absolute;
  left: 14px;
  bottom: 12px;
  z-index: 4;
  font-size: 0.72rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: rgba(28, 23, 18, 0.55);
}

/* Same paper stock as the polaroids, but deliberately upright and rectangular:
   this is the working form, so no tilt on anything you have to tap or type in. */
.dispatch {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 14px;
  padding: 30px 26px 22px;
  animation: hero-in var(--dur-hero) var(--ease-out-expo) 0.1s both;
  background:
    linear-gradient(178deg, #fffdf9 0%, var(--panel) 55%, #f4efe5 100%);
  border: 1px solid var(--bronze-line);
  border-radius: 4px;
  box-shadow:
    0 1px 0 rgba(255, 255, 255, 0.9) inset,
    0 18px 40px rgba(28, 23, 18, 0.09);
}

.dispatch::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  pointer-events: none;
  opacity: 0.16;
  background-image: var(--grain);
  mix-blend-mode: multiply;
}

/* Strip of tape holding the form to the page. */
.dispatch::after {
  content: "";
  position: absolute;
  top: -11px;
  left: 50%;
  width: 118px;
  height: 24px;
  transform: translateX(-50%) rotate(-1.4deg);
  pointer-events: none;
  background: linear-gradient(100deg, rgba(233, 224, 205, 0.75), rgba(214, 201, 176, 0.62));
  box-shadow: 0 1px 3px rgba(28, 23, 18, 0.12);
}

.dispatch > * { position: relative; z-index: 1; }

.dispatch-top {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 12px;
}

.dispatch-brand {
  margin: 0 0 4px;
  font-size: 0.72rem;
  font-weight: 650;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--bronze);
}

.dispatch h1 {
  margin: 0;
  font-size: clamp(1.55rem, 2.4vw, 2.05rem);
  line-height: 1.12;
  max-width: 16ch;
}

.month-chip {
  flex: 0 0 auto;
  margin-top: 4px;
  padding: 6px 10px;
  border: 1px solid var(--bronze-line);
  border-radius: 6px;
  font-size: 0.7rem;
  font-weight: 650;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-soft);
  white-space: nowrap;
}

#drop {
  border: 1px solid var(--bronze-line);
  border-radius: 14px;
  padding: 28px 18px;
  text-align: center;
  background: var(--panel-well);
  cursor: pointer;
  transition:
    background var(--dur-ui) var(--ease-out-soft),
    border-color var(--dur-ui) var(--ease-out-soft),
    transform var(--dur-ui) var(--ease-out-soft),
    box-shadow var(--dur-ui) var(--ease-out-soft);
}

#drop.hot {
  background: #e7dccb;
  border-color: var(--bronze);
  transform: scale(1.015);
  box-shadow: 0 0 0 4px rgba(154, 123, 79, 0.15);
}

#drop strong {
  display: block;
  font-family: var(--font-display);
  font-size: 1.05rem;
  margin-bottom: 6px;
}

.drop-icons {
  display: flex;
  justify-content: center;
  align-items: center;
  gap: 14px;
  margin-bottom: 10px;
}

.drop-icon {
  width: 32px;
  height: 32px;
  object-fit: contain;
  display: block;
  opacity: 0.78;
}

textarea,
button,
input[type=file],
input[type=email],
input[type=password] { font: inherit; }

.login-card {
  max-width: 28rem;
  margin: 8vh auto;
}
.login-card h1 { margin: 0 0 8px; }
.login-card label { display: block; margin-top: 14px; }
.login-card input[type="email"],
.login-card input[type="password"] {
  width: 100%;
  display: block;
  margin-top: 6px;
  border: 1px solid rgba(28, 23, 18, 0.14);
  border-radius: 10px;
  padding: 10px 12px;
  background: #fff;
  color: var(--ink);
  transition:
    border-color var(--dur-fast) var(--ease-out-soft),
    box-shadow var(--dur-fast) var(--ease-out-soft);
}
.login-card input[type="email"]:focus-visible,
.login-card input[type="password"]:focus-visible {
  border-color: var(--bronze);
  box-shadow: 0 0 0 3px rgba(154, 123, 79, 0.18);
  outline: none;
}
.login-card .actions { margin-top: 16px; }
.login-card button.linkish {
  width: auto;
  margin-top: 10px;
  padding: 0;
  background: transparent;
  color: #7a5530;
  text-transform: none;
  letter-spacing: 0;
  font-weight: 600;
  font-size: 0.88rem;
  transition: color var(--dur-fast) ease, opacity var(--dur-fast) ease;
}
.login-card button.linkish:hover { color: var(--ink); }
.login-card .split {
  margin-top: 18px;
  padding-top: 4px;
  border-top: 1px solid rgba(28, 23, 18, 0.08);
}

/* Sign-in / set-password: brand-first paper shell, one composition. */
body.auth-shell {
  max-width: none;
  min-height: 100vh;
  margin: 0;
  padding: 32px 18px 48px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  background:
    radial-gradient(900px 480px at 18% 8%, rgba(154, 123, 79, 0.16), transparent 58%),
    radial-gradient(700px 420px at 92% 12%, rgba(40, 30, 20, 0.07), transparent 52%),
    radial-gradient(600px 380px at 50% 100%, rgba(154, 123, 79, 0.08), transparent 55%),
    var(--paper);
  position: relative;
  overflow-x: hidden;
}

body.auth-shell::before {
  content: "";
  position: fixed;
  inset: 0;
  pointer-events: none;
  opacity: 0.22;
  background-image: var(--grain);
  mix-blend-mode: multiply;
  z-index: 0;
}

body.auth-shell .login-card {
  position: relative;
  z-index: 1;
  margin: 0;
  width: min(28rem, 100%);
  padding: 28px 26px 24px;
  animation: motion-scale-in var(--dur-hero) var(--ease-out-expo) both;
  box-shadow:
    0 1px 0 rgba(255, 255, 255, 0.65) inset,
    0 18px 44px rgba(28, 23, 18, 0.1);
}

body.auth-shell .login-card .dispatch-brand {
  margin: 0 0 10px;
  font-family: var(--font-display);
  font-size: clamp(1.55rem, 3.2vw, 2rem);
  font-weight: 650;
  letter-spacing: -0.03em;
  text-transform: none;
  color: var(--ink);
  line-height: 1.1;
}

body.auth-shell .login-card h1 {
  font-size: clamp(1.15rem, 2vw, 1.35rem);
  font-weight: 650;
  color: var(--ink-soft);
}

/* Admin: same paper ground, staggered card settle. */
body.admin-shell {
  animation: motion-fade-in var(--dur-med) var(--ease-out-soft) both;
}

body.admin-shell .card {
  animation: motion-fade-up var(--dur-enter) var(--ease-out-expo) both;
}
body.admin-shell .card:nth-of-type(1) { animation-delay: 0.04s; }
body.admin-shell .card:nth-of-type(2) { animation-delay: 0.1s; }
body.admin-shell .card:nth-of-type(3) { animation-delay: 0.16s; }

textarea {
  width: 100%;
  min-height: 72px;
  border: 1px solid rgba(28, 23, 18, 0.14);
  border-radius: 10px;
  padding: 10px 12px;
  margin-top: 6px;
  resize: vertical;
  background: #fff;
  color: var(--ink);
}

button {
  margin-top: 0;
  background: var(--ink);
  color: #faf7f2;
  border: 0;
  border-radius: 10px;
  padding: 12px 18px;
  font-weight: 650;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  font-size: 0.82rem;
  cursor: pointer;
  width: 100%;
  transition:
    background var(--dur-fast) var(--ease-out-soft),
    transform var(--dur-micro) var(--ease-out-soft),
    opacity var(--dur-fast) ease,
    box-shadow var(--dur-fast) var(--ease-out-soft);
}

button:hover:not(:disabled) {
  box-shadow: 0 6px 16px rgba(28, 23, 18, 0.16);
}
button:active:not(:disabled) { transform: translateY(1px); }
button:disabled { opacity: 0.55; cursor: not-allowed; }

.row { display: flex; gap: 8px; flex-wrap: wrap; }

.row button.ghost,
button.ghost {
  flex: 1;
  min-width: 140px;
  width: auto;
  background: var(--ink);
  color: #faf7f2;
  border: 0;
}

#go {
  margin-top: 4px;
  background: var(--ink);
}

#preview,
#previewVid {
  max-height: 160px;
  margin-top: 4px;
  border-radius: 8px;
  display: none;
  width: 100%;
  object-fit: contain;
  background: #ddd5c8;
  animation: preview-in var(--dur-ui) var(--ease-out-expo) both;
}

@keyframes preview-in {
  from { opacity: 0; transform: scale(0.985) translateY(4px); }
  to { opacity: 1; transform: none; }
}

.dispatch-foot {
  margin: 4px 0 0;
  font-size: 0.78rem;
  color: var(--ink-soft);
  line-height: 1.4;
}

#queue { margin: 0; min-height: 1.2em; }

/* —— Below-fold cards —— */
.card {
  background: rgba(250, 247, 242, 0.92);
  border: 1px solid rgba(28, 23, 18, 0.1);
  border-radius: 14px;
  padding: 20px;
  margin: 16px 0;
  transition:
    border-color var(--dur-ui) var(--ease-out-soft),
    box-shadow var(--dur-ui) var(--ease-out-soft);
}

.card:hover {
  border-color: rgba(154, 123, 79, 0.35);
  box-shadow: 0 10px 28px rgba(28, 23, 18, 0.06);
}

.warn { border-color: #c45c26; background: #fbf3ec; }
.log-card { padding: 20px 0 12px; overflow: hidden; }
.log-head { padding: 0 20px; }
.log-head .links { display: flex; flex-wrap: wrap; gap: 8px 16px; align-items: center; }
.table-scroll { width: 100%; overflow-x: auto; -webkit-overflow-scrolling: touch; }
table.log { width: 100%; border-collapse: collapse; font-size: 0.88rem; min-width: 720px; }

table.log th {
  text-align: left;
  padding: 10px 12px;
  background: rgba(232, 224, 212, 0.7);
  color: var(--ink-soft);
  font-size: 0.72rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  font-weight: 700;
  border-bottom: 1px solid rgba(28, 23, 18, 0.1);
  white-space: nowrap;
}

table.log td {
  text-align: left;
  padding: 12px;
  border-bottom: 1px solid rgba(28, 23, 18, 0.08);
  vertical-align: top;
  word-break: break-word;
}

table.log tbody tr:hover { background: rgba(239, 232, 220, 0.55); }
table.log .actions { white-space: nowrap; }
table.log .title { color: var(--ink-soft); font-size: 0.84rem; }

.chip {
  display: inline-block;
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  padding: 3px 8px;
  border-radius: 999px;
  background: #eeeae3;
}

.chip.ok { background: #e6f4ea; color: var(--ok); }
.chip.bad { background: #f8e6e6; color: var(--danger); }
.chip.muted { color: var(--ink-soft); }

button.team-btn {
  margin-top: 0;
  width: auto;
  min-width: 140px;
  flex: 1;
  background: transparent;
  color: var(--ink);
  border: 1px solid rgba(28, 23, 18, 0.25);
  text-transform: none;
  letter-spacing: 0;
}

button.team-btn.on { background: var(--ink); color: #faf7f2; }
#team-switcher { display: none; }

.role-badge {
  display: inline-block;
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  color: #5a5348;
  background: #eeeae3;
  padding: 3px 8px;
  border-radius: 6px;
}

#members-card {
  padding: 0;
  overflow: hidden;
}

#members-panel {
  margin: 0;
}

#members-summary {
  list-style: none;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 16px 18px;
  user-select: none;
}

#members-summary::-webkit-details-marker { display: none; }

#members-summary::after {
  content: "";
  flex: 0 0 auto;
  width: 0.55rem;
  height: 0.55rem;
  border-right: 2px solid var(--ink-soft);
  border-bottom: 2px solid var(--ink-soft);
  transform: rotate(45deg);
  transition: transform var(--dur-ui) var(--ease-out-soft);
  opacity: 0.7;
}

#members-panel[open] > #members-summary::after {
  transform: rotate(-135deg);
  margin-top: 4px;
}

.members-summary-copy {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 8px 12px;
  min-width: 0;
}

.members-summary-title {
  font-family: var(--font-display);
  font-size: 1.15rem;
  font-weight: 650;
  letter-spacing: -0.02em;
  color: var(--ink);
}

.members-summary-meta {
  font-size: 0.82rem;
  color: var(--ink-soft);
}

.members-body {
  padding: 0 18px 18px;
  border-top: 1px solid rgba(28, 23, 18, 0.08);
}

.members-body > .hint:first-child { margin-top: 14px; }

#members-list { list-style: none; margin: 12px 0 0; padding: 0; }

#members-list li.member-row {
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin: 0 0 12px;
  padding: 12px 14px;
  background: rgba(243, 238, 230, 0.8);
  border: 1px solid rgba(28, 23, 18, 0.08);
  border-radius: 12px;
}

#members-list .member-main {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  min-width: 0;
}

#members-list .member-main code { word-break: break-all; font-size: 0.86rem; }
#members-list .member-actions { display: flex; flex-wrap: wrap; gap: 8px; }

#members-list button.ghost {
  flex: 1 1 auto;
  min-width: 0;
  width: auto;
  margin-top: 0;
  padding: 10px 12px;
  font-size: 0.82rem;
  background: transparent;
  color: var(--ink);
  border: 1px solid rgba(28, 23, 18, 0.2);
  text-transform: none;
  letter-spacing: 0;
}

#members-list button.member-remove { color: var(--danger); border-color: #c9b4b4; }
#members-add-row { align-items: stretch; }

#members-add-row input {
  flex: 1 1 12rem;
  min-width: 0;
  width: 100%;
  padding: 10px 12px;
  border-radius: 8px;
  border: 1px solid rgba(28, 23, 18, 0.14);
  background: #fff;
}

#members-add-row #member-add {
  flex: 0 0 auto;
  width: auto;
  min-width: 5.5rem;
  margin-top: 0;
}

.phone ol { margin: 8px 0 0; padding-left: 1.2rem; }

button.retry,
button.danger {
  width: auto;
  margin-top: 0;
  margin-right: 6px;
  padding: 7px 12px;
  font-size: 0.82rem;
  text-transform: none;
  letter-spacing: 0;
}

button.danger { background: #fff; color: var(--danger); border: 1px solid #c9b4b4; }
button.retry { background: var(--ink); }
#email-card { display: none; }
#team-line { margin: 0 0 12px; }

/* Mobile-only recent strip — hidden on desktop magazine layout */
.filmstrip {
  display: none;
  margin: 0 0 20px;
}

.filmstrip-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  margin: 0 0 10px;
}

.filmstrip-label {
  margin: 0;
  font-size: 0.72rem;
  font-weight: 650;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-soft);
}

.filmstrip-track {
  display: flex;
  /* Not `stretch`: stretching a flex item to the line height overrides the
     card's film aspect ratio and squashes the square print into a strip. */
  align-items: flex-start;
  gap: 10px;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  scroll-snap-type: x proximity;
  overscroll-behavior-x: contain;
  touch-action: pan-x;
  padding: 4px 2px 10px;
}

.filmstrip-track::-webkit-scrollbar { height: 4px; }
.filmstrip-track::-webkit-scrollbar-thumb {
  background: rgba(28, 23, 18, 0.2);
  border-radius: 999px;
}

/* Phone cards are the same instant film, minus the tilt: rotated cards feel
   unstable inside a horizontal scroller under a thumb. */
.film-card {
  position: relative;
  flex: 0 0 42vw;
  max-width: 168px;
  min-width: 118px;
  aspect-ratio: 88 / 107;
  container-type: inline-size;
  padding: 0;
  border-radius: 3px;
  background: linear-gradient(178deg, #fffdf9 0%, #fbf7f0 62%, #f2ece1 100%);
  box-shadow:
    0 0 0 1px rgba(28, 23, 18, 0.08),
    0 8px 18px rgba(28, 23, 18, 0.12);
  scroll-snap-align: start;
  appearance: none;
  border: 0;
  text-align: left;
  cursor: zoom-in;
  /* A button would otherwise swallow the horizontal drag that scrolls the strip. */
  touch-action: pan-x;
}

.film-card:focus-visible {
  outline: 2px solid var(--bronze);
  outline-offset: 3px;
}

.film-card img,
.film-card video {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0;
  filter: saturate(0.1) contrast(0.6) brightness(1.3) sepia(0.3);
  transition:
    opacity 0.4s var(--ease-out-soft),
    filter 1.2s var(--ease-develop) 0.1s;
}

.film-card.is-ready img,
.film-card.is-ready video {
  opacity: 1;
  filter: none;
}

.film-card.is-video .tile-window::before {
  content: "";
  position: absolute;
  z-index: 3;
  width: 24cqw;
  height: 24cqw;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  border-radius: 50%;
  background: rgba(250, 247, 242, 0.92)
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%231c1712'%3E%3Cpath d='M9 7.5v9l8-4.5-8-4.5z'/%3E%3C/svg%3E")
    no-repeat 56% 50% / 55%;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.18);
  pointer-events: none;
}

/* —— Capture lightbox —— */
#lightbox {
  position: fixed;
  inset: 0;
  z-index: 60;
  display: none;
  align-items: center;
  justify-content: center;
  padding: 4vmin;
  background: rgba(22, 18, 14, 0.82);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
}

#lightbox.is-open {
  display: flex;
  animation: lightbox-in var(--dur-ui) var(--ease-out-soft) both;
}

@keyframes lightbox-in {
  from { opacity: 0; }
  to { opacity: 1; }
}

.lightbox-card {
  position: relative;
  max-width: min(760px, 92vw);
  padding: 14px 14px 0;
  border-radius: 4px;
  background: linear-gradient(178deg, #fffdf9, #f4efe5);
  box-shadow: 0 30px 70px rgba(0, 0, 0, 0.45);
}

#lightbox.is-open .lightbox-card {
  animation: motion-lightbox-card var(--dur-med) var(--ease-out-expo) both;
}

.lightbox-card img,
.lightbox-card video {
  display: block;
  width: 100%;
  max-height: 74vh;
  object-fit: contain;
  background: #17130f;
}

.lightbox-chin {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 14px;
  padding: 12px 4px 16px;
  font-family: var(--font-display);
}

.lightbox-chin strong {
  font-size: 1.05rem;
  font-style: italic;
  font-weight: 650;
}

.lightbox-chin span {
  font-family: var(--font-body);
  font-size: 0.74rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-soft);
}

#lightbox-close {
  position: absolute;
  top: -14px;
  right: -14px;
  width: 38px;
  height: 38px;
  padding: 0;
  border-radius: 50%;
  border: 0;
  background: var(--panel);
  color: var(--ink);
  font-size: 1.2rem;
  line-height: 1;
  cursor: pointer;
  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.35);
  transition:
    transform var(--dur-fast) var(--ease-out-soft),
    background var(--dur-fast) ease;
}

#lightbox-close:hover {
  transform: scale(1.06);
  background: #fff;
}

/* On a phone the card is nearly the full width, so a button hung off its corner
   lands half on the paper and half off the screen edge. Park it on the backdrop
   above the card instead, clear of any notch. */
@media (max-width: 720px) {
  #lightbox-close {
    position: fixed;
    top: max(12px, env(safe-area-inset-top, 0px));
    right: max(12px, env(safe-area-inset-right, 0px));
  }
}

.film-empty {
  flex: 1 1 auto;
  min-height: 88px;
  display: flex;
  align-items: center;
  padding: 14px 16px;
  border-radius: 12px;
  border: 1px dashed rgba(154, 123, 79, 0.45);
  background: rgba(250, 247, 242, 0.7);
  color: var(--ink-soft);
  font-size: 0.9rem;
  line-height: 1.35;
}

@media (max-width: 900px) {
  #dispatch-hero {
    grid-template-columns: 1fr;
    min-height: 0;
    gap: 0;
    margin-bottom: 16px;
    padding: 14px 12px 4px;
    border-radius: 16px;
    background:
      radial-gradient(ellipse 90% 60% at 12% 0%, rgba(255, 248, 235, 0.65), transparent 55%),
      radial-gradient(ellipse 80% 50% at 100% 100%, rgba(90, 70, 40, 0.08), transparent 50%),
      linear-gradient(165deg, #f6f1e8 0%, #ebe3d6 100%);
    box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.35);
    position: relative;
    overflow: hidden;
  }

  #dispatch-hero::before {
    content: "";
    position: absolute;
    inset: 0;
    pointer-events: none;
    opacity: 0.22;
    background-image: var(--grain);
    mix-blend-mode: multiply;
  }

  /* Desktop magazine board stays off-screen on phones */
  .spread {
    display: none !important;
  }

  .dispatch {
    position: relative;
    z-index: 1;
    padding: 18px 14px 16px;
    background: rgba(250, 247, 242, 0.92);
    box-shadow: 0 14px 32px rgba(28, 23, 18, 0.07);
  }

  .dispatch h1 { max-width: none; font-size: 1.55rem; }

  .filmstrip {
    display: block;
    position: relative;
    z-index: 1;
  }
}

@media (max-width: 760px) {
  body { padding: 16px 12px 64px; }
  .log-card { padding: 16px 12px 8px; }
  .log-head { padding: 0; }
  .table-scroll { overflow: visible; }
  table.log { min-width: 0; }
  table.log thead { display: none; }
  table.log,
  table.log tbody,
  table.log tr,
  table.log td { display: block; width: 100%; }

  table.log tbody tr {
    background: rgba(243, 238, 230, 0.85);
    border: 1px solid rgba(28, 23, 18, 0.1);
    border-radius: 12px;
    padding: 12px 14px 8px;
    margin: 0 0 12px;
  }

  table.log tbody tr:hover { background: rgba(243, 238, 230, 0.85); }

  table.log td {
    border: 0;
    padding: 6px 0;
    display: grid;
    grid-template-columns: 7.2rem 1fr;
    gap: 8px;
    align-items: start;
  }

  table.log td::before {
    content: attr(data-label);
    color: var(--ink-soft);
    font-size: 0.72rem;
    font-weight: 700;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    padding-top: 3px;
  }

  table.log td.actions { grid-template-columns: 1fr; }
  table.log td.actions::before { display: none; }
  #members-add-row { flex-direction: column; }
  #members-add-row #member-add { width: 100%; }
  #members-list button.ghost { flex: 1 1 calc(50% - 4px); }
  .film-card { flex-basis: 38vw; }
}

@media (prefers-reduced-motion: reduce) {
  #dispatch-hero,
  .dispatch,
  .tile,
  #preview,
  #previewVid,
  #drop,
  #lightbox,
  #lightbox.is-open .lightbox-card,
  body.auth-shell .login-card,
  body.admin-shell,
  body.admin-shell .card {
    animation: none !important;
  }

  .tile,
  #drop,
  button,
  .card {
    transition: none !important;
  }

  .tile:hover,
  .tile.is-clickable:focus-visible {
    transform: rotate(var(--tilt));
  }

  .card:hover {
    box-shadow: none;
  }

  /* Motion is off, but the print still needs to appear once it loads —
     otherwise the card sits as blank paper. Cross-fade only, no develop. */
  .tile.has-media .tile-media,
  .film-card img,
  .film-card video {
    filter: none;
    transform: none;
    transition: opacity 0.2s linear;
  }

  .tile-window::after {
    transition: opacity 0.2s linear;
  }
}
