/* ═══════════════════════════════════════════════════════════════════════════
   DSA MITRA — AUTH DESIGN SYSTEM
   Shared by login.html, signup.html and reset-password.html.

   This file replaced three separately-drifting stylesheets. login.html and
   signup.html had a full BLUE system (--brand:#1A52C5) with a dark+orange theme
   bolted on top via ~20 `!important` overrides, and reset-password.html was
   still pure blue. Change a colour here and all three move together — that is
   the whole point of this file existing.

   Fonts (loaded by the pages): Syne = display, Instrument Sans = body,
   IBM Plex Mono = micro-labels. Same trio as index.html.
   ═══════════════════════════════════════════════════════════════════════════ */

*,*::before,*::after{box-sizing:border-box;margin:0;padding:0}

:root{
  /* brand3 is the ACCENT-ON-CANVAS colour. On the old dark canvas that meant a
     LIGHTER tint (#FB923C); on this light one it has to be a DARKER one, or every
     accent it paints — kickers, links, focused labels — goes unreadable. */
  --brand:#16A34A;  --brand2:#22C55E;  --brand3:#15803D;
  --ink:#0C1F14;    --ink-dim:#4B5F55; --ink-faint:#8A9A91;
  --bg:#F7FBF8;
  --line:rgba(20,60,38,0.10);
  --line2:rgba(20,60,38,0.07);
  --green:#16A34A;  --red:#DC2626;
  --mono:'IBM Plex Mono',ui-monospace,'Courier New',monospace;
}

html{font-size:16px}
body{
  font-family:'Instrument Sans',-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif;
  background:var(--bg); color:var(--ink);
  min-height:100dvh; line-height:1.6;
  -webkit-font-smoothing:antialiased; letter-spacing:-0.005em;
  display:flex; align-items:center; justify-content:center;
  padding:32px 20px; position:relative; overflow-x:hidden;
}
h1,h2{font-family:'Syne',sans-serif; line-height:1.15; letter-spacing:-0.02em}
a{color:inherit; text-decoration:none}
button{font-family:inherit; cursor:pointer}
img,svg{max-width:100%}


/* ═══ ATMOSPHERE ════════════════════════════════════════════════════════════
   Seven stacked layers, injected by auth-bg.js. Order matters: everything below
   sits at z-index 0-1, the content shell sits at 2, grain at 3 (over everything,
   including the card — real film grain doesn't stop at the edge of an object).  */

/* ONE light source, deliberately DIM. The page's life comes from MOTION, not
   brightness. A big bright blob reads as smudge; a small dim one reads as light. */
.aurora{
  position:fixed; inset:0; z-index:0; pointer-events:none;
  background:
    radial-gradient(46% 40% at 50% 34%, rgba(22,163,74,0.10) 0%, rgba(22,163,74,0.03) 44%, transparent 70%),
    radial-gradient(120% 70% at 50% 120%, rgba(20,83,45,0.06) 0%, transparent 60%);
  animation:drift 24s ease-in-out infinite alternate;
}
/* a thin band of light along the very top of the viewport — implies the room the
   card is lit from, without hazing the whole canvas */
.aurora::after{
  content:''; position:absolute; top:0; left:0; right:0; height:1px;
  background:linear-gradient(90deg,transparent,rgba(22,163,74,.40),transparent);
}
@keyframes drift{
  0%  {transform:scale(1)    translateY(0)}
  100%{transform:scale(1.06) translateY(-1.2%)}
}

/* THE LATTICE, IN TWO PLANES.
   A single grid is flat. Two — a fine dot-field in front, a coarse line grid
   behind — that shift by DIFFERENT amounts on mouse move produce real parallax.
   The near plane must travel further than the far one; that ratio IS the depth.
   They also give the moving layers a reference frame: motion across nothing just
   looks like a rendering glitch. --px/--py are set by auth-bg.js (range -1..1). */
.plane{
  position:fixed; inset:-8%; z-index:0; pointer-events:none;
  mask-image:radial-gradient(80% 72% at 50% 45%, #000 0%, transparent 100%);
  -webkit-mask-image:radial-gradient(80% 72% at 50% 45%, #000 0%, transparent 100%);
  will-change:transform;
}
.plane.far{
  opacity:.05;
  background-image:
    linear-gradient(rgba(20,60,38,.9) 1px, transparent 1px),
    linear-gradient(90deg, rgba(20,60,38,.9) 1px, transparent 1px);
  background-size:128px 128px;
  transform:translate3d(calc(var(--px,0) * 8px), calc(var(--py,0) * 8px), 0);
}
.plane.near{
  opacity:.16;
  background-image:radial-gradient(circle, rgba(20,60,38,.55) 1px, transparent 1px);
  background-size:32px 32px;
  transform:translate3d(calc(var(--px,0) * 24px), calc(var(--py,0) * 24px), 0);
}

/* THE SPOTLIGHT — a warm light that TRAILS the cursor. The lag lives in JS (a
   lerp), not in a CSS transition: a transition eases then STOPS, which the eye
   reads as "an animation played". A lerp never quite arrives, which the eye
   reads as "that light has weight". */
.spot{
  position:fixed; inset:0; z-index:0; pointer-events:none;
  background:radial-gradient(420px circle at var(--sx,50%) var(--sy,38%),
              rgba(22,163,74,.14) 0%, rgba(22,163,74,.05) 35%, transparent 62%);
}

/* LIGHT BEAMS — two wide, very faint diagonal bars sweeping the canvas on long,
   offset loops (28s / 38s). Slow enough that you never catch one "starting". */
.beams{position:fixed; inset:0; z-index:0; pointer-events:none; overflow:hidden}
.beam{
  position:absolute; top:-60%; height:220%; width:46vw;
  background:linear-gradient(90deg,transparent,rgba(22,163,74,.07),transparent);
  transform:rotate(14deg); filter:blur(28px);
}
.beam.b1{left:-50vw; animation:sweep 28s linear infinite}
.beam.b2{left:-50vw; width:30vw; animation:sweep 38s linear infinite; animation-delay:-14s;
         background:linear-gradient(90deg,transparent,rgba(20,83,45,.035),transparent)}
@keyframes sweep{
  0%  {transform:translateX(0)     rotate(14deg)}
  100%{transform:translateX(190vw) rotate(14deg)}
}

/* DATA TRACERS — thin comets falling down grid columns. A CRM is a thing data
   flows through, so this is meaning, not decoration.
   The durations are all DIFFERENT on purpose (11/15/12/17/20s): if they shared a
   period the eye would lock onto the pattern, and a visible pattern is exactly
   what makes an animated background feel cheap. The negative delays start them
   mid-flight, so the page isn't empty for the first few seconds. */
.flow{position:fixed; inset:0; z-index:0; pointer-events:none; overflow:hidden}
.tr{
  position:absolute; top:-25%; width:1px; height:24%;
  background:linear-gradient(180deg,transparent,rgba(34,197,94,.5),rgba(22,163,74,.85),transparent);
  animation:fall 9s linear infinite;
}
.tr.t1{left:12%;              animation-duration:11s; animation-delay:-2s}
.tr.t2{left:31%; opacity:.55; animation-duration:15s; animation-delay:-9s}
.tr.t3{left:69%; opacity:.7;  animation-duration:12s; animation-delay:-5s}
.tr.t4{left:87%; opacity:.45; animation-duration:17s; animation-delay:-13s}
.tr.t5{left:50%; opacity:.3;  animation-duration:20s; animation-delay:-7s}
@keyframes fall{
  0%  {transform:translateY(0);    opacity:0}
  12% {opacity:1}
  88% {opacity:1}
  100%{transform:translateY(560%); opacity:0}
}

/* NETWORK NODES — points that flare and die, like activity on a live system. */
.nodes{position:fixed; inset:0; z-index:0; pointer-events:none}
.nd{
  position:absolute; width:5px; height:5px; border-radius:50%;
  background:var(--brand3); opacity:0;
  box-shadow:0 0 12px 2px rgba(34,197,94,.75);
  animation:blip 7s ease-in-out infinite;
}
@keyframes blip{
  0%,72%,100%{opacity:0;   transform:scale(.5)}
  78%        {opacity:.95; transform:scale(1)}
  88%        {opacity:0;   transform:scale(1.9)}
}
.nd:nth-child(1){left:16%; top:22%; animation-delay:-0.5s}
.nd:nth-child(2){left:82%; top:31%; animation-delay:-3.2s; animation-duration:9s}
.nd:nth-child(3){left:24%; top:71%; animation-delay:-5.7s; animation-duration:11s}
.nd:nth-child(4){left:74%; top:78%; animation-delay:-1.9s; animation-duration:8s}
.nd:nth-child(5){left:47%; top:12%; animation-delay:-6.6s; animation-duration:12s}
.nd:nth-child(6){left:9%;  top:52%; animation-delay:-4.1s; animation-duration:10s}

/* ═══ GHOST WIDGETS ═════════════════════════════════════════════════════════
   Pieces of the actual CRM — a KPI tile, a pipeline, a lead card, a bar chart —
   drifting in the space BEHIND the login card. Not decoration and not a
   screenshot: a reminder of what is on the other side of this door.

   Three rules keep them from becoming clutter, and all three matter:

   1. DEPTH OF FIELD. The camera is focused on the card, so everything behind it
      is out of focus. Each ghost's blur, opacity and parallax distance are tied
      to ONE number (--d, its depth): far => blurrier, dimmer, moves less.
      Without this they read as stickers pasted on the wallpaper.

   2. THEY NEVER TOUCH THE CENTRE. All of them live out at the edges, where the
      vignette is already eating them. You came here to sign in, not to read a
      chart.

   3. PARALLAX IS PURE CSS. --px/--py are set once per frame by auth-bg.js; each
      ghost multiplies them by its own --d. No per-element JS, so adding a ghost
      costs nothing at runtime.                                                 */
.ghosts{position:fixed; inset:0; z-index:0; pointer-events:none; overflow:hidden}

.ghost{
  position:absolute;
  font-family:var(--mono); color:var(--ink);
  background:linear-gradient(180deg, rgba(255,255,255,.94), rgba(247,251,248,.94));
  border:1px solid rgba(20,60,38,.10);
  border-radius:14px; padding:14px 16px;
  box-shadow:0 24px 60px -22px rgba(20,60,38,.35);
  /* the ONE number that defines this ghost's distance from the camera */
  --d:16;
  opacity:calc(.05 + var(--d) / 260);          /* nearer => more present */
  filter:blur(calc((34 - var(--d)) * 0.09px)); /* nearer => sharper      */
  transform:translate3d(calc(var(--px,0) * var(--d) * 1px),
                        calc(var(--py,0) * var(--d) * 1px), 0);
  will-change:transform;
}
/* a lit top edge, exactly like the real card — same light source, so they read
   as being in the same room */
.ghost::before{
  content:''; position:absolute; top:-1px; left:16%; right:16%; height:1px;
  background:linear-gradient(90deg,transparent,rgba(22,163,74,.5),transparent);
}

.g-label{font-size:8.5px; letter-spacing:.18em; text-transform:uppercase; color:var(--ink-faint); margin-bottom:7px}
.g-big{font-family:'Syne',sans-serif; font-size:20px; font-weight:800; letter-spacing:-.01em}
.g-up{font-size:9px; color:#16A34A; margin-left:6px; font-family:var(--mono)}

/* — KPI tile — */
.g-kpi{width:172px}

/* — bar chart — bars breathe on a long, staggered loop so the chart looks like
   it is being fed live data rather than sitting still */
.g-chart{width:194px}
.g-bars{display:flex; align-items:flex-end; gap:5px; height:52px; margin-top:10px}
.g-bars i{
  flex:1; border-radius:3px 3px 0 0;
  background:linear-gradient(180deg,var(--brand2),rgba(22,163,74,.25));
  transform-origin:bottom; animation:grow 5.5s ease-in-out infinite;
}
.g-bars i:nth-child(1){height:38%; animation-delay:-.2s}
.g-bars i:nth-child(2){height:58%; animation-delay:-1.1s}
.g-bars i:nth-child(3){height:44%; animation-delay:-2.4s}
.g-bars i:nth-child(4){height:78%; animation-delay:-.7s}
.g-bars i:nth-child(5){height:62%; animation-delay:-3.1s}
.g-bars i:nth-child(6){height:92%; animation-delay:-1.8s}
.g-bars i:nth-child(7){height:70%; animation-delay:-4.0s}
@keyframes grow{0%,100%{transform:scaleY(.82)} 50%{transform:scaleY(1)}}

/* — pipeline — */
.g-pipe{width:200px}
.g-stage{display:flex; align-items:center; gap:8px; margin-top:9px; font-size:9px; color:var(--ink-dim)}
.g-stage span{flex:0 0 54px; letter-spacing:.06em}
.g-stage b{flex:0 0 16px; text-align:right; color:var(--ink); font-size:9px}
.g-track{flex:1; height:4px; border-radius:3px; background:rgba(20,60,38,.10); overflow:hidden}
.g-track i{display:block; height:100%; border-radius:3px; background:linear-gradient(90deg,var(--brand),var(--brand3))}

/* — lead card — */
.g-lead{width:210px}
.g-row{display:flex; align-items:center; gap:9px; margin-top:10px}
.g-avt{
  width:26px; height:26px; border-radius:50%; flex-shrink:0;
  display:grid; place-items:center; font-size:9px; font-weight:600;
  background:rgba(22,163,74,.12); border:1px solid rgba(22,163,74,.30); color:var(--brand3);
}
.g-nm{font-size:10px; color:var(--ink); font-family:'Instrument Sans',sans-serif; font-weight:600}
.g-sub{font-size:8.5px; color:var(--ink-faint); margin-top:1px}
.g-amt{margin-left:auto; font-size:10px; font-weight:600; color:var(--brand3)}

/* — sparkline — */
.g-spark{width:180px}
.g-spark svg{display:block; margin-top:8px; width:100%; height:44px; overflow:visible}
/* the line draws itself, over and over — the "live feed" tell */
.g-spark path.ln{
  fill:none; stroke:var(--brand2); stroke-width:2; stroke-linecap:round; stroke-linejoin:round;
  stroke-dasharray:260; stroke-dashoffset:260; animation:draw 9s ease-in-out infinite;
}
@keyframes draw{
  0%       {stroke-dashoffset:260}
  45%,72%  {stroke-dashoffset:0}
  100%     {stroke-dashoffset:0; opacity:0}
}

/* Ghosts are a DESKTOP flourish. On a phone the card already fills the screen —
   they would only be clutter behind it, and they cost battery to composite. */
@media (max-width:980px){ .ghosts{display:none} }

/* Vignette — pulls the eye to centre and hides where the grid mask ends. It also
   does the real work of dissolving the ghosts' outer edges into the dark. */
.vig{
  position:fixed; inset:0; z-index:1; pointer-events:none;
  background:radial-gradient(120% 100% at 50% 45%, transparent 40%, rgba(247,251,248,.85) 100%);
}

/* GRAIN — SVG film noise. The single biggest upgrade on any dark page: flat CSS
   gradients are PERFECTLY smooth, and perfect smoothness is what the eye reads as
   "cheap render". Real surfaces have noise. You won't see it; you'll feel it. */
.grain{
  position:fixed; inset:0; z-index:3; pointer-events:none; opacity:.16; mix-blend-mode:multiply;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='3'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='0.5'/%3E%3C/svg%3E");
}


/* ═══ SHELL ═════════════════════════════════════════════════════════════════ */
.shell{position:relative; z-index:2; width:100%; max-width:488px}
.shell.wide{max-width:560px}   /* signup — more fields need more room */

@keyframes rise{from{opacity:0; transform:translateY(14px)} to{opacity:1; transform:none}}
.r{opacity:0; animation:rise .7s cubic-bezier(.2,.7,.2,1) forwards}
.r1{animation-delay:.05s} .r2{animation-delay:.14s} .r3{animation-delay:.23s}


/* ═══ MARK ══════════════════════════════════════════════════════════════════ */
.mark{display:flex; flex-direction:column; align-items:center; gap:16px; margin-bottom:32px}
.mark-badge{
  position:relative; width:64px; height:64px; border-radius:19px;
  background:linear-gradient(150deg,#0F2A1C,#163A27);
  border:1px solid rgba(22,163,74,.30);
  display:grid; place-items:center;
  box-shadow:0 0 0 1px rgba(255,255,255,.9), 0 16px 44px -12px rgba(22,163,74,.55),
             inset 0 1px 0 rgba(255,255,255,.28);
}
/* halo — the mark EMITS light rather than sitting on top of the page */
.mark-badge::after{
  content:''; position:absolute; inset:-16px; border-radius:32px; z-index:-1;
  background:radial-gradient(circle, rgba(22,163,74,.30) 0%, transparent 68%);
}
.wordmark{
  font-family:'Syne',sans-serif; font-size:21px; font-weight:800;
  letter-spacing:.15em; text-transform:uppercase;
}


/* ═══ CARD ══════════════════════════════════════════════════════════════════
   This rule inverted when the page went light, and the reason is worth keeping.

   On the old DARK canvas, elevation could NOT come from a shadow — a black shadow
   on a black page is invisible — so it came from the SURFACE being lighter than
   the canvas (#241F1B against #070605: a wide gap, so the card visibly floated).

   On a LIGHT canvas that trick is gone: the card is already white and there is
   nothing lighter left to reach for. So elevation now comes from the one thing
   that could not work before — a real, layered SHADOW. It is tinted with the
   canvas's own green rather than grey, because a grey shadow on a tinted page is
   the classic tell of a theme that was recoloured instead of re-thought.        */
.card{
  position:relative; border-radius:24px; padding:44px 42px 34px;
  background:linear-gradient(180deg,#FFFFFF 0%, #FBFEFC 100%);
  border:1px solid var(--line);
  box-shadow:
    0 1px 0 rgba(255,255,255,.9) inset,
    0 2px 6px rgba(20,60,38,.05),
    0 30px 70px -24px rgba(20,60,38,.28),
    0 0 70px -20px rgba(22,163,74,.14);
}
/* THE SIGNATURE: a lit top edge, brightest at centre. It tells the eye there is a
   light source above the card, which is what makes the card feel like an object
   in a room instead of a rectangle on a screen. This one hairline does more for
   "premium" than any gradient. */
.card::before{
  content:''; position:absolute; top:-1px; left:8%; right:8%; height:1px; z-index:2;
  background:linear-gradient(90deg,transparent,rgba(22,163,74,.85),transparent);
}
/* SPOTLIGHT BORDER — the card's 1px rim brightens wherever the cursor is near it,
   like a metal bevel catching light. Technique: paint a radial glow across the
   whole box, then XOR-mask out everything except the 1px padding ring, so the glow
   survives ONLY on the border. --cx/--cy come from auth-bg.js in the card's own
   coordinate space. Hidden until a real pointer exists (no cursor on phones). */
.card::after{
  content:''; position:absolute; inset:0; border-radius:inherit; padding:1px;
  background:radial-gradient(240px circle at var(--cx,50%) var(--cy,0%),
              rgba(22,163,74,.75) 0%, rgba(22,163,74,.25) 35%, transparent 65%);
  -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;
  opacity:0; transition:opacity .45s ease; pointer-events:none;
}
body.pointer .card::after{opacity:1}


/* ═══ CARD HEADINGS ═════════════════════════════════════════════════════════ */
.kicker{
  font-family:var(--mono); font-size:10px; font-weight:500;
  letter-spacing:.22em; text-transform:uppercase; color:var(--brand3);
  display:flex; align-items:center; gap:9px; margin-bottom:13px;
}
.kicker::after{content:''; flex:1; height:1px; background:linear-gradient(90deg,var(--line),transparent)}

.card h1{font-size:33px; margin-bottom:10px}
.lede{font-size:15px; color:var(--ink-dim); margin-bottom:32px; line-height:1.65}


/* ═══ FIELDS ════════════════════════════════════════════════════════════════ */
.field{margin-bottom:18px}
.field-row{display:grid; grid-template-columns:1fr 1fr; gap:14px}
.field label{
  display:block; font-family:var(--mono); font-size:10px; font-weight:500;
  letter-spacing:.16em; text-transform:uppercase; color:var(--ink-faint);
  margin-bottom:8px; transition:color .2s;
}
/* the label lights up when you focus its input — a tiny confirmation that the
   page is paying attention to you */
.field:focus-within label{color:var(--brand3)}

.field input, .field select{
  width:100%; padding:14px 15px; font-size:15px; font-family:inherit;
  color:var(--ink); background:#F5FAF7;
  border:1px solid var(--line); border-radius:12px;
  transition:border-color .18s, box-shadow .18s, background .18s;
}
.field select{cursor:pointer; appearance:none; -webkit-appearance:none;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8'%3E%3Cpath d='M1 1l5 5 5-5' stroke='%238A9A91' stroke-width='1.6' fill='none' stroke-linecap='round'/%3E%3C/svg%3E");
  background-repeat:no-repeat; background-position:right 15px center; padding-right:38px}
.field select option{background:#FFFFFF; color:var(--ink)}
.field input::placeholder{color:#9DAEA4}
.field input:focus, .field select:focus{
  outline:none; background:#FFFFFF; border-color:rgba(22,163,74,.7);
  box-shadow:0 0 0 3px rgba(22,163,74,.13), 0 0 22px -8px rgba(22,163,74,.45);
}
.field .hint{font-family:var(--mono); font-size:10px; color:#8A9A91; margin-top:7px; letter-spacing:.06em}

.pwd{position:relative}
.pwd input{padding-right:64px}
.pwd-toggle{
  position:absolute; right:8px; top:50%; transform:translateY(-50%);
  background:none; border:none; padding:7px 9px; border-radius:7px;
  font-family:var(--mono); font-size:10px; font-weight:600;
  letter-spacing:.1em; text-transform:uppercase; color:var(--ink-faint);
  transition:.16s;
}
.pwd-toggle:hover{color:var(--brand3); background:rgba(22,163,74,.09)}


/* ═══ CHECKS / LINKS ════════════════════════════════════════════════════════ */
.row{display:flex; justify-content:space-between; align-items:center; margin:16px 0 22px; font-size:13px; gap:12px; flex-wrap:wrap}
.check{display:inline-flex; align-items:center; gap:9px; color:var(--ink-dim); cursor:pointer; user-select:none}
.check input{width:15px; height:15px; accent-color:var(--brand); cursor:pointer}
.link{color:var(--ink-dim); font-weight:500; transition:color .16s}
.link:hover{color:var(--brand3)}

.check-row{display:flex; align-items:flex-start; gap:10px; font-size:12.5px; color:var(--ink-faint);
  margin:6px 0 22px; line-height:1.6; cursor:pointer}
.check-row input{margin-top:3px; width:15px; height:15px; accent-color:var(--brand); cursor:pointer; flex-shrink:0}
.check-row a{color:var(--ink-dim); border-bottom:1px solid var(--line)}
.check-row a:hover{color:var(--brand3); border-color:var(--brand3)}


/* ═══ BUTTON ════════════════════════════════════════════════════════════════ */
.btn{
  position:relative; width:100%; padding:15px 22px; overflow:hidden;
  font-size:14.5px; font-weight:700; letter-spacing:.01em;
  color:#fff; border:none; border-radius:12px;
  background:linear-gradient(180deg,var(--brand2) 0%, var(--brand) 100%);
  box-shadow:0 1px 0 rgba(255,255,255,.28) inset, 0 10px 30px -10px rgba(22,163,74,.55);
  display:inline-flex; align-items:center; justify-content:center; gap:9px;
  transition:transform .16s, box-shadow .22s, filter .18s, opacity .18s;
}
.btn:hover:not(:disabled){
  transform:translateY(-1px); filter:brightness(1.06);
  box-shadow:0 1px 0 rgba(255,255,255,.34) inset, 0 18px 42px -12px rgba(22,163,74,.7);
}
.btn:active:not(:disabled){transform:translateY(0)}
.btn:disabled{opacity:.55; cursor:not-allowed; box-shadow:none}
/* light sweeps across on hover — the detail people notice but can't name */
.btn::after{
  content:''; position:absolute; inset:0; transform:translateX(-120%);
  background:linear-gradient(105deg,transparent 30%,rgba(255,255,255,.32) 50%,transparent 70%);
}
.btn:hover:not(:disabled)::after{transform:translateX(120%); transition:transform .85s cubic-bezier(.3,.6,.3,1)}
.arrow{transition:transform .22s; display:inline-block}
.btn:hover:not(:disabled) .arrow{transform:translateX(3px)}

.btn-note{
  text-align:center; margin-top:14px;
  font-family:var(--mono); font-size:10px; letter-spacing:.12em; text-transform:uppercase;
  color:#8A9A91;
}


/* ═══ NOTES / MESSAGES ══════════════════════════════════════════════════════ */
.note{
  display:flex; gap:9px; align-items:flex-start;
  margin-top:16px; padding:11px 13px; border-radius:10px;
  background:rgba(20,60,38,.025); border:1px dashed var(--line);
  font-family:var(--mono); font-size:10.5px; line-height:1.6;
  color:var(--ink-faint); letter-spacing:.01em;
}
.note b{color:var(--ink-dim); font-weight:600}
.note-ic{color:var(--brand3); flex-shrink:0}

/* login + signup error banner (class name kept: the pages' JS toggles .show) */
.err{
  display:none; margin-bottom:18px; padding:12px 14px; border-radius:11px;
  background:rgba(220,38,38,.07); border:1px solid rgba(220,38,38,.28);
  color:#B91C1C; font-size:13px; line-height:1.55;
}
.err.show{display:block; animation:rise .3s ease forwards; opacity:1}
.err a{color:var(--brand3); font-weight:700; border-bottom:1px solid var(--brand3)}

/* reset-password message box (its JS sets .msg.err / .msg.ok) */
.msg{display:none; margin-top:18px; padding:12px 14px; border-radius:11px; font-size:13px; line-height:1.55}
.msg.err{display:block; background:rgba(220,38,38,.07); border:1px solid rgba(220,38,38,.28); color:#B91C1C}
.msg.ok {display:block; background:rgba(22,163,74,.08);  border:1px solid rgba(22,163,74,.28); color:#15803D}


/* ═══ ANDROID APP CTA ═══════════════════════════════════════════════════════
   This used to be "📱 Get the Android app" — an emoji plus an underlined link,
   sitting inside the footer directly under the Terms/Privacy line, in the same
   size and colour. Two things were killing it:

     1. It was PARKED IN THE BOILERPLATE. The eye files everything under a rule,
        next to "Terms and Privacy Policy", as legal small-print and skips it. No
        amount of styling saves an element that is standing in the wrong place —
        so it now lives in its own bordered row, above the legal line.
     2. The emoji was a LIABILITY, not an icon. 📱 renders differently on every OS
        (and as a blue tofu box on some), it can't take the brand colour, and it
        can't respond to hover. Replaced with a real Android SVG that inherits
        currentColor.

   It stays OUTLINED, not solid orange: the page already has one solid orange
   button, and that one is the primary action. Two solid buttons = neither wins. */
.app-cta{
  display:flex; align-items:center; gap:13px;
  margin-top:22px; padding:13px 15px;
  border:1px solid var(--line); border-radius:14px;
  background:linear-gradient(180deg, rgba(20,60,38,.028), rgba(20,60,38,.008));
  transition:border-color .2s, background .2s, transform .18s, box-shadow .25s;
}
.app-cta:hover{
  border-color:rgba(22,163,74,.5); transform:translateY(-1px);
  background:linear-gradient(180deg, rgba(22,163,74,.09), rgba(22,163,74,.03));
  box-shadow:0 14px 34px -14px rgba(22,163,74,.45);
}
.app-ic{
  width:38px; height:38px; border-radius:11px; flex-shrink:0;
  display:grid; place-items:center; color:var(--brand3);
  background:rgba(22,163,74,.10); border:1px solid rgba(22,163,74,.24);
  transition:background .2s, color .2s, transform .25s;
}
.app-cta:hover .app-ic{background:rgba(22,163,74,.18); color:#166534; transform:scale(1.06)}
.app-tx{min-width:0}
/* both are <span>s inside a <span> — they must be blocks to stack */
.app-t{display:block; font-size:13.5px; font-weight:600; color:var(--ink); line-height:1.35}
.app-s{
  display:block; font-family:var(--mono); font-size:9.5px; letter-spacing:.14em;
  text-transform:uppercase; color:var(--ink-faint); margin-top:3px;
}
/* The QR sits between the text and the arrow. It is hidden in the markup and only
   revealed once qr.js has actually painted a matrix, so a failed encode leaves the
   row looking exactly as it did before rather than showing an empty white square. */
.app-qr{
  margin-left:auto; flex-shrink:0; display:grid; place-items:center;
  padding:4px; border-radius:8px; background:#fff;
  border:1px solid var(--line);
  box-shadow:0 4px 12px -4px rgba(20,60,38,.22);
  transition:transform .25s, box-shadow .25s;
}
.app-qr canvas{display:block; width:60px; height:60px; image-rendering:pixelated}
.app-cta:hover .app-qr{transform:scale(1.06); box-shadow:0 8px 20px -6px rgba(22,163,74,.4)}

.app-go{
  margin-left:14px; flex-shrink:0; color:var(--ink-faint); font-size:15px;
  transition:transform .22s, color .2s;
}
/* no QR (encode failed / older browser): the arrow takes the space back */
.app-cta > .app-qr[hidden] ~ .app-go{margin-left:auto}
.app-cta:hover .app-go{transform:translateX(3px); color:var(--brand3)}


/* ═══ FOOT ══════════════════════════════════════════════════════════════════ */
.rule{height:1px; background:var(--line2); margin:26px 0 18px}

.foot{text-align:center; font-size:12.5px; color:var(--ink-faint); line-height:1.8}
.foot a{color:var(--ink-dim); border-bottom:1px solid var(--line); padding-bottom:1px; transition:.16s}
.foot a:hover{color:var(--brand3); border-color:var(--brand3)}
.foot a.plain{border:none}

.newhere{margin-top:22px; text-align:center; font-size:13px; color:var(--ink-faint)}
.newhere a{color:var(--brand3); font-weight:600}
.newhere a:hover{text-decoration:underline}

.back{
  position:fixed; top:24px; left:26px; z-index:4;
  font-family:var(--mono); font-size:10.5px; letter-spacing:.12em; text-transform:uppercase;
  color:var(--ink-faint); display:inline-flex; gap:8px; align-items:center;
  padding:9px 13px; border-radius:9px; border:1px solid transparent; transition:.18s;
}
.back:hover{color:var(--ink); border-color:var(--line); background:rgba(20,60,38,.04)}


/* ═══ SIGNUP SUCCESS STATE ══════════════════════════════════════════════════
   signup.html's showSuccess() replaces #fp-body's innerHTML with this markup,
   so these class names are load-bearing — they are written from JS. */
.success-card{text-align:center; padding:8px 0; animation:rise .45s ease forwards}
.success-ic{
  width:72px; height:72px; border-radius:50%; margin:0 auto 20px;
  display:grid; place-items:center; font-size:32px; color:#FFFFFF;
  background:linear-gradient(150deg,#22C55E,#15803D);
  box-shadow:0 16px 44px -12px rgba(22,163,74,.5);
  animation:pop .4s cubic-bezier(.2,1.4,.5,1);
}
@keyframes pop{0%{transform:scale(.5);opacity:0} 100%{transform:scale(1);opacity:1}}
.success-h{font-family:'Syne',sans-serif; font-size:26px; margin-bottom:10px}
.success-p{font-size:14px; color:var(--ink-dim); line-height:1.7; max-width:380px; margin:0 auto 24px}
.success-p b{color:var(--ink)}
.success-actions{display:flex; gap:10px; justify-content:center; flex-wrap:wrap}
.btn-solid-sm{
  padding:12px 20px; font-size:13px; font-weight:700; color:#fff; border:none; border-radius:10px;
  background:linear-gradient(180deg,var(--brand2),var(--brand));
  box-shadow:0 8px 24px -8px rgba(22,163,74,.5); transition:.18s;
}
.btn-solid-sm:hover{filter:brightness(1.08); transform:translateY(-1px)}
.btn-outline-sm{
  padding:12px 20px; font-size:13px; font-weight:700; color:var(--ink-dim);
  background:transparent; border:1px solid var(--line); border-radius:10px; transition:.18s;
}
.btn-outline-sm:hover{color:var(--ink); border-color:var(--brand3)}


/* ═══ RESPONSIVE ════════════════════════════════════════════════════════════ */
@media (max-width:560px){
  body{flex-direction:column; justify-content:flex-start; padding:26px 16px 40px}
  .back{position:static; margin-bottom:20px; align-self:flex-start; padding:9px 0}
  .card{padding:30px 22px 26px; border-radius:18px}
  .card h1{font-size:26px}
  .lede{font-size:14px; margin-bottom:26px}
  .field-row{grid-template-columns:1fr; gap:0}
  .beam{filter:blur(20px)}
  .mark-badge{width:56px; height:56px}
}

/* ═══ REDUCED MOTION ════════════════════════════════════════════════════════
   A still page for anyone who asks for one. The spotlight survives — it's a
   response to the user, not an animation playing at them. */
@media (prefers-reduced-motion:reduce){
  .aurora,.beam,.tr,.nd,.r,.success-ic,.g-bars i,.g-spark path.ln{animation:none !important}
  .r{opacity:1}
  .g-spark path.ln{stroke-dashoffset:0}
  .flow,.nodes{display:none}
  .plane,.ghost{transform:none !important}
}
