/* ==========================================================================
   Fexo — design system + site styles
   Rebuilt 2026-07-30. Dark premium theme, no framework, no external fonts.
   ========================================================================== */

:root{
  --navy-950:#050714; --navy-900:#0A0E27; --navy-850:#0D1230; --navy-800:#121838;
  --line:rgba(255,255,255,.09); --line-2:rgba(255,255,255,.16);
  --blue:#3B82F6; --blue-400:#60A5FA; --violet:#8B5CF6; --violet-400:#A78BFA;
  --ink:#F8FAFC; --ink-2:#CBD5E1; --ink-3:#94A3B8; --ink-4:#64748B;
  --grad:linear-gradient(115deg,var(--blue) 0%,var(--violet) 100%);
  --glass:rgba(255,255,255,.04);
  --shadow-lg:0 24px 60px -12px rgba(0,0,0,.65);
  --r-sm:10px; --r:16px; --r-lg:24px; --r-xl:32px;
  --wrap:1200px; --ease:cubic-bezier(.22,1,.36,1);
  --nav-h:72px;
}

*,*::before,*::after{box-sizing:border-box}
html{-webkit-text-size-adjust:100%;scroll-behavior:smooth}
@media (prefers-reduced-motion:reduce){html{scroll-behavior:auto}}
body{
  margin:0;background:var(--navy-950);color:var(--ink);
  font-family:'Inter',-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,'Helvetica Neue',Arial,sans-serif;
  font-size:16px;line-height:1.65;-webkit-font-smoothing:antialiased;
  overflow-x:hidden;
}
img{max-width:100%;height:auto;display:block}
a{color:inherit;text-decoration:none}
h1,h2,h3,h4{margin:0;line-height:1.12;letter-spacing:-.025em;font-weight:750}
p{margin:0}
::selection{background:var(--violet);color:#fff}

.wrap{width:100%;max-width:var(--wrap);margin-inline:auto;padding-inline:24px}
.eyebrow{
  display:inline-flex;align-items:center;gap:8px;font-size:.75rem;font-weight:650;
  letter-spacing:.14em;text-transform:uppercase;color:var(--blue-400);
  padding:7px 15px;border:1px solid var(--line-2);border-radius:100px;background:var(--glass);
}
.grad-text{background:var(--grad);-webkit-background-clip:text;background-clip:text;color:transparent}
.lede{color:var(--ink-2);font-size:1.075rem;max-width:62ch}
.center{text-align:center}
.center .lede{margin-inline:auto}

/* --- buttons ------------------------------------------------------------ */
.btn{
  --bg:var(--grad);
  display:inline-flex;align-items:center;justify-content:center;gap:10px;
  padding:15px 30px;border-radius:100px;font-weight:650;font-size:.95rem;
  border:0;cursor:pointer;position:relative;isolation:isolate;color:#fff;
  background:var(--bg);transition:transform .35s var(--ease),box-shadow .35s var(--ease);
  box-shadow:0 10px 30px -10px rgba(59,130,246,.6);white-space:nowrap;
}
.btn::after{
  content:"";position:absolute;inset:0;border-radius:inherit;z-index:-1;
  background:linear-gradient(115deg,var(--violet),var(--blue));
  opacity:0;transition:opacity .35s var(--ease);
}
.btn:hover{transform:translateY(-3px);box-shadow:0 18px 40px -12px rgba(139,92,246,.7)}
/* Magnetic buttons get their translate from JS, so the hover lift above must
   not fight it — the -3px baseline is folded into the JS value instead. */
.btn-magnet{transition:transform .18s var(--ease),box-shadow .35s var(--ease)}
.btn-magnet:hover{transform:none}
.btn:hover::after{opacity:1}
.btn-ghost{
  background:var(--glass);border:1px solid var(--line-2);box-shadow:none;color:var(--ink);
}
.btn-ghost::after{display:none}
.btn-ghost:hover{background:rgba(255,255,255,.09);border-color:var(--blue);box-shadow:none}
.btn:focus-visible,a:focus-visible,button:focus-visible{outline:2px solid var(--blue-400);outline-offset:3px}

/* --- store badges ------------------------------------------------------- */
.badges{display:flex;gap:14px;flex-wrap:wrap}
.badge{
  display:inline-flex;align-items:center;gap:12px;padding:12px 24px 12px 20px;
  border-radius:14px;background:rgba(255,255,255,.055);border:1px solid var(--line-2);
  transition:transform .35s var(--ease),background .3s,border-color .3s;
}
.badge:hover{transform:translateY(-3px);background:rgba(255,255,255,.1);border-color:var(--blue)}
.badge svg{width:26px;height:26px;flex:none;fill:currentColor}
.badge span{display:block;font-size:.68rem;color:var(--ink-3);line-height:1.3;letter-spacing:.04em}
.badge strong{display:block;font-size:1.02rem;font-weight:650;line-height:1.25}

/* --- header ------------------------------------------------------------- */
.hdr{
  position:fixed;inset:0 0 auto;height:var(--nav-h);z-index:100;
  display:flex;align-items:center;
  transition:background .4s var(--ease),border-color .4s,backdrop-filter .4s;
  border-bottom:1px solid transparent;
}
.hdr.stuck{
  background:rgba(5,7,20,.82);backdrop-filter:blur(18px) saturate(1.6);
  -webkit-backdrop-filter:blur(18px) saturate(1.6);border-bottom-color:var(--line);
}
.hdr .wrap{display:flex;align-items:center;gap:32px}
.logo{display:flex;align-items:center;margin-right:auto}
.logo img{height:30px;width:auto;transition:opacity .3s var(--ease)}
.logo:hover img{opacity:.82}
.ftr .logo img{height:34px}
@media(max-width:480px){.logo img{height:26px}}
.nav{display:flex;gap:4px;align-items:center}
.nav a{
  padding:9px 15px;border-radius:100px;font-size:.925rem;font-weight:520;color:var(--ink-2);
  transition:color .25s,background .25s;
}
.nav a:hover,.nav a[aria-current]{color:var(--ink);background:var(--glass)}
.burger{display:none;background:none;border:0;color:var(--ink);padding:8px;cursor:pointer}
.burger svg{width:26px;height:26px;stroke:currentColor;fill:none;stroke-width:2;stroke-linecap:round}

@media(max-width:900px){
  .hdr .wrap{gap:16px}
  .burger{display:block}
  .nav{
    position:fixed;inset:var(--nav-h) 0 auto;flex-direction:column;align-items:stretch;gap:0;
    background:rgba(5,7,20,.97);backdrop-filter:blur(20px);-webkit-backdrop-filter:blur(20px);
    padding:12px 24px 28px;border-bottom:1px solid var(--line);
    transform:translateY(-12px);opacity:0;pointer-events:none;transition:.3s var(--ease);
  }
  .nav.open{transform:none;opacity:1;pointer-events:auto}
  .nav a{padding:14px 4px;border-radius:0;border-bottom:1px solid var(--line);font-size:1rem}
  .nav .btn{margin-top:16px;border-bottom:0}
}

/* --- hero --------------------------------------------------------------- */
.hero{position:relative;padding:calc(var(--nav-h) + 80px) 0 80px;overflow:hidden}
.hero-bg{position:absolute;inset:0;z-index:-2;background:var(--navy-950)}

/* Optional photographic/AI backdrop.
   The art goes on .hero-bg's OWN background, layered under a dark scrim
   gradient, so it never competes with the ::before/::after pseudo-elements —
   those stay free for the animated colour orbs defined further down.
   Layer order in `background`: scrim first (drawn on top), image second. */
.hero-bg.has-img{
  background-image:
    linear-gradient(100deg,var(--navy-950) 4%,rgba(5,7,20,.80) 34%,rgba(5,7,20,.28) 72%,rgba(5,7,20,.12) 100%),
    var(--bg-img);
  background-size:cover,cover;
  background-position:center,center right;
  background-repeat:no-repeat,no-repeat;
}
@media(max-width:760px){
  /* Smaller file + a heavier top-down scrim, since text sits over the whole
     frame rather than beside the art on phones. */
  .hero-bg.has-img{
    background-image:
      linear-gradient(180deg,rgba(5,7,20,.62),rgba(5,7,20,.90) 68%,var(--navy-950)),
      var(--bg-img-sm,var(--bg-img));
    background-position:center,center right;
  }
}

/* Section feature image (About "our story", etc.) */
.feature-img{
  position:relative;border-radius:var(--r-xl);overflow:hidden;border:1px solid var(--line-2);
  box-shadow:var(--shadow-lg);
}
.feature-img img{width:100%;height:100%;object-fit:cover;display:block}
.feature-img::after{
  content:"";position:absolute;inset:0;pointer-events:none;
  background:linear-gradient(160deg,transparent 40%,rgba(5,7,20,.45));
}
.split{display:grid;grid-template-columns:1.05fr .95fr;gap:56px;align-items:center}
@media(max-width:900px){.split{grid-template-columns:1fr;gap:36px}}
.hero-bg::before{
  content:"";position:absolute;width:min(1100px,120vw);aspect-ratio:1;right:-18%;top:-42%;
  background:radial-gradient(circle,rgba(59,130,246,.30),rgba(139,92,246,.13) 42%,transparent 68%);
  filter:blur(48px);animation:drift 22s var(--ease) infinite alternate;
}
.hero-bg::after{
  content:"";position:absolute;width:min(760px,100vw);aspect-ratio:1;left:-16%;bottom:-46%;
  background:radial-gradient(circle,rgba(139,92,246,.22),transparent 62%);
  filter:blur(52px);animation:drift 26s var(--ease) 2s infinite alternate-reverse;
}
.grid-fade{
  position:absolute;inset:0;z-index:-1;pointer-events:none;
  background-image:linear-gradient(var(--line) 1px,transparent 1px),
                   linear-gradient(90deg,var(--line) 1px,transparent 1px);
  background-size:64px 64px;
  -webkit-mask-image:radial-gradient(ellipse 78% 58% at 50% 32%,#000 20%,transparent 76%);
          mask-image:radial-gradient(ellipse 78% 58% at 50% 32%,#000 20%,transparent 76%);
  opacity:.5;
}
@keyframes drift{to{transform:translate3d(-70px,50px,0) scale(1.14)}}
@media (prefers-reduced-motion:reduce){.hero-bg::before,.hero-bg::after{animation:none}}

.hero h1{font-size:clamp(2.5rem,6.2vw,4.6rem);margin:26px 0 22px;max-width:15ch}
.hero .lede{font-size:clamp(1.05rem,1.9vw,1.25rem);max-width:56ch}
.hero-cta{display:flex;gap:14px;flex-wrap:wrap;margin-top:30px}
.hero-badges{margin-top:34px}

/* --- stat panels --------------------------------------------------------
   Each stat is a glass panel with a progress ring that draws itself as the
   number counts up. The ring is not decoration: its sweep is the stat's real
   share of the catalogue (35/36 on Play reads nearly full, 20/36 just over
   half), so the shape carries the same information as the digits.          */
.stats{
  display:grid;grid-template-columns:repeat(4,1fr);gap:16px;margin-top:56px;
}
.stat{
  position:relative;isolation:isolate;overflow:hidden;
  padding:30px 20px 26px;text-align:center;border-radius:var(--r-lg);
  background:linear-gradient(165deg,rgba(255,255,255,.07),rgba(255,255,255,.02));
  border:1px solid var(--line);
  transition:transform .5s var(--ease),border-color .4s,box-shadow .5s var(--ease);
}
/* Ambient glow that drifts behind each panel, offset per panel via --d. */
.stat::before{
  content:"";position:absolute;z-index:-1;width:150%;aspect-ratio:1;
  left:-25%;top:-70%;border-radius:50%;
  background:radial-gradient(circle,rgba(59,130,246,.20),transparent 62%);
  opacity:.75;animation:statGlow 9s var(--ease) infinite alternate;
  animation-delay:calc(var(--d,0) * -1.6s);
}
@keyframes statGlow{
  to{transform:translate3d(14%,26%,0) scale(1.25);opacity:.35}
}
.stat:hover{
  transform:translateY(-6px);border-color:var(--line-2);
  box-shadow:0 22px 46px -20px rgba(59,130,246,.5);
}

.stat-ring{
  position:relative;width:96px;height:96px;margin:0 auto 16px;
}
.stat-ring svg{width:100%;height:100%;transform:rotate(-90deg);overflow:visible}
.stat-ring .trk{fill:none;stroke:rgba(255,255,255,.09);stroke-width:5}
.stat-ring .bar{
  fill:none;stroke:url(#statGrad);stroke-width:5;stroke-linecap:round;
  stroke-dasharray:var(--circ);stroke-dashoffset:var(--circ);
  transition:stroke-dashoffset 1.5s var(--ease);
  filter:drop-shadow(0 0 6px rgba(99,102,241,.55));
}
.stat.on .bar{stroke-dashoffset:var(--target)}

/* Number sits inside the ring. */
.stat b{
  position:absolute;inset:0;display:grid;place-items:center;
  font-size:clamp(1.6rem,2.6vw,2.05rem);font-weight:800;letter-spacing:-.045em;
  font-variant-numeric:tabular-nums;
  background:var(--grad);-webkit-background-clip:text;background-clip:text;color:transparent;
}
.stat-ico{
  position:absolute;left:50%;bottom:-3px;transform:translateX(-50%);
  width:26px;height:26px;border-radius:50%;display:grid;place-items:center;
  background:var(--navy-900);border:1px solid var(--line-2);
}
.stat-ico svg{width:12px;height:12px;fill:var(--ink-3);transform:none;transition:fill .4s}
.stat:hover .stat-ico svg{fill:var(--blue-400)}
.stat span{
  display:block;font-size:.76rem;color:var(--ink-3);letter-spacing:.08em;
  text-transform:uppercase;font-weight:650;
}

@media(max-width:860px){.stats{grid-template-columns:repeat(2,1fr);gap:14px}}
@media(max-width:420px){
  .stat{padding:24px 12px 22px}
  .stat-ring{width:82px;height:82px}
}
@media (prefers-reduced-motion:reduce){
  .stat::before{animation:none}
  .stat-ring .bar{transition:none}
}

/* --- sections ----------------------------------------------------------- */
/* 72px top and bottom means ~144px between two stacked sections. The old 104
   read as disconnected on a laptop; this keeps them breathing but related. */
.sec{padding:72px 0;position:relative}
@media(max-width:760px){.sec{padding:52px 0}}
.sec-alt{background:linear-gradient(180deg,transparent,var(--navy-900) 12%,var(--navy-900) 88%,transparent)}
.sec-head{max-width:640px;margin-bottom:40px}
.sec-head.center{margin-inline:auto}
.sec-head h2{font-size:clamp(2rem,4.2vw,3rem);margin:20px 0 18px}

/* --- app grid ----------------------------------------------------------- */
.filters{display:flex;gap:9px;flex-wrap:wrap;justify-content:center;margin-bottom:32px}
.chip{
  padding:9px 19px;border-radius:100px;border:1px solid var(--line-2);background:var(--glass);
  color:var(--ink-2);font-size:.85rem;font-weight:580;cursor:pointer;
  transition:.28s var(--ease);font-family:inherit;
}
.chip:hover{border-color:var(--blue);color:var(--ink);transform:translateY(-2px)}
.chip[aria-pressed="true"]{background:var(--grad);border-color:transparent;color:#fff;
  box-shadow:0 8px 22px -8px rgba(99,102,241,.75)}

/* --- featured app banner ------------------------------------------------
   One flagship app across the full width, above the 3x3 grid. Deliberately
   heavier than a card so the hierarchy reads instantly. */
.app-hero{
  position:relative;isolation:isolate;overflow:hidden;display:flex;align-items:center;gap:34px;
  padding:30px 34px;margin-bottom:20px;border-radius:var(--r-xl);
  border:1px solid var(--line-2);
  background:linear-gradient(120deg,rgba(59,130,246,.16),rgba(139,92,246,.13) 52%,rgba(255,255,255,.03));
  transition:transform .5s var(--ease),box-shadow .5s var(--ease),border-color .4s;
}
/* No lift on hover: the panel itself is not a link any more, and moving it
   would suggest it is. The two store buttons carry the interaction instead. */
/* drifting bloom behind the icon */
.app-hero-glow{
  position:absolute;z-index:-1;width:420px;aspect-ratio:1;left:-60px;top:-160px;
  border-radius:50%;pointer-events:none;
  background:radial-gradient(circle,rgba(99,102,241,.5),transparent 66%);
  filter:blur(52px);animation:auroraA 16s var(--ease) infinite alternate;
}
.app-hero-sheen{position:absolute;inset:0;z-index:1;pointer-events:none;overflow:hidden;border-radius:inherit}
.app-hero-sheen::before{
  content:"";position:absolute;top:-60%;bottom:-60%;left:-40%;width:30%;
  background:linear-gradient(100deg,transparent,rgba(255,255,255,.12) 45%,transparent);
  transform:translate3d(-220%,0,0) rotate(14deg);
}
@media (hover:hover){.app-hero:hover .app-hero-sheen::before{animation:sheen 1.25s var(--ease) forwards}}

.app-hero-art{position:relative;z-index:2;flex:none}
.app-hero-art img{
  width:104px;height:104px;border-radius:26px;
  box-shadow:0 20px 40px -14px rgba(0,0,0,.9);
  transition:transform .55s var(--ease);
}
.app-hero:hover .app-hero-art img{transform:scale(1.06) rotate(-3deg)}

.app-hero-body{position:relative;z-index:2;flex:1;min-width:0}
.app-hero-tag{
  display:inline-flex;align-items:center;gap:6px;margin-bottom:11px;
  font-size:.68rem;font-weight:750;letter-spacing:.1em;text-transform:uppercase;
  color:#FDE68A;padding:5px 12px;border-radius:100px;
  background:rgba(251,191,36,.14);border:1px solid rgba(251,191,36,.4);
}
.app-hero-tag svg{width:12px;height:12px;fill:currentColor}
.app-hero h3{font-size:clamp(1.3rem,2.4vw,1.7rem);font-weight:750;letter-spacing:-.025em;margin-bottom:9px}
.app-hero p{color:var(--ink-2);font-size:.97rem;max-width:62ch;margin-bottom:18px}

/* Full store buttons — each goes to its own store. Sized like real download
   badges so both platforms read as equally available. */
.app-hero-links{position:relative;z-index:3;display:flex;gap:12px;flex-wrap:wrap;align-items:center}
.hlink{
  display:inline-flex;align-items:center;gap:11px;padding:11px 20px 11px 16px;
  border-radius:14px;background:rgba(255,255,255,.08);border:1px solid var(--line-2);
  transition:transform .35s var(--ease),background .3s,border-color .3s,box-shadow .35s var(--ease);
}
.hlink svg{width:23px;height:23px;flex:none;fill:var(--ink);transition:fill .3s}
.hlink em{font-style:normal;line-height:1.15}
.hlink span{display:block;font-size:.66rem;color:var(--ink-3);letter-spacing:.04em}
.hlink strong{display:block;font-size:.95rem;font-weight:660}
.hlink:hover{
  transform:translateY(-3px);background:rgba(255,255,255,.14);
  border-color:var(--blue);box-shadow:0 14px 28px -12px rgba(59,130,246,.7);
}
.hlink:hover svg{fill:#fff}
.hlink-ios:hover{border-color:var(--violet);box-shadow:0 14px 28px -12px rgba(139,92,246,.7)}

.app-hero-cat{
  font-size:.74rem;color:var(--ink-4);letter-spacing:.07em;text-transform:uppercase;font-weight:650;
}

@media(max-width:820px){
  .app-hero{flex-direction:column;align-items:flex-start;gap:20px;padding:26px 22px;text-align:left}
  .app-hero-art img{width:80px;height:80px;border-radius:20px}
  .app-hero p{margin-bottom:16px}
  .app-hero-links{width:100%}
  .hlink{flex:1 1 auto;justify-content:center}
  .app-hero-cat{width:100%;margin-top:4px}
}
@media(max-width:420px){.hlink{flex:1 1 100%}}
@media (prefers-reduced-motion:reduce){
  .app-hero-glow{animation:none}
  .app-hero-sheen{display:none}
}

.app-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(276px,1fr));gap:20px}
/* Homepage runs a fixed 3x3 so the featured banner + 9 cards read as one block. */
.app-grid.grid-3{grid-template-columns:repeat(3,1fr)}
@media(max-width:900px){.app-grid.grid-3{grid-template-columns:repeat(2,1fr)}}
@media(max-width:600px){.app-grid.grid-3{grid-template-columns:1fr}}
.app{
  position:relative;display:flex;flex-direction:column;gap:15px;padding:24px;
  background:linear-gradient(160deg,rgba(255,255,255,.055),rgba(255,255,255,.018));
  border:1px solid var(--line);border-radius:var(--r-lg);overflow:hidden;
  transition:transform .45s var(--ease),border-color .35s,box-shadow .45s var(--ease);
}
.app::before{
  content:"";position:absolute;inset:0;border-radius:inherit;opacity:0;pointer-events:none;
  background:radial-gradient(420px circle at var(--mx,50%) var(--my,0%),rgba(99,102,241,.20),transparent 68%);
  transition:opacity .4s;
}
.app:hover{transform:translateY(-7px);border-color:var(--line-2);box-shadow:var(--shadow-lg)}
.app:hover::before{opacity:1}
.app-top{display:flex;align-items:flex-start;gap:15px;position:relative;z-index:3}
.app img{
  width:62px;height:62px;border-radius:15px;flex:none;
  box-shadow:0 10px 24px -10px rgba(0,0,0,.85);
  transition:transform .55s var(--ease),box-shadow .55s var(--ease);
}
.app:hover img{
  transform:translateY(-4px) scale(1.08) rotate(-3deg);
  box-shadow:0 18px 34px -12px rgba(99,102,241,.65);
}
/* Title clears the platform pill so long names never run underneath it. */
.app h3{font-size:1.03rem;font-weight:680;letter-spacing:-.015em;line-height:1.3;padding-right:52px}
.app .cat{font-size:.74rem;color:var(--ink-4);letter-spacing:.07em;text-transform:uppercase;font-weight:620;margin-top:5px}
.app p{font-size:.875rem;color:var(--ink-3);line-height:1.6;flex:1;position:relative;z-index:3}
.app-links{display:flex;gap:9px;flex-wrap:wrap;margin-top:2px;position:relative;z-index:3}
.slink{
  display:inline-flex;align-items:center;gap:7px;padding:8px 15px;border-radius:100px;
  font-size:.79rem;font-weight:620;background:rgba(255,255,255,.07);
  border:1px solid var(--line-2);color:var(--ink-2);transition:.28s var(--ease);
}
.slink svg{width:15px;height:15px;fill:currentColor;flex:none}
.slink:hover{background:var(--grad);border-color:transparent;color:#fff;transform:translateY(-2px)}
/* Cross-platform marker. Shows the two platform glyphs rather than the words
   "iOS & Android" — the marks read faster and never collide with a long title.
   The label is kept for screen readers. */
.dual{
  position:absolute;top:16px;right:16px;z-index:3;
  display:inline-flex;align-items:center;gap:7px;
  padding:6px 10px;border-radius:100px;
  background:rgba(10,14,39,.55);border:1px solid var(--line-2);
  backdrop-filter:blur(10px) saturate(1.4);-webkit-backdrop-filter:blur(10px) saturate(1.4);
  transition:border-color .4s var(--ease),background .4s var(--ease),transform .5s var(--ease);
}
.dual svg{width:13px;height:13px;fill:var(--ink-3);transition:fill .4s var(--ease),transform .5s var(--ease)}
.dual i{
  width:1px;height:11px;background:var(--line-2);flex:none;
  transition:background .4s var(--ease);
}
.app:hover .dual{
  border-color:rgba(139,92,246,.55);background:rgba(139,92,246,.16);transform:translateY(-1px);
}
.app:hover .dual svg{fill:#fff}
.app:hover .dual svg:first-child{transform:translateY(-1px) rotate(-6deg)}
.app:hover .dual svg:last-child{transform:translateY(-1px) rotate(6deg)}
.app:hover .dual i{background:rgba(255,255,255,.4)}

/* Live shimmer that sweeps the card on hover. GPU transform only. */
.app-sheen{
  position:absolute;inset:0;z-index:2;pointer-events:none;overflow:hidden;border-radius:inherit;
}
.app-sheen::before{
  content:"";position:absolute;top:-60%;bottom:-60%;left:-40%;width:34%;
  background:linear-gradient(100deg,transparent,rgba(255,255,255,.09) 42%,rgba(167,139,250,.16) 54%,transparent);
  transform:translate3d(-220%,0,0) rotate(14deg);
}
@media (hover:hover){
  .app:hover .app-sheen::before{
    animation:sheen 1.15s var(--ease) forwards;
  }
}
@keyframes sheen{to{transform:translate3d(560%,0,0) rotate(14deg)}}

/* Gradient hairline that lights the card edge on hover. */
.app::after{
  content:"";position:absolute;inset:0;border-radius:inherit;pointer-events:none;z-index:1;
  padding:1px;background:linear-gradient(140deg,var(--blue),var(--violet) 55%,transparent 80%);
  -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 var(--ease);
}
.app:hover::after{opacity:.85}

@media (prefers-reduced-motion:reduce){
  .app-sheen{display:none}
  .app:hover .dual svg{transform:none}
}

/* --- services -----------------------------------------------------------
   Glass cards that lift and tilt toward the cursor, with a spotlight that
   follows the pointer and an icon whose internals animate on hover. Every
   moving part is a transform or opacity, so a six-card grid stays at 60fps. */
.svc-grid{
  display:grid;grid-template-columns:repeat(auto-fit,minmax(292px,1fr));gap:20px;
  perspective:1100px;
}
.svc{
  position:relative;isolation:isolate;overflow:hidden;
  padding:32px 28px;border:1px solid var(--line);border-radius:var(--r-lg);
  background:linear-gradient(160deg,rgba(255,255,255,.055),rgba(255,255,255,.014));
  transform-style:preserve-3d;
  transition:transform .5s var(--ease),border-color .4s,box-shadow .5s var(--ease);
}
/* pointer spotlight */
.svc::before{
  content:"";position:absolute;inset:0;z-index:-1;opacity:0;pointer-events:none;
  background:radial-gradient(460px circle at var(--mx,50%) var(--my,0%),rgba(99,102,241,.20),transparent 66%);
  transition:opacity .45s var(--ease);
}
/* gradient hairline that lights the edge */
.svc::after{
  content:"";position:absolute;inset:0;border-radius:inherit;pointer-events:none;
  padding:1px;background:linear-gradient(145deg,var(--blue),var(--violet) 52%,transparent 78%);
  -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 var(--ease);
}
.svc:hover{
  transform:translateY(-8px) rotateX(var(--rx,0deg)) rotateY(var(--ry,0deg));
  border-color:transparent;
  box-shadow:0 28px 56px -22px rgba(59,130,246,.55);
}
.svc:hover::before,.svc:hover::after{opacity:1}

/* sweeping sheen */
.svc-sheen{position:absolute;inset:0;z-index:1;pointer-events:none;overflow:hidden;border-radius:inherit}
.svc-sheen::before{
  content:"";position:absolute;top:-60%;bottom:-60%;left:-40%;width:36%;
  background:linear-gradient(100deg,transparent,rgba(255,255,255,.10) 44%,rgba(167,139,250,.16) 56%,transparent);
  transform:translate3d(-220%,0,0) rotate(14deg);
}
@media (hover:hover){
  .svc:hover .svc-sheen::before{animation:sheen 1.2s var(--ease) forwards}
}

/* index number, quiet until hover */
.svc-num{
  position:absolute;top:22px;right:24px;z-index:2;
  font-size:1.5rem;font-weight:800;letter-spacing:-.04em;font-variant-numeric:tabular-nums;
  color:rgba(255,255,255,.09);
  transition:color .45s var(--ease),transform .5s var(--ease);
}
.svc:hover .svc-num{color:rgba(167,139,250,.5);transform:translateY(-2px)}

/* --- icon tile ---------------------------------------------------------- */
.svc-ico{
  position:relative;z-index:2;
  width:58px;height:58px;border-radius:17px;display:grid;place-items:center;margin-bottom:22px;
  background:linear-gradient(150deg,rgba(59,130,246,.22),rgba(139,92,246,.20));
  border:1px solid var(--line-2);
  transition:transform .55s var(--ease),box-shadow .55s var(--ease),background .45s;
}
.svc:hover .svc-ico{
  transform:translateZ(28px) scale(1.06);
  background:linear-gradient(150deg,rgba(59,130,246,.4),rgba(139,92,246,.36));
  box-shadow:0 16px 30px -12px rgba(99,102,241,.8);
}
.svc-ico svg{
  width:30px;height:30px;overflow:visible;
  stroke:var(--blue-400);fill:none;stroke-width:1.9;stroke-linecap:round;stroke-linejoin:round;
  transition:stroke .45s var(--ease);
}
.svc:hover .svc-ico svg{stroke:#fff}
.svc-ico .p2{opacity:.75}
.svc-ico .p3{opacity:.45}
.svc-ico .dot,.svc-ico .led,.svc-ico .star{fill:currentColor;stroke:none;color:var(--violet-400)}
.svc:hover .svc-ico .dot,.svc:hover .svc-ico .led,.svc:hover .svc-ico .star{color:#fff}

/* per-icon motion — each one animates the part that carries its meaning */
.svc-ico .dash,.svc-ico .arrow,.svc-ico .pen,.svc-ico .trend,.svc-ico .check{
  transition:transform .55s var(--ease),opacity .45s var(--ease);
}
.svc:hover .svc-ico .dash{animation:codeFlick .9s var(--ease)}
@keyframes codeFlick{40%{transform:scaleX(1.18)}}
.svc:hover .svc-ico .arrow{animation:arrowGo 1.05s var(--ease) infinite}
@keyframes arrowGo{50%{transform:translateX(3.5px)}}
.svc:hover .svc-ico .pen{animation:penDraw .8s var(--ease)}
@keyframes penDraw{50%{transform:translate(2px,-2px) rotate(-6deg)}}
.svc-ico .trend{stroke:var(--violet-400);stroke-dasharray:44;stroke-dashoffset:0}
.svc:hover .svc-ico .trend{stroke:#fff;animation:trendDraw .9s var(--ease)}
@keyframes trendDraw{from{stroke-dashoffset:44}to{stroke-dashoffset:0}}
.svc-ico .check{stroke-dasharray:26}
.svc:hover .svc-ico .check{animation:checkDraw .7s var(--ease)}
@keyframes checkDraw{from{stroke-dashoffset:26}to{stroke-dashoffset:0}}
.svc:hover .svc-ico .led{animation:ledBlink 1.4s var(--ease) infinite}
.svc:hover .svc-ico .led:nth-of-type(2){animation-delay:.18s}
.svc:hover .svc-ico .led:nth-of-type(3){animation-delay:.36s}
@keyframes ledBlink{50%{opacity:.35}}

.svc h3{position:relative;z-index:2;font-size:1.14rem;margin-bottom:11px;font-weight:690;letter-spacing:-.015em;padding-right:42px}
.svc p{position:relative;z-index:2;color:var(--ink-3);font-size:.915rem}

/* capability list (services page only) */
.svc-list{position:relative;z-index:2;list-style:none;padding:0;margin:20px 0 0;display:grid;gap:9px}
.svc-list li{display:flex;gap:10px;align-items:flex-start;font-size:.87rem;color:var(--ink-2)}
.svc-list svg{
  width:15px;height:15px;flex:none;margin-top:4px;
  stroke:var(--blue-400);fill:none;stroke-width:2.6;stroke-linecap:round;stroke-linejoin:round;
  transition:stroke .4s var(--ease);
}
.svc:hover .svc-list svg{stroke:var(--violet-400)}

/* staggered entrance across the grid */
.svc.rv{transform:translateY(28px) scale(.975)}
.svc.rv.in{transform:none;transition-delay:calc(var(--i,0) * 70ms)}

@media (prefers-reduced-motion:reduce){
  .svc-sheen{display:none}
  .svc:hover{transform:translateY(-4px)}
  .svc:hover .svc-ico{transform:none}
  .svc-ico *{animation:none!important}
}

/* --- process timeline ---------------------------------------------------
   A real sequence, so it is built as one: a rail runs through every node and
   fills as the section scrolls, and each node ignites when the fill reaches it.
   --p (0..1) is written by JS from scroll position; everything else is CSS.  */
.steps{
  position:relative;display:grid;grid-template-columns:repeat(4,1fr);gap:24px;
  padding-top:70px;--p:0;
}
/* the rail — sits behind the node dots */
.steps::before,.steps::after{
  content:"";position:absolute;top:31px;height:2px;border-radius:2px;
}
.steps::before{left:12.5%;right:12.5%;background:rgba(255,255,255,.10)}
.steps::after{
  left:12.5%;width:calc((100% - 25%) * var(--p));
  background:linear-gradient(90deg,var(--blue),var(--violet));
  box-shadow:0 0 14px rgba(99,102,241,.7);
  transition:width .35s linear;
}

.step{position:relative;text-align:center;padding:0 6px}

/* node */
.step-node{
  position:relative;width:62px;height:62px;margin:-74px auto 20px;
  display:grid;place-items:center;border-radius:50%;
  background:var(--navy-900);border:2px solid var(--line-2);
  transition:border-color .5s var(--ease),transform .5s var(--ease),box-shadow .5s var(--ease),background .5s;
}
.step-node svg{
  width:23px;height:23px;stroke:var(--ink-4);fill:none;stroke-width:1.8;
  stroke-linecap:round;stroke-linejoin:round;
  transition:stroke .5s var(--ease),transform .5s var(--ease);
}
/* the step index, pinned to the node */
.step-num{
  position:absolute;top:-6px;right:-6px;width:23px;height:23px;border-radius:50%;
  display:grid;place-items:center;font-size:.66rem;font-weight:800;
  font-variant-numeric:tabular-nums;color:var(--ink-4);
  background:var(--navy-850);border:1px solid var(--line-2);
  transition:color .5s var(--ease),background .5s var(--ease),border-color .5s var(--ease);
}

/* --- reached state: set by JS as the rail passes each node --------------- */
.step.on .step-node{
  border-color:transparent;background:var(--grad);
  transform:scale(1.09);
  box-shadow:0 0 0 6px rgba(99,102,241,.13),0 14px 32px -12px rgba(99,102,241,.85);
}
.step.on .step-node svg{stroke:#fff;transform:scale(1.06)}
.step.on .step-num{color:#fff;background:var(--violet);border-color:transparent}
.step.on h3{color:var(--ink)}

/* a soft pulse the moment a node is reached */
.step.on .step-node::after{
  content:"";position:absolute;inset:-2px;border-radius:50%;
  border:2px solid var(--violet-400);
  animation:nodePulse 1.1s var(--ease) 1 forwards;
}
@keyframes nodePulse{
  from{opacity:.85;transform:scale(1)}
  to{opacity:0;transform:scale(1.75)}
}

/* Steps fade in without translating — a vertical shift would pull the nodes
   off the rail while the reveal is still running. */
.step.rv{transform:none}
.step.rv.in{transform:none}

.step h3{
  font-size:1.06rem;margin-bottom:9px;font-weight:680;color:var(--ink-2);
  transition:color .5s var(--ease);
}
.step p{color:var(--ink-3);font-size:.9rem;max-width:26ch;margin-inline:auto}

/* --- stacked / vertical rail on narrow screens -------------------------- */
@media(max-width:820px){
  .steps{grid-template-columns:1fr;gap:0;padding-top:0}
  .steps::before,.steps::after{top:0;bottom:0;left:31px;right:auto;width:2px;height:auto}
  .steps::before{top:31px;bottom:31px}
  .steps::after{
    top:31px;height:calc((100% - 62px) * var(--p));width:2px;
    transition:height .35s linear;
  }
  .step{
    display:grid;grid-template-columns:62px 1fr;gap:20px;
    text-align:left;padding:0 0 34px;
  }
  .step:last-child{padding-bottom:0}
  .step-node{margin:0}
  .step p{max-width:none}
  .step-body{padding-top:6px}
}

@media (prefers-reduced-motion:reduce){
  .steps::after{transition:none}
  .step.on .step-node::after{animation:none;opacity:0}
  .step-node,.step-node svg,.step-num{transition:none}
}

/* --- blog --------------------------------------------------------------- */
.post-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(300px,1fr));gap:24px}
.post{
  display:flex;flex-direction:column;border:1px solid var(--line);border-radius:var(--r-lg);
  overflow:hidden;background:rgba(255,255,255,.03);
  transition:transform .45s var(--ease),border-color .35s,box-shadow .45s var(--ease);
}
.post:hover{transform:translateY(-6px);border-color:var(--line-2);box-shadow:var(--shadow-lg)}
.post-img{aspect-ratio:16/9;overflow:hidden;background:var(--navy-800)}
.post-img img{width:100%;height:100%;object-fit:cover;transition:transform .7s var(--ease)}
.post:hover .post-img img{transform:scale(1.07)}
.post-body{padding:24px;display:flex;flex-direction:column;gap:11px;flex:1}
.post h3{font-size:1.08rem;font-weight:670;line-height:1.35}
.post p{font-size:.89rem;color:var(--ink-3);flex:1}
.post time{font-size:.76rem;color:var(--ink-4);letter-spacing:.05em;text-transform:uppercase;font-weight:600}
.rmore{font-size:.86rem;font-weight:640;color:var(--blue-400);display:inline-flex;align-items:center;gap:7px}
.post:hover .rmore{gap:11px}
.rmore{transition:gap .3s var(--ease)}

/* --- cta band -----------------------------------------------------------
   The closing panel on six pages, so it carries real weight: two aurora blooms
   drift behind it on independent loops and a conic gradient runs the border,
   keeping the surface alive without anything blinking or demanding attention. */
.cta-band{
  position:relative;border-radius:var(--r-xl);overflow:hidden;isolation:isolate;
  padding:60px 44px;text-align:center;
  background:
    radial-gradient(ellipse 120% 90% at 50% 0%,rgba(59,130,246,.13),transparent 62%),
    linear-gradient(165deg,rgba(139,92,246,.10),rgba(10,14,39,.65));
  border:1px solid transparent;
}
/* animated conic border */
.cta-band::before{
  content:"";position:absolute;inset:0;border-radius:inherit;z-index:-1;padding:1px;
  background:conic-gradient(from var(--a,0deg),
    transparent 0deg,var(--blue) 70deg,var(--violet) 140deg,transparent 210deg,transparent 360deg);
  -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:ctaSpin 9s linear infinite;
}
@property --a{syntax:'<angle>';initial-value:0deg;inherits:false}
@keyframes ctaSpin{to{--a:360deg}}
/* Fallback for engines without @property: fade a static gradient edge in. */
@supports not (background:conic-gradient(from 0deg,red,blue)){
  .cta-band::before{background:linear-gradient(120deg,var(--blue),var(--violet));animation:none;opacity:.5}
}

/* drifting aurora blooms */
.cta-aurora{position:absolute;inset:0;z-index:-2;overflow:hidden;border-radius:inherit;pointer-events:none}
.cta-aurora i{
  position:absolute;display:block;border-radius:50%;filter:blur(58px);
}
.cta-aurora i:nth-child(1){
  width:52%;aspect-ratio:1;left:4%;top:-46%;
  background:radial-gradient(circle,rgba(59,130,246,.55),transparent 66%);
  animation:auroraA 17s var(--ease) infinite alternate;
}
.cta-aurora i:nth-child(2){
  width:46%;aspect-ratio:1;right:2%;bottom:-52%;
  background:radial-gradient(circle,rgba(139,92,246,.5),transparent 66%);
  animation:auroraB 21s var(--ease) infinite alternate;
}
@keyframes auroraA{to{transform:translate3d(38%,34%,0) scale(1.3)}}
@keyframes auroraB{to{transform:translate3d(-34%,-26%,0) scale(1.22)}}

/* fine grid, masked to the centre */
.cta-band::after{
  content:"";position:absolute;inset:0;z-index:-1;opacity:.4;pointer-events:none;
  background-image:linear-gradient(var(--line) 1px,transparent 1px),linear-gradient(90deg,var(--line) 1px,transparent 1px);
  background-size:52px 52px;
  -webkit-mask-image:radial-gradient(ellipse 68% 68% at 50% 50%,#000,transparent 74%);
          mask-image:radial-gradient(ellipse 68% 68% at 50% 50%,#000,transparent 74%);
}
.cta-band>*{position:relative;z-index:1}
.cta-band h2{font-size:clamp(1.95rem,3.9vw,2.75rem);margin-bottom:18px;text-wrap:balance}
.cta-band .lede{margin:0 auto 34px}
.cta-band .hero-cta{justify-content:center}

/* WhatsApp gets its real mark plus a live pulse — it is the low-friction
   action, so it should read as the easy one. */
.btn-wa{position:relative}
.btn-wa svg{width:18px;height:18px;fill:currentColor;flex:none}
.btn-wa::before{
  content:"";position:absolute;left:22px;top:50%;width:10px;height:10px;margin-top:-5px;
  border-radius:50%;border:1.5px solid #25D366;opacity:0;
  animation:waPulse 2.6s var(--ease) infinite;
}
@keyframes waPulse{
  0%{opacity:.75;transform:scale(.5)}
  70%{opacity:0;transform:scale(2.4)}
  100%{opacity:0;transform:scale(2.4)}
}
.btn-wa:hover{border-color:#25D366;color:#fff}
.btn-wa:hover svg{fill:#25D366}

@media(max-width:620px){
  .cta-band{padding:56px 22px}
  .cta-band .hero-cta{flex-direction:column;align-items:stretch}
  .cta-band .hero-cta .btn{justify-content:center}
}
@media (prefers-reduced-motion:reduce){
  .cta-band::before{animation:none}
  .cta-aurora i{animation:none}
  .btn-wa::before{animation:none;opacity:0}
}

/* --- forms -------------------------------------------------------------- */
.form{display:grid;gap:18px}
.row2{display:grid;grid-template-columns:1fr 1fr;gap:18px}
@media(max-width:620px){.row2{grid-template-columns:1fr}}
.field label{display:block;font-size:.82rem;font-weight:620;color:var(--ink-2);margin-bottom:8px;letter-spacing:.02em}
.field{position:relative}
.field input,.field textarea,.field select{
  width:100%;padding:15px 17px;border-radius:14px;
  background:rgba(255,255,255,.045);
  border:1px solid var(--line-2);color:var(--ink);font:inherit;font-size:.95rem;
  transition:border-color .3s var(--ease),background .3s,box-shadow .3s;
}
.field textarea{min-height:150px;resize:vertical;line-height:1.6}

/* Custom chevron, and room for it, so the native arrow never clashes. */
.field select{
  appearance:none;-webkit-appearance:none;-moz-appearance:none;
  padding-right:46px;cursor:pointer;
  background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%2360A5FA' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
  background-repeat:no-repeat;
  background-position:right 16px center;
  background-size:17px;
}
/* ⚠️ The open dropdown list is drawn by the OS, not by this page. Without an
   explicit colour pair here the options inherit the near-white text on the
   platform's white menu background and become unreadable. Always set both. */
.field select option,
.field select optgroup{
  background-color:#0D1230;
  color:#F8FAFC;
}
.field select option:checked{background-color:#1B2350}

.field input:hover,.field textarea:hover,.field select:hover{
  border-color:rgba(255,255,255,.28);background:rgba(255,255,255,.058);
}
.field input:focus,.field textarea:focus,.field select:focus{
  outline:0;border-color:var(--blue);background:rgba(255,255,255,.075);
  box-shadow:0 0 0 4px rgba(59,130,246,.16);
}
.field input::placeholder,.field textarea::placeholder{color:var(--ink-4)}

/* Only flag a field red once the visitor has actually typed something wrong. */
.field input:not(:placeholder-shown):invalid{border-color:rgba(239,68,68,.55)}

.field label{display:flex;align-items:center;gap:7px}
.field .opt{color:var(--ink-4);font-weight:500;font-size:.78rem}
.field .hint{font-size:.79rem;color:var(--ink-4);margin-top:7px}
.req{color:var(--violet-400)}

/* Character counter on the message box */
.count{
  position:absolute;right:14px;bottom:12px;font-size:.72rem;color:var(--ink-4);
  font-variant-numeric:tabular-nums;pointer-events:none;
  background:rgba(10,14,39,.75);padding:2px 8px;border-radius:100px;
  opacity:0;transition:opacity .3s var(--ease);
}
.field textarea:focus ~ .count,.count.show{opacity:1}

/* --- form shell --------------------------------------------------------- */
.form-card{
  position:relative;isolation:isolate;overflow:hidden;
  border:1px solid var(--line);border-radius:var(--r-xl);padding:34px;
  background:linear-gradient(165deg,rgba(255,255,255,.055),rgba(255,255,255,.015));
}
.form-card::before{
  content:"";position:absolute;z-index:-1;width:120%;aspect-ratio:1;left:-10%;top:-72%;
  background:radial-gradient(circle,rgba(59,130,246,.16),transparent 62%);
  filter:blur(40px);pointer-events:none;
}
.form-head{margin-bottom:26px}
.form-head h2{font-size:1.22rem;font-weight:700;letter-spacing:-.02em;margin-bottom:6px}
.form-head p{color:var(--ink-3);font-size:.9rem}

/* Submit button shows progress rather than going dead on click. */
.btn[aria-busy="true"]{pointer-events:none;opacity:.8}
.btn .bspin{
  width:15px;height:15px;border-radius:50%;flex:none;
  border:2px solid rgba(255,255,255,.4);border-top-color:#fff;
  animation:spin .7s linear infinite;
}

/* Reassurance strip under the button */
.form-trust{
  display:flex;gap:18px;flex-wrap:wrap;margin-top:20px;padding-top:20px;
  border-top:1px solid var(--line);font-size:.83rem;color:var(--ink-4);
}
.form-trust span{display:inline-flex;align-items:center;gap:7px}
.form-trust svg{width:14px;height:14px;stroke:var(--blue-400);fill:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round}

@media(max-width:620px){.form-card{padding:24px 20px}}
@media (prefers-reduced-motion:reduce){.btn .bspin{animation:none}}
.note{padding:15px 19px;border-radius:var(--r-sm);font-size:.9rem;border:1px solid}
.note-ok{background:rgba(34,197,94,.1);border-color:rgba(34,197,94,.4);color:#86EFAC}
.note-err{background:rgba(239,68,68,.1);border-color:rgba(239,68,68,.4);color:#FCA5A5}

/* --- contact cards ------------------------------------------------------ */
.info-grid{display:grid;gap:14px}
.info{
  display:flex;gap:16px;align-items:flex-start;padding:20px 22px;border-radius:var(--r);
  border:1px solid var(--line);background:rgba(255,255,255,.03);transition:.35s var(--ease);
}
.info:hover{border-color:var(--line-2);transform:translateX(4px)}
.info svg{width:21px;height:21px;stroke:var(--blue-400);fill:none;stroke-width:1.8;flex:none;margin-top:3px;stroke-linecap:round;stroke-linejoin:round}
.info span{display:block;font-size:.76rem;color:var(--ink-4);text-transform:uppercase;letter-spacing:.07em;font-weight:640;margin-bottom:4px}
.info strong{font-weight:600;font-size:.98rem;word-break:break-word}

/* --- footer ------------------------------------------------------------- */
.ftr{border-top:1px solid var(--line);background:var(--navy-900);padding:56px 0 28px;margin-top:0}
.ftr-grid{display:grid;grid-template-columns:1.7fr 1fr 1fr 1.1fr;gap:44px;margin-bottom:52px}
@media(max-width:880px){.ftr-grid{grid-template-columns:1fr 1fr;gap:36px}}
@media(max-width:520px){.ftr-grid{grid-template-columns:1fr}}
.ftr h4{font-size:.79rem;text-transform:uppercase;letter-spacing:.11em;color:var(--ink-4);margin-bottom:18px;font-weight:680}
.ftr ul{list-style:none;margin:0;padding:0;display:grid;gap:11px}
.ftr a{color:var(--ink-3);font-size:.91rem;transition:color .25s}
.ftr a:hover{color:var(--blue-400)}
.ftr-brand p{color:var(--ink-3);font-size:.91rem;margin:16px 0 22px;max-width:34ch}
.socials{display:flex;gap:10px}
.socials a{
  width:39px;height:39px;border-radius:11px;display:grid;place-items:center;
  border:1px solid var(--line-2);background:var(--glass);transition:.3s var(--ease);
}
.socials a:hover{background:var(--grad);border-color:transparent;transform:translateY(-3px)}
.socials svg{width:17px;height:17px;fill:currentColor}
.ftr-btm{
  border-top:1px solid var(--line);padding-top:26px;display:flex;justify-content:space-between;
  gap:16px;flex-wrap:wrap;font-size:.85rem;color:var(--ink-4);
}

/* --- scroll reveal ------------------------------------------------------ */
.rv{opacity:0;transform:translateY(26px);transition:opacity .8s var(--ease),transform .8s var(--ease)}
.rv.in{opacity:1;transform:none}

/* App cards rise with a slight scale and a per-card stagger driven by --i,
   so a 36-card grid arrives in waves instead of all at once. */
.app.rv{transform:translateY(30px) scale(.97)}
.app.rv.in{transform:none;transition-delay:calc(var(--i,0) * 45ms)}

/* Category filtering. `display:none` is what actually removes the card from the
   grid — animating it out first would need FLIP and is not worth the weight, so
   the remaining cards re-run their entrance stagger instead (JS re-sets --i). */
.app.filtered-out{display:none}
.app-grid.filtering .app:not(.filtered-out){
  animation:cardIn .5s var(--ease) backwards;
  animation-delay:calc(var(--i,0) * 35ms);
}
@keyframes cardIn{from{opacity:0;transform:translateY(14px) scale(.97)}}
@media (prefers-reduced-motion:reduce){
  .app-grid.filtering .app:not(.filtered-out){animation:none}
}

.sr-only{
  position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;
  clip:rect(0 0 0 0);white-space:nowrap;border:0;
}
@media (prefers-reduced-motion:reduce){
  .rv{opacity:1;transform:none;transition:none}
  *,*::before,*::after{animation-duration:.001ms!important;transition-duration:.001ms!important}
}

/* --- page hero (inner pages) -------------------------------------------- */
.phead{position:relative;padding:calc(var(--nav-h) + 62px) 0 48px;overflow:hidden;text-align:center}
.phead h1{font-size:clamp(2.1rem,5vw,3.4rem);margin:22px 0 18px}
.phead .lede{margin-inline:auto}
.crumb{font-size:.83rem;color:var(--ink-4);margin-top:22px}
.crumb a{color:var(--ink-3)}
.crumb a:hover{color:var(--blue-400)}
