/* ═══════════════════════════════════════════════════════════
   CEP MARKET — Kayseri / Hunat Çarşısı
   Palette: obsidian + electric blue + copper
   iOS-Safari-first: transform/opacity only, gradient glows
   (no animated filters), svh units, cached viewport metrics.
   ═══════════════════════════════════════════════════════════ */

:root{
  --bg:#07080B;
  --bg-2:#0A0C11;
  --panel:#0D1017;
  --ink:#F2F4F8;
  --ink-2:#A6AEBF;
  --ink-3:#6B7386;
  --blue:#2E6BFF;
  --blue-2:#6E9BFF;
  --cop:#D08A57;
  --cop-2:#EDB98C;
  --line:rgba(255,255,255,.075);
  --line-2:rgba(255,255,255,.14);

  --d:cubic-bezier(.22,1,.28,1);
  --d2:cubic-bezier(.65,0,.35,1);

  --pad:clamp(20px,5vw,80px);
  --max:1320px;
}

*,*::before,*::after{box-sizing:border-box}

html{
  -webkit-text-size-adjust:100%;
  text-size-adjust:100%;
  scroll-behavior:smooth;
}
@media (prefers-reduced-motion:reduce){html{scroll-behavior:auto}}

body{
  margin:0;
  background:var(--bg);
  color:var(--ink);
  font-family:"Inter Tight",system-ui,-apple-system,"Segoe UI",sans-serif;
  font-size:16px;
  line-height:1.55;
  -webkit-font-smoothing:antialiased;
  -moz-osx-font-smoothing:grayscale;
  overflow-x:hidden;
  overscroll-behavior-y:none;
  -webkit-tap-highlight-color:transparent;
}
body.lock{overflow:hidden;height:100%}

img,svg,canvas{display:block;max-width:100%}
a{color:inherit;text-decoration:none}
button{font:inherit}

::selection{background:var(--blue);color:#fff}

/* ── Type primitives ───────────────────────────────────── */
.eyebrow{
  display:flex;align-items:center;gap:14px;
  margin:0 0 clamp(20px,3vw,34px);
  font-size:11px;font-weight:600;letter-spacing:.22em;
  color:var(--ink-3);text-transform:uppercase;
}
.eyebrow__line{
  display:block;width:clamp(28px,5vw,56px);height:1px;
  background:linear-gradient(90deg,var(--cop),transparent);
  flex:none;
}

h1,h2,h3,h4{
  font-family:Archivo,system-ui,sans-serif;
  font-weight:700;
  letter-spacing:-.03em;
  line-height:.98;
  margin:0;
  font-variation-settings:"wdth" 105;
}
em{
  font-family:"Instrument Serif",Georgia,serif;
  font-style:italic;
  font-weight:400;
  letter-spacing:-.01em;
  color:var(--cop-2);
  font-variation-settings:normal;
}

.sec__h2{
  font-size:clamp(32px,6.4vw,74px);
  max-width:20ch;
}

/* ── Buttons ───────────────────────────────────────────── */
.btn{
  position:relative;
  display:inline-flex;align-items:center;gap:10px;
  height:52px;padding:0 26px;
  border-radius:100px;
  font-size:14.5px;font-weight:600;letter-spacing:-.01em;
  white-space:nowrap;
  transform:translate3d(0,0,0);
  transition:transform .5s var(--d),background-color .35s,border-color .35s,color .35s;
  overflow:hidden;
}
.btn svg{width:16px;height:16px;flex:none;fill:none;stroke:currentColor;stroke-width:1.7;stroke-linecap:round;stroke-linejoin:round;transition:transform .5s var(--d)}
.btn span{position:relative;z-index:1}
.btn--lg{height:58px;padding:0 32px;font-size:15.5px}

/* The handset is a solid silhouette, not an outline like the arrow, so it
   needs the opposite paint. It also leads its label rather than trailing
   it — a phone number reads as a number, and the glyph in front is what
   tells you at a glance that tapping it dials. */
.btn__tel{fill:currentColor!important;stroke:none!important;order:-1}

.btn--p{
  background:var(--ink);color:#06070A;
  box-shadow:0 1px 0 rgba(255,255,255,.5) inset;
}
.btn--g{
  border:1px solid var(--line-2);color:var(--ink);
  background:rgba(255,255,255,.02);
}
@media (hover:hover){
  .btn:hover{transform:translate3d(0,-2px,0)}
  /* The trailing arrow leads on hover wherever it appears; the handset
     stays put, since a phone icon sliding sideways reads as an error. */
  .btn:hover svg:not(.btn__tel){transform:translate3d(4px,0,0)}
  .btn--g:hover{border-color:rgba(255,255,255,.32);background:rgba(255,255,255,.055)}
}
.btn:active{transform:translate3d(0,0,0) scale(.975)}

/* ═══════════ PRELOADER ═══════════ */
.pre{
  position:fixed;inset:0;z-index:200;
  background:var(--bg);
  display:flex;align-items:flex-end;
  padding:var(--pad);
  transition:opacity .7s var(--d2),visibility .7s;
}
.pre.done{opacity:0;visibility:hidden;pointer-events:none}
.pre__inner{width:100%;max-width:var(--max);margin:0 auto}
.pre__mark{
  font-family:Archivo,sans-serif;font-weight:800;
  font-size:clamp(30px,7vw,64px);letter-spacing:-.04em;line-height:1;
  font-variation-settings:"wdth" 112;
}
.pre__mark span{color:var(--ink-3);font-weight:400}
.pre__meta{
  display:flex;justify-content:space-between;align-items:baseline;
  margin:22px 0 12px;
  font-size:11px;letter-spacing:.2em;color:var(--ink-3);font-weight:600;
}
.pre__num{font-family:Archivo,sans-serif;font-size:13px;color:var(--ink)}
.pre__bar{height:1px;background:var(--line);overflow:hidden}
.pre__bar i{
  display:block;height:100%;width:100%;
  background:linear-gradient(90deg,var(--cop),var(--blue-2));
  transform:scaleX(0);transform-origin:0 50%;
  transition:transform .25s linear;
}

/* ═══════════ NAV ═══════════ */
.nav{
  position:fixed;top:0;left:0;right:0;z-index:100;
  display:flex;align-items:center;justify-content:space-between;
  gap:20px;
  padding:16px var(--pad);
  padding-top:max(16px,env(safe-area-inset-top));
  transition:transform .55s var(--d),background-color .45s,border-color .45s;
  border-bottom:1px solid transparent;
  transform:translate3d(0,0,0);
}
/* Mobile: opaque fill, NO backdrop-filter. Allocating a backdrop
   layer mid-scroll costs WebKit one ~300ms frame, and .solid
   toggles exactly when the user starts scrolling. Desktop has the
   headroom, phones do not. */
.nav.solid{
  background:rgba(7,8,11,.93);
  border-bottom-color:var(--line);
}
@media (min-width:861px){
  .nav.solid{
    background:rgba(7,8,11,.72);
    -webkit-backdrop-filter:saturate(160%) blur(18px);
    backdrop-filter:saturate(160%) blur(18px);
  }
}
.nav.hide{transform:translate3d(0,-110%,0)}

.nav__logo{display:flex;align-items:center;gap:10px;font-weight:600;font-size:15px;letter-spacing:-.02em}
.nav__logo svg{width:17px;height:17px;fill:none;stroke:var(--cop-2);stroke-width:1.5;stroke-linecap:round}

.nav__links{display:flex;gap:30px}
.nav__links a{
  position:relative;font-size:13.5px;color:var(--ink-2);
  transition:color .3s;
}
.nav__links a::after{
  content:"";position:absolute;left:0;right:0;bottom:-5px;height:1px;
  background:var(--cop);
  transform:scaleX(0);transform-origin:0 50%;
  transition:transform .45s var(--d);
}
@media (hover:hover){
  .nav__links a:hover{color:var(--ink)}
  .nav__links a:hover::after{transform:scaleX(1)}
}

/* Calling is the primary action on the whole site, so the one CTA that is
   on screen at every scroll position is filled, not the ghost pill it used
   to be. Someone standing in the çarşı with a cracked screen wants a voice,
   not a chat thread they have to wait on. */
.nav__cta{
  display:inline-flex;align-items:center;gap:8px;
  height:38px;padding:0 18px;border-radius:100px;
  border:1px solid transparent;
  font-size:13px;font-weight:650;letter-spacing:-.01em;
  color:#06070A;
  background:var(--ink);
  box-shadow:0 1px 0 rgba(255,255,255,.55) inset,
             0 8px 22px -12px rgba(150,180,255,.85);
  transition:transform .45s var(--d),box-shadow .35s;
}
.nav__cta-i{
  width:14px;height:14px;flex:none;fill:currentColor;
  transform-origin:62% 62%;
  /* A short ring near the end of a long cycle: visible in peripheral
     vision, and rare enough that it never turns into decoration.
     Transform-only, so it costs nothing on iOS. */
  animation:ringTilt 5.2s var(--d) infinite;
}
@keyframes ringTilt{
  0%,70%,100%{transform:rotate(0)}
  75%{transform:rotate(-14deg)}
  81%{transform:rotate(11deg)}
  87%{transform:rotate(-6deg)}
  93%{transform:rotate(3deg)}
}
@media (hover:hover){
  .nav__cta:hover{
    transform:translate3d(0,-1px,0);
    box-shadow:0 1px 0 rgba(255,255,255,.55) inset,
               0 12px 26px -12px rgba(150,180,255,1);
  }
}
.nav__cta:active{transform:translate3d(0,0,0) scale(.97)}

@media (max-width:860px){
  .nav__links{display:none}
}

/* ═══════════ HERO ═══════════ */
.hero{
  position:relative;
  /* svh, deliberately NOT dvh. dvh tracks the iOS address bar, so the
     hero would resize mid-scroll — that resizes the canvas and shifts
     every scroll-driven value with it. svh is stable for the whole
     session; the extra strip revealed when the bar collapses is fine. */
  min-height:100svh;
  display:flex;flex-direction:column;justify-content:flex-end;
  /* Top padding must clear the fixed nav. With justify-content:flex-end
     it costs nothing when the content fits — flex-end just bottom-aligns
     inside the padded box. But on a short screen (iPhone SE, 568px) the
     stack IS taller than the viewport, and with padding-top:0 it
     overflowed upward and slid under the nav. */
  padding:calc(max(16px,env(safe-area-inset-top)) + 62px) var(--pad) clamp(38px,7vh,86px);
  overflow:hidden;
  isolation:isolate;
}
@supports not (min-height:100svh){.hero{min-height:calc(var(--vh,1vh) * 100)}}

/* iPhone SE class. Reclaim enough vertical space that the hero still
   resolves within one screen rather than pushing the fold down. Measured
   at 320x568: the stack overflowed the viewport by 11px AND had no room
   for the in-flow eyebrow (17px + margin), so ~40px had to come back.
   The savings below total ~62px, which also restores real breathing room
   rather than only just fitting. */
@media (max-height:600px) and (max-width:430px){
  .hero{padding-bottom:26px}
  .eyebrow--hero{margin-bottom:12px}
  .hero__h1{font-size:33px}
  .hero__sub{font-size:13px;line-height:1.5;margin-bottom:20px}
  .hero__act{gap:9px;margin-bottom:18px}
  .hero__act .btn{height:46px;padding:0 20px;font-size:13px}
}

.hero__canvas{
  position:absolute;inset:0;width:100%;height:100%;
  z-index:-2;
  opacity:0;
  transition:opacity 1.4s var(--d2);
}
.hero__canvas.on{opacity:1}

/* Gradient vignette — replaces expensive blur filters (iOS perf) */
.hero__vig{
  position:absolute;inset:0;z-index:-1;pointer-events:none;
  background:
    radial-gradient(120% 70% at 50% 6%, rgba(46,107,255,.16) 0%, transparent 62%),
    radial-gradient(70% 50% at 88% 30%, rgba(208,138,87,.10) 0%, transparent 65%),
    linear-gradient(180deg, rgba(7,8,11,.35) 0%, rgba(7,8,11,0) 26%, rgba(7,8,11,.72) 74%, var(--bg) 100%);
}

/* Mobile: the copy takes the bottom ~45% of a phone hero, so the scrim
   must bite far earlier or the device's lower contour runs straight
   through the body text. Losing the cloud's bottom third is a gain, not
   a cost — it reads as the device emerging from the dark. Static
   painted layer, so this adds nothing per frame. */
@media (max-width:860px){
  .hero__vig{
    background:
      radial-gradient(130% 58% at 50% 4%, rgba(46,107,255,.18) 0%, transparent 60%),
      radial-gradient(80% 42% at 62% 20%, rgba(208,138,87,.11) 0%, transparent 66%),
      linear-gradient(180deg,
        rgba(7,8,11,.32) 0%,
        rgba(7,8,11,0) 17%,
        rgba(7,8,11,.55) 42%,
        rgba(7,8,11,.93) 62%,
        var(--bg) 78%);
  }
}

/* Short screens: the copy starts ~110px down, so the scrim has to be
   effectively opaque by then or the object's contour crosses the
   headline. Ramps roughly twice as early as the rule above. */
@media (max-height:600px) and (max-width:430px){
  .hero__vig{
    background:
      radial-gradient(130% 40% at 50% 2%, rgba(46,107,255,.20) 0%, transparent 62%),
      linear-gradient(180deg,
        rgba(7,8,11,.30) 0%,
        rgba(7,8,11,.06) 10%,
        rgba(7,8,11,.72) 22%,
        rgba(7,8,11,.96) 34%,
        var(--bg) 46%);
  }
}

.hero__grid{position:relative;width:100%;max-width:var(--max);margin:0 auto}

/* The wireframe's chassis contour crosses this band at most phone heights,
   and at 11px/.22em the eyebrow has no weight to survive a line drawn
   through its letters. The scrim travels with the element, which a
   percentage stop in .hero__vig cannot: the eyebrow is pinned in px, so
   its position as a fraction of the hero changes on every screen. */
.eyebrow--hero{position:relative}
@media (max-width:860px){
  .eyebrow--hero::before{
    content:'';position:absolute;z-index:-1;pointer-events:none;
    left:-7%;right:-7%;top:-150%;bottom:-150%;
    background:radial-gradient(58% 48% at 38% 50%,
      rgba(7,8,11,.92) 0%, rgba(7,8,11,.66) 44%, rgba(7,8,11,0) 78%);
  }
}

/* Mobile composition. The copy is bottom-justified, which left the upper
   two-thirds of the hero reading as an accident rather than as space held
   open for the 3D object. Lifting the eyebrow to the top crowns that
   space, so the gap becomes a stage with a caption above it and the
   headline below. It leaves flow (position:absolute), so the copy stack
   below is untouched — .hero__grid drops to static purely so the eyebrow
   anchors to .hero's full height instead of the bottom-aligned grid.

   Gated on min-height:601px. Measured: at 375x600 the pinned eyebrow
   still clears the headline by 100px, but at 320x568 the bottom-aligned
   stack is already 11px TALLER than the viewport, so its top edge rises
   to y=78 and the pinned eyebrow at y=92 lands inside the headline. On a
   screen that short there is no stage to crown, so the eyebrow stays in
   flow where it cannot collide. Complements the max-height:600px block. */
@media (max-width:860px) and (min-height:601px){
  .hero__grid{position:static}
  .eyebrow--hero{
    position:absolute;
    top:calc(max(16px,env(safe-area-inset-top)) + 76px);
    left:var(--pad);right:var(--pad);
    margin:0;
    z-index:2;
  }
  .eyebrow--hero .eyebrow__line{width:34px}
}

.hero__h1{
  font-size:clamp(43px,10.4vw,138px);
  letter-spacing:-.045em;
  line-height:.92;
  font-variation-settings:"wdth" 100;
  margin:0 0 clamp(22px,3.4vw,36px);
}
.hero__h1 .l{display:block;overflow:hidden}
.hero__h1 .l>span{display:block;transform:translate3d(0,110%,0)}
.hero__h1 em{font-size:1.04em}

.hero__sub{
  max-width:44ch;margin:0 0 clamp(28px,4vw,42px);
  font-size:clamp(15px,1.75vw,19.5px);
  line-height:1.6;color:var(--ink-2);
}
.hero__act{display:flex;flex-wrap:wrap;gap:12px;margin-bottom:clamp(34px,5vw,54px)}

.hero__foot{display:flex;align-items:center;gap:14px;flex-wrap:wrap}
.stars{display:flex;gap:3px}
.stars svg{width:13px;height:13px;fill:var(--cop-2)}
.hero__foot p{
  margin:0;font-size:12.5px;color:var(--ink-2);
  display:flex;align-items:center;gap:10px;flex-wrap:wrap;
}
.hero__foot p span{
  font-size:10.5px;letter-spacing:.14em;text-transform:uppercase;
  color:var(--ink-3);padding-left:10px;border-left:1px solid var(--line-2);
}
/* Under ~370px the source label wraps to its own line and the divider rule
   goes with it, leaving a stray vertical tick hanging at the start of the
   line. Nothing separates two stacked lines, so the rule just goes. */
@media (max-width:370px){
  .hero__foot p span{padding-left:0;border-left:0}
}

.hero__cue{
  position:absolute;right:var(--pad);bottom:clamp(38px,7vh,86px);
  display:flex;flex-direction:column;align-items:center;gap:12px;
  font-size:9.5px;letter-spacing:.24em;color:var(--ink-3);font-weight:600;
}
.hero__cue span{writing-mode:vertical-rl}
.hero__cue i{
  display:block;width:1px;height:52px;
  background:linear-gradient(180deg,var(--line-2),transparent);
  position:relative;overflow:hidden;
}
.hero__cue i::after{
  content:"";position:absolute;top:0;left:0;width:1px;height:16px;
  background:var(--cop-2);
  animation:cue 2.2s var(--d2) infinite;
}
@keyframes cue{0%{transform:translateY(-18px)}70%,100%{transform:translateY(54px)}}
@media (max-width:860px){.hero__cue{display:none}}

/* ═══════════ MARQUEE ═══════════ */
.mq{
  position:relative;
  padding:clamp(22px,3vw,32px) 0;
  border-top:1px solid var(--line);
  border-bottom:1px solid var(--line);
  overflow:hidden;
  background:var(--bg-2);
}
.mq__row{display:flex;width:max-content;will-change:transform;transform:translate3d(0,0,0)}
.mq__set{
  display:flex;align-items:center;gap:clamp(28px,4vw,54px);
  padding-right:clamp(28px,4vw,54px);
  font-family:Archivo,sans-serif;
  font-size:clamp(19px,2.6vw,32px);font-weight:500;
  letter-spacing:-.02em;color:var(--ink-3);
  font-variation-settings:"wdth" 96;
  flex:none;
}
.mq__set i{font-size:.4em;color:var(--cop);font-style:normal;transform:translateY(-.15em)}

/* ═══════════ SECTION SHELL ═══════════ */
.sec{
  position:relative;
  max-width:var(--max);
  margin:0 auto;
  padding:clamp(88px,13vw,180px) var(--pad);
}
.sec__head{margin-bottom:clamp(46px,7vw,86px)}
.sec__head--c{text-align:center}
.sec__head--c .eyebrow{justify-content:center}
.sec__head--c .sec__h2{margin-inline:auto}

/* ═══════════ SCROLL-SCRUB 3D DEVICE ═══════════ */
.scrub{position:relative;height:340svh}
@supports not (height:340svh){.scrub{height:calc(var(--vh,1vh) * 340)}}

.scrub__stick{
  position:sticky;top:0;
  height:100svh;          /* stable — see .hero note on svh vs dvh */
  overflow:hidden;
}
@supports not (height:100svh){.scrub__stick{height:calc(var(--vh,1vh) * 100)}}

.scrub__stage{
  position:relative;
  height:100%;
  max-width:var(--max);
  margin:0 auto;
  padding:0 var(--pad);
  display:flex;align-items:center;
}

/* Device — CSS 3D, transform-only (iOS friendly) */
.dev{
  position:absolute;
  right:max(var(--pad),6%);
  top:50%;
  /* Width lives in a custom property because the status bar has to scale
     with the body, and a second hard-coded clamp would have drifted from
     this one the first time either was touched. */
  --devW:clamp(190px,20vw,272px);
  width:var(--devW);
  font-size:max(5px,calc(var(--devW) * .034));
  /* 163.4 × 77.6 mm — the 6.9" Pro Max body, not a generic 2:1 slab. */
  aspect-ratio:77.6/163.4;
  transform:translate3d(0,-50%,0);
  perspective:1200px;
  -webkit-perspective:1200px;
  z-index:2;
}
.dev__glow{
  position:absolute;inset:-46% -70%;
  background:radial-gradient(50% 46% at 50% 50%, rgba(46,107,255,.34) 0%, rgba(46,107,255,.06) 45%, transparent 72%);
  pointer-events:none;
}
.dev__body{
  position:relative;width:100%;height:100%;
  transform-style:preserve-3d;
  -webkit-transform-style:preserve-3d;
  transform:rotateY(0deg) rotateX(0deg);
  backface-visibility:hidden;
  -webkit-backface-visibility:hidden;
}
/* Corner radius is quoted against WIDTH on both axes (the `/` form), so it
   stays a true circular corner at 148px on a phone and 272px on a desktop.
   A fixed 30px read as a bubble at the small end and as a hard edge at the
   large end — one of the things that made this look like a cheap render. */
.dev__side{
  position:absolute;inset:0;
  border-radius:12.8%/6.08%;
  background:linear-gradient(105deg,#2A2F3A,#12151C 42%,#0A0C11 68%,#23283242);
  transform:translate3d(0,0,-13px);
  box-shadow:0 0 0 1px rgba(255,255,255,.06);
}
/* Side buttons. At ±27° of yaw one rail is always exposed, and a bare slab
   there is exactly what makes a mockup read as a rectangle rather than a
   phone. Three hard gradient stops on one element give the 17 Pro's left
   rail — action button, volume up, volume down — with no extra DOM. */
.dev__side::before{
  content:'';position:absolute;left:-2px;top:18%;width:2px;height:23%;
  border-radius:3px;
  background:linear-gradient(180deg,
    #313848 0 24%, transparent 24% 37%,
    #313848 37% 66%, transparent 66% 77%,
    #313848 77% 100%);
}
.dev__side::after{
  content:'';position:absolute;right:-2px;top:26%;width:2px;height:12%;
  border-radius:3px;background:#313848;
}
.dev__screen{
  position:absolute;inset:0;
  border-radius:12.8%/6.08%;
  /* 1.5 mm of bezel on a 77.6 mm body = 1.93% of width. Percentage padding
     resolves against width on all four sides, which is precisely what a
     uniform flagship bezel is — the old flat 6px was 2.2% at desktop size
     but 4% on mobile, and that asymmetry is what read as an old phone. */
  padding:1.93%;
  background:linear-gradient(150deg,rgba(255,255,255,.19),rgba(255,255,255,.03) 34%,rgba(255,255,255,.01) 62%,rgba(255,255,255,.13));
  box-shadow:
    0 30px 70px -18px rgba(0,0,0,.85),
    0 0 0 1px rgba(255,255,255,.05);
  overflow:hidden;
}
.dev__sheen{
  position:absolute;top:-40%;left:-60%;width:90%;height:190%;
  background:linear-gradient(90deg,transparent,rgba(255,255,255,.10) 45%,rgba(255,255,255,.16) 52%,transparent);
  transform:rotate(16deg) translate3d(0,0,0);
  pointer-events:none;z-index:3;
}
/* Outer radius minus the bezel, re-expressed against the inner box:
   (12.8% − 1.93%) / (100% − 3.86%) = 11.3% horizontally, and the same
   absolute value over the inner height = 5.27%. */
.dev__ui{
  position:relative;height:100%;border-radius:11.3%/5.27%;
  background:
    radial-gradient(90% 60% at 50% 0%, rgba(46,107,255,.24), transparent 66%),
    linear-gradient(180deg,#0B0E15,#06080C);
  padding:26px 18px 20px;
  display:flex;flex-direction:column;
  overflow:hidden;
}
/* Dynamic Island, not a notch bar. The sensor housing is 125 × 37 pt — a
   3.4:1 stadium. The old 32%-wide, 5px-tall strip was 16:1, and a pill that
   thin is the single loudest "this is not a current iPhone" signal on the
   whole mockup. aspect-ratio keeps the 3.4:1 at every width, and top is a
   percentage of the screen height so it hugs the top edge at any size. */
.dev__island{
  position:absolute;top:1.3%;left:50%;
  width:28.5%;aspect-ratio:125/37;
  border-radius:100px;
  background:#020305;
  box-shadow:0 0 0 .5px rgba(255,255,255,.05);
  transform:translateX(-50%);
}
/* Status bar. The upper two thirds of the glass were an empty gradient at
   desktop size; a clock and a signal cluster flanking the Island is the
   most recognisable thing a current iPhone has, so it fills that band with
   something that earns its place instead of decoration. Sized in em off
   --devW, so it holds its proportion from 108px to 272px wide. */
.dev__status{
  position:absolute;top:1.3%;left:8%;right:8%;
  height:2.4em;
  display:flex;align-items:center;justify-content:space-between;
  font-size:1em;font-weight:650;letter-spacing:.01em;
  color:rgba(233,238,248,.88);
  pointer-events:none;
}
.dev__ind{width:auto;height:.82em;fill:currentColor;flex:none}
.dev__val{margin-top:auto}
.dev__val small{
  display:block;font-size:8px;letter-spacing:.2em;color:var(--ink-3);
  margin-bottom:6px;font-weight:600;
}
.dev__val strong{
  display:block;
  font-family:Archivo,sans-serif;font-weight:700;
  font-size:clamp(19px,2.1vw,26px);letter-spacing:-.04em;
  line-height:1.06;
  font-variation-settings:"wdth" 100;
}
.dev__val strong b{font-weight:inherit;color:var(--cop-2)}
.dev__rows{display:flex;flex-direction:column;gap:7px;margin-top:18px}
.dev__rows i{
  display:block;height:5px;border-radius:100px;width:var(--w);
  background:linear-gradient(90deg,rgba(110,155,255,.55),rgba(110,155,255,.07));
}

/* Panes */
/* Every .pane is absolutely positioned, so this container has NO
   content to size against. Without an explicit width it collapses to
   0 as a flex item and the copy wraps one word per line. */
.scrub__panes{
  position:relative;z-index:3;
  width:min(50%,560px);
  flex:0 0 auto;
}
@media (max-width:900px){.scrub__panes{width:auto}}

.pane{
  position:absolute;top:50%;left:0;right:0;
  transform:translate3d(0,-50%,0);
  opacity:0;visibility:hidden;
  transition:opacity .55s var(--d2),visibility .55s;
}
.pane.on{opacity:1;visibility:visible}
.pane__ix{
  display:block;
  font-family:Archivo,sans-serif;font-size:11px;font-weight:700;
  letter-spacing:.2em;color:var(--cop);margin-bottom:20px;
}
.pane h2{
  font-size:clamp(30px,5.4vw,62px);
  margin-bottom:clamp(16px,2vw,24px);
}
.pane p{
  margin:0;max-width:40ch;
  font-size:clamp(14.5px,1.6vw,17.5px);
  line-height:1.62;color:var(--ink-2);
}

.scrub__prog{
  position:absolute;left:var(--pad);right:var(--pad);bottom:clamp(30px,6vh,58px);
  height:1px;background:var(--line);
}
.scrub__prog i{
  display:block;height:100%;
  background:linear-gradient(90deg,var(--cop),var(--blue-2));
  transform:scaleX(0);transform-origin:0 50%;
}

/* Mobile scrub. The old version put the device in flow at the top and
   absolutely pinned the pane rail to the bottom of the sticky stage —
   two independent anchors, so on a short viewport the device's lower
   third landed on top of the headline and on a tall one they were 132px
   apart. Both now live in ONE centred flex column, so the gap between
   them is a single `gap` value that can't collide or drift. */
@media (max-width:900px){
  .scrub{height:300svh}
  @supports not (height:300svh){.scrub{height:calc(var(--vh,1vh) * 300)}}
  .scrub__stage{
    flex-direction:column;
    align-items:stretch;
    justify-content:center;
    gap:clamp(18px,3.4vh,34px);
    padding:calc(max(16px,env(safe-area-inset-top)) + 74px) var(--pad) clamp(56px,10vh,88px);
  }
  /* Sized by HEIGHT, not width: the stage is height-constrained on a
     phone, and aspect-ratio derives the width from it. */
  .dev{
    position:relative;right:auto;top:auto;
    transform:translate3d(0,0,0);
    height:min(40svh,300px);width:auto;
    /* Height drives width here, so --devW has to be back-derived from it or
       the status bar keeps sizing off the desktop clamp. 163.4/77.6. */
    --devW:calc(min(40svh,300px) / 2.106);
    margin:0 auto;
    /* Explicit, because align-items:stretch would otherwise blow an
       auto-width flex item out to the full column and let aspect-ratio
       recompute the height from that instead of the other way round. */
    align-self:center;
    flex:0 0 auto;
  }
  @supports not (height:40svh){
    .dev{
      height:min(calc(var(--vh,1vh) * 40),300px);
      --devW:calc(min(calc(var(--vh,1vh) * 40),300px) / 2.106);
    }
  }
  /* Panes stay absolutely stacked so a swap can never nudge the device,
     but the rail reserves the tallest pane's height (--paneH, measured in
     JS) so it still occupies real space in the column. */
  .scrub__panes{
    position:relative;left:auto;right:auto;bottom:auto;
    width:auto;max-width:100%;
    flex:0 0 auto;
    min-height:var(--paneH,196px);
  }
  .pane{position:absolute;top:0;bottom:auto;transform:translate3d(0,0,0)}
  .pane__ix{margin-bottom:12px}
  .pane h2{font-size:clamp(29px,8.2vw,44px);margin-bottom:14px}
  .pane p{max-width:34ch}
}

/* iPhone SE class — same reclamation as the hero. */
@media (max-height:620px) and (max-width:430px){
  .scrub__stage{
    padding-top:calc(max(16px,env(safe-area-inset-top)) + 64px);
    padding-bottom:40px;
    gap:15px;
  }
  .pane h2{font-size:27px;margin-bottom:11px}
  .pane p{font-size:13.5px;line-height:1.55}
  .pane__ix{margin-bottom:8px}
}

/* ═══════════ SERVICES ═══════════ */
.svc__grid{
  display:grid;
  grid-template-columns:repeat(auto-fit,minmax(258px,1fr));
  gap:clamp(14px,1.6vw,20px);
}
.card{
  position:relative;
  padding:clamp(26px,2.6vw,36px);
  border-radius:20px;
  border:1px solid var(--line);
  background:linear-gradient(165deg,rgba(255,255,255,.038),rgba(255,255,255,.008));
  overflow:hidden;
  transform:translate3d(0,0,0);
  transition:border-color .5s,background-color .5s;
}
.card::before{
  content:"";position:absolute;inset:0;
  background:radial-gradient(60% 45% at 50% 0%, rgba(46,107,255,.16), transparent 70%);
  opacity:0;transition:opacity .6s var(--d2);pointer-events:none;
}
.card__ic{
  width:46px;height:46px;border-radius:13px;
  display:grid;place-items:center;
  border:1px solid var(--line-2);
  background:rgba(255,255,255,.03);
  margin-bottom:clamp(28px,3.4vw,44px);
}
.card__ic svg{
  width:22px;height:22px;fill:none;
  stroke:var(--cop-2);stroke-width:1.4;
  stroke-linecap:round;stroke-linejoin:round;
}
.card h3{
  font-size:clamp(19px,2vw,23px);letter-spacing:-.025em;
  margin-bottom:10px;line-height:1.15;
}
.card p{
  margin:0 0 22px;font-size:14.5px;line-height:1.6;color:var(--ink-2);
}
.card__k{
  display:inline-block;font-size:10.5px;letter-spacing:.14em;
  text-transform:uppercase;color:var(--ink-3);
  padding-top:16px;border-top:1px solid var(--line);width:100%;
}
@media (hover:hover){
  .card:hover{border-color:var(--line-2)}
  .card:hover::before{opacity:1}
}

/* ═══════════ 3D RING CAROUSEL ═══════════ */
.acc{padding-bottom:clamp(60px,9vw,120px)}
.ring__wrap{
  position:relative;
  height:clamp(300px,42vw,430px);
  perspective:1150px;
  -webkit-perspective:1150px;
  touch-action:pan-y;
  /* The ring is ~2.4x an item wide by construction, so it always
     exceeds a phone viewport. Clip here or it inflates
     document.scrollWidth and the whole page scrolls sideways.
     Safe: .ring__wrap only carries `perspective`, not
     `preserve-3d`, so clipping does not flatten the scene. */
  overflow:hidden;
}
.ring{
  position:absolute;top:50%;left:50%;
  width:clamp(180px,20vw,236px);
  height:clamp(112px,12vw,140px);
  margin:calc(clamp(112px,12vw,140px) / -2) 0 0 calc(clamp(180px,20vw,236px) / -2);
  transform-style:preserve-3d;
  -webkit-transform-style:preserve-3d;
  transform:translate3d(0,0,0) rotateX(-7deg) rotateY(0deg);
  cursor:grab;
  touch-action:pan-y;
}
.ring.drag{cursor:grabbing}
.ring__i{
  position:absolute;inset:0;
  border-radius:16px;
  border:1px solid var(--line-2);
  background:linear-gradient(160deg,rgba(20,25,36,.96),rgba(9,11,16,.96));
  -webkit-backface-visibility:hidden;
  backface-visibility:hidden;
  display:flex;flex-direction:column;justify-content:space-between;
  padding:clamp(15px,1.5vw,20px);
  box-shadow:0 22px 46px -20px rgba(0,0,0,.9);
  transition:border-color .4s,box-shadow .4s;
}
.ring__i span{
  font-family:Archivo,sans-serif;font-size:10.5px;font-weight:700;
  letter-spacing:.2em;color:var(--cop);
}
.ring__i b{
  font-family:Archivo,sans-serif;font-weight:600;
  font-size:clamp(14.5px,1.6vw,18px);letter-spacing:-.025em;line-height:1.12;
  font-variation-settings:"wdth" 100;
}
.ring__i.near{border-color:rgba(110,155,255,.42);box-shadow:0 22px 54px -18px rgba(46,107,255,.42)}

.ring__floor{
  position:absolute;left:50%;bottom:clamp(6px,2vw,22px);
  width:min(680px,84vw);height:120px;
  transform:translateX(-50%);
  background:radial-gradient(50% 50% at 50% 50%, rgba(46,107,255,.16), transparent 70%);
  pointer-events:none;
}
.acc__hint{
  text-align:center;margin:clamp(20px,3vw,34px) 0 0;
  font-size:10.5px;letter-spacing:.22em;text-transform:uppercase;color:var(--ink-3);
}

/* ═══════════ TRUST ═══════════ */
.trust__grid{
  display:grid;grid-template-columns:repeat(auto-fit,minmax(148px,1fr));
  gap:1px;background:var(--line);
  border:1px solid var(--line);border-radius:18px;overflow:hidden;
  margin-bottom:clamp(46px,7vw,84px);
}
/* Force 2-up rather than letting auto-fit collapse to a single
   very tall column on a 320px iPhone SE. */
@media (max-width:600px){
  .trust__grid{grid-template-columns:1fr 1fr}
}
.stat{padding:clamp(26px,3.4vw,42px);background:var(--bg)}
.stat .num{
  display:block;
  font-family:Archivo,sans-serif;font-weight:700;
  font-size:clamp(38px,6vw,72px);letter-spacing:-.05em;line-height:1;
  font-variation-settings:"wdth" 100;
  margin-bottom:12px;
  font-variant-numeric:tabular-nums;
}
.stat span{
  font-size:11px;letter-spacing:.16em;text-transform:uppercase;color:var(--ink-3);
}

.quote{
  margin:0;padding:clamp(30px,4vw,52px);
  border-radius:20px;border:1px solid var(--line);
  background:linear-gradient(150deg,rgba(208,138,87,.07),rgba(255,255,255,.006));
  position:relative;
}
.quote p{
  margin:0 0 22px;max-width:52ch;
  font-family:"Instrument Serif",Georgia,serif;
  font-size:clamp(20px,2.9vw,32px);line-height:1.34;letter-spacing:-.015em;
  color:var(--ink);
}
.quote cite{
  font-style:normal;font-size:11px;letter-spacing:.16em;
  text-transform:uppercase;color:var(--ink-3);
}

/* ═══════════ LOCATION ═══════════ */
.loc__grid{
  display:grid;grid-template-columns:1.05fr .95fr;
  gap:clamp(34px,5vw,72px);align-items:center;
}
@media (max-width:960px){.loc__grid{grid-template-columns:1fr}}

.loc__dl{
  display:grid;grid-template-columns:repeat(2,1fr);
  gap:clamp(20px,2.6vw,32px);
  margin:clamp(34px,5vw,56px) 0 clamp(30px,4vw,44px);
}
@media (max-width:520px){.loc__dl{grid-template-columns:1fr}}
.loc__dl dt{
  font-size:10.5px;letter-spacing:.16em;text-transform:uppercase;
  color:var(--ink-3);margin-bottom:8px;
}
.loc__dl dd{margin:0;font-size:15.5px;line-height:1.55;color:var(--ink)}
.loc__dl dd a{border-bottom:1px solid var(--line-2);transition:border-color .3s}
@media (hover:hover){.loc__dl dd a:hover{border-color:var(--cop-2)}}
.loc__act{display:flex;flex-wrap:wrap;gap:12px}

.loc__map{
  position:relative;
  border-radius:22px;overflow:hidden;
  border:1px solid var(--line);
  aspect-ratio:7/8;
}
.mapart{width:100%;height:100%}
.mapart__blk rect{fill:rgba(255,255,255,.035);stroke:rgba(255,255,255,.055);stroke-width:1}
.mapart__rd path{stroke:rgba(255,255,255,.075);stroke-width:9;fill:none}
.mapart__hi{stroke:var(--cop);stroke-width:3;fill:none;opacity:.75}
.mapart__t{
  fill:var(--ink-3);font-family:"Inter Tight",sans-serif;
  font-size:9px;letter-spacing:.16em;font-weight:600;
}
.mapart__pin .core{fill:var(--cop-2);stroke:#06080C;stroke-width:2}
.mapart__pin .pulse{
  fill:none;stroke:var(--cop-2);stroke-width:1.4;
  transform-origin:center;
  animation:ping 3s var(--d2) infinite;
}
.mapart__pin .pulse--2{animation-delay:1.5s}
@keyframes ping{0%{transform:scale(.5);opacity:.85}100%{transform:scale(3.4);opacity:0}}

.loc__badge{
  position:absolute;left:16px;bottom:16px;
  padding:8px 14px;border-radius:100px;
  background:#0A0C11;
  border:1px solid var(--line-2);
  font-size:11px;letter-spacing:.1em;font-weight:600;
}

/* ═══════════ CTA ═══════════ */
.cta{
  position:relative;
  text-align:center;
  padding:clamp(96px,15vw,200px) var(--pad);
  overflow:hidden;
  border-top:1px solid var(--line);
}
.cta__bg{
  position:absolute;inset:0;pointer-events:none;
  background:
    radial-gradient(70% 90% at 50% 108%, rgba(46,107,255,.24), transparent 66%),
    radial-gradient(46% 60% at 50% 106%, rgba(208,138,87,.16), transparent 70%);
}
.cta__h2{
  position:relative;
  font-size:clamp(34px,7.4vw,92px);
  margin:0 auto clamp(20px,2.6vw,30px);
  max-width:18ch;
}
.cta__p{
  position:relative;
  max-width:46ch;margin:0 auto clamp(32px,4.4vw,48px);
  font-size:clamp(15px,1.75vw,19px);line-height:1.6;color:var(--ink-2);
}
.cta__act{position:relative;display:flex;flex-wrap:wrap;gap:12px;justify-content:center}

/* ═══════════ FOOTER ═══════════ */
.ft{
  border-top:1px solid var(--line);
  background:var(--bg-2);
  padding:clamp(52px,7vw,88px) var(--pad) 0;
}
.ft__top{
  max-width:var(--max);margin:0 auto;
  display:grid;grid-template-columns:1.1fr 1.4fr;
  gap:clamp(34px,5vw,64px);
  padding-bottom:clamp(44px,6vw,72px);
}
@media (max-width:820px){.ft__top{grid-template-columns:1fr}}
.ft__mark{
  font-family:Archivo,sans-serif;font-weight:800;
  font-size:clamp(24px,3.4vw,38px);letter-spacing:-.04em;line-height:1;
  font-variation-settings:"wdth" 112;margin-bottom:16px;
}
.ft__mark span{color:var(--ink-3);font-weight:400}
.ft__brand p{margin:0;max-width:32ch;font-size:14.5px;line-height:1.6;color:var(--ink-3)}
.ft__cols{display:grid;grid-template-columns:repeat(3,1fr);gap:clamp(20px,2.6vw,34px)}
@media (max-width:520px){.ft__cols{grid-template-columns:1fr 1fr}}
.ft__cols h4{
  font-family:"Inter Tight",sans-serif;font-weight:600;
  font-size:10.5px;letter-spacing:.16em;text-transform:uppercase;
  color:var(--ink-3);margin-bottom:14px;letter-spacing:.16em;
}
.ft__cols p{margin:0;font-size:14.5px;line-height:1.8;color:var(--ink)}
.ft__cols a{color:var(--ink-2);transition:color .3s}
@media (hover:hover){.ft__cols a:hover{color:var(--cop-2)}}

.ft__bot{
  max-width:var(--max);margin:0 auto;
  border-top:1px solid var(--line);
  padding:22px 0;
  padding-bottom:max(22px,calc(env(safe-area-inset-bottom) + 12px));
  display:flex;justify-content:space-between;gap:16px;flex-wrap:wrap;
  font-size:11.5px;letter-spacing:.06em;color:var(--ink-3);
}
@media (max-width:860px){
  .ft__bot{padding-bottom:calc(74px + env(safe-area-inset-bottom))}
}

/* ═══════════ MOBILE FAB ═══════════ */
.fab{
  position:fixed;z-index:90;
  left:12px;right:12px;
  bottom:max(12px,env(safe-area-inset-bottom));
  display:none;gap:9px;
  transform:translate3d(0,140%,0);
  transition:transform .6s var(--d);
}
.fab.on{transform:translate3d(0,0,0)}
.fab__b{
  flex:1;height:50px;border-radius:100px;
  display:flex;align-items:center;justify-content:center;gap:8px;
  font-size:14.5px;font-weight:600;
  border:1px solid var(--line-2);
  background:#0E1219;                /* solid — see .nav.solid note */
  color:var(--ink);
}
.fab__b svg{width:17px;height:17px;fill:currentColor}
/* Calling first, at every width. The call pill takes the bulk of the bar
   and carries the filled treatment; WhatsApp keeps its green glyph so it
   stays instantly recognisable, but sits on the dark surface so it can't
   out-shout the action we actually want tapped. Solid green on both would
   have made the louder colour win regardless of size. */
.fab__b--call{
  flex:1 1 auto;
  background:var(--ink);border-color:transparent;color:#06070A;
  font-weight:650;
  box-shadow:0 1px 0 rgba(255,255,255,.5) inset,
             0 10px 26px -14px rgba(150,180,255,.9);
}
.fab__b--call svg{animation:ringTilt 5.2s var(--d) infinite;transform-origin:62% 62%}
.fab__b--w{
  flex:0 0 auto;padding:0 19px;
  background:#0E1219;border-color:rgba(37,211,102,.36);
  color:#93F2B7;
}
.fab__b--w svg{fill:#25D366}
/* Under ~360px the two labels start to crowd; the green glyph alone is
   unambiguous, so WhatsApp drops to an icon button and the call pill
   keeps its full label. */
@media (max-width:359px){
  .fab__lbl{display:none}
  .fab__b--w{padding:0 16px}
}
.fab__b:active{transform:scale(.97)}
@media (max-width:860px){.fab{display:flex}}

/* ═══════════ REVEAL PRIMITIVE ═══════════ */
[data-rise]{
  opacity:0;
  transform:translate3d(0,26px,0);
  transition:opacity .85s var(--d2),transform .95s var(--d);
}
[data-rise].in{opacity:1;transform:translate3d(0,0,0)}

/* ═══════════ REDUCED MOTION ═══════════ */
@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{
    animation-duration:.01ms!important;
    animation-iteration-count:1!important;
    transition-duration:.01ms!important;
  }
  [data-rise]{opacity:1;transform:none}
  .hero__h1 .l>span{transform:none}
  .pane{opacity:1;visibility:visible;position:relative;transform:none;margin-bottom:40px}
  .scrub{height:auto}
  .scrub__stick{position:relative;height:auto;padding:80px 0}
  .scrub__stage{flex-direction:column;align-items:flex-start;height:auto}
  .dev{position:relative;right:auto;top:auto;transform:none;margin:0 auto 40px}
  .hero__canvas{opacity:1}
}
