/* IRL shared components — light system. Requires tokens.css loaded first.
   Every state here matches web/design-system.md's component specs exactly;
   that file is the spec, this is the implementation. Don't add a one-off
   style for a button/input/card elsewhere — extend a class here instead. */

*{box-sizing:border-box}

/* ── Buttons ──────────────────────────────────────────────────────────── */
.btn{
  font:inherit;font-size:14.5px;font-weight:500;
  height:42px;padding:0 18px;border-radius:var(--r-control);
  border:1px solid transparent;cursor:pointer;
  display:inline-flex;align-items:center;justify-content:center;gap:8px;
  transition:background-color .12s,border-color .12s;
}
.btn:focus-visible{outline:2px solid var(--ultramarine);outline-offset:2px;
  box-shadow:0 0 0 3px var(--focus-ring)}
.btn:disabled,.btn[aria-disabled="true"]{opacity:.5;cursor:default;pointer-events:none}

.btn-primary{background:var(--sodium);color:var(--sodium-ink);box-shadow:var(--shadow-sm)}
.btn-primary:hover{background:var(--sodium-press)}
.btn-primary:active{background:var(--sodium-press);filter:brightness(.97)}

.btn-secondary{background:var(--paper);color:var(--ink);border-color:var(--line-2)}
.btn-secondary:hover{background:var(--wash)}
.btn-secondary:active{background:var(--line)}

.btn-ghost{background:transparent;color:var(--ink-2)}
.btn-ghost:hover{background:var(--wash)}
.btn-ghost:active{background:var(--line)}

.btn-destructive{background:var(--danger-bg);color:var(--danger-text);border-color:var(--danger-border)}
.btn-destructive:hover{background:var(--danger-border)}

.btn-block{width:100%}

/* ── Site footer link row — shared by every "site footer" instance
   (public.css's flow footer, auth.css/marketing.css's overlay footer).
   Positioning/spacing/border vary per context; the link treatment itself
   never does. */
.pub-footer-links{margin-top:6px}
.pub-footer-links a{color:var(--ink-3);text-decoration:underline;text-underline-offset:2px}
.pub-footer-links a:hover{color:var(--ultramarine)}
.pub-footer-links .sep{margin:0 7px}

/* Loading state — the spinner replaces nothing in the DOM; it's an
   adjacent element the caller shows/hides, so the button's accessible
   name doesn't flicker between "Send my code" and "Loading…". */
.btn .spinner{width:16px;height:16px;border-radius:50%;
  border:2px solid rgba(255,255,255,.4);border-top-color:currentColor;
  animation:spin .7s linear infinite}
.btn-secondary .spinner,.btn-ghost .spinner{border-color:var(--line-2);border-top-color:var(--ink-2)}
@keyframes spin{to{transform:rotate(360deg)}}
@media (prefers-reduced-motion:reduce){.spinner{animation-duration:1.6s}}

/* ── Text input / select ─────────────────────────────────────────────── */
.field{display:flex;flex-direction:column;gap:7px}
.label{font-size:13px;font-weight:500;line-height:1.3;color:var(--ink)}
.helper{font-size:12.5px;line-height:1.5;color:var(--ink-3)}
.helper-error{color:var(--danger-text)}

.input,.select{
  font:inherit;font-size:15px;color:var(--ink);background:var(--paper);
  border:1px solid var(--line-2);border-radius:var(--r-control);
  height:42px;padding:0 12px;box-shadow:var(--shadow-sm);
  width:100%;
}
.input::placeholder{color:var(--ink-3)}
.input:focus,.select:focus{
  outline:none;border-color:var(--ultramarine);box-shadow:0 0 0 3px var(--focus-ring);
}
.input:disabled,.select:disabled{background:var(--wash);color:var(--ink-3);cursor:default}
.input-error{border-color:var(--danger-border)}
.input-error:focus{border-color:var(--danger-border);box-shadow:0 0 0 3px rgba(179,38,30,.15)}

.select{
  appearance:none;padding-right:30px;
  background-repeat:no-repeat;background-position:right 11px center;
  background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'><path d='M2.5 4.5 6 8l3.5-3.5' fill='none' stroke='%236D7F97' stroke-width='1.4' stroke-linecap='round' stroke-linejoin='round'/></svg>");
}

/* Phone field group: combobox + number field as one visual unit, no gap,
   only the outer corners rounded. */
.phone-group{display:flex;gap:0}
.phone-group .combobox-trigger{flex:0 0 auto;min-width:104px;
  border-radius:var(--r-control) 0 0 var(--r-control);border-right:none}
.phone-group .input{flex:1;min-width:0;border-radius:0 var(--r-control) var(--r-control) 0}
.phone-group .combobox-trigger:focus{position:relative;z-index:1}

/* Country-code combobox popover */
.combobox{position:relative}
.combobox-trigger{
  font:inherit;font-size:15px;color:var(--ink);background:var(--paper);
  border:1px solid var(--line-2);height:42px;padding:0 10px;
  display:flex;align-items:center;gap:6px;cursor:pointer;box-shadow:var(--shadow-sm);
}
.combobox-trigger:focus-visible{outline:none;border-color:var(--ultramarine);
  box-shadow:0 0 0 3px var(--focus-ring)}
.combobox-panel{
  position:absolute;top:calc(100% + 6px);left:0;z-index:20;width:260px;
  background:var(--paper);border-radius:var(--r-control);box-shadow:var(--shadow-card);
  max-height:280px;overflow-y:auto;padding:6px;
}
.combobox-panel[hidden]{display:none}
.combobox-search{width:100%;border:1px solid var(--line);border-radius:8px;
  padding:8px 10px;font:inherit;font-size:14px;margin-bottom:4px}
.combobox-option{display:flex;align-items:center;gap:8px;padding:8px 10px;
  border-radius:8px;font-size:14px;cursor:pointer}
.combobox-option:hover,.combobox-option[data-active="true"]{background:var(--wash)}
.combobox-option .dial{margin-left:auto;color:var(--ink-3);font-variant-numeric:tabular-nums}

/* ── OTP input group ──────────────────────────────────────────────────── */
.otp-group{display:flex;gap:8px}
.otp-box{
  font:inherit;font-size:19px;font-weight:500;text-align:center;
  font-variant-numeric:tabular-nums;
  width:100%;height:50px;border:1px solid var(--line-2);border-radius:var(--r-control);
  background:var(--paper);color:var(--ink);
}
.otp-box:focus{outline:none;border-color:var(--ultramarine);box-shadow:0 0 0 3px var(--focus-ring)}
.otp-group.is-verifying .otp-box{background:var(--wash);pointer-events:none}
.otp-group.is-error .otp-box{border-color:var(--danger-border)}
.otp-group.is-error.shake{animation:shake .32s}
@keyframes shake{
  25%{transform:translateX(-4px)} 75%{transform:translateX(4px)}
}
@media (prefers-reduced-motion:reduce){.otp-group.shake{animation:none}}

/* ── Card ─────────────────────────────────────────────────────────────── */
.card{background:var(--paper);border-radius:var(--r-card);box-shadow:var(--shadow-card)}

/* ── Show card ────────────────────────────────────────────────────────
   One show, one card — the unit /recommendations lists and a show's own
   /event page renders as a single instance of. Shared here (rather than
   living in recommendations.css) so both places stay visually identical
   by construction. Markup: .card.rec-card > .rec-top-row (badge +
   .rec-actions), venue/title/creatives/plot, an optional
   .rec-readmore-btn + .rec-long pair, .rec-reception, .rec-meta, and a
   .rec-book link. Behaviour lives in web/static/card-interactions.js. */
.rec-card{padding:22px 26px;margin-bottom:20px}
.rec-card.top-match{border-left:3px solid var(--danger-border);
  box-shadow:var(--shadow-card),inset 0 0 0 1px transparent}

.rec-top-row{display:flex;justify-content:space-between;align-items:flex-start;margin-bottom:8px}

.badge{font-size:11px;padding:3px 9px;border-radius:5px;font-weight:600;
  letter-spacing:.01em}
.badge-top{background:var(--danger-bg);color:var(--danger-text);border:1px solid var(--danger-border)}

.rec-actions{display:flex;gap:6px;align-items:center}
.rec-actions button{background:none;border:none;cursor:pointer;padding:5px;
  color:var(--ink-3);line-height:1;border-radius:var(--r-control);
  display:inline-flex;align-items:center;justify-content:center;
  transition:color .12s,background-color .12s}
.rec-actions button:hover{color:var(--ink-2);background:var(--wash)}
.rec-actions button:focus-visible{outline:none;box-shadow:0 0 0 3px var(--focus-ring)}
.rec-vote[aria-pressed="true"][data-vote="up"]{color:var(--danger-text)}
.rec-vote[aria-pressed="true"][data-vote="down"]{color:var(--ink)}
.icon{display:inline-block;width:18px;height:18px;fill:none;
  stroke:currentColor;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round}

.rec-venue{font-size:12px;color:var(--ink-3);text-transform:uppercase;
  letter-spacing:.05em;margin:0 0 6px}
.rec-title{font-size:18px;font-weight:600;letter-spacing:-.01em;
  color:var(--ink);margin:0 0 4px}
.rec-creatives{font-size:13px;color:var(--ink-2);line-height:1.5;margin:0 0 12px}
.rec-plot{font-size:14.5px;line-height:1.65;color:var(--ink);margin:0 0 12px}

.rec-readmore-btn{display:inline-flex;align-items:center;gap:5px;font-size:13px;
  color:var(--ultramarine);background:var(--wash);border:1px solid var(--line-2);
  border-radius:999px;cursor:pointer;padding:6px 13px;font:inherit;font-weight:600;
  margin:0 0 12px}
.rec-readmore-btn:hover{background:var(--line)}
.rec-readmore-btn:focus-visible{outline:none;box-shadow:0 0 0 3px var(--focus-ring)}
.rec-readmore-chevron{width:14px;height:14px;fill:none;stroke:currentColor;
  stroke-width:2;stroke-linecap:round;stroke-linejoin:round;transition:transform .15s}
.rec-readmore-btn.open .rec-readmore-chevron{transform:rotate(180deg)}
.rec-long{font-size:13.5px;line-height:1.65;color:var(--ink-2);margin:-4px 0 12px;display:none}
.rec-long.open{display:block}

.rec-reception{font-size:13px;color:var(--ink-2);padding:11px 14px;
  background:var(--wash);border-radius:var(--r-control);line-height:1.6;margin:0 0 14px}
.reception-label{font-size:11px;color:var(--ink-3);text-transform:uppercase;
  letter-spacing:.05em;display:block;margin-bottom:4px}

.rec-meta{display:flex;flex-wrap:wrap;gap:16px;font-size:13px;color:var(--ink-3);
  padding-top:12px;border-top:1px solid var(--line)}
.rec-price{color:var(--ink);font-weight:500}

.rec-book{display:inline-block;margin-top:12px;font-size:13px;
  color:var(--ultramarine);text-decoration:none;font-weight:500}
.rec-book:hover{text-decoration:underline}
.rec-book:focus-visible{outline:none;box-shadow:0 0 0 3px var(--focus-ring);border-radius:4px}

/* ── Banner / alert ───────────────────────────────────────────────────── */
.banner{border-radius:var(--r-control);padding:12px 14px 12px 16px;
  font-size:14px;line-height:1.5;border:1px solid;border-left-width:3px}
.banner-success{background:var(--success-bg);border-color:var(--success-border);color:var(--success-text)}
.banner-warning{background:var(--warning-bg);border-color:var(--warning-border);color:var(--warning-text)}
.banner-danger{background:var(--danger-bg);border-color:var(--danger-border);color:var(--danger-text)}

/* ── Links ────────────────────────────────────────────────────────────── */
.link{color:var(--ultramarine);text-decoration:none;font:inherit}
.link:hover{text-decoration:underline}
.link:focus-visible{outline:none;box-shadow:0 0 0 3px var(--focus-ring);border-radius:4px}

/* ── Skeleton / loading ───────────────────────────────────────────────── */
.skeleton{background:var(--wash);border-radius:var(--r-control);position:relative;overflow:hidden}
.skeleton::after{content:"";position:absolute;inset:0;
  background:linear-gradient(90deg,transparent,rgba(11,23,48,.05),transparent);
  animation:shimmer 2.2s ease-in-out infinite}
@media (prefers-reduced-motion:reduce){.skeleton::after{display:none}}
@keyframes shimmer{from{transform:translateX(-100%)}to{transform:translateX(100%)}}
