/* Login / signup — aesthetic auth screens on the Stellaria canvas. */

*, *::before, *::after { box-sizing: border-box; }
[hidden] { display: none !important; }

* { scrollbar-width: thin; scrollbar-color: var(--c-surface-3) transparent; }
::-webkit-scrollbar { width: 12px; height: 12px; }
::-webkit-scrollbar-thumb { background: var(--c-surface-3); border-radius: var(--r-pill); border: 3px solid var(--c-bg); background-clip: padding-box; }

html, body { min-height: 100%; }
body {
  margin: 0;
  background: var(--c-bg);
  color: var(--c-text);
  font-family: var(--font-display);
  font-size: var(--fs-body);
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  /* The card must be reachable on a short window: overflow: hidden here
     hid the "Create an account" line with no scrollbar to hint at it. */
  overflow-x: hidden;
  overflow-y: auto;
}
a { color: var(--c-accent-hi); text-decoration: none; }
a:hover { text-decoration: underline; }
::selection { background: var(--c-accent-line); color: var(--c-on-accent); }
:focus-visible { outline: none; box-shadow: var(--shadow-focus); border-radius: var(--r-1); }

.skip-link { position: absolute; left: var(--sp-3); top: var(--sp-3); transform: translateY(-200%); background: var(--c-accent-solid); color: var(--c-on-accent); padding: var(--sp-2) var(--sp-4); border-radius: var(--r-2); z-index: 100; transition: transform var(--dur-2) var(--ease-out); }
.skip-link:focus { transform: translateY(0); }

/* ── Full-screen flow-field backdrop ─────────────────────────────────────── */
.auth-scene { position: fixed; inset: 0; width: 100%; height: 100%; z-index: 0; display: block; }
/* Soft central shade to seat the card; the field stays bold across the screen. */
.grain { position: fixed; inset: 0; z-index: 1; pointer-events: none; background:
  radial-gradient(58% 52% at 50% 48%, oklch(0.15 0.012 260 / 0.72) 0%, transparent 62%); }

/* ── Layout ──────────────────────────────────────────────────────────────── */
/* min-height, not height: the wrapper fills a tall window and grows past a
   short one. Centring is done by the card's auto margins, because
   place-items: center on an item taller than its box clips both ends of it
   and makes the top unreachable. */
.auth-wrap { position: relative; z-index: 2; min-height: 100vh; min-height: 100dvh; display: grid; grid-template-columns: 1fr; padding: var(--sp-5); }

.auth-card {
  width: min(360px, 100%);
  background: var(--c-surface);
  border: 1px solid var(--c-border);
  border-radius: var(--r-3);
  padding: var(--sp-5);
  display: flex; flex-direction: column; gap: var(--sp-4);
  animation: card-in var(--dur-3) var(--ease-out) both;
  margin: auto;
}
@keyframes card-in { from { opacity: 0; transform: translateY(20px) scale(0.98); } to { opacity: 1; transform: translateY(0) scale(1); } }

/* ── Brand ───────────────────────────────────────────────────────────────── */
.auth-brand { display: flex; flex-direction: column; align-items: center; gap: var(--sp-1); text-align: center; }
.auth-logo {
  width: 44px; height: 44px; border-radius: 12px; margin-bottom: var(--sp-1);
  animation: logo-in var(--dur-3) var(--ease-out) both, logo-float 6s var(--ease-in-out) 0.6s infinite;
}
@keyframes logo-in { from { opacity: 0; transform: scale(0.6) rotate(-12deg); } to { opacity: 1; transform: scale(1) rotate(0); } }
@keyframes logo-float { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-6px); } }
html[data-motion="off"] .auth-logo { animation: none; }
/* The way to stop the backdrop and the logo (WCAG 2.2.2): quiet, in the corner, and 24 px or more to hit. */
.auth-motion {
  position: fixed; right: var(--sp-3); bottom: var(--sp-3); z-index: 5;
  min-height: 28px; padding: 4px 10px;
  background: var(--c-surface); color: var(--c-text-dim);
  border: 1px solid var(--c-border); border-radius: var(--r-2);
  font-family: var(--font-mono); font-size: var(--fs-eyebrow); letter-spacing: 0.08em; text-transform: uppercase;
  cursor: pointer;
}
.auth-motion:hover { color: var(--c-text); border-color: var(--c-text-faint); }
.auth-motion[hidden] { display: none; }
@media (pointer: coarse) { .auth-motion { min-height: 44px; } }
.auth-brand__name { font-family: var(--font-mono); font-size: var(--fs-eyebrow); text-transform: uppercase; letter-spacing: 0.22em; color: var(--c-text-faint); }
.auth-title { font-size: var(--fs-h3); color: var(--c-white); letter-spacing: -0.01em; line-height: 1.1; margin-top: var(--sp-1); }
.auth-sub { font-size: var(--fs-label); color: var(--c-text-dim); }

/* ── Form ────────────────────────────────────────────────────────────────── */
.auth-form { display: flex; flex-direction: column; gap: var(--sp-3); }
.field {
  display: flex; flex-direction: column; gap: var(--sp-1);
  animation: field-in var(--dur-3) var(--ease-out) both;
}
.field:nth-child(1) { animation-delay: 0.08s; }
.field:nth-child(2) { animation-delay: 0.14s; }
.field:nth-child(3) { animation-delay: 0.20s; }
.field:nth-child(4) { animation-delay: 0.26s; }
@keyframes field-in { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: translateY(0); } }
.field > label { font-family: var(--font-mono); font-size: var(--fs-eyebrow); text-transform: uppercase; letter-spacing: 0.1em; color: var(--c-text-dim); }

.input-shell { position: relative; display: flex; align-items: center; }
.input-shell > svg { position: absolute; left: var(--sp-3); width: 16px; height: 16px; color: var(--c-text-faint); pointer-events: none; transition: color var(--dur-1) var(--ease-out); }
.input-shell:focus-within > svg { color: var(--c-accent); }
.auth-input {
  width: 100%; background: var(--c-surface-3); color: var(--c-text);
  border: 1px solid var(--c-border); border-radius: var(--r-2);
  padding: var(--sp-2) var(--sp-3) var(--sp-2) calc(var(--sp-3) + 24px);
  font-family: var(--font-display); font-size: var(--fs-body);
  transition: border-color var(--dur-1) var(--ease-out);
}
.auth-input::placeholder { color: var(--c-text-faint); }
.auth-input:hover { border-color: var(--c-text-faint); }
.auth-input:focus-visible { border-color: var(--c-accent); box-shadow: var(--shadow-focus); }
.auth-input[aria-invalid="true"] { border-color: var(--c-danger); }
.pw-toggle { position: absolute; right: var(--sp-2); background: transparent; border: none; color: var(--c-text-faint); cursor: pointer; padding: var(--sp-2); display: grid; place-items: center; border-radius: var(--r-1); }
.pw-toggle:hover { color: var(--c-text); }
.pw-toggle svg { width: 16px; height: 16px; }

/* password strength meter (signup) */
.pw-meter { height: 4px; border-radius: var(--r-pill); background: var(--c-surface-3); overflow: hidden; }
.pw-meter__bar { height: 100%; width: 0; border-radius: var(--r-pill); background: var(--c-accent); transition: width var(--dur-2) var(--ease-out), background var(--dur-2) var(--ease-out); }

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--sp-2);
  min-height: 42px; padding: var(--sp-2) var(--sp-4); margin-top: var(--sp-1);
  /* --c-accent-solid is the one that carries small light text at 6:1;
     --c-accent is 3.5:1 and drops to 2.5:1 on hover (tokens.css:28). */
  background: var(--c-accent-solid); color: var(--c-on-accent);
  border: 1px solid var(--c-accent); border-radius: var(--r-2);
  font-family: var(--font-display); font-size: var(--fs-body); font-weight: 600; cursor: pointer;
  transition: background var(--dur-1) var(--ease-out), transform var(--dur-1) var(--ease-out);
  animation: field-in var(--dur-3) var(--ease-out) 0.30s both;
}
/* Hover darkens rather than lightens: --c-accent-hi is the *brighter* accent and
   takes the label under 3:1 on a filled button. */
.btn:hover { background: color-mix(in oklab, var(--c-accent-solid) 88%, black); border-color: var(--c-accent-hi); }
.btn:active { transform: translateY(1px); }
.btn:disabled { opacity: 0.6; cursor: progress; }
.btn__spin { width: 16px; height: 16px; border: 2px solid color-mix(in oklab, var(--c-on-accent) 40%, transparent); border-top-color: var(--c-on-accent); border-radius: 50%; animation: spin 0.7s linear infinite; }
@keyframes spin { to { transform: rotate(360deg); } }

.auth-alt { text-align: center; font-size: var(--fs-label); color: var(--c-text-dim); animation: field-in var(--dur-3) var(--ease-out) 0.36s both; }
/* A link inside a sentence ("New here? Create an account") was told apart from it by colour alone, 1.1:1 against the
   words around it (WCAG 1.4.1): underlined, so it is a link to somebody who cannot see the blue. */
.auth-alt a { text-decoration: underline; text-underline-offset: 3px; }

.auth-msg {
  min-height: 0; font-size: var(--fs-label); text-align: center;
  border-radius: var(--r-2); overflow: hidden; max-height: 0; opacity: 0;
  transition: max-height var(--dur-2) var(--ease-out), opacity var(--dur-2) var(--ease-out), padding var(--dur-2) var(--ease-out);
  padding: 0 var(--sp-3);
}
.auth-msg.is-shown { max-height: 220px; opacity: 1; padding: var(--sp-2) var(--sp-3); }
.auth-msg--error { color: oklch(0.8 0.1 30); border: 1px solid oklch(0.6 0.14 30 / 0.5); background: oklch(0.6 0.14 30 / 0.1); }
.auth-msg--ok { color: var(--c-accent-hi); border: 1px solid var(--c-accent-line); background: var(--c-accent-ghost); }
/* The dark theme's pale salmon is 1.7:1 on the light card (axe: color-contrast); the theme's own danger colour is 5.3:1 there. */
:root[data-theme="light"] .auth-msg--error { color: var(--c-danger); }

.shake { animation: shake 0.4s var(--ease-in-out); }
@keyframes shake { 0%,100% { transform: translateX(0); } 20% { transform: translateX(-8px); } 40% { transform: translateX(7px); } 60% { transform: translateX(-5px); } 80% { transform: translateX(3px); } }

.auth-foot { position: relative; z-index: 2; padding: var(--sp-4); text-align: center; font-family: var(--font-mono); font-size: var(--fs-eyebrow); letter-spacing: 0.14em; text-transform: uppercase; color: var(--c-text-faint); display: flex; align-items: center; justify-content: center; gap: var(--sp-2); }
.auth-foot img { width: 14px; height: 14px; border-radius: 4px; }

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

/* ── Firebase sign-in (D44) ──────────────────────────────────────────────────
   One Google button above the email form, separated by a quiet "or". The
   Google mark keeps its own colours by design; everything else is the app's. */
.btn--google {
  display: inline-flex; align-items: center; justify-content: center; gap: 10px;
  width: 100%;
  background: var(--c-surface-2); color: var(--c-text);
  border: 1px solid var(--c-border);
}
.btn--google:hover { background: var(--c-surface-3); border-color: var(--c-text-faint); }
.btn--google svg { width: 18px; height: 18px; flex: none; }
.btn--google:disabled { opacity: 0.6; cursor: default; }

.auth-divider {
  display: flex; align-items: center; gap: 12px;
  margin: 14px 0 10px;
  color: var(--c-text-faint); font-family: var(--font-mono); font-size: 11px;
  text-transform: uppercase; letter-spacing: 0.12em;
}
.auth-divider::before, .auth-divider::after { content: ''; flex: 1; height: 1px; background: var(--c-border-soft); }

.auth-alt--tight { margin-top: 10px; }

/* ── Joining (D45) ─────────────────────────────────────────────────────────
   How this installation admits people, said on the page itself: a hint under
   the title, an invite field that appears only where one is needed, and the
   one thing a message may offer to do about itself. */
.auth-hint {
  margin-top: var(--sp-2); padding-top: var(--sp-2);
  border-top: 1px solid var(--c-border-soft);
  font-size: var(--fs-label); line-height: 1.5; color: var(--c-text-faint); text-align: center;
}
.auth-msg__action {
  background: none; border: none; padding: 0; font: inherit; color: inherit;
  text-decoration: underline; text-underline-offset: 2px; cursor: pointer;
}
.auth-msg__action:disabled { opacity: 0.6; cursor: default; }
#invite { text-transform: uppercase; letter-spacing: 0.08em; font-family: var(--font-mono); }
#invite::placeholder { text-transform: none; letter-spacing: normal; }

/* ── Short windows ─────────────────────────────────────────────────────────
   A laptop window is often about 540px of page, and the card was 634px: the
   last line of it, the link to create an account, sat below the fold. The
   page scrolls now, but a sign-in screen should not need scrolling to show
   the way to sign up, so on a short window the card tightens instead. */
@media (max-height: 760px) {
  .auth-wrap { padding: var(--sp-3) var(--sp-5); }
  .auth-card { gap: var(--sp-3); padding: var(--sp-4) var(--sp-5); }
  .auth-logo { width: 34px; height: 34px; border-radius: 10px; margin-bottom: 0; }
  .auth-title { margin-top: 0; }
  .auth-form { gap: var(--sp-2); }
  .auth-hint { margin-top: var(--sp-1); padding-top: var(--sp-2); }
}

/* Shorter still (a laptop window with browser chrome, about 550px of page):
   the sentence under the title only restates the two buttons beneath it, so
   it goes, and the whole card fits without scrolling. */
@media (max-height: 660px) {
  /* The signup card is the taller of the two (a name field and the strength
     meter): these last few pixels are what let its footer show as well. */
  .auth-wrap { padding: var(--sp-2) var(--sp-5); }
  .auth-card { gap: var(--sp-2); padding: var(--sp-3) var(--sp-5); }
  .auth-sub { display: none; }
  .auth-form { gap: 6px; }
  .auth-divider { margin: 2px 0; }
  .pw-meter { margin-top: 2px; }
  .auth-hint { margin-top: 0; padding-top: var(--sp-1); }
}

/* Engines without color-mix() (Safari before 16.2, Chrome 110): the declarations above that hold color-mix(var(..)) are reset there, not
   skipped, so the states they style are restated plainly. */
@supports not (background: color-mix(in oklab, red 50%, blue)) {
  .btn:hover { background: var(--c-accent-solid); }
  .btn__spin { border: 2px solid transparent; border-top-color: var(--c-on-accent); }
}
