/* HW - Hunters Map base styles: plain board ground, blister cards, seals, controls.
   Requires tokens.css. Status modifiers match STATUS_CLASS in js/status.js:
   open, closed, reported-open, reported-closed. */

*,
*::before,
*::after {
  box-sizing: border-box;
}

html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
}

body {
  margin: 0;
  min-height: 100vh;
  min-height: 100dvh;
  background: var(--board);
  color: var(--on-board);
  font-family: var(--font-body);
  font-size: var(--text-md);
  line-height: 1.45;
  padding-bottom: calc(var(--tabbar-height) + var(--space-5) + env(safe-area-inset-bottom));
  caret-color: var(--focus);
}

::selection {
  background: var(--focus);
  color: #04222a;
}

:focus-visible {
  outline: 3px solid var(--focus);
  outline-offset: 3px;
  border-radius: 0.25rem;
}

a {
  color: inherit;
  text-underline-offset: 0.2em;
  text-decoration-thickness: 0.08em;
}

/* Scrollbars follow the palette where the browser allows it */
* {
  scrollbar-color: var(--on-board-muted) transparent;
  scrollbar-width: thin;
}

h1,
h2,
h3 {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: var(--track-display);
  line-height: 1.02;
  text-wrap: balance;
}

h1 {
  font-size: var(--text-display);
}
h2 {
  font-size: var(--text-xl);
  margin-top: var(--space-6);
  margin-bottom: var(--space-3);
}
h3 {
  font-size: var(--text-lg);
}

p {
  margin: 0 0 var(--space-3);
  max-width: 68ch;
}

.page {
  width: 100%;
  max-width: var(--page-max);
  margin-inline: auto;
  padding: 0 var(--gutter);
}

/* One rhythm under the header on every page: 1.5rem to the first thing, 1rem under a page title */
main.page {
  padding-top: var(--space-5);
}

main h1:where(:not(.card__name, .visually-hidden)) {
  margin-bottom: var(--space-4);
}

.form-panel > h2:first-child {
  margin-top: 0;
}

.form-panel > .btn + form {
  margin-top: var(--space-5);
}

.muted {
  color: var(--on-board-muted);
}

.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* ---------- Header: event logo on the board + wordmark ---------- */

.board-header {
  position: sticky;
  top: 0;
  z-index: 5;
  background: var(--board);
  border-bottom: 1px solid var(--board-line);
  padding-top: env(safe-area-inset-top);
}

.board-header .page {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  min-height: 4.5rem;
  padding-block: var(--space-2);
}

/* The event logo is a transparent PNG: it sits straight on the board, lifted by a soft drop shadow */
.logo {
  flex: none;
  display: block;
  width: 3.5rem;
  height: 3.5rem;
  object-fit: contain;
  filter: drop-shadow(0 2px 3px rgba(0, 0, 0, 0.45));
}

/* Name over the tagline; takes the room between the logo and the header buttons */
.brand {
  flex: 1 1 auto;
  min-width: 0;
}

.tagline {
  margin: var(--space-1) 0 0;
  font-size: var(--text-xs);
  font-weight: 600;
  line-height: 1.25;
  color: var(--on-board-muted);
  text-wrap: balance;
}

.wordmark {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 800;
  /* Shrinks on narrow phones so the name never runs under the cup and the bell; at the floor it wraps to two lines */
  font-size: clamp(1.125rem, calc((100vw - 13rem) / 7.4), var(--text-xl));
  line-height: 1;
  text-transform: uppercase;
  letter-spacing: 0.02em;
  text-wrap: balance;
  text-decoration: none;
}

/* The header controls: the coffee cup (donate dialog) on every page, at the right, and the bell after it */
.board-header .help-btn {
  flex: none;
  width: 2.75rem;
  min-height: 2.75rem;
  margin-left: auto;
  padding: 0;
  border-radius: 50%;
}

/* Cup and bell sit together: the cup takes the push to the right, the bell follows a small gap apart so the circles never touch */
.board-header .donate-btn + .help-btn {
  margin-left: calc(var(--space-2) - var(--space-3));
}

.board-header .help-btn .icon {
  margin: 0;
}

/* ---------- Help dialog (native <dialog>, list page) ---------- */

.help-dialog {
  width: min(100% - 2 * var(--gutter), 30rem);
  max-height: calc(100dvh - 4rem);
  padding: var(--space-5) var(--space-4) var(--space-4);
  border: 0;
  border-radius: var(--radius-card);
  background: var(--card);
  color: var(--ink);
  box-shadow: var(--shadow-card);
}

.help-dialog::backdrop {
  background: rgba(4, 20, 26, 0.6);
}

.help-dialog :focus-visible {
  outline-color: var(--focus-on-card);
}

.help-dialog h2 {
  margin: 0 0 var(--space-3);
}

.help-dialog ul {
  display: grid;
  gap: var(--space-2);
  margin: 0;
  padding-left: 1.25rem;
}

.help-dialog li {
  max-width: 60ch;
}

.help-dialog li::marker {
  color: var(--ink-muted);
}

.help-dialog form {
  display: flex;
  justify-content: flex-end;
  margin-top: var(--space-5);
}

.help-dialog .btn-primary {
  background: var(--ink);
  color: var(--card);
}

.donate-dialog p {
  max-width: 60ch;
  margin: 0 0 var(--space-3);
}

/* The three amounts, each a Stripe Payment Link: ink pills on the white dialog, side by side */
.donate-amounts {
  display: flex;
  gap: var(--space-2);
  margin-top: var(--space-4);
}

.donate-amount {
  flex: 1 1 0;
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: var(--tap);
  border-radius: 999px;
  background: var(--ink);
  color: var(--card);
  font-family: var(--font-display);
  font-size: var(--text-xl);
  font-weight: 800;
  text-decoration: none;
}

.donate-amount:hover {
  filter: brightness(1.25);
}

.donate-note {
  margin: var(--space-2) 0 0;
  font-size: var(--text-xs);
  color: var(--ink-muted);
  text-align: center;
}

.donate-dialog form {
  margin-top: var(--space-3);
}

.donate-dialog .btn-primary {
  background: transparent;
  color: var(--ink);
}

/* "Needs an account" sheet (js/signin-sheet.js, the star and the bell signed out): why, then Sign in over Not now */
.signin-dialog p {
  max-width: 60ch;
  margin: 0;
}

.signin-dialog form {
  flex-direction: column;
  align-items: stretch;
  gap: var(--space-2);
}

.signin-dialog a.btn {
  text-decoration: none;
}

.signin-dialog .btn-quiet {
  border-color: transparent;
  color: var(--ink);
}

.signin-dialog .btn-quiet:hover {
  background: color-mix(in srgb, var(--ink) 6%, transparent);
}

/* Sign in page: why they are here (?why=, js/signin-logic.js) */
.login-why {
  max-width: 60ch;
  margin: 0 0 var(--space-4);
  font-weight: 600;
  color: var(--on-board);
}

/* ---------- Filter chips ---------- */

.chips {
  display: flex;
  gap: var(--space-2);
  overflow-x: auto;
  padding: 0 var(--gutter) var(--space-2);
  margin-inline: calc(var(--gutter) * -1);
  scroll-snap-type: x proximity;
  scrollbar-width: none;
}

.chips::-webkit-scrollbar {
  display: none;
}

.chip {
  flex: none;
  min-height: var(--tap);
  padding: 0 var(--space-4);
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  border: 1px solid var(--board-line);
  border-radius: 999px;
  background: transparent;
  color: var(--on-board);
  font: 600 var(--text-sm) / 1 var(--font-body);
  cursor: pointer;
  scroll-snap-align: start;
}

.chip:hover:not(:disabled) {
  border-color: var(--on-board-muted);
}

.chip[aria-pressed="true"],
.chip[aria-selected="true"] {
  background: var(--card);
  border-color: var(--card);
  color: var(--ink);
}

/* ---------- Blister card ---------- */

.card {
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: var(--space-2) var(--space-4);
  align-items: start;
  padding: var(--space-6) var(--space-4) var(--space-4);
  background: var(--card);
  color: var(--ink);
  border-radius: var(--radius-card);
  box-shadow: var(--shadow-card);
  text-decoration: none;
}

/* Die-cut hang hole */
.card::before {
  content: "";
  position: absolute;
  top: 0.55rem;
  left: 50%;
  width: 2.25rem;
  height: 0.65rem;
  transform: translateX(-50%);
  border-radius: 999px;
  background: var(--board);
  box-shadow: inset 0 2px 3px rgba(0, 0, 0, 0.5);
}

a.card:hover,
.card:has(.card__link:hover) {
  transform: translateY(-2px);
}

.card {
  transition: transform 120ms var(--ease-out);
}

/* Controls on white stock take the dark ring (cyan disappears on white) */
.card :focus-visible,
.form-panel :focus-visible {
  outline-color: var(--focus-on-card);
}

/* Stretched link: the store name's link covers the whole card, one tab stop; the quick-row buttons
   sit above it and never navigate. */
.card__link {
  color: inherit;
  text-decoration: none;
}

.card__link::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  border-radius: var(--radius-card);
}

.card .card__link:focus-visible {
  outline: none;
}

.card .card__link:focus-visible::after {
  outline: 3px solid var(--focus);
  outline-offset: 3px;
}

.card__link:hover {
  text-decoration: underline;
  text-decoration-thickness: 0.06em;
}

.card-list {
  display: grid;
  gap: var(--space-5);
  margin: 0;
  padding: var(--space-3) 0 var(--space-5);
  list-style: none;
}

.card__zone {
  grid-column: 1 / -1;
  margin: 0;
  font-size: var(--text-xs);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--ink-muted);
}

.card__name {
  grid-column: 1;
  align-self: center;
  margin: 0;
  font-size: 1.75rem;
  overflow-wrap: anywhere;
}

.card__meta {
  grid-column: 1;
  margin: 0;
  font-size: var(--text-sm);
  color: var(--ink-muted);
}

.card__wide {
  grid-column: 1 / -1;
}

.card--flat {
  display: block;
  padding-top: var(--space-6);
}

/* ---------- Bubble window + seal ---------- */

.bubble {
  position: relative;
  display: grid;
  justify-items: center;
  gap: var(--space-1);
  min-width: 6.5rem;
  padding: var(--space-3) var(--space-3) var(--space-2);
  border: 1px solid var(--ink-line);
  border-radius: var(--radius-bubble);
  background: linear-gradient(150deg, rgba(255, 255, 255, 0.95), rgba(214, 226, 232, 0.55));
  box-shadow: inset 0 1px 0 #ffffff, inset 0 -6px 10px -8px rgba(16, 32, 42, 0.3);
  color: var(--ink);
  text-align: center;
  overflow: hidden;
}

/* Soft highlight arc, the clear plastic catching light */
.bubble::after {
  content: "";
  position: absolute;
  inset: 0.25rem 0.35rem auto 0.35rem;
  height: 38%;
  border-radius: 999px 999px 60% 60%;
  background: linear-gradient(180deg, rgba(255, 255, 255, 0.75), rgba(255, 255, 255, 0));
  pointer-events: none;
}

.bubble__word {
  font-family: var(--font-display);
  font-weight: 800;
  font-size: var(--text-lg);
  line-height: 1;
  text-transform: uppercase;
  letter-spacing: 0.03em;
}

.bubble__time {
  font-size: var(--text-xs);
  font-variant-numeric: tabular-nums;
  color: var(--ink-muted);
}

/* The seal glyphs, shared by the seals, the vendor switch knob and the list card's "Open?" pill (drawn SVG
   masks painted with the element's background colour) */
:root {
  --glyph-check: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M5.5 12.5l4.2 4.2L18.8 7.6' fill='none' stroke='black' stroke-width='3.2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  --glyph-cross: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M6.5 6.5l11 11M17.5 6.5l-11 11' fill='none' stroke='black' stroke-width='3.2' stroke-linecap='round'/%3E%3C/svg%3E");
}

.seal {
  --seal-color: var(--status-open);
  --seal-tint: var(--status-open-tint);
  --seal-glyph: var(--glyph-check);
  position: relative;
  display: inline-block;
  flex: none;
  width: 2.75rem;
  height: 2.75rem;
  border-radius: 50%;
  background: var(--seal-color);
  box-shadow: inset 0 -3px 4px rgba(0, 0, 0, 0.25), 0 2px 3px rgba(16, 32, 42, 0.35);
}

.seal::after {
  content: "";
  position: absolute;
  inset: 0.5rem;
  background: var(--on-seal);
  -webkit-mask: var(--seal-glyph) center / contain no-repeat;
  mask: var(--seal-glyph) center / contain no-repeat;
}

.seal--closed {
  --seal-color: var(--status-closed);
  --seal-tint: var(--status-closed-tint);
  --seal-glyph: var(--glyph-cross);
}

.seal--reported-open,
.seal--reported-closed {
  --seal-glyph: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M8.6 9.2a3.4 3.4 0 1 1 4.8 3.1c-.9.5-1.4 1.1-1.4 2M12 18.2v.01' fill='none' stroke='black' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
}

/* Diagonal stripes and a dashed ring mean "the crowd disagrees with the vendor".
   The hue stays the status the crowd reports; the shape says it is unconfirmed. */
.seal--reported-open,
.seal--reported-closed {
  outline: 2px dashed var(--seal-color);
  outline-offset: 3px;
}

.seal--reported-open {
  --seal-color: var(--status-reported-open);
  background: repeating-linear-gradient(135deg, var(--status-open) 0 0.35rem, color-mix(in srgb, var(--status-open) 62%, black) 0.35rem 0.7rem);
}

.seal--reported-closed {
  --seal-color: var(--status-reported-closed);
  background: repeating-linear-gradient(135deg, var(--status-closed) 0 0.35rem, color-mix(in srgb, var(--status-closed) 62%, black) 0.35rem 0.7rem);
}

.seal--reported-open::after,
.seal--reported-closed::after {
  background: var(--on-seal);
  filter: drop-shadow(0 0 2px rgba(0, 0, 0, 0.6));
}

/* Not confirmed for 10 h or more (status.js isStale): the seal goes hollow, a 2px ring and the glyph in the
   status colour on no fill (about 5:1 on card stock, where the old faded seal fell under 3:1), so a fresh,
   filled seal reads first; the words beside it ("not confirmed for 11 h") carry the meaning. The crowd
   states keep their dashed outer ring. */
.seal--stale,
.seal--reported-open.seal--stale,
.seal--reported-closed.seal--stale {
  background: transparent;
  box-shadow: inset 0 0 0 2px var(--seal-color);
}

.seal--stale::after,
.seal--reported-open.seal--stale::after,
.seal--reported-closed.seal--stale::after {
  background: var(--seal-color);
  filter: none;
}

/* ---------- Badge: compact seal + word for lists and timelines ---------- */

.badge {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  font-family: var(--font-display);
  font-weight: 800;
  font-size: var(--text-md);
  text-transform: uppercase;
  letter-spacing: 0.03em;
  line-height: 1;
}

.badge .seal {
  width: 1.5rem;
  height: 1.5rem;
  box-shadow: none;
}

.badge .seal::after {
  inset: 0.25rem;
}

/* ---------- Buttons and forms ---------- */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  min-height: var(--tap);
  padding: 0 var(--space-5);
  border: 2px solid transparent;
  border-radius: var(--radius-field);
  font: 800 var(--text-lg) / 1 var(--font-display);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
  transition: transform 120ms var(--ease-out);
}

.btn:active:not(:disabled) {
  transform: translateY(1px);
}

.btn-primary {
  background: var(--card);
  color: var(--ink);
  box-shadow: var(--shadow-raised);
}

.btn-quiet {
  background: transparent;
  color: var(--on-board);
  border-color: var(--board-line);
}

.btn-danger {
  background: var(--danger);
  color: #ffffff;
}

/* On white card stock: ink outline, ink text */
.btn-ink {
  background: transparent;
  color: var(--ink);
  border-color: var(--ink-muted);
  padding: 0 var(--space-4);
  font-size: var(--text-md);
}

.btn-ink:hover:not(:disabled) {
  background: color-mix(in srgb, var(--ink) 6%, transparent);
}

.btn-quiet:hover:not(:disabled) {
  border-color: var(--on-board-muted);
}

.btn .icon {
  flex: none;
  margin-left: calc(var(--space-1) * -1);
}

/* Inside a white panel the primary action inverts to ink, so it stays a visible button */
.form-panel .btn-primary,
.photo-batch .btn-primary {
  background: var(--ink);
  color: var(--card);
}

/* Quiet buttons on white stock (forms, admin and My stores cards) take ink, never on-board white */
.form-panel .btn-quiet,
.card .btn-quiet {
  color: var(--ink);
  border-color: var(--ink-muted);
}

.form-panel .btn-quiet:hover:not(:disabled),
.card .btn-quiet:hover:not(:disabled) {
  background: color-mix(in srgb, var(--ink) 6%, transparent);
}

.icon {
  display: inline-block;
  vertical-align: middle;
  fill: none; /* ui-thumb / ui-star take their fill from here (a starred store fills ui-star solid) */
}

.btn:disabled,
.chip:disabled {
  opacity: 0.55;
  cursor: not-allowed;
  background-image: repeating-linear-gradient(135deg, transparent 0 0.4rem, rgba(0, 0, 0, 0.16) 0.4rem 0.8rem);
}

.btn-block {
  display: flex;
  width: 100%;
}

label,
.field-label {
  display: block;
  margin: 0 0 var(--space-1);
  font-size: var(--text-sm);
  font-weight: 600;
}

.hint {
  margin: var(--space-1) 0 0;
  font-size: var(--text-sm);
  color: var(--on-board-muted);
}

.form-panel .hint {
  color: var(--ink-muted);
}

.form-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
  margin-top: var(--space-5);
}

.form-actions .btn-primary {
  flex: 1 1 12rem;
}

.saved {
  margin: var(--space-3) 0;
  font-weight: 600;
}

.saved:empty {
  display: none;
}

.panel-note {
  margin: 0 0 var(--space-4);
  font-weight: 600;
}

.field {
  margin-bottom: var(--space-4);
}

input[type="text"],
input[type="email"],
input[type="number"],
input[type="search"],
input[type="datetime-local"],
input[type="time"],
select,
textarea {
  width: 100%;
  min-height: var(--tap);
  padding: var(--space-2) var(--space-3);
  border: 2px solid var(--card-edge);
  border-radius: var(--radius-field);
  background: var(--card);
  color: var(--ink);
  font: inherit;
}

textarea {
  min-height: 6rem;
  resize: vertical;
}

::placeholder {
  color: var(--ink-muted);
  opacity: 1;
}

.form-panel {
  padding: var(--space-5) var(--space-4);
  background: var(--card);
  color: var(--ink);
  border-radius: var(--radius-card);
  box-shadow: var(--shadow-card);
}

.form-panel label {
  color: var(--ink);
}

.form-panel .muted {
  color: var(--ink-muted);
}

.error {
  margin: var(--space-3) 0 0;
  padding: var(--space-3);
  border: 2px solid var(--danger);
  border-radius: var(--radius-field);
  background: #ffffff;
  color: #7f1d0b;
  font-weight: 600;
}

.error:empty {
  display: none;
}

/* ---------- Status banner (offline, notices) ---------- */

/* The offline banner rides inside the sticky header, so it stays in view over stale data */
.board-header .banner {
  border-top: 1px solid var(--board-line);
}

.banner {
  padding: var(--space-3) var(--gutter);
  background: var(--card);
  color: var(--ink);
  font-size: var(--text-sm);
  font-weight: 600;
  text-align: center;
  border-bottom: 3px solid var(--status-closed);
}

.banner--update {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: var(--space-2) var(--space-3);
  border-bottom-color: var(--focus-on-card);
}

.banner__action {
  min-height: var(--tap);
  padding: 0 var(--space-4);
  border: 0;
  border-radius: 999px;
  background: var(--ink);
  color: var(--card);
  font: inherit;
  font-weight: 700;
  cursor: pointer;
}

.banner__close {
  min-width: var(--tap);
  min-height: var(--tap);
  border: 0;
  background: none;
  color: var(--ink-muted);
  font-size: 1.5rem;
  line-height: 1;
  cursor: pointer;
}

/* ---------- Report timeline (inside a card, flat rows) ---------- */

.timeline {
  margin: 0;
  padding: 0;
  list-style: none;
}

.timeline__row {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  min-height: var(--tap);
  padding: var(--space-3) 0;
  border-top: 1px solid var(--ink-line);
  font-size: var(--text-sm);
}

.timeline__row:first-child {
  border-top: 0;
}

.timeline__time {
  margin-left: auto;
  font-variant-numeric: tabular-nums;
  color: var(--ink-muted);
  white-space: nowrap;
}

.timeline__row.is-stale {
  opacity: 0.6;
}

.thumb-btn {
  white-space: nowrap;
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  min-height: var(--tap);
  min-width: var(--tap);
  padding: 0 var(--space-3);
  border: 2px solid var(--ink-line);
  border-radius: 999px;
  background: transparent;
  color: var(--ink);
  font: 700 var(--text-sm) / 1 var(--font-body);
  font-variant-numeric: tabular-nums;
  cursor: pointer;
}

.thumb-btn[aria-pressed="true"] {
  background: var(--ink);
  color: var(--card);
  border-color: var(--ink);
}

.thumb-btn {
  gap: var(--space-2);
  border-color: color-mix(in srgb, var(--ink) 35%, transparent);
  transition: transform 120ms var(--ease-out);
}

.thumb-btn:hover:not(:disabled) {
  border-color: var(--ink-muted);
}

.thumb-btn:active:not(:disabled) {
  transform: translateY(1px);
}

.thumb-btn:disabled {
  cursor: default;
}

.thumb-btn:disabled:not([aria-pressed="true"]) {
  opacity: 0.55;
  cursor: not-allowed;
}

.thumb-btn__count {
  min-width: 1ch;
}

/* ---------- Bottom tab bar: the one navigation (Stores, Events, My stores, Profile) ---------- */

/* 3.5rem row: 0.375rem padding above and below a 2.75rem (44px) tab, plus the safe-area inset */
.tabbar {
  position: fixed;
  inset: auto 0 0 0;
  z-index: 6;
  padding: 0.375rem var(--gutter) calc(0.375rem + env(safe-area-inset-bottom));
  background: var(--board);
  border-top: 1px solid var(--board-line);
}

.tabbar:empty {
  display: none;
}

.tabbar__list {
  display: grid;
  grid-auto-columns: minmax(0, 1fr);
  grid-auto-flow: column;
  gap: var(--space-1);
  max-width: var(--page-max);
  margin: 0 auto;
  padding: 0;
  list-style: none;
}

.tabbar__tab {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.125rem;
  min-height: calc(var(--tabbar-height) - var(--space-3)); /* 2.75rem: the 44px target */
  padding: 0.125rem var(--space-1);
  border-radius: 999px;
  color: var(--on-board);
  text-decoration: none;
  transition: transform 120ms var(--ease-out);
}

.tabbar__label {
  font: 800 0.8125rem / 1 var(--font-display);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  white-space: nowrap;
}

.tabbar__tab .icon {
  flex: none;
}

.tabbar__tab:hover:not([aria-current="page"]) {
  background: color-mix(in srgb, var(--on-board) 10%, transparent);
}

.tabbar__tab:active {
  transform: translateY(1px);
}

/* My stores tab: a dot while one of the caller's stores needs them (js/nav.js) */
.tabbar__tab {
  position: relative;
}

.tabbar__dot {
  position: absolute;
  top: 0.25rem;
  left: calc(50% + 0.5rem);
  width: 0.5rem;
  height: 0.5rem;
  border-radius: 50%;
  background: var(--on-board);
  box-shadow: 0 0 0 2px var(--board);
}

.tabbar__tab[aria-current="page"] .tabbar__dot {
  background: var(--focus-on-card);
  box-shadow: 0 0 0 2px var(--card);
}

.tabbar__tab[aria-current="page"] {
  background: var(--card);
  color: var(--ink);
  box-shadow: var(--shadow-raised);
}

/* ---------- Empty and loading states ---------- */

.empty {
  padding: var(--space-6) var(--space-4);
  text-align: center;
  color: var(--on-board-muted);
}

.empty strong {
  display: block;
  margin-bottom: var(--space-2);
  font-family: var(--font-display);
  font-size: var(--text-xl);
  text-transform: uppercase;
  color: var(--on-board);
}

.disclaimer {
  margin-top: var(--space-6);
  font-size: var(--text-xs);
  color: var(--on-board-muted);
}

@media (min-width: 40rem) {
  .card-list {
    gap: var(--space-6);
  }
}

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

/* ---------- Page-specific layout (list and detail) ---------- */

.chips select {
  flex: none;
  width: auto;
  max-width: 14rem;
  border-radius: 999px;
  border-color: var(--board-line);
  font-weight: 600;
  padding-inline: var(--space-4);
}

.card--flat .bubble {
  width: fit-content;
  margin: var(--space-3) 0;
}

.store-description {
  white-space: pre-line;
  overflow-wrap: anywhere;
}

#actions {
  margin-top: var(--space-4);
}

#actions .muted {
  margin-top: var(--space-3);
  font-size: var(--text-sm);
}

/* ---------- Offline: write controls opt in with .needs-network ---------- */

html[data-offline] .needs-network {
  opacity: 0.55;
  cursor: not-allowed;
  pointer-events: none;
}

/* ---------- Quick row: the latest crowd report + one-tap thumb, and one one-tap report ---------- */

.quick {
  position: relative;
  z-index: 2; /* above the card's stretched link */
  grid-column: 1 / -1;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-3);
  margin-top: var(--space-2);
  padding-top: var(--space-3);
  border-top: 1px solid var(--ink-line);
}

.quick__crowd {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  min-width: 0;
  margin-right: auto;
}

.quick__action {
  margin-left: auto;
}

.quick__done {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  min-height: var(--tap);
  margin: 0 0 0 auto;
  font: 800 var(--text-md) / 1 var(--font-display);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.quick__error {
  flex: 1 0 100%;
  margin: 0;
  font-size: var(--text-sm);
  font-weight: 600;
  color: #7f1d0b;
}

/* ---------- List: summary line, slim filters, vertical blister cards (one per row) ---------- */

.chips--slim {
  padding-bottom: var(--space-1);
}

/* Slimmer than the 3rem controls elsewhere, still a 44px target */
.chips--slim .chip {
  min-height: 2.75rem;
  padding-inline: var(--space-3);
}

/* Floor · Open now · Favorites · Category all fit in one row: the two buttons keep their size, the two
   selects share what is left and clip their text with an ellipsis (the full name is in the open list). */
.chips--slim {
  gap: var(--space-1);
}

.chips--slim .chip {
  padding-inline: var(--space-2);
  font-size: 0.8125rem;
}

/* The native arrow is wide: a small chevron drawn in currentColor takes its place */
.chips--slim select.chip {
  flex: 1 1 auto;
  min-width: 0;
  max-width: 14rem;
  padding-inline: 0.625rem 1.25rem;
  text-overflow: ellipsis;
  appearance: none;
  background-image:
    linear-gradient(45deg, transparent 50%, currentColor 50%),
    linear-gradient(135deg, currentColor 50%, transparent 50%);
  background-position: right 0.75rem center, right 0.4375rem center;
  background-size: 0.3125rem 0.3125rem;
  background-repeat: no-repeat;
}

.chip .icon {
  flex: none;
  margin-left: calc(var(--space-1) * -1);
}

/* Selected Favorites chip: the star fills (shape, not only the chip fill) */
.chip--fav[aria-pressed="true"] .icon {
  fill: currentColor;
}

.chip__count {
  margin-left: calc(var(--space-1) * -1);
  font-variant-numeric: tabular-nums;
}

/* Search box above the filters: one full-width field on the board, a drawn magnifier inside */
.search {
  position: relative;
  margin: var(--space-3) 0 var(--space-2);
}

/* The magnifier: a mask painted in the board's muted ink, so it follows the theme */
.search::before {
  content: "";
  position: absolute;
  top: 50%;
  left: 0.875rem;
  width: 1.125rem;
  height: 1.125rem;
  transform: translateY(-50%);
  background: var(--on-board-muted);
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cg fill='none' stroke='black' stroke-width='2.25' stroke-linecap='round'%3E%3Ccircle cx='10.5' cy='10.5' r='6'/%3E%3Cpath d='M15 15l5 5'/%3E%3C/g%3E%3C/svg%3E") center / contain no-repeat;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cg fill='none' stroke='black' stroke-width='2.25' stroke-linecap='round'%3E%3Ccircle cx='10.5' cy='10.5' r='6'/%3E%3Cpath d='M15 15l5 5'/%3E%3C/g%3E%3C/svg%3E") center / contain no-repeat;
  pointer-events: none;
}

.search .search__input {
  min-height: 2.75rem;
  padding: 0 var(--space-4) 0 2.5rem;
  border: 1px solid var(--board-line);
  border-radius: 999px;
  background: color-mix(in srgb, var(--on-board) 8%, transparent);
  color: var(--on-board);
  font-weight: 600;
}

.search .search__input::placeholder {
  color: var(--on-board-muted);
  opacity: 1;
}

.search .search__input:focus {
  border-color: var(--on-board-muted);
}

/* Summary line with the Just opened toggle at its right end */
.list-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
  margin-top: var(--space-2);
}

.list-bar .list-summary {
  margin: 0;
}

/* A smaller chip, still a 44px target (the transparent border area grows the hit box) */
.chip--small {
  min-height: 2.25rem;
  margin-left: auto;
  padding-inline: var(--space-3);
  font-size: 0.8125rem;
  position: relative;
}

.chip--small::before {
  content: "";
  position: absolute;
  inset: -0.25rem 0;
}

/* "A favorite just opened": floats above the tab bar for a few seconds */
.toast {
  position: fixed;
  left: 50%;
  bottom: calc(var(--tabbar-height) + env(safe-area-inset-bottom) + var(--space-3));
  z-index: 7;
  width: min(100% - 2 * var(--gutter), 30rem);
  transform: translateX(-50%);
  border-radius: 999px;
  background: var(--card);
  color: var(--ink);
  box-shadow: var(--shadow-card);
}

.toast[hidden] {
  display: none;
}

.toast__link {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  min-height: var(--tap);
  padding: 0 var(--space-4);
  color: inherit;
  font-weight: 700;
  text-decoration: none;
}

.toast__link .icon {
  flex: none;
  fill: currentColor;
}

.list-summary {
  margin: var(--space-2) 0 0;
  font-size: var(--text-sm);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  color: var(--on-board-muted);
}

/* "Your store" (vendors only, above the search): the caller's store, its status as the card shows it, and the
   way to its status control in My stores. Teal-tinted with a teal label while it needs them (unconfirmed,
   flipped by the crowd, not approved); the label says so in words too. */
.owner-strip {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  grid-template-areas: "label label" "name go" "line line";
  align-items: center;
  gap: 0.125rem var(--space-3);
  margin: 0 0 var(--space-3);
  padding: var(--space-3) var(--space-3) var(--space-3) var(--space-4);
  border-radius: var(--radius-card);
  background: var(--card);
  color: var(--ink);
  box-shadow: var(--shadow-card);
  text-decoration: none;
  transition: transform 120ms var(--ease-out);
}

.owner-strip:hover {
  transform: translateY(-2px);
}

.owner-strip:focus-visible {
  outline-color: var(--focus);
}

.owner-strip--attention {
  background: color-mix(in srgb, var(--focus-on-card) 7%, var(--card));
}

.owner-strip__label {
  grid-area: label;
  font: 700 0.75rem / 1.2 var(--font-body);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-muted);
}

.owner-strip--attention .owner-strip__label {
  color: var(--focus-on-card);
}

.owner-strip__name {
  grid-area: name;
  overflow: hidden;
  font: 800 1.125rem / 1.1 var(--font-display);
  letter-spacing: 0.01em;
  text-transform: uppercase;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.owner-strip__line {
  grid-area: line;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0 0.375rem;
  font-size: 0.8125rem;
  font-variant-numeric: tabular-nums;
  color: var(--ink-muted);
}

.owner-strip__line .seal {
  width: 1.25rem;
  height: 1.25rem;
}

.owner-strip__line .seal::after {
  inset: 0.22rem;
}

/* the crowd seal's dashed ring sits 3px outside it: keep it off the word */
.owner-strip__line .seal--reported-open,
.owner-strip__line .seal--reported-closed {
  margin: 0 0.3rem;
}

.owner-strip__word {
  font: 800 0.875rem / 1 var(--font-display);
  letter-spacing: 0.03em;
  text-transform: uppercase;
  color: var(--ink);
}

.owner-strip__go {
  grid-area: go;
  display: inline-flex;
  align-items: center;
  min-height: 2.25rem;
  padding: 0 0.75rem;
  border: 1px solid color-mix(in srgb, var(--ink-muted) 55%, transparent);
  border-radius: 999px;
  font: 700 0.8125rem / 1 var(--font-body);
  white-space: nowrap;
}

/* My stores: the card the strip leads to (#store-<id>) clears the sticky header */
.card-list > li[id] {
  scroll-margin-top: 6rem;
}

/* One store per row, as before; the card itself stacks vertically */
.card-list--compact {
  gap: var(--space-3);
}

/* Blister card: the main column (status row, name, zone, categories, reported line, back time) beside a
   narrow right rail (the star over the "Open?" pill). The hang hole is a small die-cut bite set into the top
   edge, so it costs no height. */
.card--store {
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 0 var(--space-2);
  min-width: 0;
  padding: var(--space-3);
}

.card__main {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  min-width: 0;
}

/* The rail holds only the dispute pill, at the card's bottom right (the thumb's side), clear of the star,
   which sits alone in the card's top-right corner. Asking, it stacks the two answers. */
.card__rail {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 0.375rem;
  align-self: end;
  padding-top: 2.5rem; /* the star's corner: its 44px target never overlaps a pill */
}

.card--store > .fav {
  top: 0;
  right: 0;
}

.card--store::before {
  top: 0;
  width: 1.75rem;
  height: 0.3rem;
  border-radius: 0 0 999px 999px;
  box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.5);
}

/* Seal, word and time on one line (the time wraps under the word when short of room) */
.card__status {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-1) var(--space-2);
  min-height: 2rem;
  margin: 0;
}

.card--store .seal {
  flex: none;
  width: 2rem;
  height: 2rem;
}

.card--store .seal::after {
  inset: 0.35rem;
}

.card__word {
  font: 800 var(--text-md) / 1 var(--font-display);
  text-transform: uppercase;
  letter-spacing: 0.03em;
}

.card__time {
  font-size: var(--text-xs);
  line-height: 1.3;
  font-variant-numeric: tabular-nums;
  color: var(--ink-muted);
}

.card__time--stale {
  font-weight: 700;
  color: var(--ink);
}

.card--store .card__name {
  align-self: stretch;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  overflow: hidden;
  font-size: 1.25rem;
  line-height: 1.05;
  overflow-wrap: anywhere;
}

.card--store .card__zone,
.card__cats {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  overflow: hidden;
  margin: 0;
  font-size: 0.8125rem;
  line-height: 1.25;
  letter-spacing: 0;
  text-transform: none;
  overflow-wrap: anywhere;
}

.card--store .card__zone {
  font-weight: 700;
  color: var(--ink);
}

.card__cats {
  font-weight: 400;
  color: var(--ink-muted);
}

.card__more {
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

/* "3 reported closed · 4 h ago" / "2 reported open · 5 min ago": live crowd reports, flagged with the drawn
   report flag (the same as "It's closed") so it stands out without shouting (full ink, not muted). */
.card__reported {
  display: flex;
  align-items: baseline;
  gap: 0.3em;
  margin: 0;
  font-size: var(--text-xs);
  font-weight: 700;
  line-height: 1.3;
  font-variant-numeric: tabular-nums;
  color: var(--ink);
}

.card__reported::before {
  content: "";
  flex: none;
  align-self: center;
  width: 0.875rem;
  height: 0.875rem;
  background: currentColor;
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cg fill='none' stroke='black' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5.5 21V3.5'/%3E%3Cpath d='M5.5 4.5h12l-2.75 4.25 2.75 4.25h-12'/%3E%3C/g%3E%3C/svg%3E") center / contain no-repeat;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cg fill='none' stroke='black' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5.5 21V3.5'/%3E%3Cpath d='M5.5 4.5h12l-2.75 4.25 2.75 4.25h-12'/%3E%3C/g%3E%3C/svg%3E") center / contain no-repeat;
}

.card__back {
  margin: 0;
  font-size: var(--text-xs);
  font-weight: 700;
  line-height: 1.3;
  font-variant-numeric: tabular-nums;
  color: var(--ink);
}

.card__error {
  margin: 0;
  font-size: 0.8125rem;
  font-weight: 600;
  color: #7f1d0b;
}

/* "You said: Open" for about 3 s after a vote (role status), under the card's text */
.card__said {
  display: flex;
  align-items: center;
  gap: var(--space-1);
  margin: 0;
  font-size: 0.8125rem;
  font-weight: 700;
  line-height: 1.3;
  color: var(--ink);
}

/* Anonymous voters: "That was your 3rd store this hour. Sign up to report more." with the link. On the
   store page it sits on the board (#nudge), on a card it sits on card stock: each takes its ink. */
.card__nudge {
  margin: 0;
  font-size: 0.8125rem;
  font-weight: 600;
  line-height: 1.35;
  color: var(--ink);
}

#nudge .card__nudge {
  margin: var(--space-2) 0 0;
  color: var(--on-board);
}

.card__nudge a,
.card__error a {
  font-weight: 800;
  color: inherit;
}

/* The Turnstile check, shown only while an anonymous account is being created: above the tab bar,
   centred. Usually it passes by itself; when Cloudflare is unsure it shows a checkbox here. */
.captcha {
  position: fixed;
  left: 50%;
  bottom: calc(var(--tabbar-height) + env(safe-area-inset-bottom) + var(--space-3));
  z-index: 8;
  transform: translateX(-50%);
}

.captcha[hidden] {
  display: none;
}

/* On the sign-in form the check sits in the flow, above the send button */
.captcha--inline {
  position: static;
  transform: none;
  margin: 0 0 var(--space-3);
}

.card__said .icon {
  flex: none;
}

/* ---------- Star: favorite on this device (list card corner, detail title) ---------- */

.fav {
  position: absolute;
  top: 0;
  right: 0;
  z-index: 2; /* above the card's stretched link */
  display: grid;
  place-items: center;
  width: 2.75rem;
  height: 2.75rem;
  padding: 0;
  border: 0;
  border-radius: var(--radius-field);
  background: transparent;
  color: var(--ink-muted);
  cursor: pointer;
}

.fav .icon {
  transition: transform 120ms var(--ease-out);
}

.fav:hover {
  color: var(--ink);
}

.fav:active .icon {
  transform: scale(0.8);
}

/* Starred: filled (shape) and amber (hue) */
.fav[aria-pressed="true"] {
  color: var(--favorite);
}

.fav[aria-pressed="true"] .icon {
  fill: currentColor;
}

.card .fav:focus-visible {
  outline-offset: -3px;
}

/* ---------- Vote question: the report control in the list card's rail, above the stretched link ---------- */

/* Round 16, two taps. The question ("Is it open?", "Still open?" when stale) and its two answers ("Still
   open" over "It's closed", the detail page's words and flag) share one small pill shape: drawn 2.25rem
   tall, its ::before grows the target to 44px. */
.vote,
.vote-ask {
  position: relative;
  z-index: 2;
  display: inline-flex;
  align-items: center;
  gap: 0.375rem;
  min-height: 2.25rem;
  padding: 0 0.75rem;
  border: 1px solid color-mix(in srgb, var(--ink-muted) 55%, transparent);
  border-radius: 999px;
  background: transparent;
  color: var(--ink-muted);
  font: 700 0.8125rem / 1 var(--font-body);
  white-space: nowrap;
  cursor: pointer;
  transition: background-color 120ms var(--ease-out), color 120ms var(--ease-out), transform 120ms var(--ease-out);
}

.vote::before,
.vote-ask::before {
  content: "";
  position: absolute;
  inset: -0.25rem -0.125rem;
}

.vote .icon,
.vote-ask .icon {
  flex: none;
}

/* The question reads in full ink; a faint teal tint when the status went unconfirmed (it needs an answer) */
.vote-ask {
  color: var(--ink);
}

.vote-ask:hover {
  background: color-mix(in srgb, var(--ink) 6%, transparent);
}

.vote-ask:active {
  transform: scale(0.96);
}

.vote-ask--strong {
  background: color-mix(in srgb, var(--focus-on-card) 5%, transparent);
}

.vote-ask--strong:hover {
  background: color-mix(in srgb, var(--focus-on-card) 10%, transparent);
}

/* Second tap: the answers grow in where the question was */
.card__rail--asking .vote {
  color: var(--ink);
  animation: vote-in 200ms var(--ease-out);
}

@keyframes vote-in {
  from { opacity: 0; transform: scale(0.94); }
  to { opacity: 1; transform: none; }
}

@media (prefers-reduced-motion: reduce) {
  .card__rail--asking .vote {
    animation: none;
  }
}

.vote:hover:not(:disabled):not([aria-pressed="true"]) {
  color: var(--ink);
  background: color-mix(in srgb, var(--ink) 6%, transparent);
}

.vote:active:not(:disabled):not([aria-pressed="true"]) {
  transform: scale(0.96);
}

/* Confirmed: fills with the status it reported, a check replaces the flag, and it becomes inert */
.vote[aria-pressed="true"] {
  color: var(--on-seal);
  cursor: default;
}

.vote--open[aria-pressed="true"] {
  border-color: var(--status-open);
  background: var(--status-open);
}

.vote--closed[aria-pressed="true"] {
  border-color: var(--status-closed);
  background: var(--status-closed);
}

.card .vote:focus-visible,
.card .vote-ask:focus-visible {
  outline-offset: 2px;
}

/* Busy while the report is on its way */
.vote:disabled {
  opacity: 0.55;
  cursor: progress;
}

/* ---------- Detail: one status hero, details below with air instead of boxes ---------- */

.card--detail .card__name {
  font-size: var(--text-display);
}

.card__head {
  display: flex;
  align-items: flex-start;
  gap: var(--space-2);
}

.card__head .card__name {
  align-self: auto;
  flex: 1 1 auto;
  min-width: 0;
}

.card__head .fav {
  position: static;
  flex: none;
  margin: -0.25rem -0.5rem 0 0;
}

.card--detail .card__zone {
  margin-bottom: var(--space-2);
}

.bubble--hero {
  grid-template-columns: auto auto;
  justify-items: start;
  align-items: center;
  column-gap: var(--space-3);
  row-gap: 0;
  padding: var(--space-3) var(--space-5) var(--space-3) var(--space-3);
  text-align: left;
}

.bubble--hero .seal {
  grid-row: 1 / span 2;
  width: 3.5rem;
  height: 3.5rem;
}

.bubble--hero .seal::after {
  inset: 0.7rem;
}

.bubble--hero .bubble__word {
  font-size: var(--text-xl);
}

.card--detail .quick {
  margin-top: var(--space-4);
}

.detail-facts {
  display: grid;
  gap: var(--space-3);
  margin-top: var(--space-5);
}

.detail-facts:empty {
  display: none;
}

.detail-facts > p {
  margin: 0;
}

.vendor {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--text-sm);
}

.vendor .avatar {
  flex: none;
  color: var(--ink);
}

.vendor__label,
.detail-facts__label {
  font-size: var(--text-xs);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--ink-muted);
}

.vendor__nick {
  font-weight: 700;
}

.detail-facts__cats {
  font-size: var(--text-sm);
}

#actions {
  display: grid;
  justify-items: start;
  gap: var(--space-2);
}

#actions .muted {
  margin: 0;
}

/* ---------- My stores: page head with the add action, compact cards ---------- */

.page-head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  padding-bottom: var(--space-2);
}

.page-head h1 {
  margin: 0;
}

.page-head__action {
  margin: 0;
}

.page-head__action:empty {
  display: none;
}

.card--mine {
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-2);
}

.card--mine .card__name {
  font-size: var(--text-xl);
}

.card--mine .card__meta {
  margin-top: var(--space-1);
}

/* The switch with its word and time at left, Edit at right */
.mine-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  margin-top: var(--space-1);
}

.mine-row .btn {
  margin-left: auto;
}

/* ---------- Switch: the vendor's Open/Closed control (ON = Open) ---------- */

.switch-row {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  min-width: 0;
}

.switch-row__text {
  margin: 0;
}

.switch-row__word {
  display: block;
  font: 800 var(--text-lg) / 1 var(--font-display);
  text-transform: uppercase;
  letter-spacing: 0.03em;
}

.switch-row__time {
  display: block;
  margin-top: 0.2rem;
  font-size: var(--text-xs);
  font-variant-numeric: tabular-nums;
  color: var(--ink-muted);
}

/* The button is the 44px target; the drawn track inside it is 3.5rem x 2rem */
.switch {
  --track: var(--status-closed);
  --glyph: var(--glyph-cross);
  position: relative;
  flex: none;
  display: inline-grid;
  place-items: center;
  width: 3.75rem;
  min-height: 2.75rem;
  padding: 0;
  border: 0;
  border-radius: 999px;
  background: transparent;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

.switch[aria-checked="true"] {
  --track: var(--status-open);
  --glyph: var(--glyph-check);
}

.switch__track {
  position: relative;
  display: block;
  width: 3.5rem;
  height: 2rem;
  border-radius: 999px;
  background-color: var(--track);
  box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.3);
  transition: background-color var(--press-duration) var(--ease-out);
}

.switch__knob {
  position: absolute;
  top: 0.25rem;
  left: 0.25rem;
  width: 1.5rem;
  height: 1.5rem;
  border-radius: 50%;
  background: #ffffff;
  box-shadow: 0 2px 3px rgba(0, 0, 0, 0.35);
  transition: transform var(--press-duration) var(--ease-out), scale 120ms var(--ease-out);
}

/* The glyph in the knob carries the state too: check (Open) or cross (Closed) in the track's hue */
.switch__knob::after {
  content: "";
  position: absolute;
  inset: 0.3rem;
  background: var(--track);
  -webkit-mask: var(--glyph) center / contain no-repeat;
  mask: var(--glyph) center / contain no-repeat;
}

.switch[aria-checked="true"] .switch__knob {
  transform: translateX(1.5rem);
}

/* The switch that just changed (after the refetch) slides its knob in from the old side */
@keyframes knob-on {
  from { transform: translateX(0); }
}

@keyframes knob-off {
  from { transform: translateX(1.5rem); }
}

.switch--moved[aria-checked="true"] .switch__knob {
  animation: knob-on var(--press-duration) var(--ease-out);
}

.switch--moved[aria-checked="false"] .switch__knob {
  animation: knob-off var(--press-duration) var(--ease-out);
}

.switch:hover:not(:disabled) .switch__track {
  background-color: color-mix(in srgb, var(--track) 82%, black);
}

.switch:active:not(:disabled) .switch__knob {
  scale: 0.9;
}

.card .switch:focus-visible {
  outline-offset: 0;
  border-radius: 999px;
}

/* Busy while the change is on its way */
.switch:disabled {
  cursor: progress;
}

/* Banned or offline: hatched and dimmed */
.switch[aria-disabled="true"] {
  cursor: not-allowed;
}

.switch[aria-disabled="true"] .switch__track,
html[data-offline] .switch .switch__track {
  opacity: 0.55;
  background-image: repeating-linear-gradient(135deg, transparent 0 0.4rem, rgba(0, 0, 0, 0.16) 0.4rem 0.8rem);
}

.back-field {
  grid-column: 1 / -1;
  margin: var(--space-2) 0 0;
}

/* Opening hours: the card line, the store page list, the editor (form and My stores) */
.card__hours {
  margin: 0;
  font-size: var(--text-xs);
  line-height: 1.3;
  font-variant-numeric: tabular-nums;
  color: var(--ink-muted);
}

.hours-list {
  margin: var(--space-1) 0 0;
  padding: 0;
  list-style: none;
  font-size: var(--text-sm);
  font-variant-numeric: tabular-nums;
}

.hours-list__day {
  display: inline-block;
  min-width: 6.5em;
  font-weight: 700;
}

/* Always on white card stock: light native controls (an unchecked box must not look filled) and ink text */
.hours-editor {
  border: 0;
  margin: 0 0 var(--space-4);
  padding: 0;
  min-width: 0;
  color-scheme: light;
  color: var(--ink);
}

.hours-editor legend {
  padding: 0;
  font-size: var(--text-sm);
  font-weight: 600;
}

.hours-editor .hint {
  color: var(--ink-muted);
}

.hours-editor input[type="radio"],
.hours-editor input[type="checkbox"] {
  width: 1.15rem;
  height: 1.15rem;
  margin: 0;
  accent-color: var(--ink);
}

.hours-editor__modes {
  display: grid;
  gap: var(--space-1);
  margin: var(--space-2) 0;
}

.hours-editor__mode {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  font-weight: 400;
}

.hours-day__times {
  display: flex;
  align-items: center;
  gap: var(--space-2);
}

.hours-day__times input {
  flex: 1 1 0;
  min-width: 0;
}

.hours-days {
  display: grid;
  gap: var(--space-3);
  margin: 0;
  padding: 0;
  list-style: none;
}

.hours-day {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: var(--space-2);
  align-items: center;
}

.hours-day__label {
  font-weight: 700;
}

.hours-day .hours-day__times,
.hours-day .hours-break {
  grid-column: 1 / -1;
}

/* Only the chosen option's times show (the day list is a grid, so [hidden] needs saying), and the second period
   only with Lunch break ticked */
.hours-editor__panel[hidden],
.hours-break__times[hidden] {
  display: none;
}

.hours-editor__panel.hint {
  margin: 0 0 var(--space-2);
}

.hours-range {
  display: grid;
  gap: var(--space-2);
}

.hours-break {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--text-sm);
  font-weight: 400;
}

.hours-day__closed {
  display: flex;
  align-items: center;
  gap: var(--space-1);
  font-weight: 400;
}

.hours-quick {
  grid-column: 1 / -1;
  margin: var(--space-2) 0 0;
}

.hours-quick__line {
  margin: 0 0 var(--space-2);
  font-size: var(--text-sm);
  font-variant-numeric: tabular-nums;
}

.hours-quick__label {
  margin-right: var(--space-1);
  font-size: var(--text-xs);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--ink-muted);
}

.hours-quick__panel .hours-editor {
  margin-bottom: var(--space-2);
}

.hours-quick__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}

/* My stores: Be right back under the switch of an open store: the title, then 15 min / 30 min / 1 h */
.brb {
  margin: var(--space-2) 0 0;
}

.brb__title {
  display: flex;
  align-items: center;
  gap: var(--space-1);
  margin: 0 0 var(--space-2);
  font-size: var(--text-sm);
  font-weight: 700;
}

.brb__options {
  display: flex;
  gap: var(--space-2);
}

.brb__options .btn {
  flex: 1 1 0;
}

.brb__hint {
  margin: var(--space-1) 0 0;
  font-size: var(--text-xs);
  color: var(--ink-muted);
}

.back-field__row {
  display: flex;
  gap: var(--space-2);
}

.back-field__row input {
  flex: 1 1 auto;
  min-width: 0;
}

.crowd-notice .btn {
  margin-top: var(--space-2);
}

/* ---------- Profile: avatar picker (radio group of drawn icons) and account ---------- */

.avatar-picker {
  display: grid;
  gap: var(--space-2);
  margin-top: var(--space-3);
}

.avatar-group__title {
  margin: var(--space-3) 0 0;
  font-size: var(--text-md);
  letter-spacing: 0.04em;
  color: var(--ink-muted);
}

.avatar-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(3.5rem, 1fr));
  gap: var(--space-2);
}

.avatar-choice {
  display: grid;
  place-items: center;
  width: 3.5rem;
  height: 3.5rem;
  padding: 0;
  border: 1px solid var(--card-edge);
  border-radius: var(--radius-field);
  background: var(--card);
  color: var(--ink);
  cursor: pointer;
  transition: transform 120ms var(--ease-out);
}

.avatar-choice:hover:not([aria-disabled="true"]) {
  border-color: var(--ink-muted);
}

.avatar-choice:active:not([aria-disabled="true"]) {
  transform: translateY(1px);
}

.avatar-choice[aria-checked="true"] {
  background: var(--ink);
  color: var(--card);
  border-color: var(--ink);
  box-shadow: 0 0 0 2px var(--card), 0 0 0 4px var(--ink);
}

.avatar-choice[aria-disabled="true"] {
  opacity: 0.55;
  cursor: not-allowed;
}

.avatar-choice__none {
  font: 800 var(--text-sm) / 1 var(--font-display);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.account {
  margin-top: var(--space-6);
}

.account h2 {
  margin-top: 0;
}

.account__list {
  margin: 0 0 var(--space-4);
}

.account__list dt {
  font-size: var(--text-sm);
  font-weight: 600;
  color: var(--on-board-muted);
}

.account__list dd {
  display: grid;
  gap: var(--space-1);
  margin: var(--space-1) 0 0;
}

.account__email {
  font-weight: 600;
  overflow-wrap: anywhere;
}

.account__hint {
  font-size: var(--text-sm);
  color: var(--on-board-muted);
}

.account__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
}

.account__links {
  margin-top: var(--space-5);
  font-size: var(--text-sm);
}

/* ---------- Admin: a user's public identity ---------- */

.admin-identity {
  display: flex;
  align-items: center;
  gap: var(--space-2);
}

.admin-identity .avatar {
  flex: none;
}

/* ---------- Events: the schedule, one small heading per venue day, compact cards (no seal/vote/star) ---------- */

/* Events already over: closed at the end of the schedule */
.event-past {
  margin-top: var(--space-5);
}

.event-past__summary {
  display: flex;
  align-items: center;
  min-height: var(--tap);
  font: 800 var(--text-lg) / 1 var(--font-display);
  letter-spacing: 0.03em;
  text-transform: uppercase;
  color: var(--on-board-muted);
  cursor: pointer;
}

.event-past[open] .event-past__summary {
  color: var(--on-board);
}

.events-note {
  margin: calc(var(--space-2) * -1) 0 var(--space-4);
  font-size: var(--text-sm);
  color: var(--on-board-muted);
}

.event-day + .event-day {
  margin-top: var(--space-5);
}

.event-day__title {
  margin: 0 0 var(--space-2);
  font-size: var(--text-lg);
  letter-spacing: 0.03em;
  color: var(--on-board);
}

.event-list {
  display: grid;
  gap: var(--space-3);
  margin: 0;
  padding: 0;
  list-style: none;
}

.card--event {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  padding: var(--space-3) var(--space-4);
}

.card--event::before {
  top: 0;
  width: 1.75rem;
  height: 0.3rem;
  border-radius: 0 0 999px 999px;
  box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.5);
}

.event-card__title {
  font-size: 1.25rem;
  line-height: 1.05;
  overflow-wrap: anywhere;
}

.event-card__when {
  margin: 0;
  font-size: var(--text-sm);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  color: var(--ink);
}

.event-card__where {
  margin: 0;
  font-size: 0.8125rem;
  font-weight: 700;
  color: var(--ink-muted);
}

.event-card__desc {
  margin: var(--space-1) 0 0;
  font-size: var(--text-sm);
  line-height: 1.4;
  white-space: pre-line;
  overflow-wrap: anywhere;
}

/* ---------- Admin: the Events form (date + time pairs, per-field errors) ---------- */

.field-pair {
  display: grid;
  grid-template-columns: minmax(0, 1.2fr) minmax(0, 1fr);
  gap: var(--space-2);
}

input[type="date"] {
  width: 100%;
  min-height: var(--tap);
  padding: var(--space-2) var(--space-3);
  border: 2px solid var(--card-edge);
  border-radius: var(--radius-field);
  background: var(--card);
  color: var(--ink);
  font: inherit;
}

.field-error {
  margin: var(--space-1) 0 0;
  font-size: var(--text-sm);
  font-weight: 600;
  color: #7f1d0b;
}

.field-error:empty {
  display: none;
}

.form-panel [aria-invalid="true"] {
  border-color: var(--danger);
}

.event-admin__when {
  margin: 0;
  font-size: var(--text-sm);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

.event-when {
  min-width: 0;
  margin: 0 0 var(--space-4);
  padding: 0;
  border: 0;
}

.event-when legend {
  padding: 0;
  margin-bottom: var(--space-1);
  font-weight: 700;
}

.event-when label {
  font-weight: 400;
  color: var(--ink-muted);
}

/* ---------- Favorite note dialog (built by js/favorite-dialog.js, reuses .help-dialog) ---------- */

.favnote__head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-2);
}

.favnote__head h2 {
  margin: 0 0 var(--space-1);
}

.fav--inline {
  position: static;
  flex: none;
  margin: -0.5rem -0.5rem 0 0;
}

.favnote__store {
  margin: 0 0 var(--space-3);
  font-weight: 700;
  color: var(--ink-muted);
}

.favnote__count {
  margin: var(--space-1) 0 0;
  text-align: right;
  font-size: var(--text-sm, 0.875rem);
  color: var(--ink-muted);
}

.favnote__count--over {
  color: var(--danger);
  font-weight: 700;
}

.favnote__warn,
.favnote__error {
  margin: 0 0 var(--space-3);
  font-weight: 700;
}

.favnote__error {
  color: var(--danger);
}

.favnote__actions {
  display: flex;
  justify-content: flex-end;
  gap: var(--space-2);
  margin-top: var(--space-4);
}

/* Cancel / Keep sit on white stock: the quiet button's board colours would vanish there */
.favnote__actions .btn-quiet {
  color: var(--ink);
  border-color: var(--ink-muted);
}

.favnote__actions .btn-quiet:hover:not(:disabled) {
  border-color: var(--ink);
}

/* A long link in a panel (the privacy page's GitHub address) wraps instead of widening the page */
.form-panel a {
  overflow-wrap: anywhere;
}

/* ---------- Notification bell and popup ---------- */

.bell-btn {
  position: relative;
}

.bell-badge {
  position: absolute;
  top: 0;
  right: 0;
  min-width: 1.25rem;
  height: 1.25rem;
  padding: 0 var(--space-1);
  border-radius: 999px;
  background: var(--on-board); /* not vermilion: red would read as "closed"; inverts with the board in both schemes */
  color: var(--board);
  font-size: var(--text-xs);
  font-weight: 800;
  line-height: 1.25rem;
  text-align: center;
  font-variant-numeric: tabular-nums;
}

.bell-badge[hidden] {
  display: none;
}

.notif__list {
  display: grid;
  gap: var(--space-2);
  margin: 0;
  padding: 0;
  list-style: none;
}

.notif__item {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding-block: var(--space-2);
  border-top: 1px solid var(--ink-line);
}

.notif__item:first-child {
  border-top: 0;
}

.notif__link {
  display: grid;
  flex: 1 1 auto;
  min-width: 0;
  min-height: var(--tap);
  align-content: center;
  color: inherit;
  font-weight: 600;
  text-decoration: none;
}

.notif__time {
  font-size: var(--text-xs);
  font-weight: 400;
  color: var(--ink-muted);
}

.notif__empty {
  padding: var(--space-3) 0;
  color: var(--ink-muted);
}

.notif__read {
  flex: none;
  font-size: var(--text-sm);
}

.notif__actions {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  gap: var(--space-2);
  margin-top: var(--space-4);
}

.notif-dialog .btn-quiet {
  color: var(--ink);
}

.notif__list--page {
  margin-top: var(--space-3);
}

.notif__dot {
  flex: none;
  width: 0.625rem;
  height: 0.625rem;
  border-radius: 50%;
  background: var(--focus-on-card); /* unread: the teal accent, never a status hue */
}

.notif__item.is-unread .notif__link {
  font-weight: 800;
}

/* ---------- Settings: help row and iOS-style notification switches ---------- */

.help-row {
  margin: 0 0 var(--space-4);
}

.toggle-row + .toggle-row {
  border-top: 1px solid var(--ink-line);
}

.toggle {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  min-height: var(--tap);
  padding-block: var(--space-3);
  cursor: pointer;
}

.toggle__text {
  display: grid;
  gap: var(--space-1);
  min-width: 0;
}

.toggle__label {
  font-weight: 700;
}

.toggle__hint {
  font-size: var(--text-sm);
  color: var(--ink-muted);
}

.toggle__input {
  position: absolute;
  right: 0;
  opacity: 0;
  width: 3.25rem;
  height: 2rem;
  margin: 0;
}

.toggle__track {
  position: relative;
  flex: none;
  width: 3.25rem;
  height: 2rem;
  border-radius: 999px;
  background: var(--ink-muted);
  transition: background-color 0.18s ease;
}

.toggle__track::after {
  content: "";
  position: absolute;
  top: 0.1875rem;
  left: 0.1875rem;
  width: 1.625rem;
  height: 1.625rem;
  border-radius: 50%;
  background: var(--card);
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.4);
  transition: transform 0.18s ease;
}

/* On: teal, not the status green (green and vermilion mean open and closed only) */
.toggle__input:checked + .toggle__track {
  background: var(--focus-on-card);
}

.toggle__input:checked + .toggle__track::after {
  transform: translateX(1.25rem);
}

.toggle__input:focus-visible + .toggle__track {
  outline: 3px solid var(--focus-on-card);
  outline-offset: 2px;
}

.toggle__input:disabled + .toggle__track,
.toggle__input[aria-disabled="true"] + .toggle__track {
  opacity: 0.55;
}

@media (prefers-reduced-motion: reduce) {
  .toggle__track,
  .toggle__track::after {
    transition: none;
  }
}

.notif-dialog .notif__list {
  padding-left: 0;
}

.notif__list {
  grid-template-columns: minmax(0, 1fr);
}

/* ---------- Camera dialog ---------- */

.camera-dialog {
  width: min(100% - 2 * var(--gutter), 34rem);
}

.camera__stage {
  display: grid;
  margin-block: var(--space-3);
  border-radius: var(--radius-card);
  overflow: hidden;
  background: #000;
}

.camera__stage video,
.camera__stage img {
  display: block;
  width: 100%;
  max-height: 55dvh;
  object-fit: cover;
}

.camera__stage [hidden] {
  display: none;
}

.camera__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  justify-content: flex-end;
}

.camera-dialog .btn-quiet {
  color: var(--ink);
}

/* ---------- Owner photo manager ---------- */

.photos {
  margin-top: var(--space-5);
}

/* On the add-store form the section sits inside the form's own panel: no second card */
.form-panel .photos {
  margin: var(--space-4) 0;
  padding: 0;
  box-shadow: none;
  border-radius: 0;
}

.photo-slots {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(9rem, 1fr));
  gap: var(--space-3);
  margin: var(--space-3) 0 0;
  padding: 0;
  list-style: none;
}

.photo-slot {
  display: grid;
  gap: var(--space-2);
  align-content: start;
  padding: var(--space-2);
  border: 1px solid var(--ink-line);
  border-radius: var(--radius-card);
}

.photo-slot__img {
  display: block;
  width: 100%;
  aspect-ratio: 1;
  object-fit: cover;
  border-radius: calc(var(--radius-card) - 4px);
}

.photo-slot__title,
.photo-slot__badge {
  margin: 0;
  font-size: var(--text-sm);
}

.photo-slot__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-1);
}

.photo-slot--empty {
  place-items: center;
  min-height: 9rem;
  border-style: dashed;
}

/* ---------- Public photo square and carousel (store detail) ---------- */

#photos:empty {
  display: none;
}

.photo-square {
  position: relative;
  display: block;
  width: min(100%, 12rem);
  aspect-ratio: 1;
  margin-top: var(--space-4);
  padding: 0;
  border: 0;
  border-radius: var(--radius-card);
  overflow: hidden;
  background: var(--card);
  cursor: pointer;
}

.photo-square img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.photo-square__more {
  position: absolute;
  right: var(--space-2);
  bottom: var(--space-2);
  padding: 0 var(--space-2);
  border-radius: 999px;
  background: rgba(16, 32, 42, 0.85);
  color: #fff;
  font-weight: 800;
  line-height: 1.75rem;
}

.photo-square:focus-visible {
  outline: 3px solid var(--focus);
  outline-offset: 3px;
}

.photo-dialog {
  width: min(100% - 2 * var(--gutter), 36rem);
}

.photo-carousel {
  display: flex;
  align-items: center;
  gap: var(--space-2);
}

.photo-carousel__stage {
  flex: 1 1 auto;
  min-width: 0;
}

.photo-carousel__stage img {
  display: block;
  width: 100%;
  max-height: 65dvh;
  object-fit: contain;
  border-radius: calc(var(--radius-card) - 4px);
}

.photo-carousel__nav {
  flex: none;
  min-width: var(--tap);
  color: var(--ink);
  font-size: 1.75rem;
  line-height: 1;
}

.photo-carousel__count {
  margin: var(--space-2) 0 0;
  text-align: center;
  color: var(--ink-muted);
  font-variant-numeric: tabular-nums;
}

.photo-review {
  margin-bottom: var(--space-3);
}

.photo-review__img {
  display: block;
  width: 100%;
  max-height: 60dvh;
  object-fit: contain;
  border-radius: calc(var(--radius-card) - 4px);
  background: #000;
}

/* Admin > Photo approvals: the steps, then every pending photo in one grid; a tap marks one to reject */
.photo-steps,
.photo-batch {
  margin-bottom: var(--space-3);
}

.photo-steps ol {
  margin: var(--space-2) 0;
  padding-left: 1.25rem;
}

.photo-steps li {
  margin-bottom: var(--space-1);
}

.photo-batch__grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
  gap: var(--space-2);
  margin: var(--space-3) 0;
  padding: 0;
  list-style: none;
}

.photo-batch__tile {
  position: relative;
  display: block;
  width: 100%;
  padding: 0;
  border: 3px solid transparent;
  border-radius: calc(var(--radius-card) - 4px);
  background: #000;
  color: inherit;
  font: inherit;
  text-align: left;
  cursor: pointer;
  overflow: hidden;
}

.photo-batch__tile img {
  display: block;
  width: 100%;
  aspect-ratio: 1;
  object-fit: contain;
}

.photo-batch__name {
  display: block;
  padding: var(--space-1) var(--space-2);
  background: #fff;
  color: var(--ink);
  font-size: 0.875rem;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.photo-batch__mark {
  position: absolute;
  top: var(--space-2);
  left: var(--space-2);
  display: none;
  padding: 2px var(--space-2);
  border-radius: 999px;
  background: var(--danger);
  color: #fff;
  font-weight: 700;
  font-size: 0.8125rem;
}

.photo-batch__tile[aria-pressed="true"] {
  border-color: var(--danger);
}

.photo-batch__tile[aria-pressed="true"] img {
  opacity: 0.45;
}

.photo-batch__tile[aria-pressed="true"] .photo-batch__mark {
  display: block;
}

.photo-batch__tile:focus-visible {
  outline: 3px solid var(--focus-on-card);
  outline-offset: 2px;
}

/* The arrows sit over the photo so the image gets the full width of the dialog */
.photo-carousel {
  position: relative;
}

.photo-carousel__nav {
  position: absolute;
  top: 50%;
  z-index: 1;
  transform: translateY(-50%);
  min-height: var(--tap);
  padding: 0;
  border-radius: 50%;
  background: rgba(16, 32, 42, 0.7);
  color: #fff;
}

.photo-carousel__nav[data-step="-1"] {
  left: var(--space-2);
}

.photo-carousel__nav[data-step="1"] {
  right: var(--space-2);
}

/* Grid items must be allowed to shrink below the photo's own size, and long button labels wrap */
.photo-slots {
  grid-template-columns: repeat(auto-fill, minmax(min(9rem, 100%), 1fr));
}

.photo-slot {
  min-width: 0;
}

.photo-slot__img {
  min-width: 0;
  max-width: 100%;
  height: auto;
}

.photo-slot__actions .btn {
  white-space: normal;
  text-align: center;
}

/* .btn sets its own display, which beats the hidden attribute: the dialog shows only the buttons of its current step */
.camera-dialog [hidden] {
  display: none !important;
}

.camera-dialog .hint {
  color: var(--ink-muted);
}

/* ---------- First-run tour ---------- */

.tour-dialog {
  width: min(100% - 2 * var(--gutter), 28rem);
  text-align: center;
}

.tour-dialog [hidden] {
  display: none !important;
}

.tour__progress {
  margin: 0;
  font-size: var(--text-sm);
  color: var(--ink-muted);
}

.tour__icon {
  display: grid;
  place-items: center;
  width: 4rem;
  height: 4rem;
  margin: var(--space-3) auto;
  border-radius: 50%;
  background: var(--board);
  color: var(--on-board);
}

.tour-dialog h2 {
  margin: 0 0 var(--space-2);
}

.tour__text {
  min-height: 7.5rem;
  margin: 0 auto;
  max-width: 34ch;
  text-align: left;
}

.tour__dots {
  display: flex;
  justify-content: center;
  gap: var(--space-2);
  margin-block: var(--space-3);
}

.tour__dot {
  width: 0.625rem;
  height: 0.625rem;
  border-radius: 50%;
  background: var(--ink-line);
}

.tour__dot.is-current {
  background: var(--ink);
}

.tour__actions {
  display: flex;
  justify-content: space-between;
  gap: var(--space-2);
}

.tour__actions .btn-quiet {
  color: var(--ink);
}

.tour__actions [data-tour="next"] {
  margin-left: auto;
}

/* ---------- Account deletion, danger zone, report link, hidden donate cup ---------- */

.delete-dialog ul {
  margin-block: var(--space-2);
}

.delete__actions {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  gap: var(--space-2);
  margin-top: var(--space-4);
}

.delete-dialog .btn-quiet {
  color: var(--ink);
}

.delete-dialog .error:empty {
  display: none;
}

.danger-zone {
  margin-top: var(--space-6);
  padding-top: var(--space-4);
  border-top: 2px solid var(--status-closed);
}

.photo-carousel__report {
  margin: var(--space-2) 0 0;
  text-align: center;
  font-size: var(--text-sm);
}

.photo-carousel__report a {
  color: var(--ink-muted);
}

.donate-btn[hidden] {
  display: none;
}

.board-header .donate-btn[hidden] + .help-btn {
  margin-left: auto;
}
