/* ==========================================================================
   Trustbit ERP — premium login theme
   Scoped strictly to body[data-path="login"] so no other portal page is hit.
   Restyles Frappe's own markup; adds no auth-critical elements of its own.
   ========================================================================== */

body[data-path="login"] {
  --tb-b1:#5B7CFA;
  --tb-b2:#9B7BFF;
  --tb-b3:#35D6C5;
  --tb-radius:16px;
  --tb-ease:cubic-bezier(.22,.61,.36,1);

  /* Pinned LIGHT palette. The page no longer follows the visitor's OS
     colour scheme — every employee sees the same login screen. The brand
     panel stays dark navy by design; this is the light half of the split. */
  --tb-bg:#EEF1F8;
  --tb-panel:#FFFFFF;
  --tb-panel-brd:rgba(16,22,44,.08);
  --tb-txt:#111726;
  --tb-txt2:#5A6480;
  --tb-txt3:#8A93A8;
  --tb-field:#F5F7FC;
  --tb-field-brd:#E1E6F2;
  --tb-divider:#E6EAF4;
  --tb-ghost:rgba(16,22,44,.04);
  --tb-shadow:0 30px 70px -25px rgba(18,26,56,.35);

  /* tells the browser to render scrollbars / native form controls light */
  color-scheme:light;

  background:var(--tb-bg) !important;
  color:var(--tb-txt);
  margin:0;
  overflow-x:hidden;
}


/* ---- strip the portal chrome ---- */
body[data-path="login"] .page-breadcrumbs,
body[data-path="login"] .page-header-wrapper,
body[data-path="login"] .page-footer,
body[data-path="login"] .web-footer,
body[data-path="login"] .navbar,
body[data-path="login"] .footer-logo-extension { display:none !important; }

body[data-path="login"] .page-content-wrapper,
body[data-path="login"] main.container,
body[data-path="login"] .page_content { padding:0 !important; margin:0 !important; max-width:none !important; width:100% !important; }

/* ---- split shell (injected by trustbit_login.js) ---- */
body[data-path="login"] .tb-shell {
  min-height:100vh; display:grid; grid-template-columns:1.05fr .95fr;
}

/* ---- brand side ---- */
body[data-path="login"] .tb-brand {
  position:relative; overflow:hidden; isolation:isolate;
  padding:56px 60px; display:flex; flex-direction:column; justify-content:space-between;
  background:linear-gradient(150deg,#0A1130 0%,#141A3E 45%,#0B1226 100%);
  color:#fff;
}
body[data-path="login"] .tb-aurora { position:absolute; inset:-30%; z-index:-1; filter:blur(70px); opacity:.85; }
body[data-path="login"] .tb-blob { position:absolute; border-radius:50%; mix-blend-mode:screen; }
body[data-path="login"] .tb-b1 { width:640px;height:640px;top:-8%;left:-14%;
  background:radial-gradient(circle at 30% 30%, var(--tb-b1), transparent 62%); animation:tbd1 22s var(--tb-ease) infinite alternate; }
body[data-path="login"] .tb-b2 { width:560px;height:560px;bottom:-14%;left:22%;
  background:radial-gradient(circle at 60% 40%, var(--tb-b2), transparent 62%); animation:tbd2 26s var(--tb-ease) infinite alternate; }
body[data-path="login"] .tb-b3 { width:460px;height:460px;top:24%;right:-12%;opacity:.55;
  background:radial-gradient(circle at 50% 50%, var(--tb-b3), transparent 60%); animation:tbd3 30s var(--tb-ease) infinite alternate; }
@keyframes tbd1 { to { transform:translate3d(70px,50px,0) scale(1.12); } }
@keyframes tbd2 { to { transform:translate3d(-60px,-45px,0) scale(1.08); } }
@keyframes tbd3 { to { transform:translate3d(-45px,60px,0) scale(1.15); } }

body[data-path="login"] .tb-grid {
  position:absolute; inset:0; z-index:-1; pointer-events:none;
  background-image:linear-gradient(rgba(255,255,255,.05) 1px,transparent 1px),
                   linear-gradient(90deg,rgba(255,255,255,.05) 1px,transparent 1px);
  background-size:56px 56px;
  -webkit-mask-image:radial-gradient(ellipse at 30% 40%,#000 10%,transparent 72%);
  mask-image:radial-gradient(ellipse at 30% 40%,#000 10%,transparent 72%);
}

/* Real Trustbit wordmark. It is a dark blue/violet lockup, so on the dark
   panel it is inverted to a clean white monochrome — standard practice for
   a brand mark on a dark ground. No gradient chip, no duplicated text. */
body[data-path="login"] .tb-logo-row { display:flex; align-items:center; gap:13px; }
body[data-path="login"] .tb-logo-img {
  height:30px; width:auto; display:block;
  filter:brightness(0) invert(1);
  opacity:.97;
}
/* "ERP" as a compact accent badge rather than a text label after a rule.
   The old vertical rule took its height from line-height, not from the
   logo, so it could never align — a badge sidesteps that entirely and
   matches the pill language already used by .tb-eyebrow below. */
body[data-path="login"] .tb-logo-erp {
  font-size:10.5px; font-weight:660; letter-spacing:.2em; text-transform:uppercase;
  color:#CBD6FF; line-height:1;
  padding:5px 8px 4px; border-radius:7px;
  background:linear-gradient(135deg, rgba(91,124,250,.28), rgba(155,123,255,.28));
  border:1px solid rgba(169,184,255,.32);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.12);
  align-self:center;
}

body[data-path="login"] .tb-pitch { max-width:520px; }
body[data-path="login"] .tb-eyebrow {
  display:inline-flex;align-items:center;gap:8px;margin-bottom:26px;
  font-size:11.5px;font-weight:600;letter-spacing:.14em;text-transform:uppercase;
  color:#A9B8FF;background:rgba(169,184,255,.1);
  border:1px solid rgba(169,184,255,.22);padding:7px 13px;border-radius:999px;
}
body[data-path="login"] .tb-dot { width:6px;height:6px;border-radius:50%;background:var(--tb-b3);box-shadow:0 0 12px var(--tb-b3); }
body[data-path="login"] .tb-pitch h1 {
  margin:0 0 18px;font-size:clamp(32px,3.4vw,50px);line-height:1.06;font-weight:680;letter-spacing:-.035em;color:#fff;
}
body[data-path="login"] .tb-h1line1,
body[data-path="login"] .tb-h1line2 { display:block; }
body[data-path="login"] .tb-pitch h1 .tb-accent {
  font-style:normal;
  background:linear-gradient(100deg,#fff 0%,#B9C6FF 42%,var(--tb-b3) 100%);
  -webkit-background-clip:text;background-clip:text;color:transparent;
}
body[data-path="login"] .tb-pitch p { margin:0;color:rgba(233,238,255,.62);font-size:16px;line-height:1.65;max-width:430px; }
body[data-path="login"] .tb-features { list-style:none;margin:38px 0 0;padding:0;display:grid;gap:15px; }
body[data-path="login"] .tb-features li { display:flex;align-items:center;gap:13px;font-size:14.5px;color:rgba(233,238,255,.8); }
body[data-path="login"] .tb-tick {
  width:23px;height:23px;border-radius:8px;flex:none;display:grid;place-items:center;
  background:rgba(53,214,197,.14);border:1px solid rgba(53,214,197,.34);
}
body[data-path="login"] .tb-tick svg { width:12px;height:12px;stroke:var(--tb-b3);fill:none;stroke-width:3.2;stroke-linecap:round;stroke-linejoin:round; }
body[data-path="login"] .tb-foot { font-size:12.5px;color:rgba(233,238,255,.42); }

/* ---- form side ---- */
body[data-path="login"] .tb-formside { display:grid;place-items:center;padding:48px 40px; }
/* .page_content is a plain block wrapper holding the login/forgot/signup
   cards, so the card itself must auto-centre — margin:0 left it hard against
   the left edge with all the dead space on the right. */
body[data-path="login"] .tb-formside .page_content { width:100%; display:block; }

body[data-path="login"] .login-content.page-card {
  width:100%; max-width:414px; margin:0 auto !important;
  background:var(--tb-panel) !important;
  border:1px solid var(--tb-panel-brd) !important;
  border-radius:24px !important;
  box-shadow:var(--tb-shadow) !important;
  padding:40px 38px 34px !important;
  backdrop-filter:blur(22px); -webkit-backdrop-filter:blur(22px);
  color:var(--tb-txt);
}

body[data-path="login"] .page-card-head { border:0 !important; padding:0 0 26px !important; text-align:left; }
body[data-path="login"] .page-card-head img,
body[data-path="login"] .page-card-head .app-logo { max-height:40px; width:auto; margin:0 0 16px; }
body[data-path="login"] .page-card-head h4,
body[data-path="login"] .page-card-head .page-card-head-text {
  font-size:26px;font-weight:660;letter-spacing:-.03em;color:var(--tb-txt);margin:0;
}

body[data-path="login"] .page-card-body { padding:0 !important; }
body[data-path="login"] .form-group { margin-bottom:17px; }
body[data-path="login"] .form-label {
  display:block;font-size:12.5px;font-weight:590;color:var(--tb-txt2);margin-bottom:8px;
}
body[data-path="login"] .email-field, body[data-path="login"] .password-field { position:relative; display:flex; align-items:center; }

body[data-path="login"] .form-control {
  width:100%;font-size:14.5px;color:var(--tb-txt);
  background:var(--tb-field) !important;
  border:1px solid var(--tb-field-brd) !important;
  border-radius:var(--tb-radius) !important;
  padding:13px 42px 13px 42px !important;
  height:auto !important;
  transition:border-color .18s var(--tb-ease), box-shadow .18s var(--tb-ease), background .18s var(--tb-ease);
  box-shadow:none !important;
}
body[data-path="login"] .form-control::placeholder { color:var(--tb-txt3); }
body[data-path="login"] .form-control:focus {
  border-color:var(--tb-b1) !important;
  box-shadow:0 0 0 4px rgba(91,124,250,.16) !important;
}
body[data-path="login"] .field-icon { position:absolute; left:14px; width:16px;height:16px; color:var(--tb-txt3); pointer-events:none; }
body[data-path="login"] .toggle-password { left:auto !important; right:14px; cursor:pointer; pointer-events:auto; }
body[data-path="login"] .toggle-password:hover { color:var(--tb-b1); }

body[data-path="login"] .forgot-password-message { margin:10px 0 0; text-align:right; }
body[data-path="login"] .forgot-password-message a,
body[data-path="login"] .page-card-actions a.text-muted,
body[data-path="login"] .login-content a { color:var(--tb-b1); font-size:13.5px; font-weight:560; text-decoration:none; }
body[data-path="login"] .forgot-password-message a:hover,
body[data-path="login"] .login-content a:hover { text-decoration:underline; }

body[data-path="login"] .page-card-actions { padding:22px 0 0 !important; }
body[data-path="login"] .btn-login,
body[data-path="login"] .btn-signup,
body[data-path="login"] .btn-forgot,
body[data-path="login"] .btn-primary {
  width:100%;font-size:15px;font-weight:600;color:#fff !important;
  background:linear-gradient(135deg,var(--tb-b1),var(--tb-b2)) !important;
  border:0 !important;border-radius:var(--tb-radius) !important;
  padding:14px 18px !important;height:auto !important;
  box-shadow:0 12px 30px -10px rgba(91,124,250,.75);
  transition:transform .16s var(--tb-ease), box-shadow .2s var(--tb-ease), filter .2s var(--tb-ease);
}
body[data-path="login"] .btn-login:hover,
body[data-path="login"] .btn-signup:hover,
body[data-path="login"] .btn-forgot:hover { transform:translateY(-1px); filter:saturate(1.08); box-shadow:0 18px 40px -12px rgba(91,124,250,.85); }

body[data-path="login"] .btn-login-option,
body[data-path="login"] .btn-default:not(.btn-login):not(.btn-signup):not(.btn-forgot) {
  width:100%;margin-top:11px;font-size:15px;font-weight:600;
  color:var(--tb-txt) !important;
  background:var(--tb-field) !important;
  border:1px solid var(--tb-field-brd) !important;
  border-radius:var(--tb-radius) !important;
  padding:14px 18px !important;height:auto !important;
}
body[data-path="login"] .btn-login-option:hover { border-color:var(--tb-b1) !important; background:var(--tb-ghost) !important; }

body[data-path="login"] .field-error { color:#FF7A85; font-size:12.5px; margin:7px 0 0; }
body[data-path="login"] .login-error-banner {
  display:none; align-items:center; gap:9px; margin-bottom:16px;
  background:rgba(255,122,133,.1); border:1px solid rgba(255,122,133,.3);
  color:#FF9AA3; border-radius:12px; padding:11px 13px; font-size:13px;
}
body[data-path="login"] .login-error-banner.show { display:flex; }

body[data-path="login"] .social-logins { margin-top:14px; }
body[data-path="login"] .text-muted { color:var(--tb-txt2) !important; }

/* ==========================================================================
   MOTION — PRISM REFRACTION
   Text resolves out of a red/cyan chromatic split as a white beam rakes the
   panel; a spectral filament ignites along the card's 1px edge; a pointer-
   tracked glass glint rides the card.
   Chromatic aberration is a PAINT effect, not composited — the split is
   entrance-only (<0.7s per element). text-shadow is animated on the LINE
   SPANS, never on <h1> itself: animating it on an h1 that contains
   background-clip:text spans intermittently drops the whole headline's
   paint in Chrome (reproduced 5/8; 0/10 once moved to the spans).
   Hidden states live only inside @keyframes 0% — page can never be blank.
   ========================================================================== */
/* ==========================================================================
   MODE 5 — PRISM : chromatic split -> convergence, spectral sheen on glass
   REVIEW FIXES vs submitted draft:
     [1] .tb-brand::before/::after resting position is now baked into `transform`
         (translateX(-260%)) instead of relying on `left:-30%` alone. The
         skewX() rotated the strip's top corner back INTO the panel, so the
         ambient rake was visible as a static diagonal stripe during its 2.1s
         delay (fill-mode was `none`) and the entrance beam was visible in
         prefers-reduced-motion. Also added `backwards` fill to the rake.
     [2] .tb-formside::before conic-gradient re-masked with a radial falloff —
         the raw conic filled the whole circle, turning the soft bloom into a
         hard-edged blurred disc behind the card.
     [3] .form-control:focus scoped to .ctrl .form-control:focus so the "Keep me signed in"
         CHECKBOX (also an <input>) does not fire the split-ring animation.
     [4] prismRing removed (byte-identical duplicate of prismSpectrum).
   SAFETY : every hidden state lives inside a keyframe 0%/from step, all
   entrances use fill-mode `both`. With animation disabled every element
   renders at its normal, fully visible base state.
   ========================================================================== */

/* ---- keyframes (all prefixed `prism`) ---- */
@keyframes prismConverge{
  0%  { opacity:0; transform:translate3d(0,7px,0);
        text-shadow:-14px 0 0 rgba(255,58,112,.92), 14px 0 0 rgba(48,206,255,.92); }
  45% { opacity:1; }
  72% { text-shadow:2px 0 0 rgba(255,58,112,.40), -2px 0 0 rgba(48,206,255,.40); }
  100%{ opacity:1; transform:none;
        text-shadow:0 0 0 rgba(255,58,112,0), 0 0 0 rgba(48,206,255,0); }
}
@keyframes prismConvergeSoft{
  0%  { opacity:0; transform:translate3d(0,5px,0);
        text-shadow:-7px 0 0 rgba(255,58,112,.8), 7px 0 0 rgba(48,206,255,.8); }
  55% { opacity:1; }
  100%{ opacity:1; transform:none;
        text-shadow:0 0 0 rgba(255,58,112,0), 0 0 0 rgba(48,206,255,0); }
}
@keyframes prismLogo{
  0%  { opacity:0;
        filter:drop-shadow(-12px 0 rgba(255,58,112,.85)) drop-shadow(12px 0 rgba(48,206,255,.85)); }
  100%{ opacity:1;
        filter:drop-shadow(0 0 rgba(255,58,112,0)) drop-shadow(0 0 rgba(48,206,255,0)); }
}
@keyframes prismTick{
  0%  { opacity:0; transform:scale(.72);
        filter:drop-shadow(-9px 0 rgba(255,58,112,.9)) drop-shadow(9px 0 rgba(48,206,255,.9)); }
  100%{ opacity:1; transform:none;
        filter:drop-shadow(0 0 rgba(255,58,112,0)) drop-shadow(0 0 rgba(48,206,255,0)); }
}
@keyframes prismCardIn{
  0%  { opacity:0; transform:translate3d(0,14px,0) scale(.986); }
  100%{ opacity:1; transform:none; }
}
@keyframes prismDisperse{
  0%  { opacity:0; background-position:-130% 50%; }
  100%{ opacity:1; background-position:0% 50%; }
}
@keyframes prismSpectrum{        /* runs `alternate`, so it never jumps */
  from{ background-position:0% 50%; }
  to  { background-position:100% 50%; }
}
@keyframes prismEdgeIn{
  0%  { opacity:0; }
  55% { opacity:1; }
  100%{ opacity:.85; }
}
@keyframes prismBeam{
  0%  { opacity:0;  transform:skewX(-15deg) translateX(0); }
  14% { opacity:1; }
  70% { opacity:.9; }
  100%{ opacity:0;  transform:skewX(-15deg) translateX(520%); }
}
@keyframes prismRake{
  0%  { opacity:0;   transform:skewX(-12deg) translateX(0); }
  12% { opacity:.85; }
  58% { opacity:.85; }
  100%{ opacity:0;   transform:skewX(-12deg) translateX(620%); }
}
@keyframes prismSplit{           /* focus flicker — never touches opacity */
  0%  { text-shadow:-6px 0 0 rgba(255,58,112,.75), 6px 0 0 rgba(48,206,255,.75); }
  60% { text-shadow:1.5px 0 0 rgba(255,58,112,.3), -1.5px 0 0 rgba(48,206,255,.3); }
  100%{ text-shadow:0 0 0 rgba(255,58,112,0), 0 0 0 rgba(48,206,255,0); }
}
@keyframes prismFocusRing{       /* no fill-mode: settles back onto .form-control:focus */
  0%  { box-shadow:-7px 0 0 0 rgba(255,58,112,.55), 7px 0 0 0 rgba(48,206,255,.55); }
  100%{ box-shadow:0 0 0 4px color-mix(in srgb,var(--b1) 16%,transparent),
                   0 0 0 0 rgba(48,206,255,0); }
}
@keyframes prismDot{
  0%,100%{ filter:hue-rotate(0deg); }
  50%    { filter:hue-rotate(75deg); }
}

/* ---- brand panel : entrance beam + ambient sheen rake ---------------------
   FIX [1]: the resting (animation-disabled) position is carried by the base
   `transform`, not by `left` alone — skewX() shears the strip up to
   tan(angle) x half-height sideways, which was enough to push its top corner
   back over the panel edge. `translateX(-260%)` of a 20-26%-wide strip parks
   it >50% of the panel width out, well past any shear. The keyframes redeclare
   `transform` in full, so travel distance is unchanged. ------------------- */
body[data-path="login"] .tb-brand::before {
  content:""; position:absolute; z-index:0; pointer-events:none;
  top:-20%; bottom:-20%; left:-30%; width:26%;
  transform:skewX(-15deg) translateX(-260%);
  background:linear-gradient(90deg,transparent 0%,
    rgba(255,110,150,.16) 26%, rgba(255,255,255,.24) 48%,
    rgba(110,220,255,.18) 68%, transparent 100%);
  animation:prismBeam 1.05s cubic-bezier(.30,.72,.28,1) .02s both;
}
body[data-path="login"] .tb-brand::after {
  content:""; position:absolute; z-index:0; pointer-events:none;
  top:-15%; bottom:-15%; left:-26%; width:20%;
  transform:skewX(-12deg) translateX(-260%); will-change:transform;
  background:linear-gradient(90deg,transparent 0%,
    rgba(255,120,160,.10) 24%, rgba(255,255,255,.13) 46%,
    rgba(120,225,255,.11) 66%, rgba(150,255,215,.07) 80%, transparent 100%);
  /* `backwards` so the 0% step (opacity:0) also covers the 2.1s delay */
  animation:prismRake 11s cubic-bezier(.45,0,.55,1) 2.1s infinite backwards;
}

/* ---- brand content : chromatic convergence, staggered ---- */
body[data-path="login"] .tb-logo-row { animation:prismLogo .60s var(--ease) .06s both; }
body[data-path="login"] .tb-eyebrow { animation:prismConvergeSoft .55s var(--ease) .16s both; }
/* the split runs on the two line spans, never on <h1> itself: animating
   text-shadow directly on the h1 (which contains the background-clip:text
   accent words) intermittently drops the whole headline's paint in Blink.
   display:block also stops "gets"/"work" running together. */
body[data-path="login"] .tb-h1line1 { display:block; animation:prismConverge .68s var(--ease) .20s both; }
body[data-path="login"] .tb-h1line2 { display:block; animation:prismConverge .68s var(--ease) .27s both; }
body[data-path="login"] .tb-pitch p { animation:prismConvergeSoft .60s var(--ease) .36s both; }
body[data-path="login"] .tb-features li:nth-child(1) { animation:prismConvergeSoft .50s var(--ease) .46s both; }
body[data-path="login"] .tb-features li:nth-child(2) { animation:prismConvergeSoft .50s var(--ease) .54s both; }
body[data-path="login"] .tb-features li:nth-child(3) { animation:prismConvergeSoft .50s var(--ease) .62s both; }
body[data-path="login"] .tb-features li:nth-child(1) .tb-tick { animation:prismTick .50s var(--ease) .52s both; }
body[data-path="login"] .tb-features li:nth-child(2) .tb-tick { animation:prismTick .50s var(--ease) .60s both; }
body[data-path="login"] .tb-features li:nth-child(3) .tb-tick { animation:prismTick .50s var(--ease) .68s both; }
body[data-path="login"] .tb-foot { animation:prismConvergeSoft .55s var(--ease) .74s both; }

/* headline accent = the dispersed light itself: a spectrum that slides into
   register, then drifts forever. text-shadow:none cancels the value inherited
   from .tb-h1line2's prismConverge so the clipped gradient stays clean. */
body[data-path="login"] h1 .tb-accent {
  text-shadow:none;
  background-image:linear-gradient(100deg,#FFFFFF 0%,#FFB6CE 16%,#C3C9FF 36%,
    #8FE6FF 54%,var(--b3) 70%,#EAF3FF 88%,#FFFFFF 100%);
  background-size:260% 100%;
  animation:prismDisperse .72s var(--ease) .30s both,
            prismSpectrum 14s ease-in-out 1.15s infinite alternate;
}
body[data-path="login"] h1 .tb-h1line2 .tb-accent:nth-child(2) {
  animation:prismDisperse .72s var(--ease) .36s both,
            prismSpectrum 14s ease-in-out 1.3s infinite alternate;
}
body[data-path="login"] .tb-dot { animation:prismDot 5s ease-in-out 1.4s infinite; }

/* ---- form side ---- */
/* the halo behind the card becomes a soft spectral bloom (existing `halo`
   animation still drives it — only the paint changes).
   FIX [2]: the conic gradient is opaque to the edge of the .tb-formside::before
   circle, so on its own it read as a hard blurred disc instead of the base
   radial-gradient's falloff. The mask restores that falloff. */
body[data-path="login"] .tb-formside::before {
  background:conic-gradient(from 200deg at 50% 50%,
    rgba(255,110,155,.17), rgba(120,150,255,.22), rgba(120,235,255,.18),
    rgba(140,255,215,.13), rgba(255,110,155,.17));
  -webkit-mask:radial-gradient(circle at 50% 50%,
    rgba(0,0,0,1) 10%, rgba(0,0,0,.55) 44%, rgba(0,0,0,0) 70%);
          mask:radial-gradient(circle at 50% 50%,
    rgba(0,0,0,1) 10%, rgba(0,0,0,.55) 44%, rgba(0,0,0,0) 70%);
}
body[data-path="login"] .login-content.page-card { animation:prismCardIn .70s var(--ease) .12s both; }
body[data-path="login"] .login-content.page-card > *:nth-child(1) { animation:prismConvergeSoft .45s var(--ease) .40s both; }
body[data-path="login"] .login-content.page-card > *:nth-child(2) { animation:prismConvergeSoft .45s var(--ease) .46s both; }
body[data-path="login"] .login-content.page-card > *:nth-child(3) { animation:prismConvergeSoft .45s var(--ease) .52s both; }
body[data-path="login"] .login-content.page-card form > * { animation:prismConvergeSoft .50s var(--ease) .58s both; }

/* spectral filament along the card edge — gradient-border trick, guarded by
   @supports so unsupported browsers simply get no ring (never a colour slab) */
@supports ((-webkit-mask-composite:xor) or (mask-composite:exclude)){
  body[data-path="login"] .login-content.page-card::before {
    content:""; position:absolute; inset:-1px; border-radius:25px;
    padding:1px; pointer-events:none; opacity:.85;
    background:linear-gradient(112deg,
      rgba(255,255,255,0) 6%,  rgba(255,120,160,.85) 20%,
      rgba(255,206,140,.62) 30%, rgba(140,255,210,.72) 42%,
      rgba(110,190,255,.9) 55%,  rgba(178,132,255,.75) 68%,
      rgba(255,255,255,.35) 80%, rgba(255,255,255,0) 94%);
    background-size:280% 100%;
    -webkit-mask:linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
            mask:linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
    -webkit-mask-composite:xor;
            mask-composite:exclude;
    animation:prismEdgeIn .80s var(--ease) .30s both,
              prismSpectrum 13s ease-in-out 1.1s infinite alternate;
  }
}

/* glass glint: a chromatic specular that sits on the card and, when the JS
   below is present, follows the pointer. Static fallback = a fixed top-left
   highlight, so it is always a deliberate design element, never a blank. */
body[data-path="login"] .login-content.page-card::after {
  content:""; position:absolute; inset:0; border-radius:24px;
  pointer-events:none; opacity:.34; mix-blend-mode:screen;
  transition:opacity .35s var(--ease);
  background:
    radial-gradient(180px 130px at var(--prism-x,22%) var(--prism-y,8%),
      rgba(255,168,198,.42), transparent 70%),
    radial-gradient(210px 150px at calc(var(--prism-x,22%) + 8%) calc(var(--prism-y,8%) + 5%),
      rgba(150,205,255,.38), transparent 72%),
    radial-gradient(240px 170px at calc(var(--prism-x,22%) + 16%) calc(var(--prism-y,8%) + 10%),
      rgba(150,255,222,.26), transparent 74%);
}

body[data-path="login"] .login-content.page-card:hover::after { opacity:.55; }

/* ---- micro-interactions ---- */
/* focus: the label refracts and re-converges, the ring splits R/C then locks.
   FIX [3]: scoped to `.ctrl input` — the unscoped `.form-control:focus` also matched
   the 17px "Keep me signed in" checkbox, which then got a +/-7px split ring. */
body[data-path="login"] .form-group:focus-within .form-label { animation:prismSplit .42s var(--ease); }
body[data-path="login"] .email-field .form-control:focus, body[data-path="login"] .password-field .form-control:focus { animation:prismFocusRing .42s var(--ease); }
body[data-path="login"] .field-icon { transition:color .2s var(--ease), filter .3s var(--ease); }
body[data-path="login"] .form-group:focus-within .field-icon {
  filter:drop-shadow(-1.4px 0 rgba(255,58,112,.75)) drop-shadow(1.4px 0 rgba(48,206,255,.75));
}
body[data-path="login"] .toggle-password { transition:transform .2s var(--ease), color .2s var(--ease), filter .2s var(--ease); }
body[data-path="login"] .toggle-password:hover {
  filter:drop-shadow(-1.5px 0 rgba(255,58,112,.8)) drop-shadow(1.5px 0 rgba(48,206,255,.8));
}
/* buttons: the existing `sweep` bar becomes a spectrum, hover glow splits */
body[data-path="login"] .btn-login::after {
  background:linear-gradient(90deg,transparent,
    rgba(255,120,165,.55),rgba(255,255,255,.7),rgba(110,225,255,.55),transparent);
}
body[data-path="login"] .btn-login:hover {
  box-shadow:0 12px 30px -10px rgba(91,124,250,.75),
             -4px 0 20px -8px rgba(255,58,112,.6),
              4px 0 20px -8px rgba(48,206,255,.6);
}
body[data-path="login"] .btn-login-option:hover {
  box-shadow:-3px 0 14px -7px rgba(255,58,112,.55), 3px 0 14px -7px rgba(48,206,255,.55);
}
body[data-path="login"] .forgot-password-message a:hover {   /* keeps the base underline affordance */
  text-shadow:-1.2px 0 rgba(255,58,112,.7), 1.2px 0 rgba(48,206,255,.7);
}

@media (max-width:980px){
  body[data-path="login"] .login-content.page-card::before { border-radius:21px; }
  body[data-path="login"] .login-content.page-card::after { border-radius:20px; }
}
/* light-pinned: the glint always uses the light-card blend */
body[data-path="login"] .login-content.page-card::after {
  mix-blend-mode:multiply; opacity:.20;
}

/* ---- responsive ---- */
@media (max-width: 980px) {
  body[data-path="login"] .tb-shell { grid-template-columns:1fr; }
  body[data-path="login"] .tb-brand { padding:38px 30px 44px; }
  body[data-path="login"] .tb-features, body[data-path="login"] .tb-foot { display:none; }
  body[data-path="login"] .tb-pitch h1 { font-size:29px; }
  body[data-path="login"] .tb-formside { padding:34px 20px 60px; }
  body[data-path="login"] .login-content.page-card { padding:32px 26px 28px !important; border-radius:20px !important; }
}
/* Full opt-out. Safe because no base rule sets opacity:0 — killing every
   animation leaves all elements at their natural visible state. */
@media (prefers-reduced-motion: reduce) {
  body[data-path="login"] *,
  body[data-path="login"] *::before,
  body[data-path="login"] *::after {
    animation:none !important;
    transition-duration:.01ms !important;
  }
}
