/* Logowanie (/login): the animated sign-in.
   Tokens only: every value is a var(--...) from public/style.css (no colour, size, time or angle literals; 0, 1px, % and
   unitless numbers are fine). Everything here is CSS: no script, so the strict CSP stays as it is.

   Rules of the motion
   - Every rule below sets the FINAL look as its base state; the animations only describe how it gets there ("from" frames,
     fill-mode "backwards") or loop around it. With prefers-reduced-motion the theme turns all animation off, and the page
     is simply complete and still.
   - Only transform-like properties (translate, rotate, scale), opacity, clip-path and filter are animated.
   - After a failed sign-in the page is rendered again (data-state="error" on the card): then the entrance is skipped and
     only the card shakes, so the form does not "rebuild" itself while somebody is trying to type the password again. */

/* ==========================================================================================================
   Brand panel (left)
   ========================================================================================================== */

/* aurora: red glows on a layer larger than the panel, which drifts and tilts slowly behind everything */
.auth-aside::before {
  inset: calc(var(--auth-bleed) * -1);
  background: radial-gradient(circle at 24% 22%, var(--color-accent-deep) 0, transparent 38%),
    radial-gradient(circle at 78% 30%, var(--auth-glow-hot) 0, transparent 30%),
    radial-gradient(circle at 70% 82%, var(--color-sidebar-3) 0, transparent 46%);
  animation: auth-aurora var(--auth-t-aurora) ease-in-out infinite alternate;
}

/* embers: two fields of glowing dots (box-shadow lists, see the tokens) rising at different speeds. One loop is one screen height:
   on a panel taller than the window the strip above the first screen is simply sparser, which is not noticeable on a decoration */
.auth-aside-inner::before,
.auth-aside-inner::after {
  content: "";
  position: absolute;
  bottom: 0;
  left: 0;
  z-index: var(--z-behind);
  width: 1px;
  height: 1px;
  border-radius: 50%;
}

.auth-aside-inner::before {
  box-shadow: var(--auth-embers-slow);
  animation: auth-embers var(--auth-t-embers-slow) linear infinite;
}

.auth-aside-inner::after {
  box-shadow: var(--auth-embers-fast);
  animation: auth-embers var(--auth-t-embers-fast) linear infinite;
}

/* the wheel: the big ring of the panel becomes a wheel with a hub and spokes that turns slowly and rolls in on load */
.auth-aside::after {
  background: radial-gradient(circle, var(--color-sidebar-3) 0 6%, var(--color-sidebar-2) 6% 13%, transparent 13.5%),
    repeating-conic-gradient(var(--color-sidebar-2) 0 var(--auth-spoke), transparent var(--auth-spoke) var(--auth-spoke-gap));
  animation: auth-spin var(--auth-t-wheel) linear infinite;
}

.auth:not(:has([data-state="error"])) .auth-aside::after {
  animation: auth-roll-in var(--auth-t-roll) var(--auth-ease-out) backwards, auth-spin var(--auth-t-wheel) linear infinite;
}

/* the logo: wipes in from the left, then its red glow breathes */
.auth-logo {
  /* a base clip-path of the same kind as the one animated (a wide negative inset leaves the glow unclipped), so the wipe interpolates */
  clip-path: inset(calc(var(--space-12) * -1));
  filter: var(--auth-logo-rest-glow);
  animation: auth-logo-glow var(--auth-t-pulse) ease-in-out var(--auth-t-roll) infinite alternate;
}

.auth:not(:has([data-state="error"])) .auth-logo {
  animation: auth-logo-in var(--auth-t-roll) var(--auth-ease-out) backwards var(--auth-t-step),
    auth-logo-glow var(--auth-t-pulse) ease-in-out var(--auth-t-roll) infinite alternate;
}

.auth-bar {
  transform-origin: left center;
}

.auth:not(:has([data-state="error"])) .auth-bar {
  animation: auth-grow var(--auth-t-enter) var(--auth-ease-out) backwards calc(var(--auth-t-step) * 6);
}

.auth:not(:has([data-state="error"])) .auth-tagline {
  animation: auth-rise var(--auth-t-enter) var(--auth-ease-out) backwards calc(var(--auth-t-step) * 8);
}

.auth:not(:has([data-state="error"])) .auth-aside .demo-chip {
  animation: auth-rise var(--auth-t-enter) var(--auth-ease-out) backwards calc(var(--auth-t-step) * 10);
}

/* ==========================================================================================================
   Form side (right)
   ========================================================================================================== */

/* two soft red blobs drifting in the corners, in both colour schemes */
.auth-main {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  overflow: clip;
}

.auth-main::before,
.auth-main::after {
  content: "";
  position: absolute;
  z-index: var(--z-behind);
  width: var(--auth-blob);
  height: var(--auth-blob);
  border-radius: 50%;
  background: radial-gradient(circle, var(--auth-blob-color) 0, transparent 68%);
}

.auth-main::before {
  top: calc(var(--auth-blob) / -3);
  right: calc(var(--auth-blob) / -3);
  animation: auth-blob var(--auth-t-blob) ease-in-out infinite alternate;
}

.auth-main::after {
  bottom: calc(var(--auth-blob) / -3);
  left: calc(var(--auth-blob) / -3);
  animation: auth-blob var(--auth-t-blob) ease-in-out infinite alternate-reverse;
}

/* narrow screens: the brand plate comes in first */
.auth:not(:has([data-state="error"])) .auth-brand {
  animation: auth-rise var(--auth-t-enter) var(--auth-ease-out) backwards;
}

/* the card: rises in; while one of its fields has focus, a red light runs around its edge */
.auth-card {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  overflow: clip;
}

.auth:not(:has([data-state="error"])) .auth-card {
  animation: auth-card-in var(--auth-t-enter) var(--auth-ease-out) backwards calc(var(--auth-t-step) * 2);
}

.auth-card::before {
  content: "";
  position: absolute;
  z-index: var(--z-behind);
  top: 50%;
  left: 50%;
  width: 200%;
  aspect-ratio: 1;
  translate: -50% -50%;
  background: conic-gradient(transparent 0 62%, var(--color-accent-bright) 80%, transparent 82% 100%);
  opacity: 0;
  transition: opacity var(--duration-slow) var(--ease);
  animation: auth-orbit var(--auth-t-orbit) linear infinite;
}

/* the card surface over the light, leaving only a thin line at the edge */
.auth-card::after {
  content: "";
  position: absolute;
  z-index: var(--z-behind);
  inset: var(--auth-ring);
  border-radius: calc(var(--radius-2) - var(--auth-ring));
  background: var(--color-surface);
}

.auth-card:focus-within::before {
  opacity: 1;
}

/* reduced motion: no running light (it would stay as a frozen fragment of an arc), the card simply gets the accent border */
@media (prefers-reduced-motion: reduce) {
  .auth-card:focus-within::before {
    opacity: 0;
  }

  .auth-card:focus-within {
    border-color: var(--color-accent);
  }
}

/* the contents of the card come one after another */
.auth:not(:has([data-state="error"])) .auth-card > h1,
.auth:not(:has([data-state="error"])) .auth-card > .page-sub,
.auth:not(:has([data-state="error"])) .auth-card .field,
.auth:not(:has([data-state="error"])) .auth-card .btn-block {
  animation: auth-rise var(--auth-t-enter) var(--auth-ease-out) backwards;
}

.auth:not(:has([data-state="error"])) .auth-card > h1 {
  animation-delay: calc(var(--auth-t-step) * 3);
}

.auth:not(:has([data-state="error"])) .auth-card > .page-sub {
  animation-delay: calc(var(--auth-t-step) * 4);
}

.auth:not(:has([data-state="error"])) .auth-card .field:nth-of-type(1) {
  animation-delay: calc(var(--auth-t-step) * 5);
}

.auth:not(:has([data-state="error"])) .auth-card .field:nth-of-type(2) {
  animation-delay: calc(var(--auth-t-step) * 6);
}

.auth:not(:has([data-state="error"])) .auth-card .btn-block {
  animation-delay: calc(var(--auth-t-step) * 7);
}

/* the sign-in is the one place with large targets (the button is .btn-lg) */
.auth-card input {
  height: var(--control-h-lg);
}

/* a field that has focus glows (the theme's focus outline stays as it is) */
.auth-card input:focus {
  border-color: var(--color-accent);
  box-shadow: var(--auth-focus-ring);
}

/* the button: lifts on hover, presses on click, and a light sweeps across it now and then */
.auth-card .btn-primary {
  position: relative;
  overflow: hidden;
  isolation: isolate;
  transition: var(--transition), translate var(--duration) var(--ease), scale var(--duration) var(--ease);
}

.auth-card .btn-primary:hover {
  box-shadow: var(--auth-btn-glow);
  translate: 0 calc(var(--stroke) * -1);
}

.auth-card .btn-primary:active {
  translate: 0 0;
  scale: 0.985;
}

.auth-card .btn-primary::after {
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  width: var(--auth-sheen-w);
  background: linear-gradient(to right, transparent 0, var(--auth-sheen) 50%, transparent 100%);
  translate: -150% 0;
  pointer-events: none;
  animation: auth-sheen var(--auth-t-sheen) ease-in-out infinite;
}

/* after a failed sign-in: the card shakes, the message slides in and its icon pulses once */
.auth-card[data-state="error"] {
  animation: auth-shake var(--auth-t-shake) ease-in-out;
}

.auth-card .form-error {
  animation: auth-rise var(--auth-t-enter) var(--auth-ease-out) backwards;
}

.auth-card .form-error svg {
  animation: auth-pulse var(--auth-t-shake) var(--auth-ease-out) var(--auth-t-step);
}

/* ==========================================================================================================
   Keyframes (only the starting frames: the base styles above are the end)
   ========================================================================================================== */

@keyframes auth-rise {
  from {
    opacity: 0;
    translate: 0 var(--auth-rise);
  }
}

@keyframes auth-card-in {
  from {
    opacity: 0;
    translate: 0 var(--auth-rise);
    scale: 0.97;
  }
}

@keyframes auth-grow {
  from {
    scale: 0 1;
  }
}

@keyframes auth-logo-in {
  from {
    opacity: 0;
    clip-path: inset(calc(var(--space-12) * -1) 100% calc(var(--space-12) * -1) calc(var(--space-12) * -1));
    translate: calc(var(--auth-rise) * -1) 0;
  }
}

@keyframes auth-logo-glow {
  to {
    filter: var(--auth-logo-glow);
  }
}

@keyframes auth-roll-in {
  from {
    opacity: 0;
    translate: var(--auth-roll) 0;
  }
}

@keyframes auth-spin {
  to {
    rotate: var(--auth-turn);
  }
}

@keyframes auth-aurora {
  to {
    transform: translate(var(--auth-drift), var(--auth-drift)) rotate(var(--auth-tilt)) scale(1.08);
  }
}

@keyframes auth-embers {
  to {
    transform: translateY(calc(var(--auth-ember-span) * -1));
  }
}

@keyframes auth-blob {
  to {
    translate: calc(var(--auth-blob) / 6) calc(var(--auth-blob) / 8);
    scale: 1.2;
  }
}

@keyframes auth-orbit {
  to {
    rotate: var(--auth-turn);
  }
}

@keyframes auth-sheen {
  0%,
  60% {
    translate: -150% 0;
  }

  100% {
    translate: 350% 0;
  }
}

@keyframes auth-shake {
  10%,
  50%,
  90% {
    translate: calc(var(--auth-shake) * -1) 0;
  }

  30%,
  70% {
    translate: var(--auth-shake) 0;
  }
}

@keyframes auth-pulse {
  50% {
    scale: 1.4;
  }
}
