/* Shared animated design toolkit for the Affiliate portal (public/affiliate-login.html,
   public/affiliate-register.html, affiliate/index.html) — glassmorphism, animated
   mesh background, spotlight/tilt cards, magnetic buttons, cursor glow, scroll
   reveal, marquee, animated conic borders, gradient text. One shared file so the
   three pages never drift into three slightly-different copies of the same
   effect. Design tokens intentionally match public/index.html's/lib/pseoTemplate.js's
   :root so the affiliate portal reads as the same product, not a bolted-on skin —
   but this remains a fully separate login/session/dashboard from every other
   portal (see migrations/0056_affiliate_system.sql). */

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

@property --ang { syntax: '<angle>'; inherits: false; initial-value: 0deg; }

:root{
  --bg:#FFFFFF;--bg-soft:#F5F8FF;--ink:#0F172A;--ink2:#52607A;--ink3:#8A96AE;
  --blue:#1935A8;--blue2:#2B55E6;--blue-soft:#EEF2FF;--blue-soft2:#D7E0FB;
  --cyan:#0891B2;--cyan-bright:#00C8D4;--cyan-soft:#E3FBFC;
  --amber:#F59E0B;--amber-soft:#FFF7E6;--green:#059669;--green-soft:#E9FBF3;
  --red:#DC2626;--red-soft:#FEECEC;
  --border:#E6EAF5;--shadow:rgba(23,43,99,.08);--grape:#7C4DDC;--grape-soft:#F3EEFF;
  --sans:Inter,system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;
  --mono:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;
}

html{ scroll-behavior:smooth; }
body{ font-family:var(--sans); background:var(--bg); color:var(--ink); overflow-x:hidden; line-height:1.6; }
a{ color:inherit; }
img{ max-width:100%; height:auto; }

/* — Animated mesh background (page-level, fixed) — */
.aff-mesh{ position:fixed; inset:0; z-index:-2; overflow:hidden; pointer-events:none; background:var(--bg); }
.aff-mesh::before,.aff-mesh::after{ content:''; position:absolute; border-radius:50%; filter:blur(90px); opacity:.4; will-change:transform; }
.aff-mesh::before{ width:480px; height:480px; background:radial-gradient(circle,var(--cyan-bright),transparent 70%); top:-10%; left:-6%; animation:affMeshDrift 19s ease-in-out infinite; }
.aff-mesh::after{ width:520px; height:520px; background:radial-gradient(circle,var(--grape),transparent 70%); bottom:-14%; right:-8%; animation:affMeshDrift 23s ease-in-out infinite reverse; }
.aff-mesh .blob3{ position:absolute; width:420px; height:420px; left:42%; top:30%; border-radius:50%; background:radial-gradient(circle,var(--blue2),transparent 70%); filter:blur(90px); opacity:.3; animation:affMeshDrift 27s ease-in-out infinite; }
.aff-mesh .noise{ position:absolute; inset:0; opacity:.05; mix-blend-mode:overlay; background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 200 200'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='0.35'/%3E%3C/svg%3E"); }
@keyframes affMeshDrift{ 0%,100%{ transform:translate(0,0) scale(1); } 50%{ transform:translate(30px,-22px) scale(1.07); } }

/* — Cursor glow (desktop, fine-pointer only) — */
.aff-cursor-glow{ position:fixed; top:0; left:0; width:440px; height:440px; border-radius:50%; pointer-events:none; z-index:5; transform:translate(-50%,-50%); background:radial-gradient(circle,rgba(43,85,230,.10),rgba(0,200,212,.05) 45%,transparent 70%); opacity:0; transition:opacity .3s ease; will-change:transform; }
.aff-cursor-glow.is-active{ opacity:1; }
@media (hover:none),(pointer:coarse){ .aff-cursor-glow{ display:none; } }

/* — Glass card, spotlight + 3D tilt + animated conic border — */
.aff-glass{ position:relative; background:rgba(255,255,255,.68); backdrop-filter:blur(18px); -webkit-backdrop-filter:blur(18px); border:1px solid rgba(255,255,255,.6); border-radius:20px; box-shadow:0 20px 60px rgba(23,43,99,.12); overflow:hidden; }
.aff-tilt{ transform-style:preserve-3d; }
.aff-tilt::before{ content:''; position:absolute; inset:0; border-radius:inherit; background:radial-gradient(240px circle at var(--mx,50%) var(--my,50%),rgba(255,255,255,.55),transparent 60%); opacity:0; transition:opacity .25s ease; pointer-events:none; }
.aff-tilt:hover::before{ opacity:1; }
.aff-tilt::after{ content:''; position:absolute; inset:0; border-radius:inherit; padding:1.5px; background:conic-gradient(from var(--ang,0deg),var(--blue),var(--cyan-bright),var(--grape),var(--blue)); -webkit-mask:linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0); -webkit-mask-composite:xor; mask-composite:exclude; opacity:0; transition:opacity .25s ease; pointer-events:none; }
.aff-tilt:hover::after{ opacity:.6; animation:affBorderSpin 3s linear infinite; }
@keyframes affBorderSpin{ to{ --ang:360deg; } }

/* Gentle idle float, opt-in (.aff-float-card) — used on standalone cards
   (stat tiles, audience/step cards, the calculator), never on wide table
   wrappers where a bobbing motion would look broken rather than lively. */
@keyframes affCardFloat{ 0%,100%{ transform:translateY(0); } 50%{ transform:translateY(-7px); } }
.aff-float-card{ animation:affCardFloat 6s ease-in-out infinite; }
.aff-float-card:nth-of-type(2n){ animation-delay:-1.5s; }
.aff-float-card:nth-of-type(3n){ animation-delay:-3s; }

/* Opt-in stronger treatment for the page's one "hero" interactive widget
   (e.g. the earning calculator) — conic border always visibly spinning, not
   just on hover, so it doesn't read as flat/static at rest. */
.aff-glow-live::after{ opacity:.45; animation:affBorderSpin 4s linear infinite; }
.aff-glow-live:hover::after{ opacity:.8; animation-duration:2.5s; }
.aff-glow-live{ box-shadow:0 20px 60px rgba(23,43,99,.12),0 0 0 1px rgba(43,85,230,.06); }

@media (prefers-reduced-motion: reduce){ .aff-float-card{ animation:none; } .aff-glow-live::after{ animation:none; } }

/* — Gradient text — */
.aff-gradient-text{ background:linear-gradient(115deg,var(--ink) 25%,var(--blue) 55%,var(--cyan) 85%); -webkit-background-clip:text; background-clip:text; color:transparent; }

/* — Buttons — */
.aff-btn{ position:relative; overflow:hidden; display:inline-flex; align-items:center; justify-content:center; gap:8px; font-family:var(--sans); font-weight:700; font-size:14.5px; border-radius:12px; padding:14px 26px; text-decoration:none; cursor:pointer; border:none; transition:transform .15s ease,box-shadow .15s ease; }
.aff-btn-primary{ background:linear-gradient(135deg,var(--blue),var(--blue2)); color:#fff; box-shadow:0 10px 30px rgba(25,53,168,.3); }
.aff-btn-primary:hover{ box-shadow:0 14px 36px rgba(25,53,168,.4); }
.aff-btn-primary::after{ content:''; position:absolute; top:0; left:-60%; width:40%; height:100%; background:linear-gradient(115deg,transparent,rgba(255,255,255,.35),transparent); transform:skewX(-20deg); transition:left .5s ease; }
.aff-btn-primary:hover::after{ left:130%; }
.aff-btn-outline{ background:rgba(255,255,255,.6); backdrop-filter:blur(8px); color:var(--ink); border:1.5px solid var(--border); }
.aff-btn-outline:hover{ border-color:var(--blue-soft2); transform:translateY(-2px); }
.aff-btn:disabled{ opacity:.6; cursor:not-allowed; transform:none !important; }

/* — Form fields — */
/* — Icon system — clean line icons (24x24 SVGs), replacing emoji for a more
   credible, professional tone across every affiliate/reseller-portal page. */
.icon-wrap{ width:48px; height:48px; border-radius:12px; display:flex; align-items:center; justify-content:center; background:var(--blue-soft); border:1px solid var(--blue-soft2); color:var(--blue); flex-shrink:0; }
.icon-wrap svg{ width:24px; height:24px; flex-shrink:0; }
.icon-wrap.sm{ width:38px; height:38px; border-radius:10px; }
.icon-wrap.sm svg{ width:19px; height:19px; }

.aff-field{ margin-bottom:16px; }
.aff-field label{ display:block; font-size:12px; font-weight:700; color:var(--ink2); text-transform:uppercase; letter-spacing:.04em; margin-bottom:6px; }
.aff-field input, .aff-field select{ width:100%; padding:13px 14px; border-radius:11px; border:1.5px solid var(--border); background:rgba(255,255,255,.7); font-family:var(--sans); font-size:14.5px; color:var(--ink); transition:border-color .15s ease,box-shadow .15s ease; }
.aff-field input:focus, .aff-field select:focus{ outline:none; border-color:var(--blue2); box-shadow:0 0 0 3px var(--blue-soft); }

/* — Scroll reveal — */
.aff-reveal{ opacity:0; transform:translateY(24px) scale(.98); transition:opacity .6s ease,transform .6s ease; }
.aff-reveal.is-visible{ opacity:1; transform:translateY(0) scale(1); }

/* — Marquee — */
.aff-marquee{ overflow:hidden; -webkit-mask-image:linear-gradient(90deg,transparent,#000 6%,#000 94%,transparent); mask-image:linear-gradient(90deg,transparent,#000 6%,#000 94%,transparent); }
.aff-marquee-track{ display:flex; gap:14px; width:max-content; animation:affMarquee 28s linear infinite; }
.aff-marquee:hover .aff-marquee-track{ animation-play-state:paused; }
@keyframes affMarquee{ to{ transform:translateX(-50%); } }

/* — Floating badges — */
.aff-float{ position:absolute; z-index:1; display:flex; align-items:center; gap:6px; font-size:12px; font-weight:700; color:var(--ink); padding:9px 14px; border-radius:12px; background:rgba(255,255,255,.65); backdrop-filter:blur(14px); border:1px solid rgba(255,255,255,.6); box-shadow:0 10px 26px rgba(23,43,99,.12); animation:affFloatBob 5.5s ease-in-out infinite; }
@keyframes affFloatBob{ 0%,100%{ transform:translateY(0); } 50%{ transform:translateY(-12px); } }

@keyframes affFadeUp{ from{ opacity:0; transform:translateY(16px); } to{ opacity:1; transform:translateY(0); } }
.aff-fade-up{ opacity:0; animation:affFadeUp .6s ease forwards; }

@media (prefers-reduced-motion: reduce){
  .aff-mesh::before,.aff-mesh::after,.aff-mesh .blob3,.aff-float,.aff-marquee-track{ animation:none; }
  .aff-reveal{ opacity:1; transform:none; transition:none; }
  .aff-fade-up{ opacity:1; animation:none; }
}
