/* The buyer-facing surfaces: checkout widget, embed panel, order page.
 *
 * Deliberately NOT includes/theme.css. That file is 532KB of CRM chrome built
 * for a logged-in admin; none of it belongs on a page a stranger loads inside
 * somebody else's website, and shipping it would make the embed heavier than
 * most of the sites hosting it.
 *
 * Self-contained by necessity too: this origin's CSP has no 'unsafe-inline' for
 * style, so there are no style attributes anywhere in the markup, and no
 * external font host -- the system stack renders instantly and sends nobody's
 * IP address to a CDN. */

:root {
  --ink: #16161a;
  --ink-soft: #5b5b66;
  --paper: #ffffff;
  --line: #e2e2e8;
  --accent: #1f6feb;
  --accent-ink: #ffffff;
  --danger: #b42318;
  --ok: #067647;
  --radius: 10px;
  --gap: 16px;
}

/* The embed sits inside a page whose theme we do not control, so it follows the
 * viewer's OS preference rather than guessing. */
@media (prefers-color-scheme: dark) {
  :root {
    --ink: #f2f2f5;
    --ink-soft: #a9a9b6;
    --paper: #17171b;
    --line: #303039;
    --accent: #4d8ef7;
    --danger: #ff7b6b;
    --ok: #4ade80;
  }
}

* { box-sizing: border-box; }

body {
  margin: 0;
  padding: 20px;
  background: var(--paper);
  color: var(--ink);
  font: 16px/1.5 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
}

.checkout, .embed, .order { max-width: 460px; margin: 0 auto; }

h1 { font-size: var(--fs-20); line-height: var(--leading); margin: 0 0 4px; letter-spacing: -0.01em; }
h2 { font-size: var(--fs-15); line-height: var(--leading); margin: 24px 0 12px; color: var(--ink-soft); font-weight: 600; }

/* ---- order summary ---- */

.checkout-lines { list-style: none; margin: 0 0 12px; padding: 0; }
.checkout-lines li { display: flex; justify-content: space-between; gap: var(--gap); padding: 6px 0; }
.line-name { color: var(--ink); }
/* The nights a festival package covers, under its own line. */
.line-includes { display: block; margin-top: 2px; color: var(--ink-soft); font-size: 0.85em; line-height: var(--leading); }

/* The nights a pass covers, on the embed panel. Same shape as the event page's
   own list -- a buyer meeting the pass on somebody else's website should not be
   told less about it than one meeting it on the organizer's. */
.package-includes { list-style: none; margin: 8px 0 0; padding: 0; font-size: var(--fs-14); line-height: var(--leading); }
.package-includes li { display: flex; justify-content: space-between; gap: 12px; padding: 3px 0; color: var(--ink-soft); }
.package-includes-what::before { content: "\2713"; color: var(--accent); margin-right: 6px; }
.package-includes-when { font-variant-numeric: tabular-nums; white-space: nowrap; }
.line-amount { font-variant-numeric: tabular-nums; }

.checkout-totals {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 6px var(--gap);
  margin: 0;
  padding-top: 12px;
  border-top: 1px solid var(--line);
}
.checkout-totals dt { color: var(--ink-soft); }
.checkout-totals dd { margin: 0; text-align: right; font-variant-numeric: tabular-nums; }
.checkout-totals .is-total { font-weight: 700; color: var(--ink); font-size: var(--fs-17); line-height: var(--leading); padding-top: 6px; }

/* A discount reads as a reduction, so it is the one line here that is not the
   same ink as the rest -- and it keeps the minus sign rather than relying on
   colour alone, which a buyer who cannot distinguish it would otherwise read as
   another charge. */
.checkout-totals .is-discount { color: var(--ok, #1b7f4b); }

/* --- Discount code (a <details>, collapsed unless one is applied) ---------
   Most buyers have no code, and an open box asking for one tells them they are
   probably paying more than somebody else. */
.checkout-coupon { margin: 4px 0 12px; }
.checkout-coupon > summary {
    cursor: pointer; font-size: var(--fs-14); line-height: var(--leading); color: var(--ink-soft);
    padding: 4px 0; width: fit-content;
}
.checkout-coupon > summary:hover { color: var(--ink); }
.checkout-coupon > summary:focus-visible { outline: 2px solid var(--focus, currentColor); outline-offset: 2px; }
.checkout-coupon__row { display: flex; gap: 8px; align-items: stretch; }
.checkout-coupon__row input { flex: 1 1 auto; min-width: 0; text-transform: uppercase; }
.checkout-coupon__apply {
    flex: 0 0 auto; padding: 0 14px; cursor: pointer;
    border: 1px solid var(--line); border-radius: 8px;
    background: var(--surface-2, transparent); color: var(--ink);
    font: inherit; font-weight: 600;
}
.checkout-coupon__apply:disabled { opacity: .55; cursor: default; }

/* Both outcomes go through one element, so it must be legible as either. The
   error tone is a modifier rather than a separate node -- two nodes is how a
   success and a failure end up on screen at the same time. */
.field-status { margin: 6px 0 0; font-size: var(--fs-13); line-height: var(--leading); min-height: 1.2em; color: var(--ok, #1b7f4b); }
.field-status.is-error { color: var(--bad, #b3261e); }

/* ---- fields ---- */

.field { margin-bottom: 14px; }
.field-row { display: flex; gap: 12px; }
.field-row .field { flex: 1; }

label { display: block; font-size: var(--fs-14); line-height: var(--leading); font-weight: 600; margin-bottom: 5px; }
.req { color: var(--danger); }

input[type="email"], input[type="text"], input[type="number"] {
  width: 100%;
  padding: 10px 12px;
  font: inherit;
  color: var(--ink);
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--radius);
}

/* Never removed without a replacement -- keyboard operation is a platform
 * requirement, and this page is reachable by keyboard like any other. */
input:focus-visible, button:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

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

.hint { margin: 5px 0 0; font-size: var(--fs-13); line-height: var(--leading); color: var(--ink-soft); }

.field-check { display: flex; align-items: flex-start; gap: 9px; }
.field-check input { margin-top: 3px; }
.field-check label { font-weight: 400; font-size: var(--fs-14); line-height: var(--leading); margin: 0; }

.field-inline { display: flex; align-items: center; gap: 12px; }
.field-inline label { margin: 0; }
.field-inline input { width: 84px; }

/* ---- errors ---- */

.field-error, .form-error {
  margin: 6px 0 0;
  font-size: var(--fs-14); line-height: var(--leading);
  color: var(--danger);
  min-height: 0;
}
/* role="alert" is already announced; this only controls whether it takes space. */
.form-error { display: none; }
.form-error.is-visible { display: block; margin: 12px 0; }

/* ---- payment ---- */

.payment-element { margin: 18px 0; }

.checkout-pay {
  display: block;
  width: 100%;
  padding: 13px 16px;
  font: inherit;
  font-weight: 600;
  color: var(--accent-ink);
  background: var(--accent);
  border: 0;
  border-radius: var(--radius);
  cursor: pointer;
}
.checkout-pay:hover:not(:disabled) { filter: brightness(1.08); }
.checkout-pay:disabled { opacity: 0.55; cursor: default; }
.checkout-pay.is-busy { cursor: progress; }
/* The same control as a link, for the one place it navigates rather than
 * submits (the confirmation page's "View your tickets"). A <button>'s centred
 * text and absent underline are not inherited by an <a>, so both are restated
 * here rather than the anchor being left looking like a stray link in a box. */
a.checkout-pay { text-align: center; text-decoration: none; }

.checkout-note, .embed-closed {
  margin: 14px 0 0;
  font-size: var(--fs-13); line-height: var(--leading);
  color: var(--ink-soft);
  text-align: center;
}

/* ---- embed panel ---- */

.embed-event { font-size: var(--fs-18); line-height: var(--leading); }
.embed-date { margin: 0 0 12px; color: var(--ink-soft); font-size: var(--fs-14); line-height: var(--leading); }
.embed-tier { display: flex; justify-content: space-between; gap: var(--gap); padding: 10px 0; border-top: 1px solid var(--line); border-bottom: 1px solid var(--line); margin: 0 0 16px; }
.embed-price { font-variant-numeric: tabular-nums; font-weight: 600; }
/* See .tier-price-note in event.css -- same disclosure, same reasoning. */
.embed-price-note {
  display: block;
  font-size: var(--fs-14);
  line-height: var(--leading);
  font-weight: 400;
  color: var(--ink-soft);
}
.embed-closed { color: var(--danger); font-weight: 600; }

/* ---- order page ---- */

.order-ref { margin: 0 0 16px; color: var(--ink-soft); font-size: var(--fs-14); line-height: var(--leading); }
.ticket-list { list-style: none; margin: 20px 0; padding: 0; }
.ticket-list li {
  display: flex;
  justify-content: space-between;
  gap: var(--gap);
  padding: 12px 14px;
  margin-bottom: 8px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
}
.ticket-code { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-weight: 700; letter-spacing: 0.12em; }

.order-downloads { list-style: none; margin: 0 0 20px; padding: 0; }
.order-downloads li { margin-bottom: 8px; }
.order-downloads a { font-weight: 700; }

.checkout-done h1 { color: var(--ok); }

@media (prefers-reduced-motion: reduce) {
  * { transition: none !important; animation: none !important; }
}

/* ---- ticket page ---- */

.tickets { max-width: 420px; margin: 0 auto; }
.tickets-date { margin: 0 0 4px; color: var(--ink-soft); }
.tickets-hint { margin: 0 0 22px; color: var(--ink-soft); font-size: var(--fs-14); line-height: var(--leading); }

.ticket {
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 16px;
  margin-bottom: 16px;
  text-align: center;
  background: var(--paper);
}
.ticket-head { display: flex; justify-content: space-between; align-items: baseline; margin-bottom: 12px; }
.ticket-tier { font-weight: 600; }
.ticket-index { color: var(--ink-soft); font-size: var(--fs-13); line-height: var(--leading); }

/* The QR is always dark-on-light regardless of the viewer's theme: a scanner
 * reads contrast, and an inverted code in dark mode does not scan. */
.ticket-qr-wrap { background: #fff; padding: 12px; border-radius: 8px; display: inline-block; }
.ticket-qr-wrap svg { display: block; width: 200px; height: 200px; }
.ticket-qr-wrap svg path { fill: #000; }

.ticket-code {
  margin: 12px 0 0;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: var(--fs-22); line-height: var(--leading);
  font-weight: 700;
  letter-spacing: 0.22em;
}
.ticket-holder { margin: 6px 0 0; color: var(--ink-soft); font-size: var(--fs-14); line-height: var(--leading); }

.ticket.is-void { opacity: 0.6; }
.ticket-void { color: var(--danger); font-weight: 600; margin: 18px 0; }

/* Shown when repricing moved the total between drafting and paying. Not an
 * error -- a price change is a legitimate thing to be told about. */
.form-notice {
  margin: 12px 0;
  padding: 10px 12px;
  font-size: var(--fs-14); line-height: var(--leading);
  border-radius: var(--radius);
  border: 1px solid var(--line);
  color: var(--ink);
}
.form-notice[hidden] { display: none; }

/* ---- survey ---- */

.field-group { border: 0; margin: 18px 0; padding: 0; }
.field-group legend { font-weight: 600; font-size: var(--fs-14); line-height: var(--leading); padding: 0 0 8px; }
.field-group .field-check { padding: 5px 0; }

.survey-rating { border: 0; margin: 18px 0; padding: 0; }
.survey-rating legend { font-weight: 600; font-size: var(--fs-14); line-height: var(--leading); padding: 0 0 8px; }
/* The star row carries the meaning visually; the count is what a screen reader
 * reads, since a run of five identical glyphs announces as nothing useful. */
.survey-rating .field-check { padding: 5px 0; }
.survey-rating label { color: #d9a406; letter-spacing: 2px; }
.survey-stars-label {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip-path: inset(50%); white-space: nowrap;
}
main.order textarea {
  width: 100%; box-sizing: border-box; padding: 10px 12px; margin: 6px 0 16px;
  font: inherit; color: var(--ink); background: var(--paper);
  border: 1px solid var(--line); border-radius: var(--radius); resize: vertical;
}
main.order textarea:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
main.order form .field-check { margin: 10px 0; }
main.order form .checkout-pay { margin-top: 20px; }
main.order .order-actions { margin: 20px 0 0; }

/* ---- passing a ticket on ---- */

/* Folded shut by default: most people opening the tickets page are at a door
 * looking for a QR code, and a form about selling is in the way. */
.ticket-sell { margin: 16px 0 0; border-top: 1px solid var(--line); padding-top: 12px; }
.ticket-sell > summary {
  cursor: pointer; font-size: var(--fs-14); line-height: var(--leading); font-weight: 600; color: var(--accent);
  list-style: none; padding: 4px 0;
}
.ticket-sell > summary::-webkit-details-marker { display: none; }
.ticket-sell > summary::before { content: "\2192\00a0"; }
.ticket-sell[open] > summary::before { content: "\2193\00a0"; }
.ticket-sell > summary:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.ticket-sell input { width: 100%; box-sizing: border-box; }
.ticket-sell .checkout-pay { margin-top: 12px; }

/* Shipping method choices (docs/shipping-design-brief.md Part 1). Reuses
   .field-check's layout; only the stacking between options is new here. */
.checkout-shipping-method__option { margin: 8px 0; }

/* THE HOLD TIMER (wireframe PT1, 2026-09-09).
 *
 * Quiet by default and only raising its voice under two minutes. It is the one
 * pressure device on this page and it is a true one -- the seats really are
 * held and really are released -- so it does not need to shout to be honest. */
.checkout-hold {
  display: flex; align-items: baseline; gap: 10px;
  margin: 0 0 16px; padding: 10px 14px;
  border: 1px solid var(--line, rgba(15, 12, 8, .16)); border-radius: 8px;
  font-size: .875rem;
}
.checkout-hold__clock { font-variant-numeric: tabular-nums; font-weight: 700; }
/* Never colour alone: the clock itself is the message, and under two minutes
   the whole row takes the alert colour AND the number keeps counting. */
.checkout-hold.is-urgent { border-color: #c0442a; color: #c0442a; }
.checkout-hold__over {
  margin: 0 0 16px; padding: 10px 14px;
  border: 1px solid #c0442a; border-radius: 8px; color: #c0442a;
  font-size: .875rem;
}
