/* ==========================================================================
   TECNOMATION — CRAFT LAYER
   Loaded last. Same design, same content — this raises the finish:
   physically-layered shadows, gradient hairlines, spring easing, optical
   typography, cinematic seams, and native scroll-driven motion.
   Every rule here is additive; delete the file and the site still works.
   ========================================================================== */

/* Animatable custom properties (used for the conic hover sheen) */
@property --sheen { syntax: '<angle>'; initial-value: 0deg; inherits: false; }
@property --lift  { syntax: '<length>'; initial-value: 0px;  inherits: false; }

:root{
  /* ---- Easing. linear() gives real spring physics in pure CSS ---- */
  --e-out:cubic-bezier(.16,1,.3,1);            /* expo out — the premium default */
  --e-io:cubic-bezier(.76,0,.24,1);
  --e-soft:cubic-bezier(.33,1,.68,1);
  --e-spring:linear(0,.006,.025 2.8%,.101 6.1%,.539 18.9%,.721 25.3%,.849 31.5%,
             .937 38.1%,.968 41.8%,.991 45.7%,1.006 50.1%,1.015 55%,1.017 63.9%,1.001);

  /* ---- Shadows rebuilt as stacked layers with a consistent light source.
          One big blur reads as a sticker; five decaying layers read as depth. ---- */
  --sh-1:
    0 1px 1px rgba(8,17,13,.030),
    0 2px 3px rgba(8,17,13,.022),
    0 4px 7px rgba(8,17,13,.016);
  --sh-2:
    0 1px 1px rgba(8,17,13,.028),
    0 2px 4px rgba(8,17,13,.024),
    0 5px 9px rgba(8,17,13,.021),
    0 11px 20px rgba(8,17,13,.018),
    0 22px 40px rgba(8,17,13,.014);
  --sh-3:
    0 1px 2px rgba(8,17,13,.032),
    0 3px 6px rgba(8,17,13,.028),
    0 8px 14px rgba(8,17,13,.026),
    0 17px 30px rgba(8,17,13,.024),
    0 34px 58px rgba(8,17,13,.020),
    0 62px 96px -30px rgba(8,17,13,.10);
  --sh-4:
    0 2px 4px rgba(8,17,13,.04),
    0 8px 16px rgba(8,17,13,.035),
    0 20px 38px rgba(8,17,13,.032),
    0 44px 76px -18px rgba(8,17,13,.14),
    0 88px 130px -50px rgba(8,17,13,.20);
  --sh-mint:
    0 2px 6px rgba(20,140,80,.16),
    0 8px 18px rgba(20,140,80,.16),
    0 18px 38px -8px rgba(20,140,80,.30);

  /* Light catching the top edge of a raised surface */
  --edge-light:inset 0 1px 0 rgba(255,255,255,.9);
  --edge-light-dark:inset 0 1px 0 rgba(255,255,255,.075);
}

/* ==========================================================================
   TYPOGRAPHY CRAFT
   ========================================================================== */

/* Figures line up in columns and never jitter while counting up */
.statbar .st .v,.pricebig,.was,.capgrid b,.calcout .big,.rangefield .rval,
.hero-meta b,.cmp td,.cmp th,.kv span:last-child,[data-count]{
  font-variant-numeric:tabular-nums lining-nums;
  font-feature-settings:"tnum" 1,"lnum" 1;
}
/* Quotes and bullets hang into the margin instead of denting the text edge */
.lede,.sub,.acc-body .inner,.legal p,.legal li{hanging-punctuation:first last}
/* Headings tighten optically as they grow; small text needs the opposite */
.h-xxl,.h-xl{font-optical-sizing:auto}
.mono,.eyebrow,.pill,.card-num{font-feature-settings:"tnum" 1;font-variant-ligatures:none}
/* Stop long URLs and compound words from breaking layout */
.lede,.sub,p,li,td,th{overflow-wrap:break-word}

/* ==========================================================================
   BACK TO TOP — bottom right, every page
   Appears only once the reader is near the end. The ring is a scroll dial
   (--p is written by premium.js); the disc is dark glass; the arrow swaps
   for a fresh one on hover instead of merely nudging.
   ========================================================================== */
.btt{
  position:fixed;z-index:97;
  right:var(--fl-x);bottom:var(--fl-y);
  width:52px;height:52px;padding:0;border:0;border-radius:50%;
  background:transparent;color:#fff;cursor:pointer;
  display:grid;place-items:center;isolation:isolate;
  opacity:0;visibility:hidden;translate:0 16px;scale:.82;
  transition:opacity .42s var(--e-out),translate .6s var(--e-spring),
             scale .6s var(--e-spring),visibility 0s linear .42s;
}
.btt.on{opacity:1;visibility:visible;translate:0 0;scale:1;transition-delay:0s}

/* Scroll dial — starts at twelve o'clock and fills clockwise */
.btt-ring{
  position:absolute;inset:0;border-radius:50%;z-index:0;pointer-events:none;
  background:conic-gradient(from -90deg,var(--mint) calc(var(--p,0) * 360deg),rgba(255,255,255,.17) 0);
  -webkit-mask:radial-gradient(farthest-side,#0000 calc(100% - 2.5px),#000 calc(100% - 2.5px));
          mask:radial-gradient(farthest-side,#0000 calc(100% - 2.5px),#000 calc(100% - 2.5px));
  transition:filter .45s var(--e-out);
}
/* Dark glass disc */
.btt-disc{
  position:relative;z-index:1;width:42px;height:42px;border-radius:50%;
  display:grid;place-items:center;
  background:linear-gradient(155deg,rgba(20,64,42,.94),rgba(6,26,18,.97) 62%);
  -webkit-backdrop-filter:blur(10px) saturate(1.35);
          backdrop-filter:blur(10px) saturate(1.35);
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,.16),
    inset 0 -1px 0 rgba(0,0,0,.42),
    0 1px 2px rgba(6,26,18,.24),
    0 6px 14px rgba(6,26,18,.26),
    0 18px 34px -12px rgba(6,26,18,.46);
  transition:background .45s var(--e-out),box-shadow .5s var(--e-out);
}
/* Two arrows in a clipped box: the first leaves upward, the second follows it in */
.btt-ico{position:relative;display:grid;place-items:center;width:18px;height:18px;overflow:hidden}
.btt-ico svg{grid-area:1/1;flex:none;transition:translate .5s var(--e-spring),opacity .3s var(--e-out)}
.btt-ico .a2{translate:0 18px;opacity:0}

/* Label, on pointer devices only. Mint rather than dark ink: the button most
   often surfaces over the dark footer, where a dark pill would vanish into it. */
.btt-tip{
  position:absolute;right:calc(100% + 12px);top:50%;z-index:2;
  translate:8px -50%;opacity:0;pointer-events:none;white-space:nowrap;
  background:linear-gradient(150deg,#7CF3AE,var(--mint) 55%,#2FD37A);
  color:var(--deep);font-family:var(--display);font-weight:700;font-size:12.5px;letter-spacing:-.005em;
  padding:8px 13px;border-radius:9px;
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,.55),
    0 2px 6px rgba(6,26,18,.22),
    0 12px 26px -10px rgba(12,90,50,.6);
  transition:opacity .3s var(--e-out),translate .45s var(--e-spring);
}
.btt-tip::after{
  content:"";position:absolute;left:100%;top:50%;translate:-1px -50%;
  border:5px solid transparent;border-left-color:#2FD37A;
}

.btt.on:hover,.btt.on:focus-visible{translate:0 -3px}
.btt.on:hover .btt-ring,.btt.on:focus-visible .btt-ring{filter:drop-shadow(0 0 8px rgba(79,231,143,.6))}
.btt.on:hover .btt-disc,.btt.on:focus-visible .btt-disc{
  background:linear-gradient(155deg,rgba(26,84,54,.95),rgba(9,36,24,.98) 62%);
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,.22),
    0 2px 4px rgba(6,26,18,.24),
    0 10px 20px rgba(6,26,18,.28),
    0 24px 44px -14px rgba(6,26,18,.5),
    0 0 0 1px rgba(79,231,143,.34);
}
.btt:hover .btt-ico .a1,.btt:focus-visible .btt-ico .a1{translate:0 -18px;opacity:0}
.btt:hover .btt-ico .a2,.btt:focus-visible .btt-ico .a2{translate:0 0;opacity:1}
.btt:hover .btt-tip,.btt:focus-visible .btt-tip{opacity:1;translate:0 -50%}
.btt.on:active{translate:0 -1px;scale:.95;transition-duration:.09s}
.btt:focus-visible{outline:2px solid var(--mint);outline-offset:4px}

@media (max-width:768px){
  .btt{width:46px;height:46px}
  .btt-disc{width:37px;height:37px}
  .btt-ico{width:16px;height:16px}
  .btt-ico svg{width:16px;height:16px}
  .btt-ico .a2{translate:0 16px}
  .btt:hover .btt-ico .a1{translate:0 -16px}
}
/* No hover on touch, so the label would never be dismissable */
@media (hover:none){.btt-tip{display:none}}
@media (prefers-reduced-motion:reduce){
  .btt,.btt-disc,.btt-ico svg,.btt-ring,.btt-tip{transition:none}
}

/* ==========================================================================
   ICON SYSTEM
   Every icon on the site is <svg><use href="#i-*">. Stroke geometry was set
   per-path in the sprite and had drifted: 28 symbols carried butt caps and 22
   mitred joins, so squared-off strokes sat next to rounded ones. Presentation
   attributes lose to CSS, so these rules normalise the whole set from one
   place — and flex:none stops an icon collapsing when it shares a flex row
   with a long label.
   ========================================================================== */
svg:has(use){
  flex:none;
  stroke-linecap:round;
  stroke-linejoin:round;
}
/* Optical alignment: strokes land on the pixel grid at small sizes rather
   than smearing across two rows. */
svg:has(use){shape-rendering:geometricPrecision}

/* ==========================================================================
   SECTION MARKER
   Replaces the running 01/02/03 numbering with the supplied mark artwork.
   ========================================================================== */
/* Section marker. The two supplied files are used exactly as they are: one for
   light grounds (mark-on-light.png), one for dark (mark-on-dark.png). Only the
   height is set — width stays auto so each file keeps its own aspect ratio —
   and no filter, blend-mode, opacity or colour rule is applied to them
   anywhere, so their pixels render precisely as delivered. */
.eyebrow{gap:8px}
.eyebrow .eb-mark{flex:none;display:inline-flex;align-items:center;line-height:0}
.eyebrow .eb-mark img{display:block;height:18px;width:auto}
.eyebrow .eb-mark .m-dark{display:none}
.dark .eyebrow .eb-mark .m-light,
.price-strip .eyebrow .eb-mark .m-light,
.cine .eyebrow .eb-mark .m-light{display:none}
.dark .eyebrow .eb-mark .m-dark,
.price-strip .eyebrow .eb-mark .m-dark,
.cine .eyebrow .eb-mark .m-dark{display:block}
/* Slightly larger where the eyebrow leads a major section head */
.sec-head .eyebrow .eb-mark img{height:20px}
.sec-head.center .eyebrow .eb-mark img{height:21px}
@media (max-width:768px){
  .eyebrow .eb-mark img{height:16px}
  .sec-head .eyebrow .eb-mark img{height:17px}
  .sec-head.center .eyebrow .eb-mark img{height:18px}
}

/* ==========================================================================
   SURFACE CRAFT — cards, chips, panels
   ========================================================================== */

.card{
  transition:transform .7s var(--e-out),box-shadow .7s var(--e-out),
             border-color .5s var(--e-out),background .5s var(--e-out);
  box-shadow:var(--sh-1),var(--edge-light);
}
.dark .card{box-shadow:none,var(--edge-light-dark);box-shadow:var(--edge-light-dark)}

/* A hairline that is brighter where light would hit it, fading to nothing */
.card::after{
  content:"";position:absolute;inset:0;border-radius:inherit;pointer-events:none;
  padding:1px;background:linear-gradient(170deg,rgba(255,255,255,.95),rgba(255,255,255,0) 42%);
  -webkit-mask:linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);
  -webkit-mask-composite:xor;mask-composite:exclude;
  opacity:1;transition:opacity .5s var(--e-out);
}
.dark .card::after{background:linear-gradient(170deg,rgba(255,255,255,.14),rgba(255,255,255,0) 45%)}

.card.lift:hover{
  transform:translateY(-7px);
  box-shadow:var(--sh-3),var(--edge-light),0 0 0 1px rgba(79,231,143,.30);
}
.dark .card.lift:hover{box-shadow:var(--sh-4),var(--edge-light-dark),0 0 0 1px rgba(79,231,143,.34)}

/* Icon chips: gradient body, inner light, and a lift that follows the card */
.ico{
  background:linear-gradient(160deg,#fff,var(--mint-wash) 55%,#DFF7E9);
  border:1px solid rgba(79,231,143,.30);
  box-shadow:
    0 1px 1px rgba(8,17,13,.04),
    0 3px 8px -3px rgba(20,140,80,.18),
    inset 0 1px 0 rgba(255,255,255,.95),
    inset 0 -1px 0 rgba(20,140,80,.07);
  transition:transform .6s var(--e-spring),box-shadow .5s var(--e-out),border-color .4s;
}
.ico svg{filter:drop-shadow(0 1px 0 rgba(255,255,255,.85))}
.dark .ico{
  background:linear-gradient(160deg,rgba(79,231,143,.22),rgba(79,231,143,.06) 70%);
  border-color:rgba(79,231,143,.24);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.10);
}
.dark .ico svg{filter:none}
.card.lift:hover .ico{
  transform:translateY(-2px) scale(1.07) rotate(-3deg);
  box-shadow:0 6px 14px -4px rgba(20,140,80,.35),inset 0 1px 0 rgba(255,255,255,.95);
  border-color:rgba(79,231,143,.5);
}

/* Pills and tags get the same treatment so nothing looks flat next to a card */
.pill{box-shadow:0 1px 2px rgba(8,17,13,.04),inset 0 1px 0 rgba(255,255,255,.8)}
.dark .pill,.pill-dark{box-shadow:inset 0 1px 0 rgba(255,255,255,.08)}
.pill-mint{box-shadow:0 1px 2px rgba(20,140,80,.10),inset 0 1px 0 rgba(255,255,255,.9),0 0 0 3px rgba(79,231,143,.08)}

/* Featured plan: a slow conic sheen travelling the border */
.plan.featured{box-shadow:var(--sh-4),var(--edge-light)}
.plan.featured::before{
  background:conic-gradient(from var(--sheen),
    transparent 0deg,rgba(79,231,143,.85) 40deg,transparent 110deg,
    transparent 250deg,rgba(79,231,143,.45) 300deg,transparent 355deg);
  animation:sheenspin 9s linear infinite;
}
@keyframes sheenspin{to{--sheen:360deg}}

.formcard{box-shadow:var(--sh-3),var(--edge-light)}
.capcard,.tblwrap,.calc,.mapwrap{box-shadow:var(--sh-2),var(--edge-light)}

/* ==========================================================================
   BUTTON CRAFT
   ========================================================================== */
.btn{
  transition:transform .45s var(--e-spring),box-shadow .45s var(--e-out),
             background .3s,color .3s,border-color .3s;
}
.btn-primary{box-shadow:var(--sh-2),inset 0 1px 0 rgba(255,255,255,.12)}
.btn-primary:hover{box-shadow:var(--sh-mint),inset 0 1px 0 rgba(255,255,255,.4)}
.btn-mint{box-shadow:var(--sh-mint),inset 0 1px 0 rgba(255,255,255,.55)}
.btn-mint:hover{box-shadow:0 4px 10px rgba(20,140,80,.22),0 14px 32px -6px rgba(20,140,80,.40),inset 0 1px 0 rgba(255,255,255,.55)}
.btn-ghost{box-shadow:inset 0 1px 0 rgba(255,255,255,.7)}
.btn:active{transform:translateY(0) scale(.985);transition-duration:.09s}
/* The arrow leads, then settles — reads as intent rather than a jump */
.btn:hover svg:last-child{transform:translateX(4px)}
.btn svg{transition:transform .5s var(--e-spring)}
.btn:focus-visible{outline:2px solid var(--mint);outline-offset:3px;box-shadow:0 0 0 6px rgba(79,231,143,.22)}
#nav .btn-primary:focus-visible{outline-color:#fff}

/* Disabled / working state for the form submit */
.btn[disabled]{cursor:default;filter:saturate(.6)}
.btn.is-working{pointer-events:none}
.btn.is-working::after{
  content:"";position:absolute;inset:0;z-index:2;
  background:linear-gradient(100deg,transparent,rgba(255,255,255,.35),transparent);
  transform:translateX(-100%);animation:working 1.1s linear infinite;
}
@keyframes working{to{transform:translateX(100%)}}

/* ==========================================================================
   FORM CRAFT
   ========================================================================== */
.field input,.field select,.field textarea{
  box-shadow:inset 0 1px 2px rgba(8,17,13,.04);
  transition:border-color .3s var(--e-out),box-shadow .3s var(--e-out),background .3s;
}
.field input:hover,.field select:hover,.field textarea:hover{border-color:var(--muted-2)}
.field input:focus,.field select:focus,.field textarea:focus{
  box-shadow:0 0 0 4px rgba(79,231,143,.16),inset 0 1px 2px rgba(8,17,13,.03),0 4px 14px -6px rgba(20,140,80,.4);
}
/* A field the visitor has already completed reads as done */
.field input:not(:placeholder-shown):valid,
.field textarea:not(:placeholder-shown):valid{border-color:var(--mint-line);background:linear-gradient(0deg,var(--mint-wash),#fff 60%)}
.chip span{box-shadow:0 1px 2px rgba(8,17,13,.04),inset 0 1px 0 rgba(255,255,255,.9);transition:all .35s var(--e-spring)}
.chip input:checked+span{box-shadow:0 2px 8px -2px rgba(20,140,80,.32),inset 0 1px 0 rgba(255,255,255,.9)}

/* ==========================================================================
   CINEMATIC SEAMS
   Hard light-to-dark edges look like stacked blocks. A short gradient seam
   reads as one continuous surface.
   ========================================================================== */
.dark::after,.price-strip::after{
  content:"";position:absolute;left:0;right:0;top:0;height:90px;pointer-events:none;z-index:1;
  background:linear-gradient(180deg,rgba(255,255,255,.06),transparent);
}
.dark>.wrap,.price-strip>.wrap{position:relative;z-index:2}
/* Vignette pulls the eye to the centre of dark sections */
.dark.gridlines::after{
  height:100%;
  background:linear-gradient(180deg,rgba(255,255,255,.06),transparent 90px),
             radial-gradient(120% 90% at 50% 45%,transparent 45%,rgba(0,0,0,.32) 100%);
}

/* ==========================================================================
   SLIDER + BANNER CRAFT
   ========================================================================== */
.slider-track{transition:transform .8s var(--e-out)}
.sbtn{transition:transform .45s var(--e-spring),background .35s,border-color .35s,color .35s,box-shadow .35s}
.sbtn:hover{transform:translateY(-3px) scale(1.05);box-shadow:var(--sh-2)}
.sbtn:active{transform:translateY(0) scale(.94);transition-duration:.09s}
.ind{box-shadow:var(--sh-1)}
.ind::after{
  content:"";position:absolute;inset:0;z-index:3;border-radius:inherit;pointer-events:none;
  box-shadow:inset 0 0 0 1px rgba(255,255,255,.12);
  opacity:0;transition:opacity .5s var(--e-out);
}
.ind:hover::after{opacity:1}
.ind:hover{box-shadow:var(--sh-3)}
.ind .lbl{transform:translateY(4px);transition:transform .6s var(--e-out)}
.ind:hover .lbl{transform:translateY(0)}

.cine{box-shadow:var(--sh-4)}
/* Each slide drifts a different way, so the loop never feels mechanical */
.cine-slide:nth-child(1) img{transform-origin:70% 40%}
.cine-slide:nth-child(2) img{transform-origin:30% 60%}
.cine-slide:nth-child(3) img{transform-origin:50% 30%}
.cine-slide:nth-child(4) img{transform-origin:40% 70%}
.cine-slide.on .cine-body>*{animation:cineIn .9s var(--e-out) both}
.cine-slide.on .cine-body>*:nth-child(2){animation-delay:.08s}
.cine-slide.on .cine-body>*:nth-child(3){animation-delay:.16s}
.cine-slide.on .cine-body>*:nth-child(4){animation-delay:.24s}
@keyframes cineIn{from{opacity:0;transform:translateY(16px)}to{opacity:1;transform:none}}
/* Autoplay progress as a ring on the next button */
.cine-nav [data-cnext]{position:relative}
.cine-nav [data-cnext]::after{
  content:"";position:absolute;inset:-4px;border-radius:50%;pointer-events:none;
  background:conic-gradient(var(--mint) calc(var(--p,0)*1turn),transparent 0);
  -webkit-mask:radial-gradient(farthest-side,transparent calc(100% - 2.5px),#000 calc(100% - 2.5px));
  mask:radial-gradient(farthest-side,transparent calc(100% - 2.5px),#000 calc(100% - 2.5px));
  opacity:.85;
}

/* ==========================================================================
   NAV + STAT CRAFT
   ========================================================================== */
#nav.stuck{box-shadow:0 1px 0 rgba(255,255,255,.06),0 18px 40px -28px rgba(0,0,0,.9)}
.dropmenu{box-shadow:var(--sh-4),inset 0 1px 0 rgba(255,255,255,.07)}
.dropmenu.mega a{transition:background .3s var(--e-out),transform .4s var(--e-spring)}
.dropmenu.mega a:hover{transform:translateX(3px)}
.statbar{box-shadow:var(--sh-4),var(--edge-light-dark)}
.statbar .st{transition:background .5s var(--e-out)}
.statbar .st:hover{background:rgba(255,255,255,.035)}
.statbar .st .spark i{transition:width 1.6s var(--e-out)}
.techchip{transition:transform .45s var(--e-spring),background .4s,border-color .4s}
.techchip:hover{transform:translateY(-4px)}
.svc-item{transition:background .45s var(--e-out)}
.acc-item>button{transition:color .3s var(--e-out)}
.acc-body{transition:height .6s var(--e-out)}
.svc-item .sbody{transition:height .6s var(--e-out)}

/* ==========================================================================
   NATIVE SCROLL-DRIVEN MOTION
   Runs on the compositor — smoother than any JS scroll handler, and costs
   nothing when unsupported.
   ========================================================================== */
@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference){
    /* Photographs drift inside their frame as they pass.
       The drift uses `translate` and the zoom uses `scale` — the individual
       transform properties — so scroll motion and hover motion compose instead
       of overwriting each other the way a shared `transform` would. */
    .figure img,.ind img{
      scale:1.07;
      animation:imgDrift linear both;
      animation-timeline:view();
      animation-range:cover 0% cover 100%;
      transition:scale 1.1s var(--e-out),filter .8s var(--e-out);
    }
    @keyframes imgDrift{from{translate:0 -2.2%}to{translate:0 2.2%}}
    .imgzoom:hover img{transform:none;scale:1.14}
    .ind:hover img{transform:none;scale:1.15}
    .figure:hover img,.ind:hover img{animation-play-state:paused}

    /* Section headings settle as they enter.
       POSITION ONLY. This is a scroll-driven animation, so a heading that
       has not been scrolled to yet is sitting at its "from" frame -- and
       when that frame said opacity .35, every unreached heading and its
       paragraph were 35% transparent. An accessibility audit measures the
       page where it finds it, and read them as failing contrast: fourteen
       items on every run, from a rule that had nothing to do with the
       JavaScript reveal I spent three deploys looking at. */
    .sec-head{
      animation:headIn linear both;
      animation-timeline:view();
      animation-range:entry 0% entry 46%;
    }
    @keyframes headIn{from{transform:translateY(22px)}to{transform:none}}
  }
}

/* ==========================================================================
   RENDERING PERFORMANCE
   49 sections is a lot of layout on every frame. Skipping offscreen work
   keeps scrolling smooth on mid-range phones.
   ========================================================================== */
/* EVERY SECTION SAYS WHAT IT IS PAINTED ON.
 *
 * axe works out the backdrop of a run of text with elementsFromPoint and
 * composites whatever it finds underneath. On a transparent section that
 * means walking out to the body, and on this page that walk is unreliable:
 * the sections below are content-visibility:auto with a 700px estimate
 * against sections that are really 788px and more, so the document grows
 * from 40,300px to 47,900px as you scroll through it. A rect measured a
 * moment ago no longer points at the same paint, and the colour axe comes
 * back with is the fixed header's #061A12.
 *
 * That produced two contrast failures on text that is nowhere near a dark
 * surface: the "We don't / We do" labels reported at 2.73:1, and the
 * #whofor eyebrow at 3.6:1, both on white where they measure 7.6:1 and
 * 5.6:1. Fixing them one element at a time moved the failure to the next
 * element instead, which is the tell that the elements were never wrong.
 *
 * Of the 41 sections, 23 already declare a background -- 11 carry an inline
 * --paper-2 and 12 are .dark or .price-strip -- and not one of those has
 * ever been misread, because axe stops at the first opaque colour. The 18
 * that were transparent are the whole of the problem.
 *
 * So they say white, which is what the body behind them has always painted
 * them. It is a statement of fact, not a nudge to the audit: nothing on the
 * page changes colour. The specificity is two element selectors, so the
 * inline styles and both classes still win and keep their own surfaces. */
main > section{background:var(--paper);content-visibility:auto;contain-intrinsic-size:auto 700px}
main > section#hero,main > section#contact{content-visibility:visible}
.hero-media img,.cine-slide img{contain:paint}

/* ==========================================================================
   CROSS-PAGE VIEW TRANSITIONS
   ========================================================================== */
@view-transition{navigation:auto}
@media (prefers-reduced-motion: no-preference){
  ::view-transition-old(root){animation:vtOut .28s var(--e-io) both}
  ::view-transition-new(root){animation:vtIn .42s var(--e-out) both}
  @keyframes vtOut{to{opacity:0;transform:translateY(-8px)}}
  @keyframes vtIn{from{opacity:0;transform:translateY(10px)}}
}
/* The header and logo persist across the navigation instead of redrawing.
   A view-transition-name must be unique per document — pages carry a logo in
   the footer and sidebar too, so this is scoped to the header copy only. */
#nav{view-transition-name:site-header}
#nav .brand-logo{view-transition-name:site-logo}

/* ==========================================================================
   FLOATING WHATSAPP — bottom left, every page
   Collapsed to a disc; expands on hover/focus to name itself. WhatsApp brand
   green, not the site mint, so it is instantly recognisable.
   ========================================================================== */
/* Shared anchor for the two floating controls — WhatsApp bottom-left,
   back-to-top bottom-right — so both keep the same inset and both lift
   together when the sticky CTA appears. */
body{--fl-x:clamp(14px,2.2vw,28px);--fl-y:clamp(14px,2.2vw,28px)}
body:has(#stickycta.on){--fl-y:calc(clamp(14px,2.2vw,28px) + 74px)}
@media (max-width:768px){
  body:has(#stickycta.on){--fl-y:calc(14px + 132px)}
}

.wa-float{
  position:fixed;z-index:96;
  left:var(--fl-x);bottom:var(--fl-y);
  display:inline-flex;align-items:center;height:58px;border-radius:100px;
  background:linear-gradient(150deg,#5BE584 0%,#25D366 38%,#12A150 100%);
  color:#fff;text-decoration:none;overflow:hidden;isolation:isolate;
  box-shadow:
    0 1px 2px rgba(6,60,30,.20),
    0 4px 8px rgba(6,60,30,.18),
    0 10px 20px rgba(6,60,30,.18),
    0 22px 40px -10px rgba(6,60,30,.34),
    inset 0 1px 0 rgba(255,255,255,.45);
  transition:transform .5s var(--e-spring),box-shadow .5s var(--e-out),
             border-radius .5s var(--e-out);
}
.wa-float::before{ /* glass sheen across the top half */
  content:"";position:absolute;inset:0;z-index:1;pointer-events:none;border-radius:inherit;
  background:linear-gradient(180deg,rgba(255,255,255,.28),rgba(255,255,255,0) 52%);
}
.wa-float:hover,.wa-float:focus-visible{
  transform:translateY(-3px);
  box-shadow:
    0 2px 4px rgba(6,60,30,.22),
    0 8px 16px rgba(6,60,30,.20),
    0 18px 34px rgba(6,60,30,.20),
    0 34px 60px -12px rgba(6,60,30,.42),
    inset 0 1px 0 rgba(255,255,255,.5);
}
.wa-float:active{transform:translateY(-1px) scale(.97);transition-duration:.09s}
.wa-float:focus-visible{outline:2px solid #fff;outline-offset:3px}

.wa-ico{position:relative;z-index:2;width:58px;height:58px;flex:none;display:grid;place-items:center}
.wa-ico svg{flex:none;filter:drop-shadow(0 1px 1px rgba(6,60,30,.35))}
/* "we're reachable" indicator */
.wa-dot{
  position:absolute;top:13px;right:12px;width:9px;height:9px;border-radius:50%;
  background:#EFFFF4;box-shadow:0 0 0 2px #12A150,0 0 8px rgba(255,255,255,.9);
}
/* Expanding label — collapsed by default so it never blocks content */
/* visibility as well as opacity. Hidden by opacity alone this is still text,
   at 1:1 against whatever is behind it, and an accessibility audit counts it.
   The delay on the way out lets the fade finish before it stops being
   rendered. */
.wa-label{
  position:relative;z-index:2;display:flex;flex-direction:column;gap:1px;
  max-width:0;opacity:0;visibility:hidden;white-space:nowrap;overflow:hidden;
  transition:max-width .55s var(--e-out),opacity .35s var(--e-out),
             padding .55s var(--e-out),visibility 0s linear .35s;
}
.wa-label b{font-family:var(--display);font-weight:700;font-size:14px;letter-spacing:-.008em;line-height:1.2}
.wa-label i{font-style:normal;font-size:11.4px;opacity:.88;line-height:1.2}
.wa-float:hover .wa-label,.wa-float:focus-visible .wa-label{max-width:290px;opacity:1;visibility:visible;padding-right:22px;transition-delay:0s}

/* Pulse ring — a single slow beat, not a distraction */
.wa-ring{
  position:absolute;inset:0;border-radius:inherit;pointer-events:none;z-index:0;
  box-shadow:0 0 0 0 rgba(37,211,102,.55);
  animation:waPulse 3.4s var(--e-out) infinite;
}
@keyframes waPulse{
  0%{box-shadow:0 0 0 0 rgba(37,211,102,.5)}
  62%{box-shadow:0 0 0 20px rgba(37,211,102,0)}
  100%{box-shadow:0 0 0 0 rgba(37,211,102,0)}
}
.wa-float:hover .wa-ring{animation-play-state:paused}


@media (max-width:768px){
  .wa-float{height:52px}
  .wa-ico{width:52px;height:52px}
  .wa-ico svg{width:24px;height:24px}
  .wa-dot{top:11px;right:10px;width:8px;height:8px}
  /* Tapping cannot hover, so the label stays collapsed — the disc is the target */
  .wa-float:hover .wa-label{max-width:0;opacity:0;padding-right:0}
}
@media (prefers-reduced-motion:reduce){
  .wa-ring{animation:none}
  .wa-float,.wa-label{transition:none}
}

/* ==========================================================================
   RESPONSIVE + MOTION SAFETY
   ========================================================================== */
@media (max-width:768px){
  .card.lift:hover{transform:none}
  .ico{box-shadow:0 1px 1px rgba(8,17,13,.04),0 2px 6px -3px rgba(20,140,80,.16),inset 0 1px 0 rgba(255,255,255,.92)}
  .dark::after,.price-strip::after{height:60px}
}
@media (prefers-reduced-motion:reduce){
  .plan.featured::before{animation:none}
  .cine-slide.on .cine-body>*{animation:none}
  .btn.is-working::after{animation:none}
  #nav,#nav .brand-logo{view-transition-name:none}
}

/* ==========================================================================
   CONTACT FORM — country, clocks, progress, grouping
   The form gained a "where are you based" step, so it also gained the one
   piece of context that makes the answer useful: the current local time in
   each place. The clocks read from Intl, on the same minute-aligned timer the
   coverage atlas uses, and park themselves when the section is off screen.
   No extra webfont, no library, no canvas — this is a form.
   ========================================================================== */

/* Completion meter. Driven by how many required fields are actually filled,
   so it never overstates progress. */
.formprog{
  position:relative;height:3px;border-radius:3px;background:var(--line);
  overflow:hidden;margin:0 0 22px;
}
.formprog i{
  position:absolute;inset:0 auto 0 0;display:block;border-radius:3px;
  width:calc(var(--p,0) * 100%);
  background:linear-gradient(90deg,#7CF3AE,var(--mint) 60%,#2FD37A);
  transition:width .5s var(--e-out);
}
.formprog::after{
  content:"";position:absolute;inset:0;pointer-events:none;
  background:linear-gradient(90deg,transparent,rgba(255,255,255,.75),transparent);
  translate:-100% 0;
}
.formcard:has(:focus-within) .formprog::after{
  animation:progSheen 2.6s var(--e-out) infinite;
}
@keyframes progSheen{to{translate:200% 0}}

/* Section rule inside the form — orients without numbering the steps */
.formsec{
  display:flex;align-items:center;gap:12px;
  margin:26px 0 14px;
  font-family:var(--mono);font-size:10px;letter-spacing:.14em;text-transform:uppercase;
  color:var(--muted-2);
}
.formsec::after{content:"";flex:1;height:1px;background:var(--line)}
.formsec:first-child{margin-top:0}

/* --------------------------------------------------------------------------
   Country picker, with a live clock in each option
   -------------------------------------------------------------------------- */
.ctry{display:grid;grid-template-columns:1fr 1fr;gap:10px}
@media (max-width:420px){.ctry{grid-template-columns:1fr}}

/* .field label is mono/uppercase/9.8px for the little field captions. These
   options are labels too, so that rule reaches them and has to be undone —
   otherwise the country names render as uppercase mono captions. */
.field .ctry-opt{
  position:relative;cursor:pointer;display:block;
  font-family:var(--body);font-size:13.4px;letter-spacing:normal;
  text-transform:none;color:var(--ink);
}
.ctry-opt input{position:absolute;opacity:0;pointer-events:none}
.ctry-box{
  display:flex;align-items:center;gap:11px;
  padding:12px 13px;border-radius:13px;
  border:1px solid var(--line);background:#fff;
  transition:border-color .3s var(--e-out),background .3s var(--e-out),
             box-shadow .4s var(--e-out),transform .45s var(--e-spring);
}
.ctry-opt:hover .ctry-box{border-color:var(--muted-2)}
.ctry-opt input:checked + .ctry-box{
  border-color:var(--mint);
  background:linear-gradient(150deg,var(--mint-wash),#fff 78%);
  box-shadow:0 0 0 3px rgba(79,231,143,.16),0 6px 16px -8px rgba(20,140,80,.34);
}
.ctry-opt input:focus-visible + .ctry-box{outline:2px solid var(--green-ink);outline-offset:2px}
.ctry-opt:active .ctry-box{transform:scale(.985)}

/* Radio dot */
.ctry-dot{
  flex:none;width:17px;height:17px;border-radius:50%;
  border:1.5px solid var(--line);background:#fff;
  display:grid;place-items:center;
  transition:border-color .3s var(--e-out);
}
.ctry-dot::before{
  content:"";width:8px;height:8px;border-radius:50%;background:var(--mint);
  scale:0;transition:scale .35s var(--e-spring);
}
.ctry-opt input:checked + .ctry-box .ctry-dot{border-color:var(--mint)}
.ctry-opt input:checked + .ctry-box .ctry-dot::before{scale:1}

.ctry-txt{display:flex;flex-direction:column;gap:2px;min-width:0}
.ctry-name{
  font-family:var(--display);font-weight:600;font-size:13.4px;
  letter-spacing:-.012em;line-height:1.2;color:var(--ink);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
}
.ctry-time{
  font-family:var(--mono);font-size:10.6px;letter-spacing:.04em;
  color:var(--muted-2);line-height:1.3;font-variant-numeric:tabular-nums;
  transition:color .3s var(--e-out);
}
.ctry-opt input:checked + .ctry-box .ctry-time{color:var(--green-ink)}
/* A quiet pulse so it reads as live rather than printed */
.ctry-time b{
  display:inline-block;width:4px;height:4px;border-radius:50%;
  background:var(--mint);margin-right:5px;vertical-align:middle;
  animation:ctryBeat 2.8s var(--e-out) infinite;
}
@keyframes ctryBeat{
  0%,100%{opacity:1;box-shadow:0 0 0 0 rgba(79,231,143,.5)}
  55%{opacity:.55;box-shadow:0 0 0 4px rgba(79,231,143,0)}
}

/* --------------------------------------------------------------------------
   Field polish
   -------------------------------------------------------------------------- */
.field input,.field select,.field textarea{
  box-shadow:inset 0 1px 2px rgba(8,17,13,.035);
  transition:border-color .28s var(--e-out),box-shadow .28s var(--e-out),background .28s var(--e-out);
}
.field input:hover:not(:focus),
.field select:hover:not(:focus),
.field textarea:hover:not(:focus){border-color:var(--muted-2)}
/* A filled required field earns a quiet mint edge */
.field input:required:valid,
.field select:required:valid,
.field textarea:required:valid{border-left:2px solid var(--mint-line)}

/* --------------------------------------------------------------------------
   Supporting image in the left column
   -------------------------------------------------------------------------- */
.contact-figure{
  margin:26px 0 0;
  border-radius:var(--r-lg,16px);
  overflow:hidden;position:relative;
  border:1px solid var(--line);
  box-shadow:
    0 1px 2px rgba(8,17,13,.04),
    0 14px 30px -16px rgba(8,17,13,.22);
  background:var(--mint-wash);
}
.contact-figure img{
  display:block;width:100%;height:auto;
  aspect-ratio:16/10;object-fit:cover;
  transition:scale .9s var(--e-out);
}
.contact-figure:hover img{scale:1.03}
/* Reads as part of the page rather than a stock photo dropped in */
.contact-figure::after{
  content:"";position:absolute;inset:0;pointer-events:none;
  background:linear-gradient(190deg,rgba(6,26,18,0) 45%,rgba(6,26,18,.30) 100%);
}
@media (prefers-reduced-motion:reduce){
  .contact-figure img{transition:none}
  .contact-figure:hover img{scale:1}
  .ctry-time b{animation:none}
  .formcard:has(:focus-within) .formprog::after{animation:none}
}

/* ==========================================================================
   CONTACT COLUMN FILL
   The form runs ~360px taller than the copy beside it, which left a hole
   under the photo. Rather than padding the column with filler, the figure
   grows to close it — and because a tall narrow box would crop a landscape
   frame to a sliver, a portrait source is art-directed in at that breakpoint.
   ========================================================================== */
@media (min-width:901px){
  .contact-grid{align-items:stretch}
  .contact-col{display:flex;flex-direction:column}
  .contact-col .contact-figure{flex:1 1 auto;min-height:340px}
  .contact-col .contact-figure picture{display:block;height:100%}
  .contact-col .contact-figure img{height:100%;aspect-ratio:auto;object-position:center}
}

/* ==========================================================================
   EXO 2 ON CONTROLS AND MENUS
   Exo 2 was already the display face and is already loaded at 500/600/700/800,
   so this changes no font payload. It runs a touch narrower and lower in the
   x-height than Inter Tight, so weight goes up a step to hold the same
   presence at the same size.
   ========================================================================== */
.btn{font-family:var(--display);font-weight:600;letter-spacing:-.004em}

/* Header: top-level links, dropdown triggers, and mega-menu entries */
.navlinks>a,.navdrop>button{font-family:var(--display);font-weight:500;letter-spacing:-.002em}
.dropmenu a b,.mm-txt b{font-family:var(--display);font-weight:600}

/* Footer: column links */
footer.site a:not(.btn){font-family:var(--display);font-weight:500}
