/* 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));
}

.wordmark {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 800;
  font-size: var(--text-xl);
  line-height: 1;
  text-transform: uppercase;
  letter-spacing: 0.02em;
  white-space: nowrap;
  text-decoration: none;
}

/* The one header control, on the list page only: the "?" that opens the help dialog */
.board-header .help-btn {
  flex: none;
  width: 2.75rem;
  min-height: 2.75rem;
  margin-left: auto;
  padding: 0;
  border-radius: 50%;
}

.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);
}

/* ---------- 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));
}

/* ---------- 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 {
  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) ---------- */

.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);
}

/* ---------- 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);
}

.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;
}

.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);
}

/* 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: the star's 44px box rides up into the card's top padding, centered above the wider
   horizontal pill that hangs under it (round 4: pill rotated 90°; round 5: pill sized up 10%,
   so the rail widened to match it again) */
.card__rail {
  display: flex;
  flex-direction: column;
  align-items: center;
  width: 5.775rem;
  margin: calc(var(--space-3) * -1) calc(var(--space-2) * -1) 0 0;
}

.card__rail .fav {
  position: relative;
  top: auto;
  right: auto;
}

.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--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 a
   yellow warning emoji so it stands out without shouting (full ink, not muted). The emoji is decorative:
   the empty alt text keeps screen readers from announcing it (the first line is the fallback). */
.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: "\26A0\FE0F";
  content: "\26A0\FE0F" / "";
  flex: none;
  font-weight: 400;
}

.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);
}

.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;
}

/* ---------- "Open?" pill: the report control in the list card's rail, above the stretched link ---------- */

.vote-pill {
  position: relative;
  z-index: 2;
  display: flex;
  flex-direction: column;
  align-items: center;
}

.vote-pill__q {
  margin: 0 0 0.1875rem;
  font: 800 0.5625rem / 1 var(--font-display);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  white-space: nowrap;
  color: var(--ink-muted);
}

/* One 5.775rem-wide pill (round 5: the two halves sized up 10% on request, from round 4's 5.25rem),
   split by a vertical hairline: left = looks open, right = looks closed. Radius scaled the same 10%
   (0.825rem) so it keeps the same proportion to the taller pill and still reads as one shape. */
.vote-pill__body {
  display: flex;
  flex-direction: row;
  width: 5.775rem;
  border: 1px solid var(--ink-muted);
  border-radius: 0.825rem;
  background: var(--card);
}

/* Each half is a real button, 2.75rem (44px) tall and half the pill's inner width (~45px) wide, its
   glyph and count side by side; its ::before still extends 2px above and below and 5px past the
   pill's own outer edge (left for the open half, right for the closed one), so each target now
   comfortably exceeds 44 x 44 px while the drawn pill is 92 x 44px. */
.vote {
  position: relative;
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: center;
  gap: 0.275rem;
  flex: 1 1 0;
  min-height: 2.75rem;
  padding: 0 0.4125rem;
  border: 0;
  background: transparent;
  color: var(--ink);
  cursor: pointer;
  transition: background-color 120ms var(--ease-out);
}

.vote::before {
  content: "";
  position: absolute;
  inset: -2px 0;
}

.vote[data-vote="open"] {
  border-radius: calc(0.825rem - 1px) 0 0 calc(0.825rem - 1px);
}

.vote[data-vote="open"]::before {
  inset: -2px 0 -2px -5px;
}

.vote[data-vote="closed"] {
  border-left: 1px solid var(--ink-line);
  border-radius: 0 calc(0.825rem - 1px) calc(0.825rem - 1px) 0;
}

.vote[data-vote="closed"]::before {
  inset: -2px -5px -2px 0;
}

/* Round 6: the vote pill spells it out ("Y" / "N") instead of the seal's check/cross mask, since the
   community is answering a yes/no question, not confirming a status. The seal and the switch keep
   the drawn check/cross (--glyph-check / --glyph-cross, untouched); this is the pill's own letter,
   drawn as generated content so the markup and votes.js stay unchanged. */
.vote__glyph {
  display: block;
  flex: none;
  font: 800 0.9625rem / 1 var(--font-display);
  transition: transform 120ms var(--ease-out);
}

.vote__glyph::before {
  content: "Y";
}

.vote__glyph--closed::before {
  content: "N";
}

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

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

/* Confirmed: the half fills with its status colour and the glyph and number turn on-seal white (a fill and a
   glyph change together, plus aria-pressed), and the side becomes inert */
.vote[aria-pressed="true"] {
  color: var(--on-seal);
  cursor: default;
}

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

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

/* The ring sits outside the half and above its neighbour */
.card .vote:focus-visible {
  z-index: 1;
  outline-offset: 2px;
}

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

/* Owners: the two counts as read-only text with the same small glyphs */
.vote-tally {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-1);
  margin: 0;
  font: 700 0.75rem / 1 var(--font-body);
  font-variant-numeric: tabular-nums;
  color: var(--ink);
}

.vote-tally__side {
  display: flex;
  align-items: center;
  gap: 0.1875rem;
}

.vote-tally .vote__glyph {
  font-size: 0.75rem;
  color: var(--ink-muted);
}

/* ---------- 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;
}

.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-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);
}
