/* DizzyMeet, in the arcade look: indigo night, magenta and cyan, a little
   glow. One theme on purpose. The meets are evening events and the site is
   the meet's own signage, so it does not follow the phone's light mode.

   Magenta is the accent for actions, cyan for links and labels. The status
   colors are deliberately kept off both, so green only ever means checked in,
   amber only means money owed, and red only means strikes. */

/* The one downloaded font, self-hosted (SIL OFL), 10KB, display lines only.
   Body text stays on system fonts, so door mode still paints instantly and
   swaps the headline face in when the file lands. */
@font-face {
  font-family: "Chakra Petch";
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("/chakra-petch-700.woff2") format("woff2");
}

:root {
  /* Without this the browser draws native controls (checkboxes, radios,
     selects, the date picker) in light mode: oversized white boxes fighting
     the dark rows they sit in. */
  color-scheme: dark;
  --paper: #0d0b1a;
  --surface: #171430;
  --ink: #eeeaff;
  --muted: #8f8ab0;
  --line: #2c2750;
  --row-alt: #1b1738;
  --accent: #ff3d9a;
  --accent-strong: #ff6cb2;
  --accent-ink: #14051a;
  --accent-soft: #2b1233;
  --accent-2: #4de1ff;
  --ok: #3ddc97;
  --ok-soft: #10241d;
  --warn: #ffc44d;
  --warn-soft: #2a2214;
  --danger: #ff6b7a;
  --danger-soft: #2e1420;
  --radius: 14px;
  --glow: 0 0 22px rgb(255 61 154 / 0.35);
  --shadow-1: 0 1px 2px rgb(0 0 0 / 0.35);
  --shadow-2: 0 2px 6px rgb(0 0 0 / 0.4), 0 8px 24px rgb(0 0 0 / 0.35);
  --font: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --display: "Chakra Petch", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  --mono: ui-monospace, SFMono-Regular, "SF Mono", Consolas, "Liberation Mono", monospace;
}

* {
  box-sizing: border-box;
}

/* The hidden attribute must win over any display a class sets, or the RSVP
   form stays on screen behind its own success panel. */
[hidden] {
  display: none !important;
}

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--font);
  font-size: 16px;
  line-height: 1.5;
  -webkit-text-size-adjust: 100%;
}

a {
  color: var(--accent-2);
}

:focus-visible {
  outline: 2px solid var(--accent-2);
  outline-offset: 2px;
  border-radius: 4px;
}

.shell {
  max-width: 60rem;
  margin: 0 auto;
  padding: 1.5rem 1rem 2rem;
}

.public-shell {
  max-width: 34rem;
  padding-top: 3rem;
  padding-bottom: 4rem;
}

.public-staff-link {
  margin-top: 3.5rem;
  font-size: 0.85rem;
}

.public-staff-link a {
  color: var(--muted);
}

h1 {
  font-family: var(--display);
  font-size: 1.6rem;
  line-height: 1.2;
  margin: 0.2rem 0 0.4rem;
  text-wrap: balance;
  letter-spacing: 0.01em;
}

h2 {
  font-size: 1rem;
  margin: 0;
}

.page-head {
  margin-bottom: 1.5rem;
}

.page-sub {
  color: var(--muted);
  margin: 0 0 1rem;
  font-size: 0.94rem;
}

.back {
  display: inline-block;
  font-size: 0.85rem;
  text-decoration: none;
  color: var(--muted);
  margin-bottom: 0.4rem;
}

.back:hover {
  color: var(--accent);
}

.back::before {
  content: "\2190\00a0";
}

.dot {
  color: var(--muted);
  padding: 0 0.3rem;
}

.empty-state {
  color: var(--muted);
  padding: 2rem 0;
  text-align: center;
}

.hint {
  margin: 0.35rem 0 0;
  font-size: 0.84rem;
  color: var(--muted);
}

/* Public landing */

.home-head {
  margin-bottom: 2rem;
}

.body-home h1 {
  font-size: 2rem;
}

.home-group-name {
  font-size: 1.1rem;
  margin: 2rem 0 0.8rem;
}

.home-meet {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow-1);
  padding: 1.4rem 1.4rem 1.5rem;
  margin-bottom: 1.2rem;
}

.home-meet-label {
  margin: 0;
  font-size: 0.75rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--accent);
  font-weight: 600;
}

.home-meet-date {
  font-size: 1.45rem;
  line-height: 1.25;
  margin: 0.25rem 0 0.5rem;
  text-wrap: balance;
}

.home-meet-detail {
  margin: 0 0 0.5rem;
  color: var(--muted);
  font-size: 0.94rem;
}

.home-meet .button-primary {
  margin-top: 0.6rem;
}

.home-quiet {
  color: var(--muted);
}

.home-telegram {
  font-size: 0.94rem;
  color: var(--muted);
}

.head-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
}

/* Meets list */

.month {
  margin-bottom: 2rem;
}

.month-label {
  font-size: 0.75rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--muted);
  margin-bottom: 0.6rem;
}

.meet-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.meet-card {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 0.15rem 1rem;
  align-items: center;
  padding: 0.9rem 1rem;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow-1);
  text-decoration: none;
  color: inherit;
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

.meet-card:hover {
  border-color: var(--accent);
  box-shadow: var(--shadow-2);
}

.meet-date {
  font-weight: 600;
}

/* Only rendered once a second group exists, so it never adds noise for BloNo
   alone. */
.meet-group {
  display: inline-block;
  font-size: 0.7rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  padding: 0.15rem 0.5rem;
  margin-right: 0.4rem;
  border-radius: 999px;
  background: var(--accent-soft);
  color: var(--accent);
  vertical-align: middle;
}

.page-group {
  margin: 0;
  font-size: 0.8rem;
  text-transform: uppercase;
  letter-spacing: 0.07em;
  color: var(--accent);
}

.meet-meta {
  grid-column: 1;
  color: var(--muted);
  font-size: 0.88rem;
}

.pill {
  grid-row: 1 / span 2;
  grid-column: 2;
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  padding: 0.2rem 0.6rem;
  border-radius: 999px;
  border: 1px solid var(--line);
  color: var(--muted);
}

.pill-open {
  background: var(--accent-soft);
  border-color: transparent;
  color: var(--accent);
}

/* Stats and buttons */

.stat-row {
  display: flex;
  gap: 1.5rem;
  margin: 1rem 0;
}

.stat b {
  display: block;
  font-size: 1.5rem;
  font-variant-numeric: tabular-nums;
  line-height: 1.1;
}

.stat span {
  font-size: 0.8rem;
  color: var(--muted);
}

.stat-warn b {
  color: var(--warn);
}

.action-row {
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem;
  align-items: center;
}

.button-primary {
  display: inline-block;
  background: var(--accent);
  color: var(--accent-ink);
  text-decoration: none;
  text-align: center;
  font: inherit;
  font-weight: 700;
  border: 0;
  cursor: pointer;
  padding: 0.75rem 1.4rem;
  border-radius: var(--radius);
  min-height: 48px;
  line-height: 1.6;
  box-shadow: var(--glow);
  transition: background-color 0.15s ease;
}

.button-primary:hover {
  background: var(--accent-strong);
}

.button-primary:disabled {
  opacity: 0.6;
  cursor: default;
}

.button-secondary {
  display: inline-block;
  background: var(--surface);
  color: var(--accent);
  text-decoration: none;
  text-align: center;
  font: inherit;
  font-weight: 600;
  cursor: pointer;
  padding: 0.75rem 1.4rem;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  min-height: 48px;
  line-height: 1.6;
  transition: border-color 0.15s ease;
}

.button-secondary:hover {
  border-color: var(--accent);
}

.button-wide {
  display: block;
  width: 100%;
}

.button-small {
  padding: 0.45rem 0.9rem;
  min-height: 40px;
  font-size: 0.88rem;
}

/* Meet management: the status row and the shared RSVP link on a meet's page. */

.meet-manage {
  margin-top: 0.9rem;
  padding-top: 0.9rem;
  border-top: 1px solid var(--line);
}

.share-line {
  margin: 0.6rem 0 0;
  font-size: 0.88rem;
  color: var(--muted);
}

/* The new-meet and edit-meet forms reuse the RSVP form's field styles. */

.form-card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow-1);
  padding: 1.4rem;
  display: flex;
  flex-direction: column;
  gap: 1.3rem;
  max-width: 34rem;
}

.field-pair {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1rem;
}

.field input[type="number"],
.field input[type="date"] {
  width: 100%;
  font: inherit;
  color: inherit;
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: 0.7rem 0.9rem;
  min-height: 48px;
}

.field input[type="number"]:focus,
.field input[type="date"]:focus {
  outline: 2px solid var(--accent);
  outline-offset: 0;
  border-color: transparent;
}

/* Activity page */

.activity-section {
  margin-bottom: 2rem;
}

.cell-quiet {
  color: var(--muted);
  white-space: nowrap;
}

/* RSVP form */

.rsvp-head {
  margin-bottom: 1.2rem;
}

.rsvp-form {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow-1);
  padding: 1.4rem;
  display: flex;
  flex-direction: column;
  gap: 1.3rem;
}

.field {
  border: 0;
  padding: 0;
  margin: 0;
  min-width: 0;
}

/* Field-name labels only. Without the :not(.choice), this rule's higher
   specificity turns the checkbox and radio rows back into block flow and
   their flex layout below never applies. */
.field > label:not(.choice),
.field > legend {
  display: block;
  font-weight: 600;
  font-size: 0.94rem;
  padding: 0;
  margin: 0 0 0.4rem;
}

.field input[type="text"],
.field input[type="email"] {
  width: 100%;
  font: inherit;
  color: inherit;
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: 0.7rem 0.9rem;
  min-height: 48px;
}

.field input[type="text"]:focus,
.field input[type="email"]:focus {
  outline: 2px solid var(--accent);
  outline-offset: 0;
  border-color: transparent;
}

.choice {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  min-height: 48px;
  padding: 0.65rem 0.8rem;
  border: 1px solid var(--line);
  border-radius: 10px;
  cursor: pointer;
  font-size: 0.94rem;
}

.choice + .choice {
  margin-top: 0.5rem;
}

.choice input {
  width: 1.15rem;
  height: 1.15rem;
  margin: 0;
  accent-color: var(--accent);
  flex-shrink: 0;
}

.choice:has(input:checked) {
  border-color: var(--accent);
  background: var(--accent-soft);
}

.field .choice + .hint {
  margin-top: 0.45rem;
}

.field legend + .hint {
  margin: 0 0 0.6rem;
}

.rules {
  margin: 0 0 0.6rem;
  font-size: 0.86rem;
  color: var(--muted);
  background: var(--paper);
  border-radius: 10px;
  padding: 0.7rem 0.9rem;
}

.form-error {
  margin: 0;
  background: var(--danger-soft);
  color: var(--danger);
  padding: 0.7rem 1rem;
  border-radius: 10px;
  font-size: 0.9rem;
}

.rsvp-done {
  background: var(--ok-soft);
  border: 1px solid transparent;
  border-radius: var(--radius);
  padding: 1.4rem;
}

.rsvp-done h2 {
  color: var(--ok);
  font-size: 1.2rem;
  margin-bottom: 0.3rem;
}

.rsvp-done p {
  margin: 0 0 0.4rem;
}

.rsvp-done:focus {
  outline: none;
}

/* Roster table */

.table-scroll {
  overflow-x: auto;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow-1);
}

.roster-table {
  border-collapse: collapse;
  width: 100%;
  font-size: 0.9rem;
}

.roster-table th {
  text-align: left;
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--muted);
  font-weight: 600;
  padding: 0.7rem 0.8rem;
  border-bottom: 1px solid var(--line);
  white-space: nowrap;
}

.roster-table td {
  padding: 0.5rem 0.8rem;
  border-bottom: 1px solid var(--line);
  vertical-align: middle;
}

.roster-table tbody tr:nth-child(even) td {
  background: var(--row-alt);
}

.roster-table tr:last-child td {
  border-bottom: 0;
}

.cell-handle,
.cell-pay {
  font-family: var(--mono);
  font-size: 0.85rem;
  white-space: nowrap;
}

.paid-select,
.note-input {
  font: inherit;
  color: inherit;
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 0.35rem 0.5rem;
  min-height: 36px;
}

.note-input {
  width: 14rem;
  resize: vertical;
  font-size: 0.85rem;
}

.is-saving {
  border-color: var(--accent);
}

.is-failed {
  border-color: var(--danger);
}

/* Chips */

.chip {
  display: inline-block;
  font-size: 0.72rem;
  padding: 0.2rem 0.55rem;
  border-radius: 999px;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}

.chip-in {
  background: var(--ok-soft);
  color: var(--ok);
}

.chip-wait {
  color: var(--muted);
}

.chip-strike {
  background: var(--danger-soft);
  color: var(--danger);
  margin-left: 0.4rem;
}

.chip-cash {
  background: var(--warn-soft);
  color: var(--warn);
}

/* Door mode */

.body-door .shell {
  max-width: 34rem;
  padding-top: 0;
}

.door-head {
  position: sticky;
  top: 0;
  z-index: 2;
  background: var(--paper);
  padding: 1rem 0 0.6rem;
  border-bottom: 1px solid var(--line);
}

.door-counts {
  margin: 0 0 0.7rem;
  color: var(--muted);
  font-size: 0.9rem;
  font-variant-numeric: tabular-nums;
}

/* Sits above the sticky door header and the roster table alike. */
.toast {
  position: fixed;
  left: 50%;
  bottom: 1.2rem;
  transform: translateX(-50%);
  z-index: 10;
  max-width: calc(100vw - 2rem);
  background: var(--ink);
  color: var(--paper);
  padding: 0.6rem 1.1rem;
  border-radius: 999px;
  font-size: 0.88rem;
  box-shadow: 0 6px 20px rgb(0 0 0 / 0.25);
}

.toast[data-kind="error"] {
  background: var(--danger);
  color: #ffffff;
}

.door-search {
  width: 100%;
  font: inherit;
  font-size: 1.05rem;
  padding: 0.8rem 1rem;
  min-height: 52px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--surface);
  color: inherit;
}

.door-search:focus {
  outline: 2px solid var(--accent);
  outline-offset: 0;
  border-color: transparent;
}

.door-filters {
  display: flex;
  gap: 0.4rem;
  margin-top: 0.6rem;
  overflow-x: auto;
  padding-bottom: 0.2rem;
}

.chip-button {
  font: inherit;
  font-size: 0.85rem;
  padding: 0.4rem 0.85rem;
  min-height: 40px;
  border-radius: 999px;
  border: 1px solid var(--line);
  background: var(--surface);
  color: var(--muted);
  cursor: pointer;
  white-space: nowrap;
}

.chip-button.is-on {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--accent-ink);
  box-shadow: 0 0 14px rgb(255 61 154 / 0.4);
}

.door-error {
  background: var(--danger-soft);
  color: var(--danger);
  padding: 0.7rem 1rem;
  border-radius: var(--radius);
  margin: 0.8rem 0 0;
  font-size: 0.9rem;
}

.door-list {
  list-style: none;
  margin: 0.8rem 0 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.door-row {
  display: flex;
  flex-wrap: wrap;
  align-items: stretch;
  gap: 0.5rem;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  overflow: hidden;
}

.door-row.is-in {
  background: var(--ok-soft);
  border-color: var(--ok);
  box-shadow: 0 0 12px rgb(61 220 151 / 0.18);
}

.door-row.is-cash {
  border-left: 4px solid var(--warn);
}

.door-main {
  flex: 1;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 0.1rem;
  padding: 0.8rem 1rem;
  min-height: 64px;
  border: 0;
  background: none;
  color: inherit;
  font: inherit;
  text-align: left;
  cursor: pointer;
}

.door-row.is-in .door-main {
  cursor: default;
}

.door-handle {
  font-family: var(--mono);
  font-size: 1rem;
  font-weight: 600;
  word-break: break-all;
}

.door-sub {
  font-size: 0.82rem;
  color: var(--muted);
  word-break: break-all;
}

.door-side {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.6rem 0.8rem 0.6rem 0;
}

.door-undo,
.door-note-toggle {
  font: inherit;
  font-size: 0.78rem;
  padding: 0.35rem 0.7rem;
  min-height: 34px;
  border-radius: 8px;
  border: 1px solid var(--line);
  background: var(--surface);
  color: var(--muted);
  cursor: pointer;
}

.door-note {
  flex: 1 0 100%;
  padding: 0 1rem 0.8rem;
}

.door-note textarea {
  width: 100%;
  font: inherit;
  font-size: 0.88rem;
  color: inherit;
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 0.5rem;
  resize: vertical;
}

.door-row.just-checked {
  animation: flash 0.5s ease-out;
}

@keyframes flash {
  from {
    background: var(--ok);
  }
}

@media (prefers-reduced-motion: reduce) {
  .door-row.just-checked {
    animation: none;
  }

  .meet-card,
  .button-primary,
  .button-secondary {
    transition: none;
  }
}

/* Footer */

.app-footer {
  max-width: 60rem;
  margin: 0 auto;
  padding: 1.5rem 1rem 2.5rem;
  color: var(--muted);
  font-size: 0.78rem;
  border-top: 1px solid var(--line);
}

/* Public pages: the marquee versions of the arcade look.

   The attendee-facing pages get the poster-scale type and the gradient date;
   staff pages share the same palette above but stay plain, because rosters
   and forms are work surfaces. */

.body-public .home-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  border-bottom: 1px solid var(--line);
  padding-bottom: 0.9rem;
  margin-bottom: 0;
}

.body-public.body-home h1 {
  font-size: 1.05rem;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: var(--accent);
  text-shadow: 0 0 18px rgb(255 61 154 / 0.55);
}

.body-public .home-group-name {
  font-size: 0.9rem;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: var(--muted);
  margin: 2.4rem 0 0;
}

/* The meet is the marquee; no card box around it. */
.body-public .home-meet {
  background: none;
  border: 0;
  box-shadow: none;
  padding: 2.4rem 0 0;
  margin-bottom: 1.4rem;
}

.body-public .home-meet-label {
  display: inline-block;
  border: 1px solid var(--accent);
  border-radius: 999px;
  color: var(--accent);
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.16em;
  padding: 0.35rem 0.9rem;
  box-shadow: 0 0 14px rgb(255 61 154 / 0.3), inset 0 0 10px rgb(255 61 154 / 0.12);
}

.body-public .home-meet-date {
  font-family: var(--display);
  font-size: 4.2rem;
  line-height: 1;
  font-weight: 700;
  text-transform: uppercase;
  margin: 1.1rem 0 0.8rem;
  background: linear-gradient(100deg, var(--accent) 10%, var(--accent-2) 90%);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

.home-meet-when {
  font-size: 1.1rem;
  font-weight: 600;
  margin: 0 0 0.2rem;
}

.home-meet-where {
  font-size: 0.94rem;
  color: var(--muted);
  margin: 0;
}

.body-public .fee-strip {
  display: flex;
  gap: 0.8rem;
  margin-top: 1.4rem;
}

.body-public .fee-cell {
  flex: 1;
  text-align: center;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 0.75rem 0.5rem;
}

.body-public .fee-cell b {
  display: block;
  font-family: var(--display);
  font-size: 1.5rem;
  font-weight: 700;
  line-height: 1.2;
  color: var(--accent-2);
}

.body-public .fee-cell span {
  font-size: 0.7rem;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: var(--muted);
}

.body-public .button-primary {
  font-family: var(--display);
  font-weight: 700;
  font-size: 1.15rem;
  text-transform: uppercase;
  letter-spacing: 0.12em;
}

.body-public .home-meet .button-primary {
  margin-top: 1.1rem;
}

/* The RSVP form sits straight on the page; each field is its own panel. */
.body-public .rsvp-head {
  border-bottom: 1px solid var(--line);
  padding-bottom: 1rem;
}

.body-public .rsvp-head h1 {
  font-size: 1.7rem;
  background: linear-gradient(100deg, var(--accent) 10%, var(--accent-2) 90%);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

.body-public .back {
  text-transform: uppercase;
  letter-spacing: 0.12em;
  font-size: 0.78rem;
}

.body-public .rsvp-form {
  background: none;
  border: 0;
  box-shadow: none;
  padding: 1.6rem 0 0;
}

/* The :not(.choice) keeps checkbox and radio rows in sentence case; only the
   field names above them go caps. */
.body-public .field > label:not(.choice),
.body-public .field > legend {
  font-size: 0.78rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  color: var(--accent-2);
}

.body-public .choice {
  background: var(--surface);
  font-size: 0.98rem;
  font-weight: 600;
}

.body-public .choice:has(input:checked) {
  box-shadow: 0 0 14px rgb(255 61 154 / 0.25);
}

.body-public .field input[type="text"],
.body-public .field input[type="email"] {
  background: var(--surface);
}

.body-public .rules {
  background: var(--surface);
}

.body-public .rsvp-done {
  border-color: var(--ok);
  box-shadow: 0 0 14px rgb(61 220 151 / 0.2);
}
