/* The shared login/auth-flow shell — the animated aurora background,
   glassmorphism card, floating-label fields, method-picker buttons, and
   result-icon animations used by every portal's login experience
   (public/STUDIO/, public/COMPETITION/). Built for public/STUDIO/ first
   as page-local CSS; promoted here the moment a second portal
   (COMPETITION) needed the identical treatment — per
   plan/ui/shared-components.md's "wait for a second consumer" discipline,
   the same trigger that already promoted dom-utils.js/i18n.js. Sits on
   top of ../shared/base.css's design tokens (--bg/--panel/--accent/etc.),
   same as every other portal. */

* { box-sizing: border-box; }

body {
  font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
  margin: 0;
  overflow-x: hidden;
}

/* --- Animated aurora background --- */
.aurora {
  position: fixed;
  inset: 0;
  z-index: 0;
  overflow: hidden;
  background: var(--bg);
}
.blob {
  position: absolute;
  border-radius: 50%;
  filter: blur(70px);
  opacity: 0.35;
  will-change: transform;
}
.blob-1 {
  width: 480px; height: 480px;
  background: radial-gradient(circle, #5b8cff, transparent 70%);
  top: -10%; left: -10%;
  animation: float1 22s ease-in-out infinite;
}
.blob-2 {
  width: 420px; height: 420px;
  background: radial-gradient(circle, #8a5bff, transparent 70%);
  bottom: -15%; right: -5%;
  animation: float2 26s ease-in-out infinite;
}
.blob-3 {
  width: 360px; height: 360px;
  background: radial-gradient(circle, #35c98f, transparent 70%);
  top: 40%; left: 60%;
  animation: float3 30s ease-in-out infinite;
}
@keyframes float1 {
  0%, 100% { transform: translate(0, 0) scale(1); }
  50% { transform: translate(60px, 80px) scale(1.15); }
}
@keyframes float2 {
  0%, 100% { transform: translate(0, 0) scale(1); }
  50% { transform: translate(-70px, -50px) scale(1.1); }
}
@keyframes float3 {
  0%, 100% { transform: translate(0, 0) scale(1); }
  50% { transform: translate(-40px, 60px) scale(0.9); }
}
@media (prefers-reduced-motion: reduce) {
  .blob { animation: none; }
}

/* --- Language switcher --- */
/* A real <select>, not a button row — a row of one button per language
   doesn't scale as more languages are added (platform-wide i18n note:
   "English, Spanish, French (more later)"), and a dropdown is the more
   familiar/accessible pattern for a list that's expected to grow. */
.lang-switcher {
  position: fixed;
  top: 20px;
  right: 20px;
  z-index: 10;
  display: flex;
  align-items: center;
  gap: 6px;
  background: rgba(23, 26, 33, 0.6);
  backdrop-filter: blur(12px);
  border: 1px solid var(--panel-border);
  border-radius: 999px;
  padding: 6px 12px 6px 10px;
}
.lang-switcher .lang-icon {
  color: var(--text-dim);
  display: flex;
  flex: none;
}
.lang-select {
  appearance: none;
  -webkit-appearance: none;
  border: none;
  background: transparent;
  color: var(--text);
  font-family: inherit;
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  padding: 2px 18px 2px 2px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6' fill='none'%3E%3Cpath d='M1 1l4 4 4-4' stroke='%238a93a6' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 2px center;
}
.lang-select:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 4px; }
.lang-select option { background: var(--panel); color: var(--text); }

/* --- Shell + card --- */
.auth-shell {
  position: relative;
  z-index: 1;
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
}

.auth-card {
  width: 100%;
  max-width: 400px;
  background: rgba(23, 26, 33, 0.72);
  backdrop-filter: blur(20px);
  border: 1px solid var(--panel-border);
  border-radius: 20px;
  padding: 36px 32px;
  box-shadow: 0 20px 60px rgba(0, 0, 0, 0.45), 0 0 0 1px rgba(255,255,255,0.02) inset;
  position: relative;
  overflow: hidden;
  opacity: 0;
  transform: translateY(24px) scale(0.98);
}
/* The entrance animation only fires once the page's JS explicitly adds
   this class — after the language pack is applied (and, on the login
   page, after an existing session has been checked) — never
   unconditionally on load. Showing the card first and translating it a
   moment later is exactly the "flash of English" bug this prevents;
   gating the reveal itself means there is nothing to flash. */
/* opacity/transform are declared here as PLAIN properties (not just via
   the keyframes' `forwards` fill) so the revealed state survives
   whatever animation gets attached later — critically, .shake below.
   `animation-fill-mode: forwards` only holds a property for as long as
   THAT SAME animation stays assigned to the element; the moment a
   different animation (shake, triggered on every login/MFA/comp-code
   error) replaces `card-in` in the `animation` shorthand, the
   `forwards`-held opacity/transform would be discarded and the element
   would fall back to .auth-card's own base `opacity: 0` — invisibly
   hiding the card (and whatever error message is inside it) right when
   an error is shown. A plain property declaration on this same selector
   has no such dependency: it keeps applying regardless of which
   animation (if any) is currently attached, as long as the animation
   itself doesn't override it mid-flight (shake's keyframes never touch
   opacity/vertical transform, only translateX). Real bug, caught from a
   live browser test (a login failure made the whole card vanish), not
   theoretical — see CLAUDE.md.
*/
.auth-card.ready {
  opacity: 1;
  transform: translateY(0) scale(1);
  animation: card-in 620ms cubic-bezier(0.16, 1, 0.3, 1);
}
@keyframes card-in {
  from { opacity: 0; transform: translateY(24px) scale(0.98); }
  to { opacity: 1; transform: translateY(0) scale(1); }
}
.auth-card.shake { animation: shake 420ms cubic-bezier(.36,.07,.19,.97); }
@keyframes shake {
  10%, 90% { transform: translateX(-1px); }
  20%, 80% { transform: translateX(2px); }
  30%, 50%, 70% { transform: translateX(-4px); }
  40%, 60% { transform: translateX(4px); }
}

.api-config {
  margin-bottom: 16px;
  font-size: 12px;
  color: var(--text-dim);
}
.api-config summary { cursor: pointer; user-select: none; }
.api-config .field { margin-top: 8px; margin-bottom: 0; }
.api-config input { font-size: 12px; padding: 6px 9px; }

.brand-mark { margin-bottom: 18px; }
.brand-mark svg { display: block; }

.auth-panel h1 {
  font-size: 24px;
  font-weight: 700;
  letter-spacing: -0.02em;
  margin: 0 0 6px;
}
.auth-panel .hint { margin: 0 0 24px; font-size: 14px; line-height: 1.5; }

/* Panel cross-fade + slide transition (swapped via JS toggling [hidden]
   then re-triggering the animation on the next frame). */
.auth-panel {
  animation: panel-in 320ms cubic-bezier(0.16, 1, 0.3, 1);
}
@keyframes panel-in {
  from { opacity: 0; transform: translateX(12px); }
  to { opacity: 1; transform: translateX(0); }
}

.back-btn {
  appearance: none; border: none; background: transparent;
  color: var(--text-dim); font-family: inherit; font-size: 13px;
  cursor: pointer; padding: 0; margin-bottom: 16px;
  display: inline-flex; align-items: center; gap: 4px;
  transition: color 150ms ease;
}
.back-btn:hover { color: var(--text); }

/* --- Floating-label fields --- */
.field.floating { position: relative; margin-bottom: 16px; }
.field.floating input {
  padding: 20px 14px 8px;
  height: 54px;
}
.field.floating label {
  position: absolute;
  left: 14px;
  top: 17px;
  margin: 0;
  font-size: 14px;
  color: var(--text-dim);
  pointer-events: none;
  transform-origin: left top;
  transition: transform 150ms ease, color 150ms ease, top 150ms ease;
}
.field.floating input:focus + label,
.field.floating input:not(:placeholder-shown) + label,
.field.floating input:-webkit-autofill + label {
  top: 8px;
  transform: scale(0.78);
  color: var(--accent);
}
.field.floating input { transition: border-color 150ms ease, box-shadow 150ms ease; }
.field.floating input:focus { box-shadow: 0 0 0 3px rgba(91, 140, 255, 0.15); }

/* Browser autofill (Chrome/Edge/Safari) sets a field's value through an
   internal path that doesn't reliably flip :placeholder-shown, which is
   what the floating-label rule above depends on — the label above is
   covered separately via :-webkit-autofill. Autofill also paints its own
   background (a yellow/light-blue tint) straight over this dark theme;
   neutralized with the standard "inset box-shadow the size of the field"
   trick, since background-color itself can't override autofill's style
   with any specificity. -webkit-text-fill-color is autofill's own
   replacement for `color` and must be set separately. */
.field.floating input:-webkit-autofill,
.field.floating input:-webkit-autofill:hover,
.field.floating input:-webkit-autofill:focus {
  -webkit-text-fill-color: var(--text);
  -webkit-box-shadow: 0 0 0 1000px #0d0f14 inset;
  box-shadow: 0 0 0 1000px #0d0f14 inset;
  caret-color: var(--text);
  transition: background-color 9999s ease-in-out 0s;
}

.reveal-btn {
  position: absolute;
  right: 10px;
  top: 50%;
  transform: translateY(-50%);
  appearance: none;
  border: none;
  background: transparent;
  color: var(--text-dim);
  cursor: pointer;
  padding: 6px;
  display: flex;
  border-radius: 6px;
  transition: color 150ms ease;
}
.reveal-btn:hover { color: var(--text); }

.row-between {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 22px;
  font-size: 13px;
}
.checkbox-row { display: flex; align-items: center; gap: 6px; color: var(--text-dim); cursor: pointer; }
.checkbox-row input { width: auto; margin: 0; }

.link-btn {
  appearance: none; border: none; background: transparent;
  color: var(--accent); font-family: inherit; font-size: 13px;
  cursor: pointer; padding: 0; text-decoration: none;
  transition: color 150ms ease;
}
.link-btn:hover { color: var(--accent-hover); text-decoration: underline; }

/* --- Buttons --- */
.btn-block { width: 100%; justify-content: center; }
.btn-primary {
  height: 46px;
  font-size: 14px;
  font-weight: 600;
  position: relative;
  transition: transform 120ms ease, box-shadow 200ms ease, background 150ms ease;
  box-shadow: 0 4px 14px rgba(91, 140, 255, 0.35);
}
.btn-primary:hover:not(:disabled) { transform: translateY(-1px); box-shadow: 0 6px 20px rgba(91, 140, 255, 0.45); }
.btn-primary:active:not(:disabled) { transform: translateY(0) scale(0.98); }
.btn-primary .spinner { border-color: rgba(255,255,255,0.35); border-top-color: white; }

.code-input {
  text-align: center;
  font-size: 24px;
  font-weight: 600;
  letter-spacing: 0.4em;
  padding-left: 0.4em !important;
}

.method-list { display: flex; flex-direction: column; gap: 10px; margin-bottom: 8px; }
.method-btn {
  display: flex; align-items: center; gap: 12px;
  width: 100%; text-align: left;
  padding: 14px 16px;
  background: var(--panel);
  border: 1px solid var(--panel-border);
  border-radius: 12px;
  color: var(--text);
  font-family: inherit; font-size: 14px; font-weight: 500;
  cursor: pointer;
  transition: border-color 150ms ease, background 150ms ease, transform 120ms ease;
}
.method-btn:hover { border-color: var(--accent); background: var(--panel-hover); transform: translateX(2px); }
.method-btn .method-icon { flex: none; color: var(--accent); display: flex; }
.method-btn .method-meta { flex: 1; min-width: 0; }
.method-btn .method-title { font-weight: 600; }
.method-btn .method-sub { font-size: 12px; color: var(--text-dim); margin-top: 2px; }

.passkey-icon {
  display: flex; align-items: center; justify-content: center;
  width: 88px; height: 88px;
  margin: 8px auto 24px;
  border-radius: 50%;
  background: linear-gradient(135deg, rgba(91,140,255,0.15), rgba(138,91,255,0.15));
  color: var(--accent);
  animation: pulse-ring 2.2s ease-in-out infinite;
}
@keyframes pulse-ring {
  0%, 100% { box-shadow: 0 0 0 0 rgba(91, 140, 255, 0.25); }
  50% { box-shadow: 0 0 0 14px rgba(91, 140, 255, 0); }
}

.result-icon {
  display: flex; align-items: center; justify-content: center;
  width: 72px; height: 72px;
  margin: 0 auto 20px;
  border-radius: 50%;
}
.success-icon {
  background: rgba(53, 201, 143, 0.12);
  color: var(--success);
}
.success-icon svg { stroke-dasharray: 60; stroke-dashoffset: 60; animation: draw 500ms ease-out 150ms forwards; }
@keyframes draw { to { stroke-dashoffset: 0; } }
.success-icon.celebrate { animation: pop-in 500ms cubic-bezier(0.34, 1.56, 0.64, 1) both; }
@keyframes pop-in { from { transform: scale(0); } to { transform: scale(1); } }

[data-panel="success"] h1,
[data-panel="forgot-password-sent"] h1 { text-align: center; }
[data-panel="success"] .hint,
[data-panel="forgot-password-sent"] .hint { text-align: center; }

.hidden { display: none !important; }

@media (max-width: 480px) {
  .auth-card { padding: 28px 22px; border-radius: 16px; }
  .lang-switcher { top: 12px; right: 12px; }
}
