/* Shared styling for the hosted login/MFA/consent pages served from
   /authorize — same design tokens as the admin console (src/admin-console/
   styles.css) so the two feel like one product, kept as a separate
   stylesheet since these pages are rendered server-side, not by the
   console's SPA shell.

   Dark/mysterious/ominous by design: a near-black void with the candle-
   flame accent (--accent, the logo's ember) as the only real light source
   — everything else stays low-contrast and quiet so the flame reads as
   the thing actually lit. --accent (not a separate token) is what a
   client's themeColor override replaces (see utils/htmlPage.ts's
   pageShell), so it has to stay the single "primary" color rather than
   splitting attention with a second brand hue. */

:root {
  color-scheme: dark;
  --bg: #0b0a08;
  --bg-elevated: #1a1611;
  --bg-subtle: #211c15;
  --border: #3a3226;
  --text: #e9e1d2;
  --muted: #948a79;
  --danger: #e2584a;
  --danger-bg: #2a1512;
  --accent: #d9963f;
  --accent-contrast: #14120f;
}

* { box-sizing: border-box; }

/* .form-error below sets its own `display: flex` (to lay out its warning
   icon + text), which — being an author-stylesheet rule — beats the UA
   stylesheet's `[hidden] { display: none }` regardless of specificity:
   author styles always win over UA styles for the same property. Without
   this, an element with both `hidden` and an author `display` never
   actually hides (see the two password-reset forms' `.form-error`, shown/
   hidden via JS). Matches the fix in admin-console/account-console
   styles.css. */
[hidden] { display: none !important; }

body {
  margin: 0;
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1.5rem;
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  color: var(--text);
  background: radial-gradient(ellipse 900px 560px at 50% 38%, #1c160f 0%, var(--bg) 72%);
}

a { color: var(--accent); }

.auth-card {
  width: 100%;
  max-width: 360px;
  padding: 2rem;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--bg-elevated);
  box-shadow: 0 24px 60px rgba(0, 0, 0, 0.65), 0 0 70px -28px rgba(217, 150, 63, 0.35);
  display: flex;
  flex-direction: column;
  gap: 1rem;
}

.brand {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  font-size: 0.8rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--accent);
}

.brand-logo {
  display: block;
  max-height: 28px;
  max-width: 100%;
  filter: drop-shadow(0 0 8px rgba(217, 150, 63, 0.35));
}

/* Shared icon-sprite glyphs (src/assets/icons.svg) — sized/colored via
   currentColor so they inherit whatever text color they're dropped into. */
.icon {
  width: 1em;
  height: 1em;
  flex-shrink: 0;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.6;
  stroke-linecap: round;
  stroke-linejoin: round;
  vertical-align: -0.15em;
}

h1 {
  font-size: 1.15rem;
  margin: 0;
  line-height: 1.4;
  color: var(--text);
}

.icon-heading {
  width: 1.15em;
  height: 1.15em;
  margin-right: 0.4rem;
  color: var(--accent);
}

.client-name { font-weight: 600; }

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

.form-error {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  color: var(--danger);
  font-size: 0.85rem;
  margin: 0;
  padding: 0.5rem 0.7rem;
  border: 1px solid rgba(226, 88, 74, 0.4);
  border-radius: 6px;
  background: var(--danger-bg);
}

form { display: flex; flex-direction: column; gap: 0.6rem; }

label {
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
  font-size: 0.85rem;
  color: var(--muted);
}

.label-text {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
}

input {
  font: inherit;
  padding: 0.5rem 0.6rem;
  border: 1px solid var(--border);
  border-radius: 6px;
  background: var(--bg);
  color: var(--text);
}
input:focus {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
}

button {
  font: inherit;
  font-weight: 600;
  padding: 0.55rem 0.9rem;
  border-radius: 6px;
  border: 1px solid var(--accent);
  background: var(--accent);
  color: var(--accent-contrast);
  cursor: pointer;
  transition: box-shadow 0.15s ease, filter 0.15s ease;
}
button:hover {
  filter: brightness(1.08);
  box-shadow: 0 0 20px -4px rgba(217, 150, 63, 0.6);
}
button.secondary {
  background: transparent;
  color: var(--text);
  border-color: var(--border);
  box-shadow: none;
}
button.secondary:hover { background: var(--bg-subtle); box-shadow: none; }

.actions { display: flex; gap: 0.6rem; }
.actions button { flex: 1; }

.scope-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.scope-item {
  display: flex;
  gap: 0.6rem;
  align-items: center;
  font-size: 0.85rem;
  padding: 0.6rem 0.7rem;
  border: 1px solid var(--border);
  border-radius: 6px;
  background: var(--bg-subtle);
  color: var(--text);
}

.icon-scope {
  width: 1.1em;
  height: 1.1em;
  color: var(--accent);
  flex-shrink: 0;
}

.hint { font-size: 0.8rem; color: var(--muted); text-align: center; margin: 0; }

/* Public landing page at "/" (routes/landing.ts) — no .auth-card here,
   just the flame and the gate, so it reads as an ambient "you found
   something" moment rather than a login screen. Layered with a faint
   ember field + a pulsing threshold ring behind the flame so the page
   feels alive without adding any real content — everything here is
   decorative (aria-hidden or purely presentational) and stays under the
   text in stacking order so legibility never suffers. */
.gate-inscription {
  position: fixed;
  inset: -10%;
  z-index: -1;
  display: flex;
  flex-direction: column;
  justify-content: space-evenly;
  overflow: hidden;
  pointer-events: none;
  user-select: none;
  transform: rotate(-4deg) scale(1.15);
}

.gate-inscription p {
  margin: 0;
  font-size: 2.6rem;
  font-weight: 700;
  letter-spacing: 0.4em;
  white-space: nowrap;
  color: rgba(233, 225, 210, 0.035);
  -webkit-text-stroke: 1px rgba(233, 225, 210, 0.06);
  text-shadow: 0 1px 0 rgba(255, 255, 255, 0.03), 0 -1px 1px rgba(0, 0, 0, 0.55);
}

.gate-ambient {
  position: fixed;
  inset: 0;
  overflow: hidden;
  pointer-events: none;
  z-index: 0;
}

.ember {
  position: absolute;
  left: var(--left);
  bottom: -10px;
  width: var(--size);
  height: var(--size);
  border-radius: 50%;
  background: var(--accent);
  box-shadow: 0 0 6px 1px rgba(217, 150, 63, 0.7);
  opacity: 0;
  animation: ember-rise var(--duration) ease-in var(--delay) infinite;
}

@keyframes ember-rise {
  0% { opacity: 0; transform: translate(0, 0); }
  8% { opacity: 0.85; }
  70% { opacity: 0.35; }
  100% { opacity: 0; transform: translate(var(--drift), -92vh); }
}

.gate-page {
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 1.5rem;
  text-align: center;
  padding: 1.5rem;
}

.gate-flame-wrap {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 3rem;
  height: 3rem;
  animation: gate-rise 1.2s ease-out;
}

.gate-ring {
  position: absolute;
  inset: -0.9rem;
  border: 1px solid rgba(217, 150, 63, 0.3);
  border-radius: 50%;
  animation: gate-ring-pulse 5s ease-in-out infinite;
}

.gate-ring-outer {
  inset: -1.8rem;
  border-color: rgba(217, 150, 63, 0.15);
  animation-duration: 7s;
  animation-delay: 0.6s;
}

@keyframes gate-ring-pulse {
  0%, 100% { opacity: 0.35; transform: scale(0.94); }
  50% { opacity: 0.85; transform: scale(1.04); }
}

.gate-flame {
  width: 3rem;
  height: 3rem;
  color: var(--accent);
  filter: drop-shadow(0 0 20px rgba(217, 150, 63, 0.55));
  animation: gate-flicker 4s ease-in-out infinite;
}

@keyframes gate-flicker {
  0%, 100% { opacity: 1; transform: scale(1); }
  45% { opacity: 0.75; transform: scale(0.96) translateY(1px); }
  50% { opacity: 0.9; transform: scale(1.02); }
  78% { opacity: 0.82; transform: scale(0.98); }
}

@keyframes gate-rise {
  from { opacity: 0; transform: translateY(10px); }
  to { opacity: 1; transform: translateY(0); }
}

/* The one line on this page that names Bandua and its role — typed out
   letter by letter so it reads as inscribed rather than printed. Width
   is in monospace "ch" units matching the exact character count of
   "Bandua keeps every gate." (24) so the reveal lands flush, no
   trailing gap or clipped character. */
.gate-typewriter-line {
  margin: 0;
}

.gate-typewriter {
  display: inline-block;
  overflow: hidden;
  white-space: nowrap;
  width: 0;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 0.95rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  color: var(--text);
  border-right: 0.1em solid var(--accent);
  animation:
    gate-type 2.2s steps(24, end) 1s forwards,
    gate-caret 0.8s step-end 3.2s infinite;
}

@keyframes gate-type {
  to { width: calc(24ch + 8px); }
}

@keyframes gate-caret {
  50% { border-right-color: transparent; }
}

.gate-page .gate-line {
  color: var(--text);
  font-size: 1.05rem;
  letter-spacing: 0.01em;
  margin: 0;
  animation: gate-rise 1.2s ease-out 3.3s backwards;
}

.gate-page p {
  max-width: 380px;
  color: var(--muted);
  font-size: 0.95rem;
  line-height: 1.6;
  margin: 0;
}

.gate-page p:last-child {
  animation: gate-rise 1.2s ease-out 3.5s backwards;
}

@media (prefers-reduced-motion: reduce) {
  .gate-ambient,
  .gate-inscription {
    display: none;
  }
  .gate-flame,
  .gate-ring,
  .gate-flame-wrap,
  .gate-page .gate-line,
  .gate-page p:last-child {
    animation: none;
    opacity: 1;
    transform: none;
  }
  .gate-typewriter {
    animation: none;
    width: calc(24ch + 8px);
    border-right-color: transparent;
  }
}

/* Welcome banner atop the consent screen (see routes/authorize.ts
   renderConsentForm) — the first thing shown after a fresh sign-in (fresh
   credentials, or a completed MFA challenge) that still owes consent for
   this client, before the scope list. Fades/rises in on load, echoing the
   gate page's gate-rise treatment above, with the flame icon giving it a
   subtle flicker to match. */
.welcome-banner {
  display: flex;
  align-items: center;
  gap: 0.45rem;
  margin: 0;
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--accent);
  animation: welcome-rise 0.6s ease-out;
}

.icon-welcome {
  width: 1.1em;
  height: 1.1em;
  color: var(--accent);
  animation: gate-flicker 4s ease-in-out infinite;
}

@keyframes welcome-rise {
  from { opacity: 0; transform: translateY(-6px); }
  to { opacity: 1; transform: translateY(0); }
}

@media (prefers-reduced-motion: reduce) {
  .welcome-banner,
  .icon-welcome {
    animation: none;
  }
}

/* Company picker (see routes/authorize.ts renderCompanyPicker) — same card
   treatment as .scope-item, but as a row with the radio inline. */
.company-option {
  flex-direction: row;
  align-items: center;
  gap: 0.6rem;
  font-size: 0.9rem;
  padding: 0.6rem 0.7rem;
  border: 1px solid var(--border);
  border-radius: 6px;
  background: var(--bg-subtle);
  color: var(--text);
  cursor: pointer;
}
.company-option .hint { margin-left: auto; }
