/*
 * Guest WiFi captive portal.
 *
 * Every brand value arrives at runtime from /api/config and is written onto
 * :root by app.js — there are no brand-specific literals in this file. The
 * fallbacks below exist only so the page is legible if that call fails.
 *
 * No web fonts, no CDN assets: the guest has no internet access yet, so any
 * external request would simply hang.
 */

:root {
  --brand-primary: #2563eb;
  --brand-accent: #0ea5e9;
  --brand-bg: #0b1220;

  --surface: #ffffff;
  --surface-alt: #f8fafc;
  --text: #0f172a;
  --muted: #64748b;
  --border: #e2e8f0;
  --danger: #dc2626;
  --danger-bg: #fef2f2;

  --radius: 16px;
  --radius-sm: 12px;
  --ease: cubic-bezier(0.4, 0, 0.2, 1);
  --step-duration: 340ms;
}

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

html,
body {
  height: 100%;
}

body {
  margin: 0;
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial,
    "Noto Sans", sans-serif;
  font-size: 16px;
  line-height: 1.5;
  color: var(--text);
  background: var(--brand-bg);
  -webkit-font-smoothing: antialiased;
  -webkit-text-size-adjust: 100%;
}

/* Hold the page back until branding has been applied, so guests never see
   default colours flash to brand colours. */
.page {
  min-height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: max(20px, env(safe-area-inset-top)) 20px max(20px, env(safe-area-inset-bottom));
  background:
    radial-gradient(120% 80% at 15% 0%, color-mix(in srgb, var(--brand-accent) 55%, transparent) 0%, transparent 60%),
    radial-gradient(100% 90% at 100% 100%, color-mix(in srgb, var(--brand-primary) 50%, transparent) 0%, transparent 55%),
    var(--brand-bg);
  opacity: 1;
  transition: opacity 280ms var(--ease);
}

.is-loading .page {
  opacity: 0;
}

.card {
  width: 100%;
  max-width: 420px;
  background: var(--surface);
  border-radius: var(--radius);
  padding: 28px 22px 22px;
  box-shadow: 0 20px 50px -12px rgba(2, 6, 23, 0.45), 0 2px 6px rgba(2, 6, 23, 0.12);
}

/* --- Branding header ----------------------------------------------------- */

.brand {
  text-align: center;
  margin-bottom: 22px;
}

.brand__logo {
  display: block;
  margin: 0 auto 14px;
  max-width: 160px;
  max-height: 64px;
  width: auto;
  height: auto;
  color: var(--brand-primary);
}

.brand__name {
  margin: 0;
  font-size: 1.3rem;
  font-weight: 700;
  letter-spacing: -0.01em;
}

.brand__tagline {
  margin: 6px 0 0;
  font-size: 0.9rem;
  color: var(--muted);
}

/* --- Step stage ---------------------------------------------------------- */

/*
 * All steps stay in the flow-less layer so their height can be measured at any
 * time; the stage animates to the measured height of the active step, which is
 * what keeps the card from jumping between steps.
 */
.stage {
  position: relative;
  overflow: hidden;
  transition: height var(--step-duration) var(--ease);
}

.step {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  opacity: 0;
  visibility: hidden;
  transform: translate3d(28px, 0, 0);
  transition:
    opacity 220ms var(--ease),
    transform var(--step-duration) var(--ease),
    visibility 0s linear var(--step-duration);
}

.step.is-active {
  opacity: 1;
  visibility: visible;
  transform: translate3d(0, 0, 0);
  transition:
    opacity 260ms var(--ease) 60ms,
    transform var(--step-duration) var(--ease),
    visibility 0s;
}

.step.is-leaving {
  transform: translate3d(-28px, 0, 0);
}

.stage[data-direction="back"] .step:not(.is-active) {
  transform: translate3d(-28px, 0, 0);
}

.stage[data-direction="back"] .step.is-leaving {
  transform: translate3d(28px, 0, 0);
}

.step__title {
  margin: 0 0 6px;
  font-size: 1.05rem;
  font-weight: 650;
}

.step__hint {
  margin: 0 0 18px;
  font-size: 0.9rem;
  color: var(--muted);
  word-break: break-word;
}

/* --- Channel choices ----------------------------------------------------- */

.choices {
  display: grid;
  gap: 10px;
}

.choice {
  display: flex;
  align-items: center;
  gap: 14px;
  width: 100%;
  padding: 15px 16px;
  font: inherit;
  font-weight: 550;
  color: var(--text);
  text-align: left;
  background: var(--surface-alt);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  cursor: pointer;
  transition:
    border-color 180ms var(--ease),
    background 180ms var(--ease),
    transform 120ms var(--ease);
}

.choice:hover {
  border-color: var(--brand-primary);
}

.choice:active {
  transform: scale(0.985);
}

.choice__icon {
  flex: 0 0 auto;
  display: grid;
  place-items: center;
  width: 38px;
  height: 38px;
  border-radius: 10px;
  color: #fff;
  background: linear-gradient(135deg, var(--brand-primary), var(--brand-accent));
}

.choice__icon svg {
  width: 20px;
  height: 20px;
}

.choice__text {
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.choice__label {
  font-size: 0.98rem;
  line-height: 1.3;
}

.choice__sub {
  font-size: 0.78rem;
  font-weight: 450;
  color: var(--muted);
}

.choice__chevron {
  margin-left: auto;
  color: var(--muted);
  flex: 0 0 auto;
}

.choices__empty {
  margin: 0;
  padding: 14px;
  font-size: 0.88rem;
  color: var(--muted);
  background: var(--surface-alt);
  border-radius: var(--radius-sm);
}

/* --- Form elements ------------------------------------------------------- */

.field {
  display: block;
  margin-bottom: 14px;
}

.field__label {
  display: block;
  margin-bottom: 6px;
  font-size: 0.82rem;
  font-weight: 550;
  color: var(--muted);
}

.field__input {
  width: 100%;
  padding: 13px 14px;
  font: inherit;
  font-size: 16px; /* keeps iOS from zooming on focus */
  color: var(--text);
  background: var(--surface);
  border: 1.5px solid var(--border);
  border-radius: var(--radius-sm);
  outline: none;
  transition:
    border-color 160ms var(--ease),
    box-shadow 160ms var(--ease);
}

.field__input:focus {
  border-color: var(--brand-primary);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--brand-primary) 22%, transparent);
}

.field__input--code {
  text-align: center;
  font-size: 1.6rem;
  font-weight: 650;
  letter-spacing: 0.5em;
  text-indent: 0.5em; /* balances the trailing letter-space */
  padding: 14px 10px;
  font-variant-numeric: tabular-nums;
}

.terms {
  margin: -4px 0 12px;
  font-size: 0.76rem;
  color: var(--muted);
}

.terms a {
  color: var(--brand-primary);
}

.btn {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  width: 100%;
  min-height: 48px;
  padding: 13px 16px;
  margin-top: 8px;
  font: inherit;
  font-weight: 600;
  text-decoration: none;
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  cursor: pointer;
  transition:
    filter 160ms var(--ease),
    opacity 160ms var(--ease),
    transform 120ms var(--ease),
    background 160ms var(--ease);
}

.btn:active:not(:disabled) {
  transform: scale(0.985);
}

.btn:disabled {
  opacity: 0.55;
  cursor: default;
}

.btn--primary {
  color: #fff;
  background: linear-gradient(135deg, var(--brand-primary), var(--brand-accent));
}

.btn--primary:hover:not(:disabled) {
  filter: brightness(1.06);
}

.btn--ghost {
  color: var(--text);
  background: var(--surface-alt);
  border-color: var(--border);
}

.btn--link {
  min-height: 40px;
  color: var(--muted);
  background: none;
  font-weight: 500;
  font-size: 0.86rem;
}

.btn.is-busy .btn__label {
  opacity: 0.6;
}

.spinner {
  display: none;
  width: 16px;
  height: 16px;
  border: 2px solid rgba(255, 255, 255, 0.4);
  border-top-color: #fff;
  border-radius: 50%;
  animation: spin 700ms linear infinite;
}

.btn.is-busy .spinner {
  display: block;
}

@keyframes spin {
  to {
    transform: rotate(360deg);
  }
}

/* --- Feedback ------------------------------------------------------------ */

.alert {
  margin: 0 0 12px;
  padding: 10px 12px;
  font-size: 0.85rem;
  color: var(--danger);
  background: var(--danger-bg);
  border: 1px solid #fecaca;
  border-color: color-mix(in srgb, var(--danger) 25%, transparent);
  border-radius: var(--radius-sm);
  animation: alert-in 220ms var(--ease);
}

@keyframes alert-in {
  from {
    opacity: 0;
    transform: translateY(-4px);
  }
}

.countdown {
  margin: 0 0 12px;
  font-size: 0.82rem;
  color: var(--muted);
  text-align: center;
  font-variant-numeric: tabular-nums;
}

/* --- Success ------------------------------------------------------------- */

.success {
  text-align: center;
}

.success__mark {
  width: 66px;
  height: 66px;
  margin: 4px auto 16px;
  display: block;
}

.success__circle,
.success__check {
  fill: none;
  stroke-width: 3.5;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.success__circle {
  /* first declaration is the fallback for browsers without color-mix() */
  stroke: var(--border);
  stroke: color-mix(in srgb, var(--brand-primary) 30%, transparent);
  stroke-dasharray: 152;
  stroke-dashoffset: 152;
}

.success__check {
  stroke: var(--brand-primary);
  stroke-dasharray: 40;
  stroke-dashoffset: 40;
}

.step[data-step="success"].is-active .success__circle {
  animation: draw 500ms var(--ease) forwards;
}

.step[data-step="success"].is-active .success__check {
  animation: draw 340ms var(--ease) 340ms forwards;
}

@keyframes draw {
  to {
    stroke-dashoffset: 0;
  }
}

/* --- Support footer ------------------------------------------------------ */

.support {
  margin-top: 20px;
  padding-top: 16px;
  border-top: 1px solid var(--border);
  font-size: 0.8rem;
  color: var(--muted);
  text-align: center;
}

.support a {
  color: var(--brand-primary);
  text-decoration: none;
}

.support__row + .support__row {
  margin-top: 4px;
}

.support__company {
  margin-top: 8px;
  font-size: 0.74rem;
  opacity: 0.8;
}

.credit {
  margin: 12px 0 0;
  font-size: 0.74rem;
  line-height: 1.5;
  color: var(--muted);
  text-align: center;
}

/* When there is no support block above it, the credit takes over the divider. */
.support[hidden] + .credit {
  margin-top: 20px;
  padding-top: 16px;
  border-top: 1px solid var(--border);
}

.credit a {
  color: var(--brand-primary);
  text-decoration: none;
  font-weight: 550;
}

.credit a:hover {
  text-decoration: underline;
}

.credit__heart {
  font-style: normal;
  /* Keep the emoji from inheriting the muted colour on platforms that tint it. */
  color: initial;
}

/* --- Not connected to the guest network -------------------------------- */

.notice {
  display: flex;
  gap: 12px;
  padding: 14px;
  text-align: left;
  background: var(--surface-alt);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
}

.notice__icon {
  flex: 0 0 auto;
  color: var(--brand-primary);
  margin-top: 1px;
}

.notice__title {
  margin: 0 0 4px;
  font-size: 0.92rem;
  font-weight: 600;
  color: var(--text);
}

.notice__body {
  margin: 0;
  font-size: 0.84rem;
  color: var(--muted);
}

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

@media (max-width: 380px) {
  .card {
    padding: 22px 16px 18px;
  }
}

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
  }

  .step {
    transform: none !important;
  }
}
