/* ============================================================
   login_motion.css — sign-in page motion
   Loaded after login_styling.css, and after motion.css, which
   this page now links explicitly: it does not extend
   base/base.html, so it never received the shared layer.

   This is the first screen anyone sees, and it is the one place
   in the product where a little ceremony is unambiguously worth
   it — there is nothing else on the page competing for
   attention and nobody is trying to get work done yet.

   Everything still obeys the motion.css contract: transform and
   opacity only, entrances under 450ms, and the global
   reduced-motion switch in motion.css covers every animation
   below. login_styling.css already had its own reduced-motion
   block for .auth-card; that stays and is now redundant rather
   than load-bearing.
   ============================================================ */


/* ════════════════════════════════════════════════════════════
   1. THE CARD

   login_styling.css animates .auth-card with `cardIn`. This
   repoints it at the house entrance curve and slows it slightly
   — 380ms with a hard decelerate reads as arriving; 400ms on
   cubic-bezier(0.4,0,0.2,1) reads as sliding.
   ════════════════════════════════════════════════════════════ */

.auth-card {
  animation: fx-card-in var(--fx-dur-slow) var(--fx-ease-out) both;
}
@keyframes fx-card-in {
  from { opacity: 0; transform: translate3d(0, 18px, 0) scale(0.985); }
  to   { opacity: 1; transform: translate3d(0, 0, 0) scale(1); }
}


/* ════════════════════════════════════════════════════════════
   2. THE CONTENTS ARRIVE AFTER THE CARD

   Brand, then each field, then the button, then the footer.
   Hand-placed rather than a .fx-stagger container, because the
   form's children are not siblings of the brand block and a
   single cascade across the whole card is what makes it read as
   one movement rather than five.
   ════════════════════════════════════════════════════════════ */

.auth-brand,
.auth-form-group,
.auth-card .btn-primary,
.auth-footer-note {
  animation: fx-rise-sm var(--fx-dur-base) var(--fx-ease-out) both;
}

.auth-brand                      { animation-delay: calc(var(--fx-step) * 2); }
.auth-form-group:nth-of-type(1)  { animation-delay: calc(var(--fx-step) * 3); }
.auth-form-group:nth-of-type(2)  { animation-delay: calc(var(--fx-step) * 4); }
.auth-card .btn-primary          { animation-delay: calc(var(--fx-step) * 5); }
.auth-footer-note                { animation-delay: calc(var(--fx-step) * 6); }


/* ════════════════════════════════════════════════════════════
   3. THE LOGO MARK

   A single decorative element, which is the budget motion.css
   allows for one persistent animation per page. It breathes
   rather than spins: this sits under the product name on a
   sign-in screen, and anything busier reads as a loading state
   and makes the page feel like it is still working.
   ════════════════════════════════════════════════════════════ */

.auth-logo-icon {
  animation: fx-pop var(--fx-dur-slow) var(--fx-ease-spring) both,
             fx-logo-breathe 5s var(--fx-ease-in-out) 1s infinite;
  transition: transform var(--fx-dur-base) var(--fx-ease-spring),
              box-shadow var(--fx-dur-base) var(--fx-ease-out);
}
@keyframes fx-logo-breathe {
  0%, 100% { transform: translate3d(0, 0, 0) scale(1); }
  50%      { transform: translate3d(0, -3px, 0) scale(1.02); }
}

/* Hovering the card lifts the mark out of its idle cycle. The
   animation is dropped rather than overridden, or the keyframes
   would keep fighting the transform for the length of the
   hover. */
.auth-card:hover .auth-logo-icon {
  animation: none;
  transform: translate3d(0, -3px, 0) scale(1.06) rotate(-6deg);
  box-shadow: 0 8px 22px rgba(37, 99, 235, 0.42);
}


/* ════════════════════════════════════════════════════════════
   4. FIELDS

   The label lifts with its field on focus, so the eye follows
   one object rather than noticing a border change. Colour is
   already handled by login_styling.css; this only adds the
   movement.
   ════════════════════════════════════════════════════════════ */

.auth-form-group label {
  transition: color var(--fx-dur-fast) var(--fx-ease-out),
              transform var(--fx-dur-fast) var(--fx-ease-out);
  transform-origin: left center;
}
.auth-form-group:focus-within label {
  color: var(--brand-primary);
  transform: translate3d(2px, 0, 0);
}

.auth-form-group .form-control,
.auth-card .form-control {
  /* login_styling.css transitions border, shadow and background.
     Naming them again here would drop that; this adds transform
     to the same list instead. */
  transition: border-color var(--fx-dur-fast) var(--fx-ease-out),
              box-shadow var(--fx-dur-fast) var(--fx-ease-out),
              background var(--fx-dur-fast) var(--fx-ease-out);
}

.toggle-btn {
  transition: color var(--fx-dur-fast) var(--fx-ease-out),
              transform var(--fx-dur-fast) var(--fx-ease-spring);
}
.toggle-btn:hover  { transform: translateY(-50%) scale(1.15); }
.toggle-btn:active { transform: translateY(-50%) scale(0.92); }


/* ════════════════════════════════════════════════════════════
   5. SUBMIT

   The sweep is a pseudo-element crossing the button on
   transform. It exists because this is the one button on the
   page and pressing it is the whole purpose of the screen.
   ════════════════════════════════════════════════════════════ */

.auth-card .btn-primary {
  position: relative;
  overflow: hidden;
  transition: transform var(--fx-dur-fast) var(--fx-ease-out),
              box-shadow var(--fx-dur-fast) var(--fx-ease-out),
              background var(--fx-dur-fast) var(--fx-ease-out);
}

.auth-card .btn-primary::after {
  content: "";
  position: absolute;
  inset: 0;
  transform: translate3d(-100%, 0, 0);
  background: linear-gradient(90deg,
              transparent,
              rgba(255, 255, 255, 0.22),
              transparent);
  pointer-events: none;
}
.auth-card .btn-primary:hover::after {
  animation: fx-shimmer 0.75s var(--fx-ease-in-out);
}

.auth-card .btn-primary:active { transform: scale(0.985); }

/* The loading state. login_styling.css drops the opacity and
   kills pointer events; this gives it something to look at, so
   a slow sign-in reads as working rather than stuck. */
.auth-card .btn-primary.loading i {
  animation: fx-spin 0.7s linear infinite;
}
.auth-card .btn-primary.loading::after {
  animation: fx-shimmer 1.1s var(--fx-ease-in-out) infinite;
}


/* ════════════════════════════════════════════════════════════
   6. THE BACKGROUND WASHES

   body carries three radial gradients. Animating a gradient is
   a paint operation and this is a full-screen element, so the
   drift lives on a fixed pseudo-element that is composited
   instead — one layer, transform only, and 40s so it is never
   caught moving.
   ════════════════════════════════════════════════════════════ */

body::before {
  content: "";
  position: fixed;
  inset: -25%;
  z-index: -1;
  pointer-events: none;
  background:
    radial-gradient(circle at 30% 30%, var(--glow-1) 0%, transparent 45%),
    radial-gradient(circle at 70% 70%, var(--glow-2) 0%, transparent 45%);
  animation: fx-wash-drift 40s var(--fx-ease-in-out) infinite alternate;
}
@keyframes fx-wash-drift {
  from { transform: translate3d(-2%, -1%, 0) scale(1); }
  to   { transform: translate3d(2%, 1%, 0) scale(1.06); }
}


/* ════════════════════════════════════════════════════════════
   TOUCH — hover states a finger can get stuck in.
   ════════════════════════════════════════════════════════════ */

@media (hover: none), (pointer: coarse) {
  .auth-card:hover .auth-logo-icon {
    /* Restore the idle cycle rather than freezing the mark in
       its hovered pose after a stray tap on the card. */
    animation: fx-logo-breathe 5s var(--fx-ease-in-out) infinite;
    transform: none;
    box-shadow: 0 4px 14px rgba(37, 99, 235, 0.3);
  }
  .toggle-btn:hover { transform: translateY(-50%); }
  .auth-card .btn-primary:hover::after { animation: none; }
}


/* ════════════════════════════════════════════════════════════
   REDUCED MOTION — last in the file.

   motion.css collapses every animation and transition globally.
   What it cannot undo is a transform that is a hover rule's
   resting state, and it cannot remove the drifting wash layer,
   which is decoration with no informational content at all.
   ════════════════════════════════════════════════════════════ */

@media (prefers-reduced-motion: reduce) {
  body::before { animation: none !important; transform: none !important; }
  .auth-logo-icon,
  .auth-card:hover .auth-logo-icon,
  .auth-card .btn-primary.loading i,
  .auth-card .btn-primary.loading::after,
  .auth-card .btn-primary:hover::after { animation: none !important; }
  .auth-card:hover .auth-logo-icon,
  .toggle-btn:hover,
  .toggle-btn:active,
  .auth-card .btn-primary:active,
  .auth-form-group:focus-within label { transform: none !important; }
  .toggle-btn:hover,
  .toggle-btn:active { transform: translateY(-50%) !important; }
}
