/* ============ Alpha IT Solutions — 3D Site ============ */
:root{
  --bg:#05060f;
  --bg-2:#0a0c1a;
  --panel:rgba(255,255,255,.04);
  --panel-brd:rgba(255,255,255,.09);
  --text:#e9ebff;
  --muted:#9095b4;
  --cyan:#22d3ee;
  --blue:#4f7cff;
  --violet:#a855f7;
  --pink:#ec4899;
  --grad:linear-gradient(100deg,#22d3ee 0%,#4f7cff 45%,#a855f7 100%);
  --glow:0 0 60px rgba(79,124,255,.35);
  --ease:cubic-bezier(.19,1,.22,1);
  --maxw:1200px;
}

*{margin:0;padding:0;box-sizing:border-box}
html{scroll-behavior:smooth}
body{
  font-family:"Inter",system-ui,sans-serif;
  background:var(--bg);
  color:var(--text);
  overflow-x:hidden;
  line-height:1.6;
  -webkit-font-smoothing:antialiased;
}
body.loading{overflow:hidden;height:100vh}
h1,h2,h3,h4,.nav__name,.hero__meta b,.stat b,.plan__price{font-family:"Space Grotesk",sans-serif;letter-spacing:-.02em}
a{color:inherit;text-decoration:none}
.grad{background:var(--grad);-webkit-background-clip:text;background-clip:text;color:transparent}

/* ============ 3D canvas ============ */
#scene{position:fixed;inset:0;width:100%;height:100%;z-index:0;display:block}
.scene-veil{
  position:fixed;inset:0;z-index:1;pointer-events:none;
  background:radial-gradient(ellipse 80% 60% at 50% 0%,transparent 40%,var(--bg) 100%),
             linear-gradient(180deg,transparent 60%,var(--bg) 100%);
}
main,.nav{position:relative;z-index:2}

/* Backdrop for when scene-boot.js skips the WebGL scene (small screens,
   reduced motion, data saver, no WebGL). Static nebula + starfield, no JS,
   no extra requests — keeps the depth without the 330 KB three.js payload. */
html.no-scene #scene{display:none}
html.no-scene body{
  background:
    radial-gradient(ellipse 70% 50% at 22% 10%,rgba(79,124,255,.17),transparent 60%),
    radial-gradient(ellipse 62% 46% at 84% 28%,rgba(168,85,247,.14),transparent 62%),
    radial-gradient(ellipse 84% 56% at 46% 96%,rgba(34,211,238,.10),transparent 60%),
    var(--bg);
  background-attachment:fixed;
}
html.no-scene .scene-veil{
  background:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='420' height='420'%3E%3Cg fill='%23fff'%3E%3Ccircle cx='31' cy='58' r='.9' opacity='.55'/%3E%3Ccircle cx='118' cy='24' r='.7' opacity='.38'/%3E%3Ccircle cx='203' cy='91' r='1' opacity='.6'/%3E%3Ccircle cx='287' cy='41' r='.7' opacity='.32'/%3E%3Ccircle cx='366' cy='109' r='.9' opacity='.5'/%3E%3Ccircle cx='74' cy='163' r='.8' opacity='.45'/%3E%3Ccircle cx='167' cy='201' r='.7' opacity='.3'/%3E%3Ccircle cx='249' cy='158' r='1' opacity='.58'/%3E%3Ccircle cx='341' cy='223' r='.7' opacity='.35'/%3E%3Ccircle cx='23' cy='268' r='.9' opacity='.52'/%3E%3Ccircle cx='131' cy='311' r='.7' opacity='.33'/%3E%3Ccircle cx='214' cy='276' r='.8' opacity='.47'/%3E%3Ccircle cx='299' cy='338' r='.9' opacity='.5'/%3E%3Ccircle cx='388' cy='291' r='.7' opacity='.3'/%3E%3Ccircle cx='58' cy='377' r='.8' opacity='.44'/%3E%3Ccircle cx='176' cy='398' r='.7' opacity='.36'/%3E%3Ccircle cx='262' cy='366' r='.9' opacity='.53'/%3E%3C/g%3E%3C/svg%3E") repeat,
    radial-gradient(ellipse 80% 60% at 50% 0%,transparent 40%,var(--bg) 100%),
    linear-gradient(180deg,transparent 60%,var(--bg) 100%);
}

/* ============ Preloader ============ */
.preloader{position:fixed;inset:0;z-index:999;background:var(--bg);display:grid;place-items:center;transition:opacity .8s var(--ease),visibility .8s}
.preloader.done{opacity:0;visibility:hidden}
.preloader__inner{text-align:center;width:min(260px,60vw)}
.preloader__logo{font-family:"Space Grotesk";font-size:56px;font-weight:700;margin-bottom:26px}
.preloader__logo span{background:var(--grad);-webkit-background-clip:text;background-clip:text;color:transparent}
.preloader__bar{height:3px;border-radius:3px;background:rgba(255,255,255,.1);overflow:hidden}
.preloader__bar span{display:block;height:100%;width:0;background:var(--grad);transition:width .3s ease}
.preloader__pct{margin-top:14px;font-size:13px;color:var(--muted);letter-spacing:.2em}

/* ============ Cursor ============ */
.cursor,.cursor-dot{position:fixed;top:0;left:0;border-radius:50%;pointer-events:none;z-index:900;mix-blend-mode:difference;translate:-50% -50%}
.cursor{width:34px;height:34px;border:1.5px solid rgba(255,255,255,.6);transition:width .25s,height .25s,background .25s}
.cursor-dot{width:5px;height:5px;background:#fff}
.cursor.hover{width:58px;height:58px;background:rgba(255,255,255,.12);border-color:transparent}
@media (hover:none){.cursor,.cursor-dot{display:none}}

/* ============ Scroll progress ============ */
.scroll-progress{position:fixed;top:0;left:0;height:3px;width:0;z-index:800;background:var(--grad);box-shadow:0 0 12px var(--cyan)}

/* ============ Nav ============ */
.nav{
  position:fixed;top:0;left:0;right:0;z-index:200;
  display:flex;align-items:center;justify-content:space-between;
  padding:22px clamp(18px,5vw,56px);transition:padding .4s var(--ease),background .4s;
}
.nav.scrolled{padding:12px clamp(18px,5vw,56px);background:rgba(6,8,18,.7);backdrop-filter:blur(18px);border-bottom:1px solid var(--panel-brd)}
.nav__brand{display:flex;align-items:center;gap:12px;font-weight:600}
.nav__mark{
  display:grid;place-items:center;width:38px;height:38px;border-radius:11px;
  font-family:"Space Grotesk";font-weight:700;font-size:20px;color:#fff;
  background:var(--grad);box-shadow:var(--glow);
}
.nav__mark i{font-style:normal;opacity:.6}
.nav__name{font-size:18px}
.nav__name b{background:var(--grad);-webkit-background-clip:text;background-clip:text;color:transparent}
.nav__links{display:flex;align-items:center;gap:34px}
.nav__links a{font-size:15px;color:var(--muted);transition:color .25s;position:relative}
.nav__links a:not(.nav__cta):after{content:"";position:absolute;left:0;bottom:-6px;width:0;height:2px;background:var(--grad);transition:width .3s var(--ease)}
.nav__links a:not(.nav__cta):hover{color:var(--text)}
.nav__links a:not(.nav__cta):hover:after{width:100%}
/* ---------- Header dropdowns ---------- */
.nav__item{position:relative}
.nav__toggle{display:inline-flex;align-items:center;gap:7px;background:none;border:0;padding:0;cursor:pointer;
  font-family:inherit;font-size:15px;font-weight:400;color:var(--muted);transition:color .25s;position:relative}
.nav__toggle:after{content:"";position:absolute;left:0;bottom:-6px;width:0;height:2px;background:var(--grad);
  transition:width .3s var(--ease)}
.nav__item:hover .nav__toggle,.nav__toggle:focus-visible,.nav__toggle[aria-expanded="true"]{color:var(--text)}
.nav__item:hover .nav__toggle:after,.nav__toggle[aria-expanded="true"]:after{width:100%}
.nav__toggle.active{color:var(--text)}
.nav__toggle.active:after{width:100%}
.nav__chev{transition:transform .32s var(--ease);opacity:.75}
.nav__item:hover .nav__chev,.nav__toggle[aria-expanded="true"] .nav__chev{transform:rotate(180deg);opacity:1}

.nav__drop{
  position:absolute;top:calc(100% + 16px);left:50%;min-width:246px;padding:9px;
  /* fully opaque: at .97 the hero text bled through the panel */
  border-radius:16px;background:#0b0e20;background-image:linear-gradient(180deg,#11152c,#0a0d1e);
  border:1px solid var(--panel-brd);
  box-shadow:0 26px 64px -22px rgba(0,0,0,.92),0 0 0 1px rgba(255,255,255,.03) inset;
  display:flex;flex-direction:column;gap:1px;z-index:220;
  opacity:0;visibility:hidden;pointer-events:none;
  transform:translateX(-50%) translateY(-10px) scale(.97);transform-origin:top center;
  transition:opacity .26s var(--ease),transform .34s var(--ease),visibility .34s}
/* invisible bridge so the pointer can cross the gap without the panel closing */
.nav__drop:before{content:"";position:absolute;left:0;right:0;top:-18px;height:18px}
.nav__item:hover .nav__drop,.nav__item:focus-within .nav__drop,.nav__drop.open{
  opacity:1;visibility:visible;pointer-events:auto;transform:translateX(-50%) translateY(0) scale(1)}
.nav__drop a{display:block;padding:11px 15px;border-radius:10px;font-size:14.6px;color:var(--muted);
  white-space:nowrap;transition:background .22s,color .22s,transform .22s var(--ease);
  opacity:0;transform:translateY(7px)}
.nav__item:hover .nav__drop a,.nav__item:focus-within .nav__drop a,.nav__drop.open a{opacity:1;transform:none}
/* stagger the items in behind the panel */
.nav__drop a:nth-child(1){transition-delay:.05s}
.nav__drop a:nth-child(2){transition-delay:.085s}
.nav__drop a:nth-child(3){transition-delay:.12s}
.nav__drop a:nth-child(4){transition-delay:.155s}
.nav__drop a:nth-child(5){transition-delay:.19s}
.nav__drop a:nth-child(6){transition-delay:.225s}
.nav__drop a:nth-child(7){transition-delay:.26s}
.nav__drop a:nth-child(8){transition-delay:.295s}
.nav__drop a:nth-child(9){transition-delay:.33s}
.nav__drop a:after{display:none}
.nav__drop a:hover{background:rgba(255,255,255,.07);color:var(--text)}
.nav__drop a.is-here{color:var(--cyan);background:rgba(34,211,238,.09)}
/* the last entry in each panel is the "all …" catch-all */
.nav__drop a:last-child{margin-top:5px;padding-top:13px;border-top:1px solid var(--panel-brd);
  border-radius:0 0 10px 10px;font-weight:600;color:var(--text)}
.nav__drop a:last-child:hover{background:rgba(255,255,255,.07)}
@media (prefers-reduced-motion:reduce){
  .nav__drop,.nav__drop a,.nav__chev{transition-duration:.01s!important;transition-delay:0s!important}
}

/* Admin access: a utility door for existing clients, so it is deliberately
   quieter than .nav__cta. Two pills of equal weight sitting side by side blunt
   the conversion path, which is what the CTA is for. */
/* The ongoing fee under each build price. Quiet on purpose: the build fee
   is still the headline number, this is the answer to "and then what?" */
.plan__care{margin:-10px 0 18px;font-size:13.5px;color:var(--muted);letter-spacing:.01em}
.rate__care{display:block;margin:2px 0 6px;font-size:13px;color:var(--muted)}
.nav__admin{
  display:inline-flex;align-items:center;gap:8px;
  padding:8px 15px;border-radius:100px;font-size:13.5px;
  color:var(--muted)!important;border:1px solid var(--panel-brd);
  transition:color .25s,border-color .25s,background .25s
}
.nav__admin .nav__lock{width:14px;height:14px;flex:0 0 auto;opacity:.9}
.nav__admin:hover{
  color:var(--text)!important;border-color:var(--cyan);
  background:rgba(255,255,255,.05)
}
/* the generic nav underline would run across the pill */
.nav__links a.nav__admin:after{display:none}
.nav__cta{padding:10px 20px;border-radius:100px;background:var(--panel);border:1px solid var(--panel-brd);color:var(--text)!important;transition:.3s}
.nav__cta:hover{background:var(--grad);border-color:transparent;box-shadow:var(--glow)}
.nav__burger{display:none;flex-direction:column;gap:6px;background:none;border:0;cursor:pointer;padding:8px}
.nav__burger span{width:26px;height:2px;background:var(--text);transition:.3s}

/* ============ Buttons ============ */
.btn{display:inline-flex;align-items:center;gap:10px;padding:15px 26px;border-radius:100px;font-weight:600;font-size:15px;cursor:pointer;border:1px solid transparent;transition:.35s var(--ease);font-family:inherit}
.btn .arr{transition:transform .35s var(--ease)}
.btn:hover .arr{transform:translateX(5px)}
.btn--primary{background:var(--grad);color:#fff;box-shadow:var(--glow)}
.btn--primary:hover{box-shadow:0 0 80px rgba(79,124,255,.6);transform:translateY(-2px)}
.btn--ghost{background:var(--panel);border-color:var(--panel-brd);color:var(--text)}
.btn--ghost:hover{background:rgba(255,255,255,.09);transform:translateY(-2px)}
.btn.full{width:100%;justify-content:center}

/* ============ Hero ============ */
.hero{min-height:100vh;display:flex;flex-direction:column;justify-content:center;align-items:center;text-align:center;padding:120px clamp(18px,5vw,56px) 60px;position:relative}
.hero__inner{max-width:920px}
.hero__badge{display:inline-flex;align-items:center;gap:9px;padding:8px 16px;border-radius:100px;background:var(--panel);border:1px solid var(--panel-brd);font-size:13.5px;color:var(--muted);margin-bottom:30px;backdrop-filter:blur(10px)}
.pulse{width:8px;height:8px;border-radius:50%;background:var(--cyan);box-shadow:0 0 0 0 var(--cyan);animation:pulse 2s infinite}
@keyframes pulse{0%{box-shadow:0 0 0 0 rgba(34,211,238,.6)}70%{box-shadow:0 0 0 10px rgba(34,211,238,0)}100%{box-shadow:0 0 0 0 rgba(34,211,238,0)}}
.hero__title{font-size:clamp(42px,8vw,92px);line-height:1.02;font-weight:700;margin-bottom:26px}
.hero__title .line{display:block;overflow:hidden}
.hero__title .line>span{display:inline-block;transform:translateY(110%);animation:riseUp 1s var(--ease) forwards}
.hero__title .line:nth-child(2)>span{animation-delay:.12s}
.hero__title .line:nth-child(3)>span{animation-delay:.24s}
@keyframes riseUp{to{transform:translateY(0)}}
.hero__sub{font-size:clamp(16px,2vw,20px);color:var(--muted);max-width:600px;margin:0 auto 38px}
.hero__actions{display:flex;gap:16px;justify-content:center;flex-wrap:wrap;margin-bottom:56px}
.hero__meta{display:flex;gap:clamp(24px,5vw,64px);justify-content:center;flex-wrap:wrap}
.hero__meta b{display:block;font-size:clamp(28px,4vw,40px);font-weight:700}
.hero__meta b span{font-size:.5em;color:var(--cyan)}
.hero__meta small{color:var(--muted);font-size:13px;letter-spacing:.04em}
.hero__scrollcue{position:absolute;bottom:28px;left:50%;translate:-50% 0;color:var(--muted);font-size:12px;letter-spacing:.3em;text-transform:uppercase;display:flex;flex-direction:column;align-items:center;gap:10px}
.hero__scrollcue span{width:22px;height:34px;border:2px solid var(--panel-brd);border-radius:20px;position:relative}
.hero__scrollcue span:after{content:"";position:absolute;top:6px;left:50%;translate:-50% 0;width:4px;height:7px;border-radius:4px;background:var(--cyan);animation:scrolldot 1.6s infinite}
@keyframes scrolldot{0%{opacity:0;top:6px}40%{opacity:1}80%{opacity:0;top:18px}100%{opacity:0}}

/* ============ Marquee ============ */
.marquee{overflow:hidden;border-top:1px solid var(--panel-brd);border-bottom:1px solid var(--panel-brd);background:rgba(255,255,255,.02);padding:20px 0}
.marquee__track{display:flex;align-items:center;gap:34px;white-space:nowrap;width:max-content;animation:scrollX 32s linear infinite}
.marquee__track span{font-family:"Space Grotesk";font-size:clamp(20px,3vw,30px);font-weight:600;color:rgba(255,255,255,.35)}
.marquee__track i{color:var(--cyan);font-style:normal}

/* ============ Sections ============ */
.section{max-width:var(--maxw);margin:0 auto;padding:clamp(80px,12vw,150px) clamp(18px,5vw,40px)}
.section__head{max-width:640px;margin:0 auto clamp(46px,7vw,72px);text-align:center}
.eyebrow{display:inline-block;font-size:13px;letter-spacing:.25em;text-transform:uppercase;color:var(--cyan);margin-bottom:18px}
.section__head h2,.about__copy h2,.contact h2{font-size:clamp(30px,5vw,52px);font-weight:700;line-height:1.1}
.section__head p{color:var(--muted);margin-top:16px;font-size:17px}

/* ============ Service cards ============ */
/* Centred flex, not a fixed 3-column grid. With 2, 4, 5 or 7 cards the grid
   left-aligned the short final row against an empty gap - the same defect the
   .quotes strip had. Cards keep their third-width; a short row now centres. */
.cards{display:flex;flex-wrap:wrap;justify-content:center;gap:20px}
.cards>.card{flex:1 1 290px;max-width:calc((100% - 40px)/3)}
.card{position:relative;padding:34px 30px;border-radius:22px;background:var(--panel);border:1px solid var(--panel-brd);overflow:hidden;transition:transform .1s linear,border-color .4s;transform-style:preserve-3d;backdrop-filter:blur(14px)}
.card:hover{border-color:rgba(79,124,255,.5)}
.card__glow{position:absolute;width:240px;height:240px;border-radius:50%;background:radial-gradient(circle,rgba(79,124,255,.35),transparent 70%);top:var(--my,50%);left:var(--mx,50%);translate:-50% -50%;opacity:0;transition:opacity .4s;pointer-events:none;filter:blur(8px)}
.card:hover .card__glow{opacity:1}
.card__icon{width:58px;height:58px;border-radius:16px;display:grid;place-items:center;color:var(--acc,#7ea8ff);
  background:linear-gradient(140deg,rgba(255,255,255,.08),rgba(255,255,255,.015));
  border:1px solid var(--panel-brd);margin-bottom:22px;transform:translateZ(40px);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.09);
  transition:border-color .35s var(--ease),box-shadow .35s var(--ease)}
.card__icon svg{width:27px;height:27px;display:block}
.card:hover .card__icon{border-color:var(--acc,#7ea8ff);box-shadow:inset 0 1px 0 rgba(255,255,255,.09),0 0 26px -6px var(--acc,#7ea8ff)}
/* One accent per card so the row reads as a considered set, not six clones. */
.cards .card:nth-child(1){--acc:#7ea8ff}
.cards .card:nth-child(2){--acc:#22d3ee}
.cards .card:nth-child(3){--acc:#8b9dff}
.cards .card:nth-child(4){--acc:#5eead4}
.cards .card:nth-child(5){--acc:#a855f7}
.cards .card:nth-child(6){--acc:#c084fc}
.card h3{font-size:22px;margin-bottom:10px;transform:translateZ(30px)}
.card p{color:var(--muted);font-size:15px;margin-bottom:18px;transform:translateZ(20px)}
.card ul{list-style:none;display:flex;flex-direction:column;gap:7px}
.card ul li{font-size:14px;color:var(--text);opacity:.85;padding-left:20px;position:relative}
.card ul li:before{content:"→";position:absolute;left:0;color:var(--cyan)}

/* /security/ stacks eight sections in a row. .svc-sec zeroes top padding for
   the services pages, which left these butting into each other, so give them
   real breathing room back on this page only. */
.security-page .svc-sec{padding-top:clamp(34px,5.5vw,64px)!important}
.security-page .section__head{margin-bottom:clamp(30px,4.5vw,48px)}
/* the control lists ran ~1100px wide, far past a comfortable measure */
.security-page .svc-sec .prose{max-width:760px;margin-inline:auto}

/* ============ Accreditations strip ============
   Centred flex, not grid: the list grows one entry at a time as certifications
   land, and auto-fit grid would strand the odd last card on the left. A short
   final row centres under the one above at any count. */
.accred{
  list-style:none;display:flex;flex-wrap:wrap;justify-content:center;gap:18px;
  max-width:1100px;margin-inline:auto
}
.accred__item{
  flex:1 1 300px;max-width:350px;display:flex;gap:16px;align-items:flex-start;
  padding:24px 22px;border-radius:18px;background:var(--panel);
  border:1px solid var(--panel-brd);backdrop-filter:blur(12px)
}
.accred__icon{
  flex:0 0 auto;width:44px;height:44px;border-radius:13px;display:grid;place-items:center;
  color:var(--cyan);background:rgba(34,211,238,.10);border:1px solid rgba(34,211,238,.22)
}
.accred__body{display:flex;flex-direction:column;gap:5px;min-width:0}
.accred__body b{font-family:"Space Grotesk",sans-serif;font-size:16px;letter-spacing:-.01em}
.accred__body>span{color:var(--muted);font-size:14px;line-height:1.5}
.accred__verify{
  color:var(--cyan);font-size:13.5px;font-weight:600;margin-top:4px;
  display:inline-flex;align-items:center;gap:6px;align-self:flex-start
}
.accred__verify:hover{text-decoration:underline}
.accred__verify .arr{transition:transform .25s var(--ease)}
.accred__verify:hover .arr{transform:translateX(3px)}

/* Official brand logos sitting in the icon tile (Google G, Trustpilot). The
   tile's cyan wash and border are dropped so a multicolour logo isn't tinted -
   altering these marks is exactly what the brand permissions forbid. */
.accred__icon:has(img){background:rgba(255,255,255,.06);border-color:rgba(255,255,255,.14)}
.accred__icon img{display:block;width:auto;height:auto;max-width:60%;max-height:60%;
  object-fit:contain}

/* Apple / Google Play store badges. Used unmodified and always as the link to a
   live listing. Apple's asset is tight to its artwork; Google's ships with its
   own mandated clear space baked in, so it is set taller and the surplus padding
   is pulled back with negative margins to keep the two optically level. */
.accred__badge{display:inline-block;align-self:flex-start;margin-top:9px;
  border-radius:8px;transition:opacity .2s,transform .2s var(--ease)}
.accred__badge img{display:block;width:auto}
.accred__badge:hover{opacity:.85;transform:translateY(-1px)}
.accred__badge:focus-visible{outline:2px solid var(--cyan);outline-offset:3px}
.accred__badge--ios img{height:42px}
.accred__badge--play img{height:69px;margin:-13px -13px -13px -12px}
.accred__badge--tp{padding:11px 0}
.accred__badge--tp img{height:22px}
@media (max-width:760px){
  .accred__item{flex-basis:100%;max-width:none}
}

/* ============ Footer credentials bar ============
   One item is shown at a time and cross-fades to the next. The keyframes are
   generated per page by _build/build_accreditations.py because their timing
   depends on how many credentials are held; only the layout lives here. */
/* Desktop shows every credential at once — a rotator hides most of them at any
   given moment, which defeats the point. It collapses to the cross-fading
   carousel only below 760px, where they will not fit side by side. */
/* ============================ CREDENTIALS RIBBON ============================
   A white ribbon in the footer instead of a flat panel, with a slow
   cloth-in-the-wind loop.

   The motion is deliberately SMALL. This band carries six clickable brand
   marks, and a big wave makes badges hard to hit and text hard to read - the
   transform stays under two degrees and most of the "wind" comes from the
   travelling fold-shadow instead. Only transform, opacity and
   background-position are animated, so it stays on the compositor and never
   triggers layout on any of the 40 pages it appears on.

   White forces two knock-on changes, both handled below: the Trustpilot mark
   switches to its dark variant (the white one would vanish), and the label,
   text and line-art icons flip from cyan to dark. The Apple and Google Play
   badges are black artwork and are designed for light backgrounds, so they
   gain contrast here rather than losing it. */
.ribbon{
  position:relative;
  /* Full bleed. The ribbon is the first child of .footer, so cancelling the
     footer's own horizontal padding runs the band edge to edge. NOT 100vw -
     that counts the scrollbar and overflows by its width. */
  margin:0 calc(-1 * clamp(18px,5vw,56px)) clamp(46px,6vw,72px)
}
.ribbon__wrap{position:relative}

/* The band stretches to whatever height the credentials need, hence
   preserveAspectRatio="none" on the SVG. Only the outline is animated, by a
   morph between five sampled phases - see _build/ribbon_art.py. */
.ribbon__band{
  position:absolute;inset:0;width:100%;height:100%;z-index:1;
  filter:drop-shadow(0 10px 24px rgba(0,0,0,.38))
}

/* Content sits clear of the ripple at every phase. Padding is px, not
   percentages: percentage padding resolves against WIDTH, and this clearance is
   a fraction of the band's HEIGHT. The edges swing by WAVE either way, so the
   top edge is at worst 25% down and the bottom at worst 79%. */
.accbar{
  position:relative;z-index:3;overflow:hidden;
  /* No cap and no side padding: the marks leave the screen on the left and come
     back in on the right, so the strip is as wide as the band. Vertical padding
     clears the ripple - px, not %, because percentage padding resolves against
     WIDTH. */
  padding:28px 0 26px;
  color:#0b1120;background:none;border:0;border-radius:0;box-shadow:none;
  /* Fade the ends. A marquee that guillotines its items at the viewport edge
     always looks unfinished; this makes the entry and exit deliberate. The band
     itself is NOT masked - only the content that travels across it. */
  -webkit-mask-image:linear-gradient(90deg,transparent 0,#000 clamp(40px,7vw,120px),
    #000 calc(100% - clamp(40px,7vw,120px)),transparent 100%);
          mask-image:linear-gradient(90deg,transparent 0,#000 clamp(40px,7vw,120px),
    #000 calc(100% - clamp(40px,7vw,120px)),transparent 100%)
}
.accbar__track{display:flex;flex-wrap:nowrap;width:max-content;will-change:transform}
.accbar__list{
  list-style:none;display:flex;flex-wrap:nowrap;align-items:center;
  gap:clamp(24px,3vw,46px);margin:0;padding:0 clamp(12px,1.5vw,23px);
  max-width:none;position:static;width:max-content
}
.accbar__item{
  position:static;opacity:1;display:flex;align-items:center;gap:11px;
  white-space:nowrap;flex:0 0 auto;will-change:transform
}
/* A dot before EVERY item, not between siblings: the marquee is several copies
   of one list, so a :not(:first-child) rule would drop the separator at each
   copy boundary and the rhythm would stutter once per cycle. */
.accbar__item::before{
  content:"";flex:0 0 auto;width:3px;height:3px;border-radius:50%;
  background:rgba(11,34,51,.3);margin-right:clamp(24px,3vw,46px)
}
.accbar__item a{display:flex;align-items:center;gap:11px}
.accbar__item a:hover b{color:#0b1120}
.accbar__item svg{color:#2b6d87;flex:0 0 auto;width:22px;height:22px}
.accbar__item b{
  font-family:"Space Grotesk",sans-serif;font-size:14px;font-weight:600;
  letter-spacing:.005em;color:#123246;transition:color .25s var(--ease)
}
.accbar__more{
  color:#3c5a70;font-size:12.5px;line-height:1;letter-spacing:.02em;
  transition:color .25s var(--ease);white-space:nowrap
}
.accbar__more:hover{color:#0b2233}

/* Official brand marks. Store badges stand ALONE - each already reads
   "Download on the App Store" / "Get it on Google Play", so pairing one with our
   own label says it twice. Both render at a 45px VISIBLE badge, clearing
   Apple's 40px floor and Google's 45px floor at matching optical height.
   Google's asset bakes in 41px of mandated clear space per side (visible
   artwork is 67.2% of the file), hence 67px against Apple's 45px, with the
   surplus pulled back by negative margins. Resize either and redo that maths. */
.accbar__badge{flex:0 0 auto;width:auto;display:block}
.accbar__badge.accred__badge--ios{height:45px;margin:-4px 0}
.accbar__badge.accred__badge--play{height:67px;margin:-15px -13px -15px -12px}
.accbar__item a:has(.accbar__badge){gap:0}
.accbar__logo{flex:0 0 auto;width:auto;height:20px;display:block}
.accbar__item a:has(.accbar__logo){gap:10px}

.accbar__more{
  color:#294055;font-size:13px;line-height:1;
  transition:color .25s var(--ease);white-space:nowrap
}
.accbar__more:hover{color:#083c50}

/* Narrow screens: smaller folds, tighter band. The band goes full width down
   here (see the carousel block below), so the tails offset OUTWARDS from it
   rather than in from the viewport edge - pinned at 2px they landed 2px inside
   the band and disappeared behind it. */



/* ============ Stats + About ============ */
.stats{display:grid;grid-template-columns:1.1fr 1fr;gap:clamp(40px,6vw,80px);align-items:center}
.stats__grid{display:grid;grid-template-columns:1fr 1fr;gap:18px}
.stat{padding:30px 26px;border-radius:20px;background:var(--panel);border:1px solid var(--panel-brd);backdrop-filter:blur(12px)}
.stat b{display:block;font-size:clamp(34px,5vw,52px);font-weight:700;background:var(--grad);-webkit-background-clip:text;background-clip:text;color:transparent;line-height:1}
.stat>span{color:var(--muted);font-size:14px;margin-top:8px;display:block}
/* Suffix inside the number (+, %, /7) — must stay on the same line as it. */
.stat b span{display:inline;font-size:.55em;margin:0;color:inherit;vertical-align:baseline}
.about__copy .eyebrow{margin-top:0}
.about__copy p{color:var(--muted);margin:18px 0 26px;font-size:17px}
.about__points{display:grid;grid-template-columns:1fr 1fr;gap:14px}
.about__points div{display:flex;align-items:center;gap:10px;font-size:15px}
.about__points i{display:grid;place-items:center;width:24px;height:24px;border-radius:8px;font-style:normal;font-size:13px;background:var(--grad);color:#fff;flex-shrink:0}

/* ============ Process ============ */
/* 3 cards, so 3 columns — a 4th column left the row hanging off to the left. */
.steps{display:grid;grid-template-columns:repeat(3,1fr);gap:22px;max-width:1040px;margin-inline:auto}
.step{padding:30px 26px;border-radius:20px;background:var(--panel);border:1px solid var(--panel-brd);position:relative;overflow:hidden;transition:transform .4s var(--ease),border-color .4s;backdrop-filter:blur(12px)}
.step:hover{transform:translateY(-8px);border-color:rgba(168,85,247,.5)}
.step__n{font-family:"Space Grotesk";font-size:46px;font-weight:700;background:var(--grad);-webkit-background-clip:text;background-clip:text;color:transparent;opacity:.9;display:block;margin-bottom:14px}
.step h3{font-size:19px;margin-bottom:8px}
.step p{color:var(--muted);font-size:14.5px}

/* ============ Pricing ============ */
.plans{display:grid;grid-template-columns:repeat(3,1fr);gap:20px;align-items:start}
.plan{position:relative;padding:38px 32px;border-radius:24px;background:var(--panel);border:1px solid var(--panel-brd);overflow:hidden;transition:transform .1s linear,border-color .4s;transform-style:preserve-3d;backdrop-filter:blur(14px)}
.plan__glow{position:absolute;inset:0;opacity:0;transition:opacity .4s;background:radial-gradient(circle at 50% 0,rgba(79,124,255,.18),transparent 60%);pointer-events:none}
.plan:hover .plan__glow{opacity:1}
.plan--featured{border-color:rgba(79,124,255,.55);box-shadow:var(--glow);background:linear-gradient(180deg,rgba(79,124,255,.08),var(--panel))}
.plan__tag{position:absolute;top:20px;right:20px;font-size:12px;padding:6px 12px;border-radius:100px;background:var(--grad);color:#fff;font-weight:600}
.plan h3{font-size:24px;margin-bottom:6px}
.plan__for{color:var(--muted);font-size:14.5px;min-height:42px;margin-bottom:18px}
.plan__price{font-size:clamp(44px,6vw,60px);font-weight:700;line-height:1;margin-bottom:24px;display:flex;align-items:baseline;gap:2px}
.plan__price span{font-size:.5em;color:var(--muted)}
.plan__price small{font-size:.28em;color:var(--muted);font-weight:500;font-family:"Inter";margin-left:6px}
.plan ul{list-style:none;margin-top:26px;display:flex;flex-direction:column;gap:12px}
.plan ul li{font-size:14.5px;color:var(--text);opacity:.9}

/* ============ Contact ============ */
.contact__card{display:grid;grid-template-columns:1fr 1fr;gap:clamp(30px,5vw,60px);padding:clamp(30px,5vw,56px);border-radius:28px;background:linear-gradient(160deg,rgba(79,124,255,.1),rgba(168,85,247,.06));border:1px solid var(--panel-brd);backdrop-filter:blur(16px);position:relative;overflow:hidden}
.contact__card:before{content:"";position:absolute;width:400px;height:400px;border-radius:50%;background:radial-gradient(circle,rgba(34,211,238,.25),transparent 70%);top:-160px;right:-120px;filter:blur(30px);pointer-events:none}
.contact__left p{color:var(--muted);margin:16px 0 28px;font-size:16px}
.contact__info{display:flex;flex-direction:column;gap:14px}
.contact__info a{display:flex;align-items:center;gap:12px;color:var(--text);font-size:15px;transition:color .25s}
.contact__info a i{display:grid;place-items:center;width:38px;height:38px;border-radius:11px;background:var(--panel);border:1px solid var(--panel-brd);font-style:normal}
.contact__info a:hover{color:var(--cyan)}
.contact__form{display:flex;flex-direction:column;gap:16px}
.field{position:relative}
.field input,.field textarea{width:100%;padding:16px 16px 16px;border-radius:13px;background:rgba(0,0,0,.25);border:1px solid var(--panel-brd);color:var(--text);font-family:inherit;font-size:15px;resize:none;transition:border-color .3s}
.field input:focus,.field textarea:focus{outline:none;border-color:var(--blue)}
.field label{position:absolute;left:16px;top:16px;color:var(--muted);pointer-events:none;transition:.25s var(--ease);font-size:15px}
.field input:focus+label,.field input:not(:placeholder-shown)+label,
.field textarea:focus+label,.field textarea:not(:placeholder-shown)+label{top:-9px;left:12px;font-size:11.5px;padding:0 6px;background:var(--bg-2);color:var(--cyan)}
.form__note{font-size:13.5px;color:var(--cyan);min-height:18px}
/* callback checkbox + expectation-setting note under the form */
.check{display:flex;align-items:flex-start;gap:11px;cursor:pointer;font-size:14.5px;color:var(--muted);
  line-height:1.5;margin:-4px 0 4px;user-select:none}
.check input{appearance:none;-webkit-appearance:none;flex:0 0 auto;width:20px;height:20px;margin:1px 0 0;
  border-radius:6px;border:1.5px solid var(--panel-brd);background:rgba(0,0,0,.25);cursor:pointer;
  transition:.25s var(--ease);position:relative}
.check input:checked{background:var(--grad);border-color:transparent}
.check input:checked:after{content:"";position:absolute;left:6.5px;top:2.5px;width:5px;height:10px;
  border:solid #fff;border-width:0 2.2px 2.2px 0;transform:rotate(45deg)}
.check input:focus-visible{outline:2px solid var(--cyan);outline-offset:2px}
.check:hover{color:var(--text)}
.form__next{font-size:13px;color:var(--muted);line-height:1.6;margin-top:2px;opacity:.85}
.send-done__next{list-style:none;text-align:left;margin:22px auto 16px;max-width:340px;display:flex;
  flex-direction:column;gap:11px}
.send-done__next li{position:relative;padding-left:24px;font-size:14.5px;color:var(--muted);line-height:1.55}
.send-done__next li:before{content:"";position:absolute;left:2px;top:8px;width:7px;height:7px;border-radius:50%;
  background:var(--grad)}
.send-done__next b{color:var(--text);font-weight:600}
.send-done__urgent{font-size:13.5px;color:var(--muted)}
.send-done__urgent a{color:var(--cyan);border-bottom:1px solid rgba(34,211,238,.4)}

/* ============ Footer ============ */
.footer{border-top:1px solid var(--panel-brd);background:rgba(5,6,15,.6);backdrop-filter:blur(10px);padding:clamp(50px,7vw,80px) clamp(18px,5vw,56px) 30px}
.footer__top{max-width:var(--maxw);margin:0 auto;display:grid;grid-template-columns:1fr 2.9fr;gap:46px}
.footer__brand{display:flex;flex-direction:column;gap:12px}
.footer__brand .nav__mark{width:44px;height:44px}
.footer__brand{align-items:flex-start}
.footer__brand p{color:var(--muted);font-size:14.5px;max-width:300px;margin-top:6px}
.footer__cols{display:grid;grid-template-columns:repeat(4,1fr);gap:24px}
@media (max-width:1100px){.footer__cols{grid-template-columns:repeat(2,1fr);gap:24px 20px}}
.footer__cols h4{font-size:15px;margin-bottom:16px}
.footer__cols a{display:block;color:var(--muted);font-size:14px;margin-bottom:10px;transition:color .25s}
.footer__cols a:hover{color:var(--text)}
.footer__bottom{max-width:var(--maxw);margin:40px auto 0;padding-top:26px;border-top:1px solid var(--panel-brd);display:flex;justify-content:space-between;flex-wrap:wrap;gap:12px;color:var(--muted);font-size:13px}

/* ============ Reveal animations ============ */
.reveal{opacity:0;transform:translateY(40px);transition:opacity .9s var(--ease),transform .9s var(--ease)}
.reveal.in{opacity:1;transform:none}

/* ============ Responsive ============ */
@media (max-width:980px){
  .steps,.plans{grid-template-columns:1fr 1fr}
  .cards>.card{max-width:calc((100% - 20px)/2)}
  .stats{grid-template-columns:1fr}
  .contact__card,.footer__top{grid-template-columns:1fr}
  /* A backdrop-filter on the header makes it the containing block for the fixed
     menu panel below it — once .scrolled kicked in, the panel collapsed to the
     height of the header strip and you saw the page through it. Solid bg instead. */
  .nav.scrolled{background:rgba(6,8,18,.94);backdrop-filter:none;-webkit-backdrop-filter:none}
  .nav:before{content:"";position:fixed;inset:0;background:rgba(3,4,10,.74);
    opacity:0;visibility:hidden;transition:opacity .45s var(--ease),visibility .45s;z-index:-1}
  .nav:has(.nav__links.open):before{opacity:1;visibility:visible}
  .nav__links{position:fixed;inset:0 0 0 auto;width:min(340px,84vw);z-index:205;
    /* flex-start + scroll, not centred: an expanded accordion is taller than the
       screen, and centring pushed the first row up under the burger. */
    flex-direction:column;justify-content:flex-start;align-items:flex-start;gap:14px;
    overflow-y:auto;overscroll-behavior:contain;
    padding:96px 34px 40px;
    background:#080a16;background-image:linear-gradient(205deg,#141a3d 0%,#0a0d20 44%,#05060f 100%);
    border-left:1px solid rgba(255,255,255,.10);box-shadow:-34px 0 70px -12px rgba(0,0,0,.8);
    transform:translateX(100%);transition:transform .45s var(--ease)}
  .nav__links.open{transform:none}
  .nav__links a{font-size:19px}
  .nav__links .nav__admin{width:100%;justify-content:center;font-size:16px;margin-top:16px}
  .nav__links .nav__cta{display:block;width:100%;text-align:center;margin-top:10px}
  /* dropdowns become accordions inside the drawer */
  .nav__item{width:100%}
  .nav__toggle{width:100%;justify-content:space-between;font-size:19px;color:var(--text);
    padding:11px 0;min-height:46px}
  .nav__toggle:after{display:none}
  .nav__chev{width:15px;height:15px}
  .nav__drop{position:static;min-width:0;padding:0;background:none;border:0;box-shadow:none;
    opacity:1;visibility:visible;pointer-events:auto;z-index:auto;
    transform:none!important;max-height:0;overflow:hidden;
    transition:max-height .4s var(--ease),padding .32s var(--ease)}
  .nav__drop:before{display:none}
  .nav__toggle[aria-expanded="true"]+.nav__drop{max-height:620px;padding:4px 0 12px}
  .nav__drop a{opacity:1;transform:none;transition-delay:0s!important;white-space:normal;
    font-size:16px;padding:11px 0 11px 17px;border-radius:0;color:var(--muted);
    border-left:2px solid var(--panel-brd);min-height:44px;display:flex;align-items:center}
  .nav__drop a:hover,.nav__drop a.is-here{background:none;border-left-color:var(--cyan);color:var(--cyan)}
  .nav__drop a:last-child{margin-top:0;padding-top:11px;border-top:0;border-radius:0}
  /* blog.css floats the language chip to the top of the drawer; it reads better last. */
  .nav__links .lang{order:1;margin-top:6px}
  .nav__burger{display:flex;z-index:210}
  .nav__burger.open span:first-child{transform:translateY(4px) rotate(45deg)}
  .nav__burger.open span:last-child{transform:translateY(-4px) rotate(-45deg)}
  /* Chat bubble sits at z-index 700, above the nav — get it out of the drawer's way. */
  body:has(.nav__links.open){overflow:hidden}
  body:has(.nav__links.open) #chatWidget{opacity:0;pointer-events:none;transition:opacity .3s}
}
@media (max-width:640px){
  .steps,.plans,.about__points,.stats__grid,.footer__cols{grid-template-columns:1fr}
  .cards>.card{max-width:100%;flex-basis:100%}
  .plan--featured{order:-1}
  .footer__bottom{flex-direction:column}
}
@media (prefers-reduced-motion:reduce){
  *{animation-duration:.001s!important;transition-duration:.001s!important}
  .hero__title .line>span{transform:none}
}

/* ============ Web design pricing row ============ */
.plans--web{margin-top:28px}
.plans--web .plan{min-height:auto}
.plans--web .plan__price{margin-bottom:8px}

/* ============ Clients / Portfolio ============ */
.client-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:14px;max-width:940px;margin:0 auto}
.client-chip{display:flex;align-items:center;gap:12px;padding:16px 20px;border-radius:14px;background:var(--panel);border:1px solid var(--panel-brd);backdrop-filter:blur(12px);transition:.35s var(--ease)}
.client-chip img{width:24px;height:24px;border-radius:6px;flex:0 0 auto}
.client-chip span{font-weight:600;font-size:15px;color:var(--text);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.client-chip:hover{transform:translateY(-5px);border-color:rgba(79,124,255,.5);box-shadow:0 18px 40px -18px rgba(79,124,255,.5)}

/* Verbatim client quotes */
/* Centered flex-wrap so ANY number of review cards balances — a short last row
   centres under the row above instead of leaving a left-aligned orphan.
   Works for 4 (2x2 / 4-up), 5 (3+2 centred), 6 (3x2), etc. */
.quotes{display:flex;flex-wrap:wrap;justify-content:center;gap:20px;margin-top:56px;max-width:1180px;margin-inline:auto}
.quote{flex:1 1 300px;max-width:360px;
  margin:0;padding:30px 28px;border-radius:20px;background:var(--panel);border:1px solid var(--panel-brd);
  backdrop-filter:blur(12px);display:flex;flex-direction:column;gap:14px;transition:border-color .4s var(--ease)}
.quote:hover{border-color:rgba(79,124,255,.45)}
.quote__stars{font-size:17px;letter-spacing:3px;color:#f5b544}
.quote blockquote{margin:0;font-size:15.5px;line-height:1.62;color:var(--text);opacity:.92}
.quote blockquote:before{content:"“";font-family:"Space Grotesk";font-size:34px;line-height:0;
  color:var(--cyan);vertical-align:-12px;margin-right:4px}
.quote figcaption{font-size:14.5px;font-weight:600;color:var(--text);margin-top:auto;display:flex;
  align-items:baseline;gap:9px;flex-wrap:wrap}
.quote figcaption span{font-weight:400;font-size:12.5px;color:var(--muted)}
@media (max-width:760px){.quotes{margin-top:40px}.quote{flex-basis:100%;max-width:none}}
.reviews{display:flex;flex-direction:column;align-items:center;gap:14px;margin-top:34px;text-align:center}
.reviews__stars{font-size:26px;letter-spacing:4px;background:var(--grad);-webkit-background-clip:text;background-clip:text;color:transparent}
.reviews__text{color:var(--muted);font-size:16px}
.reviews__text b{color:var(--text)}

/* ============ FAQ ============ */
.faq__list{max-width:820px;margin:0 auto;display:flex;flex-direction:column;gap:14px}
.faq__item{background:var(--panel);border:1px solid var(--panel-brd);border-radius:16px;padding:0 24px;backdrop-filter:blur(12px);transition:border-color .3s}
.faq__item[open]{border-color:rgba(79,124,255,.4)}
.faq__item summary{list-style:none;cursor:pointer;display:flex;justify-content:space-between;align-items:center;gap:16px;padding:22px 0;font-family:"Space Grotesk",sans-serif;font-weight:600;font-size:18px;color:var(--text)}
.faq__item summary::-webkit-details-marker{display:none}
.faq__item summary i{font-style:normal;font-size:26px;color:var(--cyan);transition:transform .3s var(--ease);flex:0 0 auto;line-height:1}
.faq__item[open] summary i{transform:rotate(45deg)}
.faq__item p{color:var(--muted);font-size:15.5px;padding:0 0 24px;max-width:70ch}

/* ============ Contact hours + footer social + disclosure ============ */
.contact__hours{display:flex;align-items:center;gap:12px;color:var(--muted);font-size:15px}
.contact__hours i{display:grid;place-items:center;width:38px;height:38px;border-radius:11px;background:var(--panel);border:1px solid var(--panel-brd);font-style:normal}
.footer__social{display:flex;gap:10px;margin-top:16px}
.footer__social a{display:grid;place-items:center;width:44px;height:44px;border-radius:11px;background:var(--panel);border:1px solid var(--panel-brd);color:var(--muted);font-weight:700;font-size:14px;transition:.3s}
.footer__social a:hover{background:var(--grad);border-color:transparent;color:#fff;transform:translateY(-3px)}
.disclosure{max-width:var(--maxw);margin:22px auto 0;padding-top:20px;border-top:1px solid var(--panel-brd);color:var(--muted);font-size:12.5px;line-height:1.7;opacity:.8}

@media (max-width:980px){ .client-grid{grid-template-columns:1fr 1fr} }
@media (max-width:640px){ .client-grid{grid-template-columns:1fr} }

/* ============================================================================
   v2 — award-caliber polish (atmosphere, readability, micro-interactions)
   ========================================================================= */

/* Readability wash + vignette so content stays crisp over the live 3D field */
body::before{
  content:"";position:fixed;inset:0;z-index:1;pointer-events:none;
  background:
    radial-gradient(ellipse 92% 72% at 50% 38%,transparent 52%,rgba(5,6,15,.6) 100%),
    linear-gradient(rgba(5,6,15,.22),rgba(5,6,15,.22));
}
/* Fine film grain over everything (very subtle) */
body::after{
  content:"";position:fixed;inset:0;z-index:6;pointer-events:none;opacity:.05;mix-blend-mode:overlay;
  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='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}
/* Soften the veil a touch so the starfield reads through it */
.scene-veil{opacity:.85}

/* Headline/body legibility over motion */
.hero__title{text-shadow:0 2px 44px rgba(0,0,0,.55)}
.hero__sub,.section__head p,.about__copy p{text-shadow:0 1px 22px rgba(5,6,15,.85)}
.section__head h2,.about__copy h2,.contact h2{text-shadow:0 2px 34px rgba(0,0,0,.5)}
.eyebrow{text-shadow:0 0 20px rgba(34,211,238,.35)}

/* Magnetic buttons feel */
.btn,.nav__cta,.nav__mark{will-change:transform}

/* Portfolio hover-reveal (Peter-Tarka-style "materialize") */
.client-chip{position:relative;overflow:hidden;padding-right:44px}
.client-chip::before{
  content:"";position:absolute;inset:0;pointer-events:none;
  background:linear-gradient(120deg,transparent 20%,rgba(255,255,255,.10),transparent 80%);
  transform:translateX(-130%);transition:transform .7s var(--ease);
}
.client-chip:hover::before{transform:translateX(130%)}
.client-chip::after{
  content:"↗";position:absolute;right:18px;top:50%;translate:0 -50%;
  color:var(--cyan);font-weight:800;font-size:16px;opacity:0;transition:.35s var(--ease);
}
.client-chip:hover::after{opacity:1}
.client-chip img{transition:transform .4s var(--ease)}
.client-chip:hover img{transform:scale(1.18) rotate(-5deg)}

/* Gradient hairline that traces featured plan + contact card */
.plan--featured::after,.contact__card::after{
  content:"";position:absolute;inset:0;border-radius:inherit;padding:1px;pointer-events:none;
  background:var(--grad);-webkit-mask:linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);
  -webkit-mask-composite:xor;mask-composite:exclude;opacity:.5;
}

/* Scrollcue + marquee sit above the wash */
.hero__scrollcue,.marquee{position:relative;z-index:2}

/* ============ Contact send: light-speed envelope animation ============ */
.hp{position:absolute!important;left:-9999px!important;width:1px;height:1px;opacity:0;pointer-events:none}
.send-overlay{position:absolute;inset:0;z-index:6;display:none;place-items:center;border-radius:inherit;overflow:hidden;
  background:radial-gradient(circle at 50% 45%,rgba(10,14,30,.86),rgba(5,6,15,.97))}
.send-overlay.active{display:grid}
/* ---- realistic 3D envelope: letter drops in, flap folds shut, then launch ---- */
.fly-envelope{position:absolute;left:50%;top:56%;translate:-50% -50%;
  perspective:700px;will-change:transform,opacity,filter;opacity:0}
.send-overlay.launch .fly-envelope{animation:envFly 2.05s cubic-bezier(.33,0,.2,1) forwards}
@keyframes envFly{
  0%  {transform:translate(0,26px) scale(.8) rotate(-4deg);opacity:0;filter:blur(0)}
  10% {transform:translate(0,0) scale(1) rotate(0);opacity:1}
  55% {transform:translate(0,0) scale(1) rotate(0);opacity:1;filter:blur(0)}      /* sealing */
  63% {transform:translate(0,16px) scale(.97) rotate(2deg);opacity:1}              /* wind-up */
  70% {transform:translate(-4px,4px) scale(1.06) rotate(-2deg);opacity:1;filter:blur(0)}
  86% {transform:translate(26vw,-30vh) scale(.5) rotate(12deg);opacity:1;filter:blur(3px)}
  100%{transform:translate(78vw,-88vh) scale(.04) rotate(20deg);opacity:0;filter:blur(9px)}
}
.env3d{position:relative;width:132px;height:86px;transform-style:preserve-3d;transform:rotateX(14deg)}
/* back panel */
.env__back{position:absolute;inset:0;border-radius:7px;
  background:linear-gradient(160deg,#1b2a52,#0e1730);border:1px solid rgba(126,156,255,.5);
  box-shadow:0 18px 40px -14px rgba(0,0,0,.8)}
/* the letter that drops inside */
.env__letter{position:absolute;left:10px;right:10px;top:-30px;height:74px;border-radius:4px;padding:11px 10px;
  background:linear-gradient(#f6f9ff,#dbe4fb);box-shadow:0 8px 18px -8px rgba(0,0,0,.7);transform-origin:50% 100%}
.env__letter i{display:block;height:3px;border-radius:3px;background:#9fb0d8;margin-bottom:7px;opacity:.85}
.env__letter i:nth-child(2){width:78%}
.env__letter i:nth-child(3){width:52%}
.send-overlay.launch .env__letter{animation:letterIn .75s cubic-bezier(.5,0,.2,1) .12s forwards}
@keyframes letterIn{0%{transform:translateY(0)}100%{transform:translateY(30px)}}
/* front body with the classic V fold */
.env__body{position:absolute;inset:0;border-radius:7px;overflow:hidden;
  background:linear-gradient(160deg,#25376a,#131e3d);border:1px solid rgba(126,156,255,.55)}
.env__body::before,.env__body::after{content:"";position:absolute;bottom:0;width:52%;height:100%;
  background:linear-gradient(150deg,rgba(255,255,255,.07),transparent 60%);}
.env__body::before{left:0;clip-path:polygon(0 100%,100% 100%,0 12%)}
.env__body::after{right:0;clip-path:polygon(100% 100%,0 100%,100% 12%)}
/* top flap folds down to seal */
.env__flap{position:absolute;left:0;right:0;top:0;height:52%;transform-origin:50% 0;
  transform:rotateX(180deg);backface-visibility:hidden;
  clip-path:polygon(0 0,100% 0,50% 100%);
  background:linear-gradient(#31477f,#1d2c56);border-top:1px solid rgba(126,156,255,.6)}
.send-overlay.launch .env__flap{animation:flapShut .5s cubic-bezier(.6,0,.3,1) .8s forwards}
@keyframes flapShut{0%{transform:rotateX(180deg)}100%{transform:rotateX(0)}}
/* thruster glow that ignites at launch */
.env__glow{position:absolute;left:50%;top:60%;width:120px;height:26px;translate:-50% -50%;border-radius:50%;
  background:radial-gradient(closest-side,rgba(34,211,238,.95),rgba(79,124,255,.5),transparent);opacity:0;filter:blur(6px)}
.send-overlay.launch .env__glow{animation:thrust .9s ease-out 1.28s forwards}
@keyframes thrust{0%{opacity:0;transform:scaleX(.3)}25%{opacity:1;transform:scaleX(1.5)}100%{opacity:0;transform:scaleX(3)}}
/* sonic-boom shockwave ring at the moment of launch */
.boom{position:absolute;left:50%;top:56%;width:40px;height:40px;translate:-50% -50%;border-radius:50%;
  border:2px solid rgba(126,200,255,.85);opacity:0}
.send-overlay.launch .boom{animation:boom .85s cubic-bezier(.2,.7,.3,1) 1.3s forwards}
@keyframes boom{0%{opacity:.9;transform:scale(.3)}70%{opacity:.25}100%{opacity:0;transform:scale(11)}}
/* hyperspace warp streaks (spans injected by JS, angle via --a) */
.warp{position:absolute;left:50%;top:56%;width:0;height:0}
.warp span{position:absolute;left:0;top:0;width:3px;height:1.6px;border-radius:2px;transform-origin:0 50%;opacity:0;
  background:linear-gradient(90deg,transparent,rgba(126,200,255,.9) 55%,#fff)}
.send-overlay.launch .warp span{animation:streak .9s cubic-bezier(.35,0,.85,.35) forwards}
@keyframes streak{
  0%{transform:rotate(var(--a)) translateX(14px) scaleX(0);opacity:0}
  20%{opacity:1}
  100%{transform:rotate(var(--a)) translateX(130vmax) scaleX(110);opacity:0}
}
/* success panel */
.send-done{position:relative;z-index:2;max-width:420px;text-align:center;padding:0 24px;opacity:0;transform:translateY(14px) scale(.94);pointer-events:none}
.send-overlay.done .send-done{animation:doneIn .7s var(--ease) forwards}
@keyframes doneIn{to{opacity:1;transform:none}}
.send-done__ring{width:74px;height:74px;margin:0 auto 20px;border-radius:50%;display:grid;place-items:center;color:#fff;
  background:radial-gradient(circle at 30% 25%,rgba(34,211,238,.35),transparent 60%),var(--grad);
  box-shadow:0 0 0 6px rgba(34,211,238,.12),0 18px 50px -12px rgba(79,124,255,.7)}
.send-overlay.done .send-done__ring{animation:ringPop .6s var(--ease) .05s both}
@keyframes ringPop{0%{transform:scale(.4);opacity:0}60%{transform:scale(1.12)}100%{transform:scale(1);opacity:1}}
.send-done h3{font-family:"Space Grotesk";font-size:clamp(22px,3vw,28px);font-weight:700;margin-bottom:10px}
.send-done p{color:var(--muted);font-size:15.5px}
@media (prefers-reduced-motion:reduce){
  .send-overlay.launch .fly-envelope,.send-overlay.launch .warp span{animation-duration:.001s}
  .send-done{transition:opacity .3s}.send-overlay.done .send-done{animation:none;opacity:1;transform:none}
}

/* Nav scroll-spy active state */
.nav__links a.active:not(.nav__cta){color:var(--text)}
.nav__links a.active:not(.nav__cta):after{width:100%}

/* Mobile touch targets on the homepage chrome (matches blog.css rules) */
@media (max-width:768px){
  .footer__cols a{display:flex;align-items:center;min-height:44px;padding:13px 2px;font-size:14px;line-height:1.35;box-sizing:border-box}
  .footer__social a{width:48px;height:48px}
  .nav__burger{padding:12px;min-width:46px;min-height:46px;align-items:center;justify-content:center}
  .hero__actions .btn,.article__cta-actions .btn{min-height:48px}
  .btn{min-height:46px}
  .field input,.field textarea,.contact__form select{font-size:16px}  /* stops iOS zoom-on-focus */
}

/* Brand logo images (preloader / nav / footer) */
.preloader__logo{margin-bottom:26px}
.preloader__logo img{width:min(250px,64vw);height:auto;display:block;margin:0 auto;filter:drop-shadow(0 14px 55px rgba(34,211,238,.22))}
.preloader__tagline{font-family:"Space Grotesk",sans-serif;font-size:clamp(14px,2.4vw,18px);font-weight:500;
  letter-spacing:.16em;text-transform:uppercase;color:var(--muted);margin:-6px 0 24px;white-space:nowrap;
  opacity:0;animation:tagIn 1.1s var(--ease) .35s forwards}
@keyframes tagIn{0%{opacity:0;transform:translateY(10px);letter-spacing:.34em}100%{opacity:1;transform:none;letter-spacing:.16em}}
.nav__logo{height:54px;width:auto;display:block;filter:drop-shadow(0 4px 16px rgba(34,211,238,.3));transition:height .4s var(--ease)}
.nav.scrolled .nav__logo{height:44px}
@media (max-width:600px){.nav__logo{height:46px}}
.footer__logo{width:180px;max-width:62vw;height:auto;display:block;margin-bottom:6px}

/* Footer legal / utility links bar */
.footer__legal{max-width:var(--maxw);margin:26px auto 0;display:flex;flex-wrap:wrap;gap:20px;justify-content:center}
.footer__legal a{color:var(--muted);font-size:13.5px;transition:color .25s}
.footer__legal a:hover{color:var(--cyan)}

@media (prefers-reduced-motion:reduce){
  body::after{display:none}
}

/* ---- Cookie consent bar (analytics.js injects this) ---------------------- */
.cbar{position:fixed;left:16px;right:16px;bottom:16px;z-index:900;
  display:flex;align-items:center;gap:18px;flex-wrap:wrap;justify-content:space-between;
  max-width:1040px;margin-inline:auto;padding:18px 22px;
  background:#080a16;border:1px solid var(--panel-brd);border-radius:18px;
  box-shadow:0 18px 50px rgba(0,0,0,.55);
  opacity:0;transform:translateY(14px);transition:opacity .35s var(--ease),transform .35s var(--ease)}
.cbar.in{opacity:1;transform:none}
.cbar__txt{font-size:14px;line-height:1.6;color:var(--muted);margin:0;flex:1 1 420px}
.cbar__txt a{color:var(--cyan)}
.cbar__btns{display:flex;gap:10px;flex-shrink:0}
.cbar__btn{min-height:44px;padding:0 20px;border-radius:999px;font:inherit;font-size:14px;
  font-weight:600;cursor:pointer;border:1px solid var(--panel-brd);transition:filter .2s}
.cbar__btn--no{background:transparent;color:var(--text)}
.cbar__btn--yes{background:var(--grad);color:#fff;border-color:transparent}
.cbar__btn:hover{filter:brightness(1.15)}
/* The banner is transient, the chat FAB is not — hide the FAB while a choice is
   pending rather than let a z-900 panel sit on top of it. Same precedent as the
   open nav drawer hiding it. */
body:has(.cbar) #chatWidget{display:none}

@media (max-width:760px){
  /* bottom must clear the sticky call bar (fixed, ~69px tall, z-690). Covering
     it would hide the phone CTA on exactly the first visit an ad click lands. */
  .cbar{left:10px;right:10px;bottom:82px;padding:16px;gap:12px}
  .cbar__btns{width:100%}
  .cbar__btn{flex:1}
}
@media (prefers-reduced-motion:reduce){
  .cbar{transition:none;opacity:1;transform:none}
}

/* == portal-shots:start == */
/* Portal screenshots on /services/managed-it-support/ and /pricing/. Images carry
   width/height so the reserved box is correct before they load - the galleries sit
   mid-article and would otherwise shove the rest of the page down on every decode.

   These are dense UI screenshots, so they break out of the 80ch .legal prose column
   to the full section width. At 808px the helpdesk table was unreadable.

   minmax(0,1fr) and min-width:0 are load-bearing: a grid item defaults to
   min-width:auto, so on mobile the 1500px-wide image refused to shrink and blew
   the column out to 1502px instead of turning the frame into a scroller. */
.shots,.shots__note{position:relative;left:50%;transform:translateX(-50%);
  width:min(1120px, calc(100vw - 2*clamp(18px,5vw,40px)))}
.shots{margin:30px 0 0;display:grid;grid-template-columns:minmax(0,1fr);gap:34px}
.shots figure{margin:0;min-width:0;position:relative}
.shots__frame{border-radius:12px;border:1px solid var(--panel-brd);background:#0b1120;
  box-shadow:0 18px 44px rgba(0,0,0,.38);overflow:hidden}
.shots img{width:100%;height:auto;display:block}
.shots figcaption{margin-top:12px;max-width:78ch;font-size:14.5px;line-height:1.65;
  color:var(--muted)}
.shots figcaption b{color:var(--text);font-weight:600}
.shots__hint{display:none}

/* Zoom affordance. Sits on the figure, not inside the frame, so it does not scroll
   away when the frame pans. Always visible on touch, hover-revealed on pointers. */
.shots__zoom{position:absolute;top:12px;right:12px;z-index:2;display:inline-flex;
  align-items:center;gap:6px;min-height:34px;padding:0 13px;border-radius:999px;
  border:1px solid rgba(255,255,255,.16);background:rgba(8,11,24,.82);color:#fff;
  font:600 12.5px/1 Inter,system-ui,sans-serif;letter-spacing:.02em;cursor:zoom-in;
  backdrop-filter:blur(6px);opacity:.72;
  transition:opacity .22s,background .22s,border-color .22s}
.shots__zoom::before{content:"";width:13px;height:13px;flex:none;
  background:currentColor;-webkit-mask:var(--zi) center/contain no-repeat;
  mask:var(--zi) center/contain no-repeat;
  --zi:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23fff' stroke-width='2' stroke-linecap='round'%3E%3Ccircle cx='11' cy='11' r='7'/%3E%3Cpath d='M20 20l-3.5-3.5M11 8v6M8 11h6'/%3E%3C/svg%3E")}
.shots figure:hover .shots__zoom,.shots__zoom:focus-visible{opacity:1}
.shots__zoom:hover{background:rgba(8,11,24,.95);border-color:rgba(255,255,255,.3)}
.shots__frame img{cursor:zoom-in}

.shots__note{margin:34px 0 0;padding:16px 18px;border:1px solid var(--panel-brd);
  border-left:3px solid var(--cyan);border-radius:10px;background:rgba(255,255,255,.03);
  font-size:14.5px;line-height:1.7;color:var(--muted)}
.shots__note strong{color:var(--text)}

/* Lightbox. z-index sits above the chat FAB (700) and the mobile call bar (690). */
.lb{position:fixed;inset:0;z-index:1200;display:flex;flex-direction:column;
  background:rgba(4,6,14,.94);backdrop-filter:blur(8px);animation:lb-in .22s var(--ease)}
.lb[hidden]{display:none}
@keyframes lb-in{from{opacity:0}to{opacity:1}}
.lb__bar{flex:none;display:flex;align-items:center;gap:14px;
  padding:12px clamp(12px,3vw,22px);border-bottom:1px solid rgba(255,255,255,.09)}
.lb__cap{flex:1;min-width:0;font:600 14px/1.4 Inter,system-ui,sans-serif;color:#fff;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.lb__btn{flex:none;min-height:40px;padding:0 15px;border-radius:999px;
  border:1px solid rgba(255,255,255,.18);background:rgba(255,255,255,.06);color:#fff;
  font:600 13px/1 Inter,system-ui,sans-serif;cursor:pointer;transition:background .2s}
.lb__btn:hover{background:rgba(255,255,255,.14)}
.lb__btn[hidden]{display:none}
.lb--nozoom .lb__stage img{cursor:default}
.lb__x{flex:none;width:40px;height:40px;border-radius:50%;
  border:1px solid rgba(255,255,255,.18);background:rgba(255,255,255,.06);color:#fff;
  font:400 22px/1 Inter,system-ui,sans-serif;cursor:pointer;transition:background .2s}
.lb__x:hover{background:rgba(255,255,255,.14)}
.lb__stage{flex:1;min-height:0;overflow:auto;display:grid;place-items:center;
  padding:clamp(10px,2.5vw,26px);overscroll-behavior:contain}
.lb__stage img{display:block;max-width:100%;max-height:100%;border-radius:8px;
  border:1px solid rgba(255,255,255,.12);cursor:zoom-in}
.lb.is-zoomed .lb__stage{place-items:start}
.lb.is-zoomed .lb__stage img{max-width:none;max-height:none;cursor:grab}
.lb.is-zoomed .lb__stage img.is-dragging{cursor:grabbing}
@media(max-width:600px){.lb__cap{white-space:normal;font-size:12.5px;
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical}}

/* A 1500px dashboard squeezed into a narrow column is a smear of coloured dots -
   it reads as decoration rather than evidence. Below 900px, where the fitted
   image would drop under ~820px, let each frame scroll sideways at natural size
   instead. The caption sits outside the scroller so it stays put. */
@media(max-width:900px){
  .shots__frame{max-width:100%;overflow-x:auto;overflow-y:hidden;
    -webkit-overflow-scrolling:touch;overscroll-behavior-x:contain}
  .shots__frame img{width:auto;max-width:none}
  .shots__hint{display:block;margin:26px 0 -8px;font-size:13.5px;color:var(--muted)}
}
@media(prefers-reduced-motion:reduce){.lb{animation:none}}
/* == portal-shots:end == */
