/* ═══════════════════════════════════════════════════════════════════════════
   Tickgen — "Concourse"

   Light-first, cool neutrals, one confident red. Type does most of the work:
   Sora for headings, Manrope for interface, IBM Plex Mono for anything a
   customer reads as data (seat, row, member number, balance).

   Every colour is a token defined on bare :root. Dark redefines tokens only,
   in both the un-stamped (system) state and the explicitly stamped one.
   ═══════════════════════════════════════════════════════════════════════════ */

:root {
  --bg:         #F6F7F9;
  --surface:    #FFFFFF;
  --surface-2:  #F1F3F6;
  --border:     #E4E7EC;
  --border-2:   #D2D7DF;

  --ink:        #0C0E12;
  --ink-2:      #454C59;
  --muted:      #5F6875;

  --accent:     #CE2B37;
  --accent-ink: #FFFFFF;
  --accent-dim: #FDF0F1;
  --accent-line:#F3C9CD;

  --good:       #047857;
  --good-dim:   #E8F5F0;
  --good-line:  #B9DED0;

  --discord:    #5865F2;
  --discord-ink:#FFFFFF;

  --shadow-xs:  0 1px 2px rgba(12, 14, 18, .05);
  --shadow-sm:  0 1px 2px rgba(12, 14, 18, .05), 0 1px 3px rgba(12, 14, 18, .04);
  --shadow-md:  0 1px 2px rgba(12, 14, 18, .04), 0 8px 24px -8px rgba(12, 14, 18, .10);
  --shadow-accent: 0 1px 2px rgba(206, 43, 55, .18), 0 6px 16px -6px rgba(206, 43, 55, .32);

  --font-display: "Sora", system-ui, -apple-system, "Segoe UI", sans-serif;
  --font-body:    "Manrope", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --font-mono:    "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, monospace;

  --r-xs: 6px;
  --r-sm: 9px;
  --r:    12px;
  --r-lg: 16px;
  --r-xl: 22px;

  --page: 1080px;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --bg:         #0B0D11;
    --surface:    #131720;
    --surface-2:  #1A1F2A;
    --border:     #242B37;
    --border-2:   #333C4B;

    --ink:        #F2F4F8;
    --ink-2:      #C3CAD6;
    --muted:      #8C97A8;

    --accent:     #FF6069;
    --accent-ink: #26060A;
    --accent-dim: #2A1116;
    --accent-line:#4A1D24;

    --good:       #34D399;
    --good-dim:   #0E241C;
    --good-line:  #1E4736;

    --discord:    #808CF8;
    --discord-ink:#0B0E1C;

    --shadow-xs:  0 1px 2px rgba(0, 0, 0, .5);
    --shadow-sm:  0 1px 2px rgba(0, 0, 0, .5);
    --shadow-md:  0 1px 2px rgba(0, 0, 0, .5), 0 12px 32px -12px rgba(0, 0, 0, .8);
    --shadow-accent: 0 1px 2px rgba(0, 0, 0, .5), 0 6px 18px -8px rgba(255, 96, 105, .45);
  }
}

:root[data-theme="dark"] {
  --bg:         #0B0D11;
  --surface:    #131720;
  --surface-2:  #1A1F2A;
  --border:     #242B37;
  --border-2:   #333C4B;

  --ink:        #F2F4F8;
  --ink-2:      #C3CAD6;
  --muted:      #8C97A8;

  --accent:     #FF6069;
  --accent-ink: #26060A;
  --accent-dim: #2A1116;
  --accent-line:#4A1D24;

  --good:       #34D399;
  --good-dim:   #0E241C;
  --good-line:  #1E4736;

  --discord:    #808CF8;
  --discord-ink:#0B0E1C;

  --shadow-xs:  0 1px 2px rgba(0, 0, 0, .5);
  --shadow-sm:  0 1px 2px rgba(0, 0, 0, .5);
  --shadow-md:  0 1px 2px rgba(0, 0, 0, .5), 0 12px 32px -12px rgba(0, 0, 0, .8);
  --shadow-accent: 0 1px 2px rgba(0, 0, 0, .5), 0 6px 18px -8px rgba(255, 96, 105, .45);
}

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

/* The browser's [hidden] rule is a UA-stylesheet default, so any author rule
   setting `display` on the same element silently defeats it — the element
   keeps its stale contents on screen. Several things here are toggled with
   the hidden attribute AND set display:flex, so make hidden win outright. */
[hidden] { display: none !important; }

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

body {
  margin: 0;
  min-height: 100vh;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: 15.5px;
  line-height: 1.6;
  letter-spacing: -.005em;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

h1, h2, h3, h4 {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 600;
  letter-spacing: -.028em;
  line-height: 1.15;
  text-wrap: balance;
}

p { margin: 0; }

a { color: inherit; text-decoration-color: var(--border-2); text-underline-offset: 3px; }
a.plain { text-decoration: none; }
a.plain:hover { text-decoration: none; }

:where(a, button, input, select, textarea, [tabindex]):focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: var(--r-xs);
}

::selection { background: var(--accent); color: var(--accent-ink); }

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

/* ── Layout ──────────────────────────────────────────────────────────────── */
.page { width: 100%; max-width: var(--page); margin: 0 auto; padding-inline: 24px; }
@media (max-width: 600px) { .page { padding-inline: 18px; } }

.pad        { padding-block: 44px 64px; }
.pad-narrow { padding-block: 52px 72px; max-width: 560px; margin-inline: auto; }

.stack { display: flex; flex-direction: column; }
.gap-4 { gap: 4px; } .gap-8 { gap: 8px; }  .gap-12 { gap: 12px; }
.gap-16{ gap: 16px; } .gap-20{ gap: 20px; } .gap-28 { gap: 30px; }

.row { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; }
.proto-spacer { flex: 1 1 auto; }

footer {
  border-top: 1px solid var(--border);
  margin-top: 40px;
  padding-block: 28px 40px;
  color: var(--muted);
  font-size: 13px;
}

/* ── Header ──────────────────────────────────────────────────────────────── */
.shell {
  background: color-mix(in srgb, var(--surface) 82%, transparent);
  border-bottom: 1px solid var(--border);
  position: sticky;
  top: 0;
  z-index: 20;
  backdrop-filter: saturate(1.6) blur(12px);
  -webkit-backdrop-filter: saturate(1.6) blur(12px);
}

.app-nav {
  display: flex;
  align-items: center;
  gap: 8px;
  height: 62px;
}

.brand {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 17px;
  letter-spacing: -.035em;
  margin-right: 10px;
}
.brand .mark {
  width: 30px; height: 30px;
  display: block;
  color: var(--accent);
  flex: none;
}
.brand .mark svg { width: 100%; height: 100%; display: block; }

.app-nav nav { display: flex; gap: 2px; }
.app-nav nav button {
  font: inherit;
  font-size: 14px;
  font-weight: 500;
  color: var(--muted);
  background: none;
  border: 0;
  padding: 7px 12px;
  border-radius: var(--r-sm);
  cursor: pointer;
  transition: color .14s, background .14s;
}
.app-nav nav button:hover { color: var(--ink); background: var(--surface-2); }
.app-nav nav button[aria-current="page"] { color: var(--ink); background: var(--surface-2); font-weight: 600; }

.balance-chip {
  margin-left: auto;
  display: inline-flex;
  align-items: baseline;
  gap: 6px;
  padding: 6px 13px;
  border-radius: 100px;
  border: 1px solid var(--border);
  background: var(--surface);
  box-shadow: var(--shadow-xs);
}
.balance-chip b {
  font-family: var(--font-mono);
  font-size: 14px; font-weight: 600;
  font-variant-numeric: tabular-nums;
  color: var(--ink);
}
.balance-chip span {
  font-size: 10px; font-weight: 600;
  letter-spacing: .1em; text-transform: uppercase;
  color: var(--muted);
}

.logout {
  font: inherit; font-size: 14px; font-weight: 500;
  background: none; border: 0; cursor: pointer;
  color: var(--muted); padding: 7px 10px; border-radius: var(--r-sm);
}
.logout:hover { color: var(--ink); background: var(--surface-2); }

.avatar {
  width: 30px; height: 30px; border-radius: 50%;
  background: var(--surface-2); border: 1px solid var(--border);
  display: grid; place-items: center;
  font-size: 11px; font-weight: 600; color: var(--ink-2);
}

/* ── Type ────────────────────────────────────────────────────────────────── */
.eyebrow {
  font-family: var(--font-mono);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--muted);
}

.h-xl { font-size: clamp(34px, 5.2vw, 56px); line-height: 1.04; font-weight: 700; letter-spacing: -.038em; }
.h-lg { font-size: clamp(24px, 3vw, 31px); font-weight: 600; letter-spacing: -.032em; }
.h-md { font-size: 18px; font-weight: 600; letter-spacing: -.022em; }

.sub  { color: var(--ink-2); max-width: 60ch; font-size: 16px; }
.tiny { font-size: 13.5px; color: var(--muted); line-height: 1.55; }
.mono { font-family: var(--font-mono); font-variant-numeric: tabular-nums; }

.note-line {
  font-size: 13px;
  color: var(--muted);
  display: flex; gap: 8px; align-items: flex-start;
}

.empty {
  padding: 40px 24px;
  text-align: center;
  color: var(--muted);
  font-size: 14px;
  border: 1px dashed var(--border-2);
  border-radius: var(--r);
  background: var(--surface);
}

/* ── Buttons ─────────────────────────────────────────────────────────────── */
.btn {
  font: inherit;
  font-weight: 600;
  font-size: 14.5px;
  letter-spacing: -.012em;
  padding: 11px 20px;
  border-radius: var(--r-sm);
  border: 1px solid transparent;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 9px;
  white-space: nowrap;
  transition: transform .12s cubic-bezier(.2,.7,.4,1), background .14s, border-color .14s, box-shadow .14s;
}
.btn:active { transform: translateY(1px); }

.btn-primary {
  background: var(--accent);
  color: var(--accent-ink);
  box-shadow: var(--shadow-accent);
}
.btn-primary:hover { background: color-mix(in srgb, var(--accent) 88%, var(--ink)); }

.btn-quiet {
  background: var(--surface);
  color: var(--ink);
  border-color: var(--border-2);
  box-shadow: var(--shadow-xs);
}
.btn-quiet:hover { background: var(--surface-2); border-color: var(--muted); }

.btn-discord { background: var(--discord); color: var(--discord-ink); box-shadow: var(--shadow-sm); }
.btn-discord:hover { filter: brightness(1.06); }

.btn-block { width: 100%; }
.btn-lg { padding: 14px 26px; font-size: 15.5px; border-radius: var(--r); }

/* ── Cards & fields ──────────────────────────────────────────────────────── */
.card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  padding: 24px;
  box-shadow: var(--shadow-sm);
}
.card-quiet { background: var(--surface-2); box-shadow: none; }

.field { display: flex; flex-direction: column; gap: 7px; }
.field label { font-size: 13.5px; font-weight: 600; color: var(--ink-2); }
.field input {
  font: inherit;
  font-size: 15px;
  padding: 12px 14px;
  border-radius: var(--r-sm);
  border: 1px solid var(--border-2);
  background: var(--surface);
  color: var(--ink);
  transition: border-color .14s, box-shadow .14s;
}
.field input::placeholder { color: var(--muted); opacity: .8; }
.field input:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-dim);
}
.field .hint { font-size: 12.5px; color: var(--muted); }

.notice {
  display: flex; gap: 12px;
  padding: 15px 17px;
  border-radius: var(--r);
  background: var(--good-dim);
  border: 1px solid var(--good-line);
  font-size: 13.5px;
  color: var(--ink-2);
  line-height: 1.55;
}
.notice svg { flex: none; margin-top: 3px; color: var(--good); }
.notice b { color: var(--ink); font-weight: 600; }

.flash {
  display: flex; gap: 12px;
  padding: 14px 16px;
  border-radius: var(--r);
  background: var(--accent-dim);
  border: 1px solid var(--accent-line);
  font-size: 14px;
  color: var(--ink);
}
.flash svg { flex: none; margin-top: 3px; color: var(--accent); }

.banner { padding: 13px 16px; border-radius: var(--r); font-size: 14px; border: 1px solid; }
.banner-ok  { color: var(--good);  background: var(--good-dim);  border-color: var(--good-line); }
.banner-err { color: var(--accent); background: var(--accent-dim); border-color: var(--accent-line); }
.banner b { color: var(--ink); font-weight: 600; }

/* ── Landing ─────────────────────────────────────────────────────────────── */
.hero {
  display: grid;
  grid-template-columns: minmax(0, 1.08fr) minmax(0, .92fr);
  gap: 56px;
  align-items: center;
  padding-block: 76px 68px;
}
@media (max-width: 860px) {
  .hero { grid-template-columns: 1fr; gap: 40px; padding-block: 48px 40px; }
}

.hero h1 em { font-style: normal; color: var(--accent); }

.steps {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 16px;
  padding-bottom: 72px;
}
@media (max-width: 860px) { .steps { grid-template-columns: 1fr; padding-bottom: 48px; } }

.step {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  padding: 24px;
  display: flex; flex-direction: column; gap: 8px;
  box-shadow: var(--shadow-xs);
}
.step .n {
  font-family: var(--font-mono);
  font-size: 11px; font-weight: 500;
  letter-spacing: .12em;
  color: var(--accent);
}

/* ── Ticket stub ─────────────────────────────────────────────────────────── */
.stub {
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 1fr) 128px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-md);
  overflow: hidden;
}
@media (max-width: 620px) { .stub { grid-template-columns: 1fr; } }

.stub-main { padding: 22px 24px; display: flex; flex-direction: column; gap: 18px; }

.stub-tear {
  position: relative;
  background: var(--surface-2);
  border-left: 1px dashed var(--border-2);
  display: flex; flex-direction: column;
  align-items: center; justify-content: center;
  gap: 12px; padding: 20px 12px; text-align: center;
}
@media (max-width: 620px) {
  .stub-tear { border-left: 0; border-top: 1px dashed var(--border-2); }
}
/* the tear notches — softer than a punched hole, still reads as a stub */
.stub-tear::before, .stub-tear::after {
  content: "";
  position: absolute; left: -7px;
  width: 14px; height: 14px;
  border-radius: 50%;
  background: var(--bg);
  border: 1px solid var(--border);
}
.stub-tear::before { top: -8px; }
.stub-tear::after  { bottom: -8px; }
@media (max-width: 620px) { .stub-tear::before, .stub-tear::after { display: none; } }

.stub-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(72px, 1fr));
  gap: 14px 20px;
  padding-top: 4px;
  border-top: 1px solid var(--border);
}
.stub-cell { display: flex; flex-direction: column; gap: 2px; }
.stub-cell .k {
  font-family: var(--font-mono);
  font-size: 9.5px; font-weight: 500;
  letter-spacing: .13em; text-transform: uppercase;
  color: var(--muted);
}
.stub-cell .v {
  font-family: var(--font-mono);
  font-size: 15.5px; font-weight: 600;
  font-variant-numeric: tabular-nums;
  color: var(--ink);
}

.tap-btn {
  font: inherit;
  font-size: 12.5px; font-weight: 600;
  padding: 9px 16px;
  border-radius: 100px;
  border: 0;
  background: var(--accent);
  color: var(--accent-ink);
  cursor: pointer;
  box-shadow: var(--shadow-accent);
  text-decoration: none;
}
.tap-btn:hover { background: color-mix(in srgb, var(--accent) 88%, var(--ink)); }

.pill {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: 11px; font-weight: 600;
  letter-spacing: .06em; text-transform: uppercase;
  padding: 4px 10px;
  border-radius: 100px;
  border: 1px solid;
}
.pill-good { color: var(--good); background: var(--good-dim); border-color: var(--good-line); }

/* ── Credit picker ───────────────────────────────────────────────────────── */
.qty-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 12px; }
@media (max-width: 520px) { .qty-grid { grid-template-columns: repeat(2, 1fr); } }

.qty {
  font: inherit;
  padding: 20px 10px;
  border-radius: var(--r);
  border: 1px solid var(--border-2);
  background: var(--surface);
  color: var(--ink);
  cursor: pointer;
  display: flex; flex-direction: column; align-items: center; gap: 4px;
  transition: border-color .14s, background .14s, box-shadow .14s, transform .12s;
}
.qty:hover { border-color: var(--muted); transform: translateY(-1px); }
.qty[aria-pressed="true"] {
  border-color: var(--accent);
  background: var(--accent-dim);
  box-shadow: 0 0 0 3px var(--accent-dim);
}
.qty .num {
  font-family: var(--font-mono);
  font-size: 22px; font-weight: 600;
  font-variant-numeric: tabular-nums;
}
.qty .lbl { font-size: 12.5px; color: var(--muted); font-weight: 500; }

.total-row {
  display: flex; align-items: baseline; justify-content: space-between;
  padding-block: 18px;
  border-top: 1px solid var(--border);
}
.total-row .amt {
  font-family: var(--font-mono);
  font-size: 30px; font-weight: 600;
  font-variant-numeric: tabular-nums;
  letter-spacing: -.02em;
}

/* ── Ticket picker ───────────────────────────────────────────────────────── */
.pick {
  display: flex; align-items: center; gap: 15px;
  padding: 15px 18px;
  border: 1px solid var(--border);
  border-radius: var(--r);
  background: var(--surface);
  cursor: pointer;
  text-align: left;
  font: inherit;
  color: inherit;
  width: 100%;
  box-shadow: var(--shadow-xs);
  transition: border-color .14s, background .14s, box-shadow .14s;
}
.pick:hover { border-color: var(--border-2); }
.pick[aria-pressed="true"] {
  border-color: var(--accent);
  background: var(--accent-dim);
}
.pick .box {
  width: 20px; height: 20px; flex: none;
  border-radius: 6px;
  border: 1.5px solid var(--border-2);
  background: var(--surface);
  display: grid; place-items: center;
  color: transparent;
  transition: background .14s, border-color .14s;
}
.pick[aria-pressed="true"] .box {
  background: var(--accent); border-color: var(--accent); color: var(--accent-ink);
}
.pick .who { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.pick .who b { font-size: 14.5px; font-weight: 600; letter-spacing: -.015em; }
.pick .seat {
  margin-left: auto;
  font-family: var(--font-mono);
  font-size: 12.5px;
  color: var(--ink-2);
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}

.sticky-bar {
  display: flex; align-items: center; gap: 16px; flex-wrap: wrap;
  padding: 16px 18px;
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  background: var(--surface);
  box-shadow: var(--shadow-sm);
}

.progress {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  font-size: 13px; color: var(--ink-2);
}
.progress .bead {
  width: 8px; height: 8px; border-radius: 50%;
  background: var(--border-2); flex: none;
}
.progress .bead[data-on="true"]  { background: var(--good); }
.progress .bead[data-run="true"] { background: var(--accent); animation: pulse 1.2s ease-in-out infinite; }
@keyframes pulse { 0%, 100% { opacity: 1; } 50% { opacity: .25; } }

/* ── Tables ──────────────────────────────────────────────────────────────── */
.table-wrap {
  overflow-x: auto;
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  background: var(--surface);
  box-shadow: var(--shadow-xs);
}
table { border-collapse: collapse; width: 100%; min-width: 480px; }
th, td { text-align: left; padding: 13px 18px; border-bottom: 1px solid var(--border); }
th {
  font-family: var(--font-mono);
  font-size: 10px; font-weight: 500;
  letter-spacing: .12em; text-transform: uppercase;
  color: var(--muted);
  background: var(--surface-2);
  white-space: nowrap;
}
td { font-size: 14px; }
tr:last-child td { border-bottom: 0; }
tbody tr { transition: background .12s; }
tbody tr:hover { background: var(--surface-2); }
td.num { font-family: var(--font-mono); font-variant-numeric: tabular-nums; }
td.pos { color: var(--good); font-weight: 600; }

/* ── Admin ───────────────────────────────────────────────────────────────── */
.admin-tabs {
  display: flex; gap: 4px; flex-wrap: wrap;
  border-bottom: 1px solid var(--border);
}
.admin-tabs a {
  font-size: 14px; font-weight: 500;
  padding: 11px 14px;
  color: var(--muted);
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
  text-decoration: none;
  transition: color .14s, border-color .14s;
}
.admin-tabs a:hover { color: var(--ink); }
.admin-tabs a[aria-current="page"] { color: var(--ink); font-weight: 600; border-bottom-color: var(--accent); }

.tiles {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(168px, 1fr));
  gap: 14px;
}
.tile {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  padding: 20px;
  display: flex; flex-direction: column; gap: 5px;
  box-shadow: var(--shadow-xs);
}
.tile .k {
  font-family: var(--font-mono);
  font-size: 9.5px; font-weight: 500;
  letter-spacing: .13em; text-transform: uppercase;
  color: var(--muted);
}
.tile .v {
  font-family: var(--font-mono);
  font-size: 27px; font-weight: 600;
  font-variant-numeric: tabular-nums;
  letter-spacing: -.02em;
  line-height: 1.1;
}
.tile .v.warn { color: var(--accent); }
.tile .sub2 { font-size: 12.5px; color: var(--muted); }

.searchbar { display: flex; gap: 10px; flex-wrap: wrap; align-items: center; }
.searchbar input[type="text"],
.searchbar input[type="number"],
.searchbar select {
  font: inherit; font-size: 14.5px;
  padding: 10px 13px;
  border-radius: var(--r-sm);
  border: 1px solid var(--border-2);
  background: var(--surface);
  color: var(--ink);
}
.searchbar input[type="text"] { flex: 1; min-width: 170px; }
.searchbar input:focus, .searchbar select:focus {
  outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-dim);
}

.state {
  font-size: 10.5px; font-weight: 600;
  letter-spacing: .07em; text-transform: uppercase;
  padding: 4px 9px; border-radius: 100px;
  border: 1px solid; white-space: nowrap;
}
.state-done    { color: var(--good);   background: var(--good-dim);   border-color: var(--good-line); }
.state-running { color: var(--accent); background: var(--accent-dim); border-color: var(--accent-line); }
.state-failed  { color: var(--muted);  background: var(--surface-2);  border-color: var(--border-2); }

.nfc-link { font-family: var(--font-mono); font-size: 11.5px; word-break: break-all; color: var(--muted); }

/* ── Generation motion ───────────────────────────────────────────────────────
   Three purposeful animations, all tied to the act of generating a ticket:
   a stub printing out, a scan sweeping the account while we read it, and the
   tap waves rippling on a ready ticket. All disabled under
   prefers-reduced-motion by the global rule near the top of this file.
   ────────────────────────────────────────────────────────────────────────── */

/* 1. Tickets dispense — each stub prints downward, one after the next. */
.stub { animation: dispense .58s cubic-bezier(.16,.84,.44,1) both; }
@keyframes dispense {
  from { opacity: 0; transform: translateY(-10px); clip-path: inset(0 0 100% 0); }
  to   { opacity: 1; transform: none;              clip-path: inset(0 0 0 0); }
}
.stack .stub:nth-child(1)   { animation-delay: .02s; }
.stack .stub:nth-child(2)   { animation-delay: .16s; }
.stack .stub:nth-child(3)   { animation-delay: .30s; }
.stack .stub:nth-child(4)   { animation-delay: .44s; }
.stack .stub:nth-child(n+5) { animation-delay: .56s; }

/* the printed data settles a beat after the stub itself */
.stub-grid .stub-cell { animation: settle .4s ease-out both; }
.stub-grid .stub-cell:nth-child(1) { animation-delay: .30s; }
.stub-grid .stub-cell:nth-child(2) { animation-delay: .36s; }
.stub-grid .stub-cell:nth-child(3) { animation-delay: .42s; }
.stub-grid .stub-cell:nth-child(4) { animation-delay: .48s; }
@keyframes settle {
  from { opacity: 0; transform: translateY(4px); }
  to   { opacity: 1; transform: none; }
}

/* one highlight sweep across a freshly produced stub */
.stub::after {
  content: "";
  position: absolute; inset: 0;
  background: linear-gradient(105deg, transparent 38%,
              color-mix(in srgb, var(--accent) 13%, transparent) 50%, transparent 62%);
  animation: sweep .9s ease-out .35s both;
  pointer-events: none;
}
@keyframes sweep {
  from { transform: translateX(-100%); }
  to   { transform: translateX(100%); }
}

/* 2. The tap waves on a ready ticket keep rippling outward. */
.stub-tear > svg path { animation: ripple 2.6s ease-in-out infinite; }
.stub-tear > svg path:nth-of-type(2) { animation-delay: .16s; }
.stub-tear > svg path:nth-of-type(3) { animation-delay: .32s; }
.stub-tear > svg path:nth-of-type(4) { animation-delay: .48s; }
@keyframes ripple {
  0%, 62%, 100% { opacity: .34; }
  20%           { opacity: 1; }
}

/* 3. The reader — shown while we sign in and pull the account's tickets. */
.reader {
  position: relative;
  height: 128px;
  border-radius: var(--r);
  border: 1px dashed var(--border-2);
  background: var(--surface-2);
  overflow: hidden;
}
.reader::before {
  content: "";
  position: absolute; inset: 22px 28px;
  background:
    linear-gradient(var(--border-2) 2px, transparent 2px) 0 0 / 100% 21px,
    linear-gradient(90deg, var(--border-2) 2px, transparent 2px) 0 0 / 32% 100%;
  opacity: .55;
}
.reader::after {
  content: "";
  position: absolute; left: 0; right: 0; height: 40%;
  background: linear-gradient(180deg, transparent,
              color-mix(in srgb, var(--accent) 15%, transparent) 62%, var(--accent));
  border-bottom: 2px solid var(--accent);
  animation: scan 1.9s cubic-bezier(.5,0,.5,1) infinite;
}
@keyframes scan {
  0%   { transform: translateY(-44%); opacity: 0; }
  12%  { opacity: 1; }
  86%  { opacity: 1; }
  100% { transform: translateY(240%); opacity: 0; }
}

/* the balance reacting when credits are spent */
.balance-chip.changed b { animation: bump .5s cubic-bezier(.2,1.6,.4,1); color: var(--accent); }
@keyframes bump {
  0%   { transform: translateY(0)    scale(1); }
  35%  { transform: translateY(-3px) scale(1.16); }
  100% { transform: translateY(0)    scale(1); }
}

/* ── Credit quantity + pricing ───────────────────────────────────────────── */
.stepper { display: flex; align-items: stretch; gap: 8px; }
.stepper input[type="number"] {
  flex: 1; min-width: 0;
  font-family: var(--font-mono);
  font-size: 26px; font-weight: 600;
  font-variant-numeric: tabular-nums;
  text-align: center;
  padding: 10px 8px;
  border-radius: var(--r-sm);
  border: 1px solid var(--border-2);
  background: var(--surface);
  color: var(--ink);
  -moz-appearance: textfield;
}
.stepper input::-webkit-outer-spin-button,
.stepper input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.stepper input:focus {
  outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-dim);
}
.step-btn {
  font: inherit; font-family: var(--font-mono);
  font-size: 13px; font-weight: 500;
  min-width: 48px; padding: 0 10px;
  border-radius: var(--r-sm);
  border: 1px solid var(--border-2);
  background: var(--surface);
  color: var(--ink-2);
  cursor: pointer;
  transition: background .14s, border-color .14s, color .14s;
}
.step-btn:hover { background: var(--surface-2); border-color: var(--muted); color: var(--ink); }
.step-btn:active { transform: translateY(1px); }

.quote {
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  background: var(--surface);
  box-shadow: var(--shadow-xs);
  overflow: hidden;
}
.quote-line {
  display: flex; justify-content: space-between; align-items: baseline; gap: 12px;
  padding: 14px 18px;
  border-bottom: 1px solid var(--border);
  font-size: 13.5px;
}
.quote-qty  { color: var(--ink); font-weight: 500; }
.quote-unit { color: var(--muted); }
.quote-total {
  display: flex; justify-content: space-between; align-items: baseline;
  padding: 16px 18px;
}
.quote-total .amt {
  font-size: 32px; font-weight: 600;
  font-variant-numeric: tabular-nums; letter-spacing: -.025em;
}
.quote-save {
  display: flex; align-items: center; gap: 8px;
  padding: 11px 18px;
  background: var(--good-dim);
  border-top: 1px solid var(--good-line);
  color: var(--good);
  font-size: 13px; font-weight: 600;
}

.upsell {
  display: flex; align-items: center; gap: 14px;
  width: 100%; text-align: left;
  font: inherit;
  padding: 14px 16px;
  border-radius: var(--r-lg);
  border: 1px solid var(--accent-line);
  background: var(--accent-dim);
  color: var(--ink);
  cursor: pointer;
  animation: settle .35s ease-out both;
  transition: border-color .14s, transform .12s;
}
.upsell:hover { border-color: var(--accent); }
.upsell:active { transform: translateY(1px); }
.upsell b { font-size: 14px; font-weight: 600; }
.upsell .tiny { color: var(--ink-2); }
.upsell-icon {
  width: 32px; height: 32px; flex: none;
  border-radius: 50%;
  background: var(--accent); color: var(--accent-ink);
  display: grid; place-items: center;
}
.upsell-go {
  margin-left: auto; flex: none;
  font-size: 12.5px; font-weight: 700;
  color: var(--accent);
  white-space: nowrap;
}

.tier-table {
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  background: var(--surface);
  overflow: hidden;
  box-shadow: var(--shadow-xs);
}
.tier-row {
  display: grid;
  grid-template-columns: 84px 1fr auto;
  align-items: center;
  gap: 14px;
  padding: 12px 18px;
  border-bottom: 1px solid var(--border);
  cursor: pointer;
  transition: background .14s;
}
.tier-row:last-child { border-bottom: 0; }
.tier-row:hover { background: var(--surface-2); }
.tier-row[aria-current="true"] { background: var(--accent-dim); }
.tier-range { font-size: 13px; font-weight: 500; color: var(--ink-2); }
.tier-row[aria-current="true"] .tier-range { color: var(--ink); font-weight: 600; }
.tier-bar { height: 6px; border-radius: 100px; background: var(--surface-2); overflow: hidden; }
.tier-row[aria-current="true"] .tier-bar { background: color-mix(in srgb, var(--accent) 18%, transparent); }
.tier-bar i { display: block; height: 100%; border-radius: 100px; background: var(--border-2); }
.tier-row[aria-current="true"] .tier-bar i { background: var(--accent); }
.tier-price { font-size: 14px; font-weight: 600; color: var(--ink); white-space: nowrap; }
.tier-per { font-size: 11px; font-weight: 400; color: var(--muted); margin-left: 2px; }

/* ── Generation status (account page) ────────────────────────────────────── */
.job {
  display: flex; align-items: center; gap: 14px;
  padding: 15px 18px;
  border: 1px solid var(--border);
  border-radius: var(--r);
  background: var(--surface);
  box-shadow: var(--shadow-xs);
}
.job b { font-size: 14.5px; font-weight: 600; letter-spacing: -.015em; }
.job .tiny { color: var(--muted); }
.job-go { margin-left: auto; flex: none; padding: 8px 16px; font-size: 13.5px; }

/* A coloured rail carries the state, so it reads before the label does. */
.job-dot {
  width: 8px; align-self: stretch; flex: none;
  border-radius: 100px;
  background: var(--border-2);
  margin: -3px 0;
}
.job-running   .job-dot { background: var(--accent); animation: pulse 1.4s ease-in-out infinite; }
.job-unclaimed .job-dot { background: var(--good); }
.job-failed    .job-dot { background: var(--muted); }
.job-done      .job-dot { background: var(--border-2); }

.job-unclaimed { border-color: var(--good-line); background: var(--good-dim); }
.job-running   { border-color: var(--accent-line); }

.state-running   { color: var(--accent); background: var(--accent-dim); border-color: var(--accent-line); }
.state-unclaimed { color: var(--good);   background: var(--good-dim);   border-color: var(--good-line); }
.state-done      { color: var(--muted);  background: var(--surface-2);  border-color: var(--border-2); }

/* ── Account chrome ──────────────────────────────────────────────────────── */
.balance-card {
  display: flex; align-items: center; gap: 20px;
  padding: 14px 16px 14px 20px;
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  background: var(--surface);
  box-shadow: var(--shadow-xs);
}
.balance-num { font-size: 28px; font-weight: 600; line-height: 1.1; letter-spacing: -.02em; }
.gap-2 { gap: 2px; }

.tabs {
  display: flex; gap: 4px; flex-wrap: wrap;
  border-bottom: 1px solid var(--border);
}
.tabs a {
  display: inline-flex; align-items: center; gap: 7px;
  font-size: 14.5px; font-weight: 500;
  padding: 11px 14px;
  color: var(--muted);
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
  transition: color .14s, border-color .14s;
}
.tabs a:hover { color: var(--ink); }
.tabs a[aria-current="page"] { color: var(--ink); font-weight: 600; border-bottom-color: var(--accent); }
.tab-n {
  font-family: var(--font-mono);
  font-size: 11px; font-weight: 600;
  padding: 2px 7px; border-radius: 100px;
  background: var(--surface-2); color: var(--muted);
}
.tabs a[aria-current="page"] .tab-n { background: var(--accent-dim); color: var(--accent); }

.acct-foot { padding-top: 8px; }

/* ── Filter bar ──────────────────────────────────────────────────────────── */
.filterbar { display: flex; gap: 10px; flex-wrap: wrap; align-items: center; }

.search-wrap { position: relative; display: flex; flex: 1; min-width: 200px; }
.search-wrap svg {
  position: absolute; left: 12px; top: 50%;
  transform: translateY(-50%);
  color: var(--muted); pointer-events: none;
}
.search-wrap input {
  font: inherit; font-size: 14.5px;
  width: 100%;
  padding: 9px 12px 9px 35px;
  border-radius: var(--r-sm);
  border: 1px solid var(--border-2);
  background: var(--surface);
  color: var(--ink);
  -webkit-appearance: none; appearance: none;
}
.search-wrap input::placeholder { color: var(--muted); opacity: .85; }
.search-wrap input:focus {
  outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-dim);
}
.search-wrap input::-webkit-search-cancel-button { -webkit-appearance: none; }

/* The chevron is a mask painted with a token rather than a coloured data URI,
   because a colour baked into the URI cannot follow the theme. */
.select-wrap { position: relative; display: inline-flex; }
.select-wrap::after {
  content: "";
  position: absolute; right: 11px; top: 50%;
  width: 11px; height: 11px;
  transform: translateY(-50%);
  background: var(--muted);
  pointer-events: none;
  -webkit-mask: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12 16 4 8h16z' fill='%23fff'/%3E%3C/svg%3E") no-repeat center / contain;
          mask: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12 16 4 8h16z' fill='%23fff'/%3E%3C/svg%3E") no-repeat center / contain;
}
.filterbar select {
  font: inherit; font-size: 14.5px; font-weight: 500;
  padding: 9px 32px 9px 13px;
  border-radius: var(--r-sm);
  border: 1px solid var(--border-2);
  background: var(--surface);
  color: var(--ink);
  cursor: pointer;
  -webkit-appearance: none; appearance: none;
}
.filterbar select:focus {
  outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-dim);
}
.filterbar .btn { padding: 9px 18px; font-size: 14px; }

/* ── Ticket card ─────────────────────────────────────────────────────────── */
.tk {
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  background: var(--surface);
  box-shadow: var(--shadow-xs);
  overflow: hidden;
}
.tk-head {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  padding: 12px 18px;
  border-bottom: 1px solid var(--border);
  background: var(--surface-2);
}
.tk-date { margin-left: auto; }
.tk-body { padding: 16px 18px 4px; display: flex; flex-direction: column; gap: 4px; }
.tk-actions { display: flex; gap: 8px; flex-wrap: wrap; padding: 14px 18px 16px; }
.tk-btn { padding: 9px 16px; font-size: 13.5px; }

/* ── Open + Copy inside the stub tear ────────────────────────────────────── */
.tear-actions { display: flex; flex-direction: column; gap: 7px; width: 100%; align-items: stretch; }
.tear-actions .tap-btn { width: 100%; text-align: center; }
.tap-btn-quiet {
  background: var(--surface);
  color: var(--ink);
  border: 1px solid var(--border-2);
  box-shadow: none;
}
.tap-btn-quiet:hover { background: var(--surface-2); border-color: var(--muted); }

/* A notice carrying the page's most useful instruction, not an aside. */
.notice-lead {
  background: var(--surface);
  border-color: var(--border-2);
  font-size: 14px;
}
.notice-lead svg { color: var(--accent); }
.notice-lead em { font-style: normal; font-weight: 600; color: var(--ink); }
.notice-lead a { font-weight: 600; text-decoration-color: var(--accent-line); }

/* ── Already-generated tickets ───────────────────────────────────────────── */
.flash-warn {
  background: var(--surface-2);
  border-color: var(--border-2);
  color: var(--ink-2);
}
.flash-warn svg { color: var(--accent); }
.flash-warn b { color: var(--ink); }
.flash-warn a { font-weight: 600; }

.pick-seen {
  cursor: default;
  opacity: .72;
  background: var(--surface-2);
  border-style: dashed;
}
.pick-seen:hover { border-color: var(--border); }
.pick-seen .box { background: var(--surface-2); color: var(--muted); border-color: var(--border-2); }
.pick-seen .who b { color: var(--ink-2); font-weight: 500; }
.seen-note { color: var(--accent); }
.seen-note a { color: inherit; font-weight: 600; }

/* A generation that found only tickets the customer already holds. */
.job-duplicate .job-dot { background: var(--border-2); }
.state-duplicate { color: var(--muted); background: var(--surface-2); border-color: var(--border-2); }

/* ── Scope toggle (one fixture / all games) ──────────────────────────────── */
.scope-field { border: 0; padding: 0; margin: 0; min-width: 0; }
.scope-field legend { font-size: 13.5px; font-weight: 600; color: var(--ink-2); padding: 0; margin-bottom: 7px; }
.segmented {
  display: grid; grid-template-columns: 1fr 1fr; gap: 4px;
  padding: 4px;
  border-radius: var(--r);
  background: var(--surface-2);
  border: 1px solid var(--border);
}
.seg { position: relative; cursor: pointer; }
.seg input { position: absolute; opacity: 0; pointer-events: none; }
.seg span {
  display: block; text-align: center;
  padding: 9px 12px;
  border-radius: var(--r-sm);
  font-size: 14px; font-weight: 500;
  color: var(--muted);
  transition: background .14s, color .14s, box-shadow .14s;
}
.seg:hover span { color: var(--ink); }
.seg input:checked + span {
  background: var(--surface);
  color: var(--ink);
  font-weight: 600;
  box-shadow: var(--shadow-sm);
}
.seg input:focus-visible + span { outline: 2px solid var(--accent); outline-offset: 1px; }

/* ── Grouped ticket picker (all-games results) ───────────────────────────── */
.fixture-group { display: flex; flex-direction: column; gap: 10px; }
.fixture-head {
  display: flex; align-items: flex-end; gap: 12px;
  padding: 0 2px 6px;
  border-bottom: 1px solid var(--border);
}
.fixture-head b { font-family: var(--font-display); font-size: 15.5px; font-weight: 600; letter-spacing: -.02em; }
.fixture-head > .stack { flex: 1; }
.fixture-head [data-group-toggle] { margin-left: auto; }

.pick-toolbar {
  display: flex; align-items: center; gap: 14px;
  padding: 10px 14px;
  border-radius: var(--r);
  background: var(--surface-2);
  border: 1px solid var(--border);
}

.linkish {
  font: inherit; font-size: 13px; font-weight: 600;
  background: none; border: 0; padding: 4px 2px;
  color: var(--accent); cursor: pointer; white-space: nowrap;
}
.linkish:hover { text-decoration: underline; text-underline-offset: 3px; }

/* Selection stays in view while scrolling a long all-games list. */
.sticky-bottom { position: sticky; bottom: 14px; z-index: 5; box-shadow: var(--shadow-md); }
#count.is-over { color: var(--accent); }
#over { color: var(--accent); }
.btn:disabled { opacity: .45; cursor: not-allowed; box-shadow: none; transform: none; }
