/* components.css -- buttons, inputs, and the small shared pieces. Written once, used on
   every page. A page never restyles these locally (DESIGN.md section 5). */

/* ---- Buttons: primary (filled), secondary (outlined), quiet (text). 36px tall. ---- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  height: 36px; padding: 0 16px; border-radius: var(--radius-control);
  font: 600 var(--t-body)/1 var(--font); cursor: pointer;
  border: 1px solid transparent; background: none; color: var(--ink);
  transition: background var(--dur-fast), color var(--dur-fast), border-color var(--dur-fast);
}
.btn-primary { background: var(--accent); color: var(--bg); border-color: var(--accent); }
.btn-primary:hover { filter: brightness(1.08); }
.btn-secondary { border-color: var(--line); }
.btn-secondary:hover { background: var(--bg-raised); }
.btn-quiet { color: var(--ink-soft); padding: 0 8px; }
.btn-quiet:hover { color: var(--ink); }
/* The one button that removes something, after a sentence naming it (DESIGN.md section 8). */
.btn-danger { background: var(--bad); color: var(--bg); border-color: var(--bad); }
.btn-danger:hover { filter: brightness(1.08); }
.btn[disabled] { opacity: .6; cursor: default; }
/* The spinner that lives inside a slow button. Only transform animates. */
.btn .spin { width: 14px; height: 14px; border-radius: 50%; border: 2px solid currentColor;
  border-right-color: transparent; animation: spin 700ms linear infinite; display: none; }
.btn.busy .spin { display: inline-block; }
@keyframes spin { to { transform: rotate(360deg); } }

/* ---- Fields: label above, 36px input, focus ring in the accent. ---- */
.field { display: flex; flex-direction: column; gap: 4px; }
.field label { font-size: var(--t-small); line-height: 1.4; color: var(--ink-soft); }
.field input {
  height: 36px; padding: 0 12px; border-radius: var(--radius-control);
  border: 1px solid var(--line); background: var(--bg); color: var(--ink);
  font: var(--t-body)/1 var(--font);
  transition: border-color var(--dur-fast), box-shadow var(--dur-fast);
}
.field input:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 2px var(--accent-soft); }
/* An error is a sentence under the field, never a colour alone. */
.field-error { font-size: var(--t-small); color: var(--bad); min-height: 18px; }

/* ---- The sign-in ticket: a concert ticket, a paper card with a perforated stub on the right. ----
   Used on the sign-in page (index.html, where it slides in over the opening screen) and on the
   first page (welcome.html, where it fades in under "Get early access"). It is paper in both the
   Day and the Night look. Each page says for itself how the ticket arrives; this is only its look. */
.ticket { position: relative; display: grid; grid-template-columns: 1fr 112px;
  width: 100%; max-width: 560px; background: var(--paper); color: var(--paper-ink);
  border-radius: var(--radius); box-shadow: 0 1px 2px rgba(0,0,0,.4); }
/* The two round notches where the perforation meets the edge. They are the colour of
   the ground so they look punched out of the paper. */
.ticket::before, .ticket::after { content: ""; position: absolute; right: 101px;
  width: 22px; height: 22px; border-radius: 50%; background: var(--bg); }
.ticket::before { top: -11px; }
.ticket::after { bottom: -11px; }

/* The main body of the ticket: the form. */
.ticket-main { padding: 24px; border-right: 2px dashed var(--paper-line);
  display: flex; flex-direction: column; gap: 12px; }
.ticket-main .label { color: var(--paper-soft); }
.ticket-main h1, .ticket-main h2 { font-size: var(--t-title); color: var(--paper-ink); }
.ticket-main .field label { color: var(--paper-soft); }
.ticket-main .field input { background: var(--bg-raised); color: var(--paper-ink);
  border-color: var(--paper-line); }
:root[data-theme="dark"] .ticket-main .field input { background: #ffffff; }
.ticket-main .field input:focus { border-color: var(--paper-brass); box-shadow: 0 0 0 2px var(--accent-soft); }
.ticket-main .btn-primary { background: var(--paper-brass); border-color: var(--paper-brass); color: var(--paper); }
.ticket-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-top: 4px; }
.ticket-main .btn-quiet { color: var(--paper-soft); }
.ticket-main .btn-quiet:hover { color: var(--paper-ink); }

/* The stub: ADMIT ONE, turned on its side like a real stub. */
.ticket-stub { display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 12px; padding: 24px 12px; }
.ticket-stub .admit { writing-mode: vertical-rl; transform: rotate(180deg);
  font-size: var(--t-head); font-weight: 600; letter-spacing: .18em; text-transform: uppercase;
  color: var(--paper-brass); }
.ticket-stub .mark { width: 32px; height: 32px; }
.ticket-stub .site { font-size: var(--t-micro); letter-spacing: .06em; text-transform: uppercase;
  color: var(--paper-soft); writing-mode: vertical-rl; transform: rotate(180deg); }

/* Below 600px the stub sits under the body instead of beside it. */
@media (max-width: 600px) {
  .ticket { grid-template-columns: 1fr; }
  .ticket::before, .ticket::after { right: auto; top: auto; bottom: 69px; }
  .ticket::before { left: -11px; }
  .ticket::after { right: -11px; }
  .ticket-main { border-right: 0; border-bottom: 2px dashed var(--paper-line); }
  .ticket-stub { flex-direction: row; padding: 16px 24px; height: 80px; }
  .ticket-stub .admit, .ticket-stub .site { writing-mode: horizontal-tb; transform: none; }
}
