:root{--bg:#0a0d1c;--bg2:#12162a;--bg3:#181d36;--text:#e9ecff;--muted:#8b93b8;--accent:#ff3d8a;--accent2:#e0296f;--cyan:#7df9ff;--border:#242a48;--max:1100px;--head:Rajdhani,"IBM Plex Sans",system-ui,sans-serif;--body:"IBM Plex Sans",system-ui,-apple-system,"Segoe UI",sans-serif}
*{box-sizing:border-box}html{scroll-behavior:smooth}
body{margin:0;font-family:var(--body);background:var(--bg);color:var(--text);line-height:1.6;-webkit-font-smoothing:antialiased}
a{color:var(--cyan)}
h1,h2,h3{font-family:var(--head);line-height:1.05;margin:0 0 .5em;font-weight:700;text-transform:uppercase;letter-spacing:.02em;text-wrap:balance}
h1{font-size:clamp(2.4rem,6vw,4.4rem)}h2{font-size:clamp(1.7rem,3.6vw,2.6rem)}h3{font-size:1.35rem}
h1 em{font-style:normal;color:var(--accent)}
p{margin:0 0 1em}
.nav{position:sticky;top:0;z-index:10;display:flex;justify-content:space-between;align-items:center;padding:.9rem 1.5rem;background:rgba(10,13,28,.85);backdrop-filter:blur(10px);border-bottom:1px solid var(--border)}
.brand{display:flex;align-items:center;color:var(--text);text-decoration:none;flex:0 1 auto;min-width:0}.brand svg{height:34px;width:auto;max-width:100%;display:block}
.menu-btn{display:none;flex:0 0 auto;width:42px;height:42px;border-radius:8px;border:1px solid var(--border);background:var(--bg3);color:var(--text);font-size:1.15rem;line-height:1;cursor:pointer;place-items:center}
.menu-btn:hover{border-color:var(--cyan);color:var(--cyan)}
.menu-btn:focus-visible{outline:2px solid var(--cyan);outline-offset:2px}
.nav nav{display:flex;gap:1.25rem;align-items:center}.nav nav a{color:var(--muted);text-decoration:none;font-weight:500;font-size:.95rem}.nav nav a:hover,.nav nav a.active{color:var(--text)}
.btn{display:inline-block;background:var(--accent);color:var(--bg)!important;font-weight:700;padding:.85rem 1.5rem;border-radius:6px;text-decoration:none;border:0;cursor:pointer;font-size:1rem;font-family:var(--body)}
.btn:hover{background:var(--accent2)}.btn-sm{padding:.5rem 1rem;font-size:.9rem}
.btn-ghost{background:transparent;color:var(--cyan)!important;border:1px solid var(--cyan)}.btn-ghost:hover{background:rgba(125,249,255,.08)}
.hero{position:relative;overflow:hidden;background:linear-gradient(180deg,var(--bg) 0,#141a3a 100%);border-bottom:1px solid var(--border)}
.hero::after{content:"";position:absolute;inset:auto 0 0 0;height:110px;background:repeating-linear-gradient(90deg,transparent 0 46px,#2a3270 46px 48px);-webkit-mask:linear-gradient(180deg,transparent,#000);mask:linear-gradient(180deg,transparent,#000);opacity:.55;pointer-events:none}
.hero-in{max-width:var(--max);margin:0 auto;padding:6rem 1.5rem 6rem;position:relative;z-index:1}
.lead{font-size:1.15rem;color:var(--muted);max-width:60ch}
.standout{font-family:var(--head);font-weight:700;text-transform:uppercase;letter-spacing:.01em;font-size:clamp(1.3rem,2.8vw,2rem);line-height:1.15;color:var(--accent);max-width:26ch;margin:0 0 2rem}
.eyebrow{text-transform:uppercase;letter-spacing:.16em;font-size:.75rem;font-weight:600;color:var(--cyan);margin:0 0 1rem;font-family:var(--head);font-size:.9rem}
.cta-row{display:flex;gap:1rem;flex-wrap:wrap;margin-top:2rem}
.section{max-width:var(--max);margin:0 auto;padding:4.5rem 1.5rem}
.section.alt{max-width:none;background:var(--bg2);border-top:1px solid var(--border);border-bottom:1px solid var(--border)}
.section.alt>*{max-width:var(--max);margin-left:auto;margin-right:auto}
.section-head{display:grid;grid-template-columns:1fr 1fr;gap:2rem;align-items:end;margin-bottom:2rem}
.section-head h2{margin-bottom:0}.section-head .eyebrow{color:var(--cyan);margin-bottom:.6rem}
.section-head p{color:var(--muted);margin:0}
@media(max-width:800px){.section-head{grid-template-columns:1fr}}
.grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(270px,1fr));gap:1.25rem}
.grid.two{grid-template-columns:repeat(auto-fit,minmax(320px,1fr))}
.grid.four{grid-template-columns:repeat(auto-fit,minmax(230px,1fr))}
.card{background:var(--bg3);border:1px solid var(--border);border-radius:10px;padding:1.5rem}
.section.alt .card{background:var(--bg)}
.card p{color:var(--muted);margin:0}.card h3{margin-bottom:.4rem}
.card .price{font-family:var(--head);font-size:2.2rem;font-weight:700;color:var(--text);line-height:1;margin:.5rem 0 .25rem}
.card .price small{font-size:1rem;color:var(--muted);font-weight:500;text-transform:none;letter-spacing:0}
.card.featured{border-color:var(--accent);box-shadow:0 0 0 1px var(--accent) inset, 0 0 40px rgba(255,61,138,.15)}
.tag{display:inline-block;font-family:var(--head);text-transform:uppercase;letter-spacing:.1em;font-size:.75rem;font-weight:700;color:var(--accent);border:1px solid var(--accent);border-radius:4px;padding:.15rem .5rem;margin-bottom:.75rem}
.tag.cyan{color:var(--cyan);border-color:var(--cyan)}
.ticks{list-style:none;padding:0;margin:.75rem 0 0}.ticks li{padding-left:1.5rem;position:relative;margin:.45rem 0;color:var(--muted)}.ticks li::before{content:"";position:absolute;left:0;top:.65em;width:10px;height:2px;background:var(--cyan)}
.fine{font-size:.85rem;color:var(--muted);margin-top:1rem}
.card .fine{margin-top:1rem}.card .fine+.fine{margin-top:.75rem}
.steps{counter-reset:s;list-style:none;padding:0;margin:0;display:grid;grid-template-columns:repeat(auto-fit,minmax(220px,1fr));gap:1.5rem}
.steps li{counter-increment:s;color:var(--muted);padding-top:2.6rem;position:relative;border-top:1px solid var(--border)}.steps li strong{color:var(--text);font-family:var(--head);text-transform:uppercase;font-size:1.1rem;letter-spacing:.03em}
.steps li::before{content:counter(s,decimal-leading-zero);position:absolute;top:.6rem;left:0;color:var(--accent);font-weight:700;font-size:1.1rem;font-family:var(--head)}
.split{display:grid;grid-template-columns:1fr 1fr;gap:3rem;align-items:start}
@media(min-width:801px){.split.offset>:last-child{padding-top:7.5rem}}
@media(max-width:800px){.split{grid-template-columns:1fr}}
.case{display:grid;grid-template-columns:1.2fr 1fr;gap:2rem;align-items:center;border:1px solid var(--border);border-radius:14px;padding:1.5rem;background:var(--bg2)}
.case-media a,.case-media .placeholder{display:block;position:relative;border-radius:8px;overflow:hidden;border:1px solid var(--border);aspect-ratio:16/10;background:var(--bg3)}
.case-media img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;object-position:top center;display:block}
.case-media .placeholder::after{content:attr(data-label);display:flex;align-items:center;justify-content:center;height:100%;color:var(--muted);font-family:var(--head);font-weight:700;font-size:1.6rem;text-transform:uppercase;letter-spacing:.05em}
.case-body p{color:var(--muted)}
.tags{list-style:none;padding:0;margin:1rem 0 0;display:flex;flex-wrap:wrap;gap:.5rem}.tags li{font-size:.78rem;padding:.3rem .7rem;border:1px solid var(--border);border-radius:4px;color:var(--muted)}
.callout{background:linear-gradient(135deg,#2a1230,var(--bg));border:1px solid #4a1f3f;border-radius:14px;padding:2.5rem;margin:2rem auto}
.callout p{color:var(--muted);max-width:60ch}
.form{display:grid;gap:1rem;max-width:560px;margin-top:1.5rem}.form label{display:grid;gap:.4rem;font-weight:500;font-size:.9rem}
.form input,.form textarea,.form select{font:inherit;padding:.8rem;border-radius:6px;border:1px solid var(--border);background:var(--bg2);color:var(--text)}
.form input:focus,.form textarea:focus,.form select:focus{outline:2px solid var(--cyan);border-color:transparent}
.form fieldset{border:1px solid var(--border);border-radius:6px;padding:.75rem 1rem;margin:0}.form legend{font-size:.85rem;color:var(--muted);padding:0 .4rem}
.form .radio{display:flex;gap:1.5rem;flex-wrap:wrap}.form .radio label{display:flex;align-items:center;gap:.5rem;font-weight:400}
.form input[type=file]{padding:.6rem;cursor:pointer;color:var(--muted)}
.form input[type=file]::file-selector-button{font:inherit;font-weight:600;margin-right:.75rem;padding:.4rem .8rem;border-radius:4px;border:1px solid var(--border);background:var(--bg3);color:var(--text);cursor:pointer}
.form input[type=file]::file-selector-button:hover{border-color:var(--cyan);color:var(--cyan)}
.form .hint{font-size:.8rem;color:var(--muted);font-weight:400}
.muted{color:var(--muted);font-size:.95rem}
footer{border-top:1px solid var(--border);padding:2.5rem 1.5rem;color:var(--muted);font-size:.9rem}
footer .in{max-width:var(--max);margin:0 auto;display:flex;justify-content:space-between;gap:1rem;flex-wrap:wrap;align-items:center}
footer nav{display:flex;gap:1rem}footer nav a{color:var(--muted);text-decoration:none}footer nav a:hover{color:var(--text)}
@media(max-width:820px){
  .case{grid-template-columns:1fr}
  .hero-in{padding:4rem 1.5rem 5rem}
  .nav{flex-wrap:wrap;gap:.75rem}
  .menu-btn{display:grid}
  .nav nav{display:none;flex-basis:100%;flex-direction:column;align-items:stretch;gap:0;margin:0;padding-top:.5rem;border-top:1px solid var(--border)}
  .nav nav.open{display:flex}
  .nav nav a{padding:.75rem .25rem}
  .nav nav a.btn{margin:.5rem 0 .25rem;text-align:center}
}
@media(prefers-reduced-motion:reduce){html{scroll-behavior:auto}}

/* ---- carousel ---- */
.carousel{position:relative}
.carousel .track{display:flex;overflow-x:auto;scroll-snap-type:x mandatory;scroll-behavior:smooth;gap:1.25rem;padding-bottom:.5rem;scrollbar-width:none}
.carousel .track::-webkit-scrollbar{display:none}
.carousel .slide{flex:0 0 100%;scroll-snap-align:start}
.carousel .controls{display:flex;align-items:center;gap:.75rem;margin-top:1.25rem}
.carousel button.nav-btn{width:40px;height:40px;border-radius:50%;border:1px solid var(--border);background:var(--bg3);color:var(--text);font:inherit;font-size:1.1rem;line-height:1;cursor:pointer;display:grid;place-items:center}
.carousel button.nav-btn:hover{border-color:var(--cyan);color:var(--cyan)}
.carousel button.nav-btn:focus-visible{outline:2px solid var(--cyan);outline-offset:2px}
.carousel .dots{display:flex;gap:.5rem;margin-left:.25rem}
.carousel .dots button{width:9px;height:9px;padding:0;border-radius:50%;border:1px solid var(--border);background:transparent;cursor:pointer}
.carousel .dots button[aria-current="true"]{background:var(--accent);border-color:var(--accent)}
.carousel .dots button:focus-visible{outline:2px solid var(--cyan);outline-offset:2px}
.carousel .count{margin-left:auto;font-size:.85rem;color:var(--muted);font-variant-numeric:tabular-nums}
@media(prefers-reduced-motion:reduce){.carousel .track{scroll-behavior:auto}}

/* ---- motion -------------------------------------------------------------
   Arrival: the rev counter sweeps up as the page loads, then the hero rises
   in behind it. Sections fade up as they come into view.
   The needle sits at ~49deg from the pivot and the dial starts at 180deg, so
   -130deg parks it at the bottom of the sweep before it climbs. ---------- */
.brand svg{overflow:visible}
.brand svg .dial-needle,
.brand svg .dial-arc,
.brand svg .dial,
.brand svg .dial-word{transform-box:view-box}
/* Arrival: the dial comes in oversized and shrinks into place while it revs,
   and the wordmark only appears once it has settled. Scaled about the needle
   pivot so it collapses into the right spot rather than drifting. */
.brand svg .dial{transform-origin:26px 34px;animation:dial-land 2.9s .2s cubic-bezier(.2,.85,.25,1) both}
.brand svg .dial-word{transform-origin:58px 32px;animation:word-in 2.2s .55s cubic-bezier(.1,.82,.22,1) both}
/* Grows in, holds oversized while it revs, then drops into place. Starting
   big meant there was nothing to watch: it was simply large, then small.
   The peak is capped: the dial's radius is 20 and its pivot sits about 48px
   below the top of the header, so anything past ~2.4 clips off the page. */
@keyframes dial-land{
  0%{transform:scale(.2);opacity:0}
  12%{opacity:1}
  22%{transform:scale(2.25)}
  32%{transform:scale(2.05)}
  80%{transform:scale(2.05)}
  93%{transform:scale(.94)}
  100%{transform:scale(1)}
}
/* Arrives at speed from the right while the dial is revving, overshoots its
   resting position, then rocks back and settles: a car braking hard, not a
   label sliding into place. Stretched horizontally at the start so the entry
   carries some weight. */
/* Arrives from the left under braking, then shakes in sympathy with the
   needle: each time the needle slams into the limiter the wordmark is knocked
   to the right, and it comes back as the needle rebounds. The peak percentages
   line up with the peaks in dial-sweep, allowing for the two animations'
   different delays and durations. */
@keyframes word-in{
  0%{opacity:0;transform:translateX(-260px) scaleX(1.18)}
  12%{opacity:1}
  24%{transform:translateX(16px) scaleX(1)}
  28%{transform:translateX(-4px)}
  31.5%{transform:translateX(5px)}
  36.4%{transform:translateX(0)}
  41.3%{transform:translateX(4.5px)}
  44.9%{transform:translateX(0)}
  48.5%{transform:translateX(4px)}
  52.1%{transform:translateX(0)}
  55.7%{transform:translateX(3.5px)}
  59.3%{transform:translateX(0)}
  62.9%{transform:translateX(3px)}
  66.5%{transform:translateX(0)}
  70%{transform:translateX(2.5px)}
  73.6%{transform:translateX(0)}
  77.3%{transform:translateX(2px)}
  80.8%{transform:translateX(0)}
  84.4%{transform:translateX(1.5px)}
  88%{transform:translateX(0)}
  91.6%{transform:translateX(1px)}
  95.2%{transform:translateX(0)}
  98.8%{transform:translateX(.5px)}
  100%{opacity:1;transform:none}
}
.brand svg .dial-needle{transform-origin:26px 34px;animation:dial-sweep 2.9s .2s cubic-bezier(.2,.85,.25,1) both}
.brand svg .dial-arc{stroke-dasharray:42;stroke-dashoffset:42;animation:dial-fill 2.9s .2s cubic-bezier(.2,.85,.25,1) both}
.brand svg .dial-pin{animation:dial-pin .6s .2s ease-out both}
.brand{cursor:pointer}
/* Two bounces off the limiter before it settles, so the sweep reads as a rev
   rather than a slide. Slow enough to be seen after the page has painted. */
/* Redline. The dial sweeps 180deg and the needle rests at about 49deg from its
   pivot, so the limiter sits at rotate(14deg), the peak this already used.
   The needle climbs to it, then chatters against it ten times with the motor
   shoving it back down, each bounce shallower than the last, before dropping
   to its resting position. */
@keyframes dial-sweep{
  0%,14%{transform:rotate(-130deg)}
  36%{transform:rotate(14deg)}
  40.7%{transform:rotate(5deg)}
  43.4%{transform:rotate(14deg)}
  46.2%{transform:rotate(6.2deg)}
  48.9%{transform:rotate(14deg)}
  51.6%{transform:rotate(7.3deg)}
  54.3%{transform:rotate(14deg)}
  57.1%{transform:rotate(8.2deg)}
  59.8%{transform:rotate(14deg)}
  62.5%{transform:rotate(9deg)}
  65.2%{transform:rotate(14deg)}
  68%{transform:rotate(9.7deg)}
  70.7%{transform:rotate(14deg)}
  73.4%{transform:rotate(10.4deg)}
  76.1%{transform:rotate(14deg)}
  78.9%{transform:rotate(11deg)}
  81.6%{transform:rotate(14deg)}
  84.3%{transform:rotate(11.6deg)}
  87%{transform:rotate(13.6deg)}
  94%{transform:rotate(-4deg)}
  100%{transform:rotate(0)}
}
@keyframes dial-fill{0%,14%{stroke-dashoffset:42}36%{stroke-dashoffset:0}100%{stroke-dashoffset:0}}
@keyframes dial-pin{0%{opacity:0}100%{opacity:1}}

/* Hero entrance, staggered behind the dial. */
.hero-in>*{animation:rise .42s cubic-bezier(.2,.8,.2,1) both}
.hero-in>*:nth-child(1){animation-delay:.05s}
.hero-in>*:nth-child(2){animation-delay:.11s}
.hero-in>*:nth-child(3){animation-delay:.17s}
.hero-in>*:nth-child(4){animation-delay:.23s}
.hero-in>*:nth-child(5){animation-delay:.29s}
/* Short travel and a fast, decisive ease. A long opacity ramp reads as the
   page still loading; a quick one reads as the page arriving. */
@keyframes rise{0%{opacity:0;transform:translateY(10px)}100%{opacity:1;transform:none}}

/* Scroll-linked reveals.
   Tied to scroll position rather than a timer, so the motion advances as you
   scroll down and reverses as you scroll up. A timed fade that fires on a
   trigger looks like content loading no matter how fast it is; motion that
   tracks the scrollbar visibly belongs to the reader.

   Everything is visible by default. The animation only exists inside the
   @supports block, so a browser without scroll timelines shows a normal static
   page rather than a broken one. */
@supports (animation-timeline: view()){
  @media (prefers-reduced-motion: no-preference){
    .section>*{
      animation:slide-in linear both;
      animation-timeline:view();
      animation-range:entry 2% cover 20%;
    }
    /* The grid itself stays put so its columns can arrive one at a time. */
    .section>.grid{animation:none}
    .grid>*{
      animation:slide-in linear both;
      animation-timeline:view();
    }
    /* Staggered ranges, not delays: each column is driven by how far the
       section has travelled, so they arrive left to right and leave right to
       left on the way back up. */
    .grid>*:nth-child(1){animation-range:entry 0% cover 16%}
    .grid>*:nth-child(2){animation-range:entry 9% cover 25%}
    .grid>*:nth-child(3){animation-range:entry 18% cover 34%}
    .grid>*:nth-child(4){animation-range:entry 27% cover 43%}
  }
}
/* Long travel and a little scale, so a column visibly moves across rather
   than just brightening. Blur does the heavy lifting: it reads as depth of
   field rather than as something failing to load. */
/* Blur and opacity resolve by two thirds of the way through; only the last of
   the travel is left after that. Carrying the blur to 100% meant a column
   could still be soft by the time it was being read. */
@keyframes slide-in{
  0%{opacity:0;transform:translate3d(-90px,0,0) scale(.94);filter:blur(7px)}
  45%{opacity:1}
  66%{filter:blur(0)}
  100%{opacity:1;transform:none;filter:blur(0)}
}

/* Buttons and cards lift a little on hover, on pointers that can hover. */
@media(hover:hover){
  .btn{transition:transform .18s ease,box-shadow .18s ease}
  .btn:hover{transform:translateY(-2px)}
  .card{transition:transform .25s ease,border-color .25s ease}
  .card:hover{transform:translateY(-3px);border-color:var(--cyan)}
}

@media(prefers-reduced-motion:reduce){
  .brand svg .dial-needle,.brand svg .dial-arc,.brand svg .dial-pin,.brand svg .dial,.brand svg .dial-word,.hero-in>*{animation:none}
  .brand svg .dial-arc{stroke-dashoffset:0}
  .reveal-ready,.reveal-ready.stagger>*{opacity:1;transform:none;transition:none}
  @media(hover:hover){.btn:hover,.card:hover{transform:none}}
}
