/* ==========================================================================
   ARKADE LOUNGE — Components
   Buttons, badges, cards, panels and form controls.
   Depends on tokens.css and base.css.
   ========================================================================== */

/* --------------------------------------------------------------------------
   BUTTONS
   The cut corner is the signature shape of the brand. It is applied with
   clip-path, which cannot be combined with a box-shadow glow (the shadow is
   clipped away too), so glowing variants carry the glow on a wrapper or use
   an inset ring instead.
   -------------------------------------------------------------------------- */

.btn {
  --btn-cut: var(--cut-sm);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-2);
  /* 48px minimum touch target on every variant, per WCAG target size. */
  min-block-size: 3rem;
  padding: var(--sp-3) var(--sp-6);
  font-family: var(--font-sans);
  font-size: var(--fs-sm);
  font-weight: var(--fw-bold);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
  border: 1px solid transparent;
  clip-path: polygon(
    var(--btn-cut) 0, 100% 0, 100% calc(100% - var(--btn-cut)),
    calc(100% - var(--btn-cut)) 100%, 0 100%, 0 var(--btn-cut)
  );
  transition: background-color var(--dur-fast) var(--ease-out),
              border-color var(--dur-fast) var(--ease-out),
              color var(--dur-fast) var(--ease-out),
              transform var(--dur-fast) var(--ease-out);
}

.btn:active { transform: translateY(1px); }

.btn:disabled,
.btn[aria-disabled='true'] {
  opacity: 0.45;
  cursor: not-allowed;
  transform: none;
}

/* clip-path removes the outline, so focus is drawn as an inset ring. */
.btn:focus-visible {
  outline: none;
  box-shadow: inset 0 0 0 2px var(--focus-ring);
}

/* The primary call to action. Reserved for the single most important action
   on a view — in practice, almost always BOOK NOW. */
.btn--primary {
  background: var(--accent-fill);
  color: var(--text-on-accent);
}

.btn--primary:hover { background: var(--purple-500); }

/* Secondary: outlined, for the alternative path beside a primary. */
.btn--secondary {
  background: transparent;
  border-color: var(--purple-500);
  color: var(--purple-200);
}

.btn--secondary:hover {
  background: var(--accent-quiet);
  border-color: var(--purple-400);
  color: var(--text);
}

/* Ghost: low-emphasis, for tertiary actions and dense toolbars. */
.btn--ghost {
  background: transparent;
  border-color: var(--line);
  color: var(--text-2);
}

.btn--ghost:hover {
  border-color: var(--line-strong);
  background: rgba(237, 239, 241, 0.05);
  color: var(--text);
}

/* Alert: magenta. Deliberately rare — destructive or genuinely urgent only. */
.btn--alert {
  background: var(--magenta-600);
  color: var(--text-on-accent);
}

.btn--alert:hover { background: var(--magenta-500); }

/* 2.75rem, not 2.5rem. The small button is what the header BOOK NOW and every
   card action use on a phone, and at 40px they sat under the 44px minimum in
   WCAG 2.5.8 — the most important call to action on the site was the hardest
   one to hit. The variant stays visually smaller through its type size and
   horizontal padding rather than by shrinking the tap area. */
.btn--sm {
  --btn-cut: 6px;
  min-block-size: 2.75rem;
  padding: var(--sp-2) var(--sp-4);
  font-size: var(--fs-xs);
}

.btn--lg {
  --btn-cut: var(--cut);
  min-block-size: 3.5rem;
  padding: var(--sp-4) var(--sp-8);
  font-size: var(--fs-body);
}

.btn--block { inline-size: 100%; }

/* --------------------------------------------------------------------------
   BADGES & STATUS
   Tournament state is communicated by colour AND by text, never colour
   alone — a colour-blind visitor must still be able to read the state.
   -------------------------------------------------------------------------- */

.badge {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  padding: 0.3rem var(--sp-3);
  font-size: var(--fs-micro);
  font-weight: var(--fw-bold);
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  color: var(--text-2);
  background: rgba(0, 0, 0, 0.25);
}

.badge--accent {
  border-color: var(--purple-500);
  color: var(--purple-200);
  background: var(--accent-quiet);
}

.badge--open {
  border-color: var(--success);
  color: var(--success);
  background: rgba(52, 199, 123, 0.12);
}

.badge--full {
  border-color: var(--warning);
  color: var(--warning);
  background: rgba(232, 163, 61, 0.12);
}

.badge--live {
  border-color: var(--magenta-500);
  color: var(--magenta-400);
  background: var(--alert-quiet);
}

.badge--done {
  color: var(--text-dim);
  border-color: var(--line);
}

/* The pulsing dot that marks a genuinely live broadcast or match. */
.badge--live .badge__dot {
  inline-size: 0.5rem;
  block-size: 0.5rem;
  border-radius: var(--r-full);
  background: var(--magenta-500);
  animation: ark-pulse 1.8s var(--ease-move) infinite;
}

@keyframes ark-pulse {
  0%, 100% { opacity: 1;   transform: scale(1); }
  50%      { opacity: 0.4; transform: scale(0.82); }
}

@media (prefers-reduced-motion: reduce) {
  .badge--live .badge__dot { animation: none; }
}

/* --------------------------------------------------------------------------
   CARDS
   -------------------------------------------------------------------------- */

.card {
  position: relative;
  display: flex;
  flex-direction: column;
  background: var(--bg-raised);
  border: 1px solid var(--line-soft);
  border-radius: var(--r-lg);
  overflow: hidden;
  transition: border-color var(--dur-base) var(--ease-out),
              transform var(--dur-base) var(--ease-out),
              box-shadow var(--dur-base) var(--ease-out);
}

.card__media {
  position: relative;
  aspect-ratio: 16 / 10;
  background: var(--surface-void);
  overflow: hidden;
}

.card__media img {
  inline-size: 100%;
  block-size: 100%;
  object-fit: cover;
  transition: transform var(--dur-slow) var(--ease-out);
}

.card__body {
  display: flex;
  flex-direction: column;
  gap: var(--sp-3);
  padding: var(--sp-5);
  flex: 1;
}

.card__title {
  font-size: var(--fs-h4);
  font-weight: var(--fw-bold);
  color: var(--text);
}

.card__text {
  font-size: var(--fs-sm);
  color: var(--text-muted);
}

/* Pushes the action to the bottom so a row of cards aligns its CTAs even
   when the descriptions differ in length. */
.card__foot { margin-block-start: auto; padding-block-start: var(--sp-2); }

/* Interactive cards lift and light their edge. The whole card is clickable
   via the stretched-link pattern below, so the markup keeps a real <a> for
   screen readers and keyboards instead of a click handler on the card. */
.card--link:hover,
.card--link:focus-within {
  border-color: var(--purple-500);
  transform: translateY(-4px);
  box-shadow: var(--shadow-lg);
}

.card--link:hover .card__media img { transform: scale(1.05); }

@media (prefers-reduced-motion: reduce) {
  .card--link:hover { transform: none; }
  .card--link:hover .card__media img { transform: none; }
}

.stretched-link::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 1;
}

/* A thin accent rule down the leading edge, used to mark a featured card. */
.card--featured {
  border-color: var(--purple-500);
}

.card--featured::before {
  content: '';
  position: absolute;
  inset-block: 0;
  inset-inline-start: 0;
  inline-size: 3px;
  background: linear-gradient(180deg, var(--purple-400), var(--magenta-600));
  z-index: 2;
}

/* --------------------------------------------------------------------------
   PANEL — a flat surface for stats, detail blocks and forms.
   -------------------------------------------------------------------------- */

.panel {
  background: var(--bg-raised);
  border: 1px solid var(--line-soft);
  border-radius: var(--r-lg);
  padding: var(--sp-5);
}

.panel--quiet { background: rgba(255, 255, 255, 0.02); }

/* HUD-style stat readout. */
.stat { display: flex; flex-direction: column; gap: var(--sp-1); }

.stat__value {
  font-family: var(--font-display);
  font-size: clamp(1.75rem, 1.3rem + 2vw, 2.75rem);
  font-weight: var(--fw-black);
  line-height: 1;
  color: var(--text);
}

.stat__label {
  font-size: var(--fs-xs);
  font-weight: var(--fw-semi);
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--text-muted);
}

/* --------------------------------------------------------------------------
   PRICE ROW — used by the Play page and booking summary.
   -------------------------------------------------------------------------- */

.price-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--sp-4);
  padding-block: var(--sp-3);
  border-block-end: 1px solid var(--line-soft);
}

.price-row:last-child { border-block-end: none; }

.price-row__label { color: var(--text-2); font-size: var(--fs-sm); }

.price-row__value {
  font-weight: var(--fw-bold);
  color: var(--text);
  white-space: nowrap;
}

/* --------------------------------------------------------------------------
   FORMS
   -------------------------------------------------------------------------- */

.field { display: flex; flex-direction: column; gap: var(--sp-2); }

.field__label {
  font-size: var(--fs-xs);
  font-weight: var(--fw-semi);
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--text-2);
}

.input,
.select,
.textarea {
  inline-size: 100%;
  min-block-size: 3rem;
  padding: var(--sp-3) var(--sp-4);
  background: var(--surface-void);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  color: var(--text);
  /* 16px minimum stops iOS Safari zooming the viewport on focus. */
  font-size: 1rem;
  transition: border-color var(--dur-fast) var(--ease-out),
              box-shadow var(--dur-fast) var(--ease-out);
}

.textarea { min-block-size: 8rem; resize: vertical; }

.input::placeholder,
.textarea::placeholder { color: var(--text-dim); }

.input:focus-visible,
.select:focus-visible,
.textarea:focus-visible {
  outline: none;
  border-color: var(--purple-400);
  box-shadow: 0 0 0 3px var(--accent-quiet);
}

.input[aria-invalid='true'],
.textarea[aria-invalid='true'] { border-color: var(--magenta-500); }

.field__error {
  font-size: var(--fs-xs);
  color: var(--magenta-400);
}

.field__hint {
  font-size: var(--fs-xs);
  color: var(--text-dim);
}

/* --------------------------------------------------------------------------
   NOTICE — inline messaging.
   -------------------------------------------------------------------------- */

.notice {
  display: flex;
  gap: var(--sp-3);
  padding: var(--sp-4);
  border: 1px solid var(--line);
  border-inline-start-width: 3px;
  border-radius: var(--r-md);
  font-size: var(--fs-sm);
  color: var(--text-2);
  background: rgba(0, 0, 0, 0.2);
}

.notice--info    { border-inline-start-color: var(--purple-400); }
.notice--success { border-inline-start-color: var(--success); }
.notice--warning { border-inline-start-color: var(--warning); }
.notice--error   { border-inline-start-color: var(--magenta-500); }

/* --------------------------------------------------------------------------
   CHOICE — a selectable card wrapping a hidden radio.
   Lived in book.css until the Take Over page needed the same control and
   silently rendered three unstyled lines of text, because a page stylesheet
   is not a place for a component two pages use. The radio itself stays
   visually hidden and the whole card is the target, which is what keeps it
   above the 44px touch minimum.
   -------------------------------------------------------------------------- */

.choice-grid {
  display: grid;
  gap: var(--sp-3);
  grid-template-columns: repeat(auto-fit, minmax(min(14rem, 100%), 1fr));
}

/* PAYMENT OPTIONS ARE STACKED, NOT SIDE-BY-SIDE-WITH-THE-TEXT.

   These were laid out like the service tiers: a mark on the left and the
   words beside it, in a column narrow enough for four to fit across. With
   two words per option that is fine. With a sentence explaining that a
   wallet needs an account, it produced four ribbons of text one or two words
   wide, hyphenated down the page — unreadable, and it looked broken.

   So each option is now a card: mark on top, name, then the description
   underneath it with room to be a sentence. The minimum is wide enough that
   a line holds several words, and the grid drops to fewer columns rather
   than squeezing them. */
.choice-grid--compact {
  grid-template-columns: repeat(auto-fit, minmax(min(15rem, 100%), 1fr));
}

.choice-grid--compact .choice {
  flex-direction: column;
  align-items: flex-start;
  gap: var(--sp-3);
  padding: var(--sp-5);
}

.choice-grid--compact .choice__body {
  inline-size: 100%;
}

.choice {
  position: relative;
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  min-block-size: 3.5rem;
  padding: var(--sp-4);
  cursor: pointer;
  background: var(--bg-raised);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  transition: border-color var(--dur-fast) var(--ease-out),
              background-color var(--dur-fast) var(--ease-out);
}

.choice:hover { border-color: var(--line-strong); }

.choice input {
  position: absolute;
  opacity: 0;
  inline-size: 1px;
  block-size: 1px;
  margin: 0;
}

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

/* Focus must be visible on the card, not on the invisible input. */
.choice:has(input:focus-visible) {
  outline: 2px solid var(--focus-ring);
  outline-offset: 3px;
}

.choice__body {
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
  min-inline-size: 0;
}

.choice__title {
  font-weight: var(--fw-semi);
  color: var(--text);
}

.choice__meta {
  font-size: var(--fs-xs);
  color: var(--text-muted);
}

.choice__price {
  margin-inline-start: auto;
  font-weight: var(--fw-bold);
  color: var(--purple-200);
  white-space: nowrap;
}

/* A refused card is not an error and not a success. It gets the same warning
   accent as "processing" rather than the alarm red used for real faults —
   nothing has gone wrong with the venue or the booking, a bank simply said
   no, and the station is still held. */
.pay-card--declined {
  border-color: var(--warning, #E8A33D);
}

/* --------------------------------------------------------------------------
   PAYMENT OPTIONS
   --------------------------------------------------------------------------
   A mark beside each option, and a description under it that is meant to be
   read rather than squinted at.

   The description used to be set in the same dim, tight style as a service's
   "60 minutes" caption — fine for two words, wrong for a sentence explaining
   that a wallet needs an account or that a fee is added later. This is the
   step where somebody decides how to hand over money; it can afford a line
   of real text.
   -------------------------------------------------------------------------- */

.choice__mark {
  flex: 0 0 auto;
  inline-size: 2.5rem;
  block-size: 2.5rem;

  /* The artwork is a MASK, and the colour is this element's background.
     An <img> pointing at an external SVG is its own document — currentColor
     inside it resolves against its own root and paints black, which on this
     background is an invisible icon. Masking puts the colour under our
     control, so a mark brightens with the option when it is selected. */
  background-color: var(--ink-dim, #B9B4C0);
  -webkit-mask-image: var(--mark);
  mask-image: var(--mark);
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
  -webkit-mask-position: center;
  mask-position: center;
  -webkit-mask-size: contain;
  mask-size: contain;
}

.choice:has(input:checked) .choice__mark {
  background-color: var(--brand, #A855F7);
}

/* Only where an option carries a description worth reading. The compact grid
   is used for payment options; service tiers keep their tight caption. */
.choice-grid--compact .choice__meta {
  margin-block-start: 0.2rem;
  font-size: 0.875rem;
  line-height: 1.45;
  /* Not clamped. A description that cuts off mid-sentence is worse than none,
     and "you will need the WAM app and an account" is exactly the half that
     would be lost. */
  white-space: normal;
}

/* A provider that has colours of its own gets them. WiPay is a name people
   recognise on a blue square, and a grey card icon beside it threw that
   away. Set in the site's own font so it renders identically everywhere,
   which an SVG wordmark loaded as an image does not. */
.choice__brand {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-inline-size: 5rem;
  block-size: 2.5rem;
  padding-inline: var(--sp-3);
  background: var(--brand-bg, #1E5AA8);
  color: var(--brand-ink, #FFFFFF);
  border-radius: var(--r-sm);
  font-weight: var(--fw-bold);
  font-size: var(--fs-sm);
  letter-spacing: 0.01em;
}

/* --------------------------------------------------------------------------
   BUYING A MEMBERSHIP
   --------------------------------------------------------------------------
   The total has to be the largest thing in the block. It is the number
   somebody checks against what they expect before they commit, and it
   changes when they change how they are paying — so it must be impossible to
   miss changing.
   -------------------------------------------------------------------------- */

.buy { display: grid; gap: var(--sp-4); }

.buy__total {
  font-size: var(--fs-h3);
  font-weight: 700;
  letter-spacing: var(--tracking-display);
  margin: 0;
}

/* Trailer links on an announcement card: numbered, and above the card's
   stretched link so a tap lands on the trailer. */
.card__trailers {
  margin: var(--sp-3) 0 0;
  padding-left: 1.25rem;
  display: grid;
  gap: var(--sp-1);
  font-size: var(--fs-sm);
}
.card__trailers li::marker { color: var(--text-muted); }
.card__trailer-link {
  position: relative;
  z-index: 2;
  color: var(--accent-text);
  text-decoration: underline;
  text-underline-offset: 0.15em;
}
.card__trailer-link:hover { color: var(--text); }
