/* ============================================================
   VITALITY LOOP — SSO LOGIN (ORBITAL, NO CARD)
   Shared stylesheet. CANONICAL SOURCE — do not edit copies.

   Source of truth:
     _pulse/01 - Projects/Vitality Loop Unified Access/login-kit/
   Propagate with ./sync.sh after any edit.

   The box is gone. The loop ring IS the container: sign-in
   controls float inside the circle the starfield orbits.
   Controls are boxless: borderless provider rows over thin
   rules, and an underline-only email field with an inline
   circular arrow submit.

   Every class is `vl-` prefixed so this can drop into a
   Tailwind app or onto wp-login.php without collisions.

   --vl-ring-r is written by vitality-loop-ring.js so the DOM
   content and the canvas ring stay one system. Preserve it.
   ============================================================ */

:root {
  --vl-bg: #0a0a0b;
  --vl-scanline: rgba(255, 255, 255, 0.015);
  --vl-text-primary: #f2f2f2;
  --vl-text-secondary: #8a8a8f;
  --vl-text-muted: #5c5c62;
  --vl-rule: rgba(255, 255, 255, 0.16);
  --vl-rule-focus: rgba(255, 255, 255, 0.4);
  --vl-teal: #1d9e75;
  --vl-teal-bright: #23b586;
  --vl-error: #e5484d;
  --vl-font-mono: ui-monospace, "SF Mono", "Cascadia Code", "JetBrains Mono", Menlo, Consolas, monospace;
  --vl-font-sans: -apple-system, "Helvetica Neue", "Segoe UI", Arial, sans-serif;
  --vl-ring-r: 300px; /* JS keeps this in sync with the canvas ring */
}

/* ---------- Full-bleed backdrop ----------
   Fixed, not a body background: these pages mount inside app
   shells (Next.js layout, wp-login.php) whose <body> we don't
   own. Covering with a fixed layer keeps the host untouched. */
.vl-login {
  position: fixed;
  inset: 0;
  z-index: 999;
  background: var(--vl-bg);
  color: var(--vl-text-primary);
  font-family: var(--vl-font-mono);
  -webkit-font-smoothing: antialiased;
  overflow-y: auto;
}

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

.vl-login::before {
  content: "";
  position: fixed;
  inset: 0;
  background: repeating-linear-gradient(
    to bottom,
    transparent 0px,
    transparent 3px,
    var(--vl-scanline) 3px,
    var(--vl-scanline) 4px
  );
  pointer-events: none;
  z-index: 2;
}

.vl-canvas {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  display: block;
  z-index: 0;
  pointer-events: none;
}

.vl-wrap {
  position: relative;
  z-index: 3;
  min-height: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 24px;
}

/* Everything lives inside the ring. No card, no borders. */
.vl-orbital {
  width: min(calc(var(--vl-ring-r) * 1.5), 92vw);
  text-align: center;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0;
}

/* ---------- Wordmark ---------- */
.vl-mark h1 {
  margin: 0;
  padding: 0;
  font-family: var(--vl-font-sans);
  font-size: clamp(30px, 4.5vw, 44px);
  font-weight: 800;
  letter-spacing: -0.8px;
  line-height: 1;
  color: var(--vl-text-primary);
}

.vl-loop-word {
  position: relative;
  display: inline-block;
  padding: 0 8px;
}

.vl-loop-word svg {
  position: absolute;
  inset: -11px -14px;
  width: calc(100% + 28px);
  height: calc(100% + 22px);
  overflow: visible;
  pointer-events: none;
}

.vl-loop-stroke {
  fill: none;
  stroke: var(--vl-teal);
  stroke-width: 2.5;
  stroke-linecap: round;
  stroke-dasharray: 600;
  stroke-dashoffset: 600;
  animation: vlDrawLoop 1.4s ease-out 0.3s forwards;
}

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

.vl-tagline {
  margin: 14px 0 0;
  color: var(--vl-text-secondary);
  font-size: 12.5px;
  letter-spacing: 1.4px;
}

.vl-tagline .vl-dot {
  color: var(--vl-teal);
  padding: 0 7px;
}

/* ---------- Auth controls ---------- */
.vl-auth {
  width: 100%;
  max-width: 340px;
  margin-top: 38px;
}

/* Provider rows: borderless, each over a thin rule.
   .vl-row is the single pattern every provider uses — Google,
   Apple, Facebook, Microsoft, and the RootPlayBook "Sign in via
   Journey" cross-link all render identically. */
.vl-row {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 12px;
  background: transparent;
  border: none;
  border-bottom: 1px solid var(--vl-rule);
  padding: 14px 4px 16px;
  color: var(--vl-text-primary);
  font-family: var(--vl-font-mono);
  font-size: 15px;
  font-weight: 600;
  text-align: center;
  text-decoration: none;
  cursor: pointer;
  transition: border-color 0.2s, opacity 0.2s;
}

.vl-row:hover {
  border-bottom-color: var(--vl-teal);
}

.vl-row:focus-visible {
  outline: 2px solid var(--vl-teal);
  outline-offset: 4px;
  border-radius: 4px;
}

.vl-row[disabled],
.vl-row[aria-disabled="true"] {
  opacity: 0.55;
  cursor: default;
}

.vl-row svg {
  flex-shrink: 0;
}

/* Trailing arrow for rows that leave the property (Journey link) */
.vl-row .vl-ext {
  margin-left: 2px;
  color: var(--vl-text-muted);
  font-size: 13px;
}

/* ---------- Social row ----------
   Circular icon buttons over the same thin rule the text rows use, so the
   boxless language holds. Providers that are not wired yet render dimmed and
   answer with a "coming soon" note rather than doing nothing on click — a
   button that silently ignores you reads as broken. */
.vl-social {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 14px;
  padding: 6px 0 18px;
  border-bottom: 1px solid var(--vl-rule);
}

.vl-social-btn {
  width: 46px;
  height: 46px;
  flex: 0 0 46px;
  padding: 0;
  border-radius: 50%;
  border: 1px solid var(--vl-rule);
  background: transparent;
  color: inherit;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: border-color 0.2s, opacity 0.2s, transform 0.15s;
}

.vl-social-btn svg {
  width: 21px;
  height: 21px;
  display: block;
}

.vl-social-btn:hover {
  border-color: var(--vl-teal);
  transform: translateY(-1px);
}

.vl-social-btn:focus-visible {
  outline: 2px solid var(--vl-teal);
  outline-offset: 3px;
}

/* Not wired up yet. Still focusable and still clickable — it has something to
   say. */
.vl-social-btn.vl-soon {
  opacity: 0.38;
}

.vl-social-btn.vl-soon:hover {
  opacity: 0.6;
  border-color: var(--vl-rule);
  transform: none;
}

/* The "coming soon" answer. Deliberately an in-page live region, never a
   window.alert: a modal dialog blocks the page and is the wrong weight for
   this. Reserves its own height so the layout never jumps. */
.vl-toast {
  /* line-height and min-height must match exactly. Leaving min-height at a
     round 16px against a 17.25px computed line-height shifted the whole auth
     block by 1.25px every time the note appeared. */
  line-height: 16px;
  min-height: 16px;
  margin-top: 12px;
  color: var(--vl-text-secondary);
  font-size: 11.5px;
  letter-spacing: 0.8px;
  opacity: 0;
  transition: opacity 0.25s;
  pointer-events: none;
}

.vl-toast.vl-visible {
  opacity: 1;
}

.vl-or {
  margin: 22px 0 6px;
  color: var(--vl-text-muted);
  font-size: 10.5px;
  letter-spacing: 3px;
}

/* Email / password: underline-only fields with an inline arrow submit */
.vl-field {
  display: flex;
  align-items: center;
  gap: 8px;
  border-bottom: 1px solid var(--vl-rule);
  transition: border-color 0.2s;
}

.vl-field + .vl-field {
  margin-top: 4px;
}

.vl-field:focus-within {
  border-bottom-color: var(--vl-rule-focus);
}

/* Text-entry inputs only. WordPress renders its submit as an <input
   type="submit">, so a bare `.vl-field input` also captures the submit and
   hands it flex:1 — it then stretches and overruns the row. Anything that is
   not a text field is excluded here rather than fought per property. */
.vl-field input:not([type="submit"]):not([type="button"]):not([type="checkbox"]):not([type="radio"]) {
  flex: 1;
  min-width: 0;
  background: transparent;
  border: none;
  padding: 14px 4px 15px;
  color: var(--vl-text-primary);
  font-family: var(--vl-font-mono);
  font-size: 15px;
  text-align: center;
}

.vl-field input:focus {
  outline: none;
}

.vl-field input::placeholder {
  color: var(--vl-text-muted);
}

/* Kill the browser's yellow autofill wash — it reintroduces a box. */
.vl-field input:-webkit-autofill,
.vl-field input:-webkit-autofill:hover,
.vl-field input:-webkit-autofill:focus {
  -webkit-text-fill-color: var(--vl-text-primary);
  -webkit-box-shadow: 0 0 0 1000px var(--vl-bg) inset;
  caret-color: var(--vl-text-primary);
}

.vl-go {
  flex-shrink: 0;
  width: 38px;
  height: 38px;
  border-radius: 50%;
  border: 1px solid var(--vl-rule);
  background: transparent;
  color: var(--vl-text-secondary);
  font-family: var(--vl-font-mono);
  font-size: 17px;
  line-height: 1;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: border-color 0.2s, color 0.2s, background 0.2s;
}

.vl-field:focus-within .vl-go,
.vl-go:hover {
  border-color: var(--vl-teal);
  color: #08130f;
  background: var(--vl-teal);
}

.vl-go:focus-visible {
  outline: 2px solid var(--vl-teal);
  outline-offset: 2px;
}

.vl-go[disabled] {
  opacity: 0.5;
  cursor: default;
}

/* Password row stays hidden until the email step is satisfied
   (RootPlayBook). Revealed by adding .vl-revealed. */
.vl-step-hidden {
  display: none;
}

.vl-step-hidden.vl-revealed {
  display: flex;
}

/* "Keep me signed in" — small checkbox row, no box */
.vl-check {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  margin-top: 18px;
  color: var(--vl-text-secondary);
  font-size: 12px;
  letter-spacing: 0.3px;
}

.vl-check input[type="checkbox"] {
  width: 13px;
  height: 13px;
  accent-color: var(--vl-teal);
  cursor: pointer;
}

.vl-check label {
  cursor: pointer;
}

.vl-check input[type="checkbox"]:focus-visible {
  outline: 2px solid var(--vl-teal);
  outline-offset: 2px;
}

/* ---------- Messaging ---------- */
.vl-msg {
  margin-top: 16px;
  font-size: 12px;
  line-height: 1.6;
  letter-spacing: 0.2px;
}

.vl-msg-error {
  color: var(--vl-error);
}

.vl-msg-ok {
  color: var(--vl-teal-bright);
}

.vl-msg-note {
  color: var(--vl-text-secondary);
}

.vl-error-msg {
  display: none;
  color: var(--vl-error);
  font-size: 12px;
  margin-top: 10px;
}

.vl-error-msg.vl-visible {
  display: block;
}

.vl-footnote {
  margin: 46px 0 0;
  color: var(--vl-text-muted);
  font-size: 12px;
  letter-spacing: 0.4px;
  line-height: 1.7;
}

.vl-footnote a {
  color: var(--vl-text-secondary);
  text-decoration: none;
  border-bottom: 1px solid var(--vl-rule);
  transition: color 0.2s, border-color 0.2s;
}

.vl-footnote a:hover {
  color: var(--vl-text-primary);
  border-bottom-color: var(--vl-teal);
}

.vl-footnote a:focus-visible {
  outline: 2px solid var(--vl-teal);
  outline-offset: 3px;
  border-radius: 2px;
}

/* Visually hidden but available to screen readers */
.vl-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;
}

/* ---------- Mobile ----------
   At 375px the ring keeps scaling down and reads as ambient
   rather than a hard frame; controls stay centered and tappable. */
@media (max-width: 560px) {
  .vl-orbital {
    width: 92vw;
  }
  .vl-auth {
    margin-top: 30px;
  }
  .vl-footnote {
    margin-top: 34px;
  }
}

/* ---------- Reduced motion ----------
   Static frame. The traveler parks at 12 o'clock (handled in
   vitality-loop-ring.js); the wordmark stroke renders drawn. */
@media (prefers-reduced-motion: reduce) {
  .vl-loop-stroke {
    animation: none;
    stroke-dashoffset: 0;
  }
  .vl-row,
  .vl-field,
  .vl-go,
  .vl-footnote a,
  .vl-social-btn,
  .vl-toast {
    transition: none;
  }
  .vl-social-btn:hover {
    transform: none;
  }
}
