/* ishlar — login page v3: abstract-shapes stage + two-step form. Loaded only by views/auth/login.php (after app.css). Tokens only; nothing here defines a colour, size or radius of its own. */

.auth-v3 { min-height: 100dvh; display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); background: var(--bg); color: var(--text); overflow-x: hidden; }
.auth-v3 .auth-form-wrap { padding: var(--sp-6); transition: opacity 350ms var(--ease), transform 350ms var(--ease); }
.auth-v3 .auth-mobile-brand { display: none !important; }

/* ---------- form ---------- */
/* username / password are LTR values: the wrapper is LTR so icon, text and caret all sit on the same side */
.auth-v3 .input-icon { direction: ltr; }
.auth-v3 .input-icon > .input { padding-inline: var(--sp-10); text-align: start; }
.auth-v3 .input-icon > i { transition: color var(--t-fast); }
.auth-v3 .input-icon:focus-within > i { color: var(--primary); }
.auth-v3 .input-icon > .toggle-pass { inset-inline-end: var(--sp-1); }

.lg-progress { display: flex; align-items: center; gap: var(--sp-3); }
.lg-steps { flex: 1; display: flex; gap: var(--sp-2); }
.lg-steps i { position: relative; flex: 1; height: var(--sp-1); border-radius: var(--r-full); background: var(--surface-3); overflow: hidden; }
/* origin on the right: RTL fills from the start side */
.lg-steps i::after { content: ''; position: absolute; inset: 0; background: var(--primary); transform: scaleX(0); transform-origin: 100% 50%; transition: transform 300ms var(--ease); }
.lg-steps i.on::after { transform: scaleX(1); }
.lg-stepno { font-size: var(--fs-xs); color: var(--muted); white-space: nowrap; }

/* one message line under the active field: an error from the server, or the Caps Lock warning. Fixed one-line height, so nothing ever moves when it appears */
.lg-msg { height: calc(var(--fs-sm) * var(--lh-ui)); margin: calc(var(--sp-2) * -1) 0; font-size: var(--fs-sm); line-height: var(--lh-ui); color: var(--danger); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; opacity: 0; transform: translateY(calc(var(--sp-1) * -1)); transition: opacity var(--t-fast), transform var(--t-fast) var(--ease); }
.lg-msg.show { opacity: 1; transform: none; }
.lg-msg.warn { color: var(--warn); }
.auth-v3.lg-js #loginForm #formError { display: none; } /* mirrored into .lg-msg by login-stage.js (without JS the red box still shows) */

/* step change: the step that comes in fades in from its side (forward = leftwards in RTL) */
.auth-v3.lg-ready #loginForm [data-step="2"]:not([hidden]) { animation: lg-step-fwd var(--t-med) var(--ease); }
.auth-v3.lg-ready #loginForm [data-step="1"]:not([hidden]) { animation: lg-step-back var(--t-med) var(--ease); }
@keyframes lg-step-fwd { from { opacity: 0; transform: translateX(var(--sp-6)); } to { opacity: 1; transform: none; } }
@keyframes lg-step-back { from { opacity: 0; transform: translateX(calc(var(--sp-6) * -1)); } to { opacity: 1; transform: none; } }

/* submit button: ripple + success colour */
.auth-v3 #loginForm .btn-primary { overflow: hidden; }
.auth-v3 #loginForm .btn-primary[data-state="success"] { background: var(--success); border-color: var(--success); }
.lg-ripple { position: absolute; width: var(--sp-10); height: var(--sp-10); margin: calc(var(--sp-5) * -1) 0 0 calc(var(--sp-5) * -1); border-radius: 50%; background: currentColor; opacity: .3; pointer-events: none; animation: lg-ripple 450ms var(--ease) forwards; }
@keyframes lg-ripple { to { transform: scale(8); opacity: 0; } }
@keyframes lg-shake { 0%, 100% { transform: translateX(0); } 20% { transform: translateX(-8px); } 40% { transform: translateX(8px); } 60% { transform: translateX(-5px); } 80% { transform: translateX(5px); } }
.lg-shake { animation: lg-shake 300ms var(--ease); }
.lg-done { pointer-events: none; }

/* staggered entrance: heading first, then fields, then secondary links (40ms apart) */
.auth-v3.lg-js [data-rise] { opacity: 0; transform: translateY(var(--sp-3)); animation: lg-rise 300ms var(--ease) forwards; animation-delay: calc(var(--i, 0) * 40ms); }
@keyframes lg-rise { to { opacity: 1; transform: none; } }

/* ---------- stage ---------- */
.auth-stage { --ab-core: var(--on-primary); --ab-ink: var(--brand-500); --ab-a: var(--brand-300); --ab-b: var(--brand-200); --ab-c: var(--brand-100); --ab-d: var(--brand-400); --ab-ring: var(--brand-200);
  position: relative; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: var(--sp-6); padding: var(--sp-8) var(--sp-6); overflow: hidden;
  background: linear-gradient(160deg, var(--brand-500), var(--brand-700)); color: var(--on-primary); }
.auth-stage h2 { margin: 0; font-size: var(--fs-xl); line-height: var(--lh-head); text-align: center; color: var(--on-primary); }
.auth-stage p { margin: 0; max-width: 32ch; font-size: var(--fs-sm); line-height: var(--lh-body); text-align: center; color: var(--brand-100); }
:root[data-theme="dark"] .auth-stage { --ab-core: var(--primary); --ab-ink: var(--on-primary); --ab-c: var(--text-2); --ab-ring: var(--brand-300); background: linear-gradient(160deg, var(--brand-100), var(--bg)); }
:root[data-theme="dark"] .auth-stage h2 { color: var(--text); }
:root[data-theme="dark"] .auth-stage p { color: var(--text-2); }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .auth-stage { --ab-core: var(--primary); --ab-ink: var(--on-primary); --ab-c: var(--text-2); --ab-ring: var(--brand-300); background: linear-gradient(160deg, var(--brand-100), var(--bg)); }
  :root:not([data-theme="light"]) .auth-stage h2 { color: var(--text); }
  :root:not([data-theme="light"]) .auth-stage p { color: var(--text-2); }
}
/* dimmed after 10 s idle: the shapes slide to deeper brand blues (no filter, no grey) — the centre circle keeps its colour */
:root:root .auth-stage[data-idle] { --ab-a: var(--brand-500); --ab-b: var(--brand-400); --ab-c: var(--brand-300); --ab-d: var(--brand-600); --ab-ring: var(--brand-600); }

/* day / night layers, stars (night) and clouds (day) sit under the shapes */
.ab-tod { position: absolute; inset: 0; pointer-events: none; opacity: 0; transition: opacity 800ms; }
.ab-tod-day { background: linear-gradient(160deg, color-mix(in srgb, var(--brand-200) 30%, transparent), transparent 70%); }
.ab-tod-night { background: linear-gradient(var(--scrim), var(--scrim)), linear-gradient(160deg, var(--scrim), color-mix(in srgb, var(--scrim) 60%, transparent)); }
[data-tod="day"] .ab-tod-day, [data-tod="night"] .ab-tod-night { opacity: 1; }
.ab-stars { position: absolute; inset: 0; z-index: 0; pointer-events: none; opacity: 0; transition: opacity 800ms; animation: ab-twinkle 4s ease-in-out infinite;
  background-size: 220px 220px;
  background-image:
    radial-gradient(1.5px 1.5px at 12% 18%, var(--brand-100) 99%, transparent), radial-gradient(1px 1px at 34% 52%, var(--brand-100) 99%, transparent),
    radial-gradient(2px 2px at 58% 12%, var(--brand-100) 99%, transparent), radial-gradient(1px 1px at 72% 66%, var(--brand-100) 99%, transparent),
    radial-gradient(1.5px 1.5px at 88% 34%, var(--brand-100) 99%, transparent), radial-gradient(1px 1px at 22% 82%, var(--brand-100) 99%, transparent),
    radial-gradient(2px 2px at 46% 90%, var(--brand-100) 99%, transparent), radial-gradient(1px 1px at 92% 88%, var(--brand-100) 99%, transparent);
  /* stars keep 40px away from the tagline: a hole is cut out of the layer (--hx/--hy/--hw/--hh come from JS) */
  --m: linear-gradient(black, black); -webkit-mask-image: var(--m), var(--m); mask-image: var(--m), var(--m);
  -webkit-mask-size: 100% 100%, var(--hw, 0px) var(--hh, 0px); mask-size: 100% 100%, var(--hw, 0px) var(--hh, 0px);
  -webkit-mask-position: 0 0, var(--hx, 0px) var(--hy, 0px); mask-position: 0 0, var(--hx, 0px) var(--hy, 0px);
  -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat; -webkit-mask-composite: xor; mask-composite: exclude; }
[data-tod="night"] .ab-stars { opacity: 1; }
@keyframes ab-twinkle { 0%, 100% { filter: none; } 50% { filter: brightness(.55); } }
.ab-clouds { position: absolute; inset: 0; z-index: 0; overflow: hidden; pointer-events: none; opacity: 0; transition: opacity 800ms; }
[data-tod="day"] .ab-clouds { opacity: 1; }
/* physical left on purpose: the clouds travel left → right in screen space */
.ab-clouds i { position: absolute; left: 0; width: calc(var(--sp-10) * 3); height: var(--sp-8); border-radius: var(--r-full); background: var(--brand-200); opacity: .3; animation: ab-cloud 46s linear infinite; }
.ab-clouds i:nth-child(1) { top: 16%; } .ab-clouds i:nth-child(2) { top: 44%; width: calc(var(--sp-10) * 4); animation-duration: 62s; animation-delay: -22s; } .ab-clouds i:nth-child(3) { top: 70%; animation-duration: 54s; animation-delay: -40s; }
@keyframes ab-cloud { from { transform: translateX(-200px); } to { transform: translateX(60vw); } }

/* physical left/top on purpose: JS positions the glow with raw pointer coordinates */
.ab-glow { position: absolute; left: 0; top: 0; z-index: 0; width: 480px; height: 480px; margin: -240px 0 0 -240px; border-radius: 50%; background: radial-gradient(circle, color-mix(in srgb, var(--brand-300) 45%, transparent), transparent 65%); pointer-events: none; will-change: transform; transition: opacity 800ms; }
[data-idle] .ab-glow { opacity: 0; }
.auth-stage h2, .auth-stage p { position: relative; z-index: 1; }

/* ---------- shapes ---------- */
.ab-field { position: relative; z-index: 2; width: min(420px, 80%); aspect-ratio: 1; cursor: pointer; touch-action: manipulation; transition: opacity 800ms; }
.ab { display: block; width: 100%; height: 100%; overflow: visible; will-change: transform; }
.ab-s { will-change: transform; }
.ab .a { fill: var(--ab-a); } .ab .b { fill: var(--ab-b); } .ab .c { fill: var(--ab-c); } .ab .d { fill: var(--ab-d); }
.ab .a.o { fill: none; stroke: var(--ab-a); stroke-width: 8; }
.ab .c.t { stroke: var(--ab-c); stroke-width: 8; stroke-linejoin: round; }
.ab .a, .ab .b, .ab .c, .ab .d { transition: fill 800ms, stroke 800ms; }
.ab-s.caps .d { transition: fill var(--t-med); }
.auth-stage[data-caps] .ab-s.caps .d { fill: var(--warn); } /* Caps Lock is on: one shape turns amber */

/* rings: three layers cross-fade with the state (dots → solid → open arc) */
.ab-ring { fill: none; stroke: var(--ab-ring); stroke-width: 3; opacity: 0; transition: opacity var(--t-med), stroke var(--t-med); }
.ab-ring-dots { stroke-width: 4; stroke-dasharray: 2 14; stroke-linecap: round; opacity: .8; }
.ab-ring-open { stroke-dasharray: 560 144; stroke-linecap: round; }
.auth-stage[data-state="pass"] .ab-ring-dots, .auth-stage[data-state="peek"] .ab-ring-dots, .auth-stage[data-state="success"] .ab-ring-dots { opacity: 0; }
.auth-stage[data-state="pass"] .ab-ring-solid { opacity: .9; }
.auth-stage[data-state="peek"] .ab-ring-open { opacity: .9; }

/* core: breathes, closes into a lock on the password step, turns green with a check on success */
.ab-core { fill: var(--ab-core); transition: fill var(--t-med); }
.ab-lock { opacity: 0; transition: opacity var(--t-med); }
.ab-lock rect { fill: var(--ab-ink); }
.ab-shackle { fill: none; stroke: var(--ab-ink); stroke-width: 7; stroke-linecap: round; transition: transform var(--t-med) var(--ease); }
.ab-check { fill: none; stroke: var(--on-primary); stroke-width: 9; stroke-linecap: round; stroke-linejoin: round; stroke-dasharray: 90; stroke-dashoffset: 90; transition: stroke-dashoffset 400ms var(--ease) 120ms; }
.auth-stage[data-state="pass"] .ab-lock, .auth-stage[data-state="peek"] .ab-lock { opacity: 1; }
.auth-stage[data-state="peek"] .ab-shackle { transform: translateY(-9px); }
.auth-stage[data-state="error"] .ab-core { fill: var(--danger); }
.auth-stage[data-state="success"] .ab-core { fill: var(--success); }
.auth-stage[data-state="success"] .ab-check { stroke-dashoffset: 0; }
#core { transition: opacity 400ms; }
.lg-boarding #core { opacity: 0; } /* the green circle hides while it turns into the columns */

/* success: the circle morphs into 3 board columns where it stands — the lanes start squeezed into its footprint and open outwards */
.ab-board rect { fill: var(--ab-ring); fill-opacity: .12; stroke: var(--ab-ring); stroke-width: 2; vector-effect: non-scaling-stroke; opacity: 0;
  transform-box: fill-box; transform-origin: center; transform: translateX(var(--sx, 0px)) scale(.45, .8); transition: opacity 500ms, transform 650ms var(--ease); }
.ab-board rect:nth-child(1) { --sx: 80px; }
.ab-board rect:nth-child(3) { --sx: -80px; }
.auth-stage[data-sorted] .ab-board rect { opacity: .6; transform: none; }

/* each shape cross-fades into a card face once it lands; a completed card gets a green bar and tick */
.ab-s > * { transition: opacity 220ms; }
.ab-cardg { opacity: 0; }
.ab-s.landed > :not(.ab-cardg) { opacity: 0; }
.ab-s.landed > .ab-cardg { opacity: 1; }
.ab .ab-card { fill: var(--ab-core); }
.ab .ab-line { fill: var(--ab-ink); opacity: .25; }
.ab .ab-acc { transition: fill 250ms; }
.ab-tick, .ab-tickp { opacity: 0; transform-box: fill-box; transform-origin: center; transform: scale(.3); transition: opacity 200ms, transform 300ms cubic-bezier(.34, 1.4, .64, 1); }
.ab-tick { fill: var(--success); }
.ab-tickp { fill: none; stroke: var(--on-primary); stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
.ab-s.done .ab-tick, .ab-s.done .ab-tickp { opacity: 1; transform: none; }
.ab-s.done .ab-cardg .ab-acc { fill: var(--success); }
.ab-s.done .ab-cardg .ab-line { opacity: .12; }

/* ---------- exit: the form leaves, the board travels to the centre and grows, then the page washes into the dashboard colour ---------- */
.lg-leaving .auth-form-wrap { opacity: 0; transform: scale(.97); pointer-events: none; }
.lg-leaving .auth-stage h2, .lg-leaving .auth-stage p { opacity: 0; transition: opacity 350ms var(--ease); }
.auth-fill { position: fixed; inset: 0; z-index: 4; padding: 0; opacity: 0; pointer-events: none; transition: opacity 700ms var(--ease); }
.auth-fill.on { opacity: 1; }
.auth-wash { position: fixed; inset: 0; z-index: 8; background: var(--bg); opacity: 0; pointer-events: none; transition: opacity 600ms var(--ease); }
.lg-washing .auth-wash { opacity: 1; }

/* repeated clicks on the circle (and on the robot popup) must never select text */
.auth-v3, .robot-zoom { -webkit-user-select: none; user-select: none; -webkit-tap-highlight-color: transparent; }
.auth-v3 input, .auth-v3 textarea { -webkit-user-select: text; user-select: text; }

@media (max-width: 899px) {
  .auth-v3 { grid-template-columns: 1fr; grid-template-rows: auto 1fr; }
  .auth-stage { order: -1; padding-block: var(--sp-6) var(--sp-4); }
  .auth-stage h2, .auth-stage p { display: none; }
  .ab-field { width: 180px; }
  .auth-v3 .auth-form-wrap { align-items: start; padding-block: var(--sp-4) var(--sp-8); }
}
@media (prefers-reduced-motion: reduce) {
  .auth-v3 *, .auth-v3 *::before, .auth-v3 *::after { animation: none !important; transition-duration: .01ms !important; }
  .auth-v3.lg-js [data-rise] { opacity: 1; transform: none; }
  .ab-stars, .ab-clouds i { animation: none; }
}
