/* ==========================================================================
   Zedex Logistics - shared design system

   One stylesheet for every page on the marketing site: the landing page, the
   service and company pages behind the nav, and the customer doors
   (track / signin / contact). Page-specific rules stay inline on the page
   that needs them; anything two pages share belongs here.

   Font paths are relative to the site root, so every page must live at the
   root too. That is already true and keeps the URLs short (/same-day, not
   /services/same-day).
   ========================================================================== */

/* ---------- General Sans (self-hosted, subset to the 4 weights in use) ---------- */
@font-face{font-family:'General Sans';src:url('../fonts/GeneralSans-Regular.woff2') format('woff2');
  font-weight:400;font-style:normal;font-display:swap}
@font-face{font-family:'General Sans';src:url('../fonts/GeneralSans-Medium.woff2') format('woff2');
  font-weight:500;font-style:normal;font-display:swap}
@font-face{font-family:'General Sans';src:url('../fonts/GeneralSans-Semibold.woff2') format('woff2');
  font-weight:600;font-style:normal;font-display:swap}
@font-face{font-family:'General Sans';src:url('../fonts/GeneralSans-Bold.woff2') format('woff2');
  font-weight:700;font-style:normal;font-display:swap}
:root{
  --navy:#0A1D56; --navy-2:#0d2570; --navy-9:#050f2e; --navy-ink:#061238;
  --red:#E30613; --red-2:#c10510; --red-3:#ff5a63;
  --paper:#F2F4F7; --ink:#141a30; --slate:#59637a; --muted:#8792a8; --line:#e2e6ef;
  /* Theming tokens. --navy stays the brand colour in both themes; --heading is
     navy *as text*, which is the part that has to flip. Splitting them is what
     lets the navy sections (hero, promo, footer) look identical in both. */
  --bg:#fff; --surface:#fff; --heading:#0A1D56;
  --font:'General Sans',-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;
  --max:1240px;
  --sh:0 1px 2px rgba(10,29,86,.06),0 6px 18px rgba(10,29,86,.06);
  --sh-md:0 14px 40px rgba(10,29,86,.14);
  --sh-lg:0 34px 90px rgba(10,29,86,.24);
}
/* ---------- dark theme -------------------------------------------------------
   Opt-in only. Set by assets/js/zdx-theme.js writing data-theme="dark" onto
   <html>. There is deliberately NO prefers-color-scheme rule anywhere: light is
   the default for everyone, including visitors whose operating system is set to
   dark, and only an explicit click on the toggle changes that.

   This is a dim, not a blackout. Surfaces move to the brand's own navy family
   rather than to grey or black, and four things are deliberately left exactly
   as they are in light mode:

     * --navy / --navy-9 / --red   the brand colours themselves
     * every navy section          hero, promo, network, footer, subpage headers
                                   already read as dark, so they are unchanged
     * photographs                 never filtered or dimmed
     * the logo                    same asset, same colours

   The result is a page that dims around artwork that stays put, which is what
   stops it feeling like a different website at night.
   -------------------------------------------------------------------- */
:root[data-theme="dark"]{
  --bg:#0E1730;          /* page */
  --surface:#17203C;     /* cards and panels, a step above the page */
  --paper:#1C2647;       /* the subtle banded sections */
  --heading:#E6EAF3;     /* navy-as-text becomes off-white */
  --ink:#E6EAF3;         /* body text - off-white, not #fff, to cut glare */
  --slate:#AAB4CA;       /* secondary text */
  --muted:#94A0BA;       /* tertiary - still clears 4.5:1 on --surface */
  --line:#2A3557;        /* hairlines */
  /* Navy-tinted shadows read as a blue haze on a dark page. Go black and
     deeper, since there is less luminance contrast to carry the edge. */
  --sh:0 1px 2px rgba(0,0,0,.30),0 6px 18px rgba(0,0,0,.28);
  --sh-md:0 14px 40px rgba(0,0,0,.42);
  --sh-lg:0 34px 90px rgba(0,0,0,.55);
}

/* The handful of colours that are written literally rather than through a
   token, because they are blends rather than flat fills. Each of these is a
   higher-specificity selector than the rule it corrects, so placement here
   is safe. Every other literal in this file is white-on-navy inside a section
   that stays navy in both themes, so it needs no correction. */
[data-theme="dark"] header.site{background:rgba(14,23,48,.95)}
[data-theme="dark"] header.site.stuck{box-shadow:0 8px 28px rgba(0,0,0,.45)}
/* the lift-on-hover border, one step brighter than the resting hairline */
[data-theme="dark"] .tile:hover,
[data-theme="dark"] .f:hover,
[data-theme="dark"] .mv .m:hover,
[data-theme="dark"] .val:hover,
[data-theme="dark"] .dir:hover{border-color:#3A4670}
/* navy-tinted card borders disappear against a navy page */
[data-theme="dark"] .val,
[data-theme="dark"] .mv .m{border-color:var(--line)}
/* the pale red wash behind a chosen service option */
[data-theme="dark"] .svc-opt input:checked+label{background:rgba(227,6,19,.14)}

*{box-sizing:border-box}
html{scroll-behavior:smooth}
body{margin:0;font-family:var(--font);background:var(--bg);color:var(--ink);font-size:16.5px;line-height:1.62;
  -webkit-font-smoothing:antialiased;overflow-x:hidden}
h1,h2,h3,h4{margin:0;line-height:1.08;letter-spacing:-.02em;color:var(--heading);font-weight:800}
p{margin:0}a{color:inherit;text-decoration:none}img{max-width:100%;display:block}
.wrap{max-width:var(--max);margin:0 auto;padding:0 24px}
.eyebrow{font-weight:800;font-size:15px;letter-spacing:.15em;text-transform:uppercase;color:var(--red);
  display:inline-flex;align-items:center;gap:10px}
.eyebrow .leaf{width:17px;height:17px;flex:0 0 auto}
.eyebrow.on-navy{color:var(--red-3)}

.btn{display:inline-flex;align-items:center;gap:10px;font-weight:700;font-size:15.5px;padding:15px 28px;
  border-radius:10px;border:2px solid transparent;cursor:pointer;white-space:nowrap;
  transition:transform .18s cubic-bezier(.2,.7,.2,1),box-shadow .18s,background .18s,border-color .18s}
.btn:active{transform:translateY(1px)}
.btn-red{background:var(--red);color:#fff;box-shadow:0 12px 28px rgba(227,6,19,.3)}
.btn-red:hover{background:var(--red-2);transform:translateY(-2px);box-shadow:0 18px 38px rgba(227,6,19,.38)}
.btn-navy{background:var(--navy);color:#fff}
.btn-navy:hover{background:var(--navy-2);transform:translateY(-2px)}
.btn-ghost{background:transparent;color:var(--heading);border-color:var(--line)}
.btn-ghost:hover{border-color:var(--heading)}
.btn-ghost.on-navy{color:#fff;border-color:rgba(255,255,255,.45)}
.btn-ghost.on-navy:hover{border-color:#fff;background:rgba(255,255,255,.1)}
.btn .arw{transition:transform .18s}.btn:hover .arw{transform:translateX(4px)}

/* ---------- utility + header ---------- */
.util{background:var(--navy-9);color:rgba(255,255,255,.82);font-size:13px}
.util .wrap{display:flex;justify-content:flex-end;align-items:center;gap:20px;height:42px}
.util a{display:inline-flex;align-items:center;gap:7px;color:rgba(255,255,255,.82);font-weight:500;transition:.15s}
.util a:hover{color:#fff}
.util a+a{border-left:1px solid rgba(255,255,255,.2);padding-left:20px}
.util svg{width:14px;height:14px}
header.site{position:sticky;top:0;z-index:60;background:rgba(255,255,255,.95);backdrop-filter:blur(14px);
  border-bottom:1px solid var(--line);transition:box-shadow .25s}
header.site.stuck{box-shadow:0 8px 28px rgba(10,29,86,.1)}
header.site .bar{display:flex;align-items:center;justify-content:space-between;height:78px;gap:20px}
/* The logo sits in an <a> that is a flex child of .bar. Without flex:0 0 auto
   the anchor shrinks when the CTA and burger crowd it, and the global
   img{max-width:100%} then squashes the logo horizontally while height:44px
   holds it tall - so it distorts instead of scaling. max-width:none stops
   that, and the anchor is no longer allowed to shrink. */
header.site .bar > a{flex:0 0 auto;display:flex;align-items:center;min-width:0}
.brand-logo{height:44px;width:auto;max-width:none;flex:0 0 auto}
/* ---------- pill navigation ----------------------------------------------
   One navy pill slides behind whichever link is hovered, and rests on the
   section you are actually reading. This is the Framer Motion "NavHeader"
   behaviour rebuilt in plain CSS + JS, because this site has no build step
   (see the note in README â€” three static files, no bundler, no React).
   -------------------------------------------------------------------- */
nav.main{position:relative;display:flex;align-items:center;gap:2px;
  background:var(--paper);border:1px solid var(--line);border-radius:999px;padding:5px}
nav.main .navcursor{position:absolute;z-index:1;top:5px;left:0;width:0;height:calc(100% - 10px);
  border-radius:999px;background:var(--navy);opacity:0;pointer-events:none;
  box-shadow:0 6px 18px rgba(10,29,86,.30);
  transition:left .34s cubic-bezier(.22,.8,.2,1),width .34s cubic-bezier(.22,.8,.2,1),opacity .22s ease}
nav.main a.lnk{position:relative;z-index:2;font-weight:600;font-size:14.5px;color:var(--slate);
  padding:9px 16px;border-radius:999px;white-space:nowrap;transition:color .26s ease}
nav.main a.lnk.on{color:#fff}
@media (prefers-reduced-motion:reduce){
  nav.main .navcursor{transition:opacity .15s ease}
}
.nav-cta{display:flex;align-items:center;gap:12px}
.menu-btn{display:none;background:none;border:0;cursor:pointer;padding:8px}
.menu-btn span{display:block;width:24px;height:2px;background:var(--navy);margin:5px 0;border-radius:2px;transition:.25s}
.menu-btn.on span:nth-child(1){transform:translateY(7px) rotate(45deg)}
.menu-btn.on span:nth-child(2){opacity:0}
.menu-btn.on span:nth-child(3){transform:translateY(-7px) rotate(-45deg)}

/* ---------- HERO ---------- */
.hero{position:relative;min-height:clamp(520px,72vh,720px);display:flex;align-items:center;
  background:var(--navy-9);color:#fff;overflow:hidden;padding:80px 0 150px}
.hero .aurora{position:absolute;inset:-30%;pointer-events:none;filter:blur(16px);
  background:radial-gradient(38% 44% at 20% 30%, rgba(29,60,160,.6), transparent 62%),
             radial-gradient(34% 40% at 80% 24%, rgba(227,6,19,.22), transparent 64%),
             radial-gradient(46% 52% at 60% 80%, rgba(16,38,120,.6), transparent 66%);
  animation:drift 28s ease-in-out infinite alternate}
@keyframes drift{0%{transform:translate3d(-2%,-1%,0) scale(1)}50%{transform:translate3d(2%,2%,0) scale(1.07)}
  100%{transform:translate3d(-1%,1%,0) scale(1.02)}}
.hero .grid{position:absolute;inset:0;pointer-events:none;opacity:.4;
  background-image:radial-gradient(rgba(255,255,255,.12) 1.2px,transparent 1.2px);background-size:28px 28px;
  -webkit-mask-image:linear-gradient(to bottom,#000 0,#000 55%,transparent 100%);
  mask-image:linear-gradient(to bottom,#000 0,#000 55%,transparent 100%)}
/* ---------- hero artwork -----------------------------------------------------
   Three drawn scenes instead of a stock clip, one per headline: the route a
   parcel takes, the proof captured at the door, and the volume an account
   carries. They cross-fade with the slides, so the background is always
   illustrating the sentence being read.

   Built the same way as the nav pill and the network map: CSS keyframes and
   SVG, no React and no bundler (see the note in README - three static files).
   Everything is drawn from primitives, so the whole hero costs about 6 KB and
   stays crisp at any width instead of a 2 MB video that softens on a 4K panel.
   -------------------------------------------------------------------- */
.heroart{position:absolute;inset:0;z-index:0;pointer-events:none;overflow:hidden}
/* Fade out, then in - not a true cross-fade. Two scenes at full strength at
   once reads as a muddle of unrelated lines, so the outgoing one clears first
   and the incoming one arrives behind it. */
.heroart .scene{position:absolute;inset:0;width:100%;height:100%;
  opacity:0;transition:opacity .42s ease;
  -webkit-mask-image:linear-gradient(100deg,transparent 0%,#000 34%,#000 100%);
  mask-image:linear-gradient(100deg,transparent 0%,#000 34%,#000 100%)}
.heroart .scene.on{opacity:1;transition:opacity .8s ease .3s}
/* an inactive scene keeps its frame but stops costing anything to run */
.heroart .scene:not(.on) *{animation-play-state:paused!important}

/* shared drawing language ------------------------------------------------- */
.heroart .struct{stroke:rgba(255,255,255,.10);stroke-width:1.5;fill:none}
.heroart .panel{fill:rgba(255,255,255,.045);stroke:rgba(255,255,255,.16);stroke-width:1.5}
.heroart .bar{fill:rgba(255,255,255,.16)}
.heroart .bar.dim{fill:rgba(255,255,255,.09)}
.heroart .node{fill:#fff}
.heroart .hub{fill:var(--red)}
.heroart .accent{fill:var(--red-3)}

/* the route itself: marching dashes, with a red pulse running the length */
.heroart .rt{fill:none;stroke:rgba(255,255,255,.26);stroke-width:2.5;stroke-linecap:round;
  stroke-dasharray:6 9;animation:hdash 4s linear infinite}
@keyframes hdash{to{stroke-dashoffset:-30}}
/* Two pulses, half a cycle apart, so the route is never empty. One vehicle on
   a loop reads as a demo that has stopped; a road with something always on it
   reads as a service that is running. */
.heroart .rt-live{fill:none;stroke:var(--red-3);stroke-width:3;stroke-linecap:round;
  stroke-dasharray:70 900;stroke-dashoffset:70;animation:hpulse 7.2s linear infinite}
.heroart .rt-live.b{animation-delay:-3.6s;opacity:.55}
@keyframes hpulse{0%{stroke-dashoffset:70;opacity:0}
  6%{opacity:1}84%{opacity:1}100%{stroke-dashoffset:-900;opacity:0}}

/* a pin that keeps sending out a ring */
.heroart .halo{fill:none;stroke:var(--red);stroke-width:2;opacity:0;
  animation:hhalo 3.4s ease-out infinite}
@keyframes hhalo{0%{r:8;opacity:.8}70%{r:34;opacity:0}100%{r:34;opacity:0}}
.heroart .halo.b{animation-delay:1.7s}

/* The vans running the route. Linear, not eased: a courier holds a steady
   speed, and an ease-in-out here makes the van look like it is braking for
   no reason halfway down the road. The second van is offset half a cycle so
   there is always one in view. */
.heroart .van{offset-path:path("M735 612 C 858 612 892 470 1010 452 S 1178 372 1268 258");
  offset-rotate:auto;animation:hrun 7.2s linear infinite}
.heroart .van.b{animation-delay:-3.6s;opacity:.5}
@keyframes hrun{0%{offset-distance:0%;opacity:0}
  6%{opacity:1}84%{opacity:1}100%{offset-distance:100%;opacity:0}}

/* Status chips lighting up in the order they actually happen. They hold until
   the next one arrives rather than blinking out, so at any moment the picture
   shows a delivery mid-journey instead of an empty frame. */
.heroart .chip{opacity:0;animation:hchip 7.2s ease-in-out infinite}
.heroart .chip.c1{animation-delay:.4s}
.heroart .chip.c2{animation-delay:2.6s}
.heroart .chip.c3{animation-delay:4.8s}
@keyframes hchip{0%{opacity:0;transform:translateY(7px)}
  7%{opacity:1;transform:none}72%{opacity:1;transform:none}
  82%{opacity:0;transform:translateY(-5px)}100%{opacity:0;transform:translateY(-5px)}}

/* scene 2: the signature drawing itself, then the stamp landing */
.heroart .sig{fill:none;stroke:#fff;stroke-width:3.4;stroke-linecap:round;stroke-linejoin:round;
  stroke-dasharray:620;stroke-dashoffset:620;animation:hsig 6.4s ease-in-out infinite}
@keyframes hsig{0%{stroke-dashoffset:620}42%{stroke-dashoffset:0}
  88%{stroke-dashoffset:0;opacity:1}100%{stroke-dashoffset:0;opacity:0}}
.heroart .stamp{transform-box:fill-box;transform-origin:center;opacity:0;
  animation:hstamp 6.4s cubic-bezier(.2,1.5,.4,1) infinite}
@keyframes hstamp{0%,46%{opacity:0;transform:scale(.4)}
  56%{opacity:1;transform:scale(1)}88%{opacity:1;transform:scale(1)}
  100%{opacity:0;transform:scale(1)}}
.heroart .shutter{transform-box:fill-box;transform-origin:center;
  animation:hshutter 6.4s ease-in-out infinite}
@keyframes hshutter{0%,12%{opacity:.25;transform:scale(1)}
  18%{opacity:1;transform:scale(1.08)}26%{opacity:.25;transform:scale(1)}100%{opacity:.25}}

/* scene 3: parcels riding the belts. They start at x=780 in the viewBox and
   run off the right edge, so they never cross the headline column. */
.heroart .flow{animation:hflow linear infinite}
@keyframes hflow{0%{transform:translateX(0)}100%{transform:translateX(740px)}}
.heroart .f1{animation-duration:9s}
.heroart .f2{animation-duration:11s;animation-delay:-3s}
.heroart .f3{animation-duration:7.6s;animation-delay:-5s}
.heroart .f4{animation-duration:12.5s;animation-delay:-1.5s}
.heroart .f5{animation-duration:8.6s;animation-delay:-6.5s}
/* the running total ticking up under them */
.heroart .rise{transform-box:fill-box;transform-origin:bottom;
  animation:hrise 5.2s ease-in-out infinite alternate}
.heroart .r1{animation-delay:-.2s}.heroart .r2{animation-delay:-1.1s}
.heroart .r3{animation-delay:-2.0s}.heroart .r4{animation-delay:-2.9s}
@keyframes hrise{0%{transform:scaleY(.42)}100%{transform:scaleY(1)}}

/* On a phone the viewBox is cropped hard to the middle, which drops the
   headline straight on top of the storytelling parts. So the art keeps only
   its structure - streets, routes and pins - and reads as a map texture. */
@media (max-width:820px){
  .heroart{opacity:.45}
  .heroart .scene{-webkit-mask-image:linear-gradient(180deg,transparent 0%,#000 44%);
    mask-image:linear-gradient(180deg,transparent 0%,#000 44%)}
  .heroart .chip,.heroart .van,.heroart .flow,.heroart .panel,.heroart .bar,
  .heroart .sig,.heroart .stamp,.heroart .shutter,.heroart .rise{display:none}
}
.hero .wrap{position:relative;z-index:2;width:100%}
.slides{position:relative;min-height:300px}
.slide{position:absolute;inset:0;opacity:0;transform:translateY(18px);pointer-events:none;
  transition:opacity .7s ease,transform .7s cubic-bezier(.2,.7,.2,1)}
.slide.on{opacity:1;transform:none;pointer-events:auto;position:relative}
.hero h1{color:#fff;font-size:clamp(38px,6vw,72px);letter-spacing:-.028em;max-width:16ch}
.hero h1 .accent{color:var(--red-3)}
.hero .lede{font-size:19.5px;color:rgba(255,255,255,.85);margin-top:22px;max-width:56ch}
.hero .cta-row{display:flex;gap:14px;margin-top:34px;flex-wrap:wrap}
.dots{display:flex;gap:9px;margin-top:36px}
.dots button{width:34px;height:4px;border:0;border-radius:3px;background:rgba(255,255,255,.28);cursor:pointer;
  padding:0;transition:.25s}
.dots button.on{background:var(--red);width:52px}

/* ---------- quick action tiles ----------------------------------------------
   Each tile opens on a photograph of the job it describes. All four pictures
   are graded to the same cool, low-saturation look and finished with a navy
   scrim, so the row reads as one commissioned shoot rather than four stock
   pulls, and the red icon badge is the only saturated thing in the frame.
   -------------------------------------------------------------------- */
.quick{position:relative;z-index:5;margin-top:-92px}
.quick .grid4{display:grid;grid-template-columns:repeat(4,1fr);gap:16px}
.tile{position:relative;isolation:isolate;overflow:hidden;background:var(--surface);border:1px solid var(--line);
  border-radius:20px;box-shadow:var(--sh-md);
  display:flex;flex-direction:column;
  transition:transform .38s cubic-bezier(.22,.9,.24,1),box-shadow .38s cubic-bezier(.22,.9,.24,1),
             border-color .3s ease}
.tile:hover{transform:translateY(-7px);border-color:#d4dcec;
  box-shadow:0 3px 6px rgba(10,29,86,.05),0 26px 60px rgba(10,29,86,.17)}
.tile:focus-visible{outline:3px solid var(--red);outline-offset:3px}
.tile .pic{position:relative;display:block;aspect-ratio:16/10;overflow:hidden;background:var(--navy-9)}
.tile .pic img{width:100%;height:100%;object-fit:cover;
  transition:transform .65s cubic-bezier(.22,.9,.24,1)}
.tile:hover .pic img{transform:scale(1.055)}
.tile .pic::after{content:"";position:absolute;inset:0;pointer-events:none;
  background:linear-gradient(198deg,rgba(10,29,86,.10) 0%,rgba(10,29,86,.28) 55%,rgba(5,15,46,.78) 100%)}
.tile .ic{position:absolute;left:16px;bottom:14px;z-index:2;width:44px;height:44px;border-radius:14px;
  display:flex;align-items:center;justify-content:center;
  background:var(--red);box-shadow:0 8px 22px rgba(227,6,19,.45);
  transition:transform .38s cubic-bezier(.22,.9,.24,1)}
.tile:hover .ic{transform:translateY(-3px)}
.tile .ic svg{width:21px;height:21px;color:#fff}
.tile .body{position:relative;padding:20px 22px 24px;display:flex;flex-direction:column;gap:9px;flex:1}
/* brand hairline drawn across the join on hover */
.tile .body::before{content:"";position:absolute;left:22px;right:22px;top:0;height:2px;
  background:linear-gradient(90deg,var(--red),#ff8a90);border-radius:0 0 3px 3px;
  transform:scaleX(0);transform-origin:left;
  transition:transform .45s cubic-bezier(.22,.9,.24,1)}
.tile:hover .body::before{transform:scaleX(1)}
.tile h3{font-size:18px;letter-spacing:-.015em}
.tile p{color:var(--slate);font-size:14.5px;line-height:1.58}
.tile .go{margin-top:auto;padding-top:4px;color:var(--red);font-weight:700;font-size:14px;
  display:inline-flex;gap:7px;align-items:center}
.tile .go .arw{transition:transform .3s cubic-bezier(.22,.9,.24,1)}
.tile:hover .go .arw{transform:translateX(5px)}
@media (prefers-reduced-motion:reduce){
  .tile,.tile .ic,.tile .pic img,.tile .body::before,.tile .go .arw{transition:none}
  .tile:hover,.tile:hover .ic{transform:none}
  .tile:hover .pic img{transform:none}
}

/* ---------- audience selector ---------- */
.aud{background:var(--paper);border-top:1px solid var(--line);border-bottom:1px solid var(--line)}
.aud .wrap{padding:52px 24px;display:flex;align-items:center;gap:28px;flex-wrap:wrap;justify-content:space-between}
/* the audience strip is an inline band, so it goes red but keeps its scale -
   at 54px it would push the picker onto its own row */
.aud h2{font-size:clamp(22px,2.6vw,30px)}
.aud p{color:var(--slate);margin-top:8px}
.aud .picks{display:flex;gap:12px;flex-wrap:wrap}
.pick{background:var(--surface);border:1.5px solid var(--line);border-radius:12px;padding:14px 20px;font-weight:700;
  color:var(--heading);display:inline-flex;align-items:center;gap:10px;transition:.18s}
.pick:hover{border-color:var(--red);transform:translateY(-2px);box-shadow:var(--sh)}
.pick small{display:block;font-weight:500;color:var(--muted);font-size:12.5px}

section.block{padding:96px 0}
.sec-head{max-width:720px;margin-bottom:52px}
.sec-head.center{margin-left:auto;margin-right:auto;text-align:center}
.sec-head.center .eyebrow{justify-content:center}
.sec-head h2{font-size:clamp(30px,3.8vw,46px);margin-top:14px}
.sec-head p{color:var(--slate);font-size:17.5px;margin-top:16px}

/* ---------- solutions ---------- */
.sol{display:grid;grid-template-columns:repeat(3,1fr);gap:22px}
/* Same treatment as the track hero's picture pane: one photograph, a navy
   wash over the foot of it, the copy sitting straight on top in white. No
   card underneath, no separate text block, no edge-fading - the picture
   carries the words itself. */
.card{position:relative;background:transparent;border:0;box-shadow:none;
  transition:transform .22s}
.card .top{position:relative;min-height:460px;overflow:hidden;border-radius:20px;background:var(--navy-9)}
.card .top img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
.card .top::after{content:"";position:absolute;inset:0;
  background:linear-gradient(168deg,rgba(5,15,46,.28) 0%,rgba(10,29,86,.62) 50%,rgba(5,15,46,.96) 100%)}
/* The copy is anchored to the foot of the picture, so the bottom padding is
   what lifts it clear of the edge. At 26px it read as sitting on the rim
   rather than resting inside the frame; 40px gives it somewhere to sit. The
   block grows upward into the darkest part of the scrim, so contrast holds. */
.card-copy{position:absolute;left:0;right:0;bottom:0;z-index:2;padding:28px 26px 40px;color:#fff}
.card-copy h3{color:#fff;font-size:20px;margin-bottom:9px}
.card-copy p{color:rgba(255,255,255,.82);font-size:15px}
.card-copy ul{list-style:none;padding:0;margin:16px 0 0;display:grid;gap:9px}
.card-copy li{display:flex;gap:9px;font-size:14.5px;align-items:flex-start;color:rgba(255,255,255,.9)}
.card-copy li svg{width:17px;height:17px;color:var(--red-3);flex:0 0 auto;margin-top:2px}
.card-copy .more{display:inline-flex;gap:7px;align-items:center;margin-top:18px;color:var(--red-3);font-weight:700;font-size:14.5px}

/* ---------- industries we serve ------------------------------------------
   Nine industries is too long a list to give a grid without it feeling like
   a form. A strip that scrolls itself says "we cover a lot of ground"
   without asking the reader to read all nine - the list is duplicated once
   so the loop has no seam, and it pauses on hover for anyone who wants to
   actually read a label. */
.ind-rail{position:relative;overflow:hidden;width:100%;margin-top:46px;
  -webkit-mask-image:linear-gradient(to right, transparent 0, #000 90px, #000 calc(100% - 90px), transparent 100%);
  mask-image:linear-gradient(to right, transparent 0, #000 90px, #000 calc(100% - 90px), transparent 100%)}
/* Travels left to right. The second, aria-hidden copy of the chips sits to the
   left of the visible set once the track is offset, so running the same
   keyframes in reverse moves the row rightwards with no seam and no second
   animation to keep in step. */
.ind-track{display:flex;align-items:center;gap:16px;width:max-content;
  animation:indScroll 36s linear infinite reverse}
.ind-track:hover{animation-play-state:paused}
@keyframes indScroll{from{transform:translateX(0)}to{transform:translateX(-50%)}}
.ind-chip{display:inline-flex;align-items:center;gap:12px;flex:0 0 auto;white-space:nowrap;
  background:var(--surface);border:1.5px solid var(--line);border-radius:14px;padding:12px 22px 12px 12px;
  font-weight:700;color:var(--heading);font-size:15px;transition:border-color .2s ease,box-shadow .2s ease}
.ind-chip:hover{border-color:var(--red);box-shadow:var(--sh)}
.ind-ic{display:flex;align-items:center;justify-content:center;flex:0 0 auto;
  width:38px;height:38px;border-radius:10px;background:rgba(227,6,19,.09)}
.ind-ic svg{width:20px;height:20px;color:var(--red)}
@media (max-width:700px){
  .ind-rail{margin-top:34px;
    -webkit-mask-image:linear-gradient(to right, transparent 0, #000 44px, #000 calc(100% - 44px), transparent 100%);
    mask-image:linear-gradient(to right, transparent 0, #000 44px, #000 calc(100% - 44px), transparent 100%)}
  .ind-chip{padding:10px 18px 10px 10px;font-size:14px;gap:10px}
  .ind-ic{width:33px;height:33px}
  .ind-ic svg{width:18px;height:18px}
}
/* Reduced motion: stopping the animation is not enough on its own. The track is
   width:max-content inside an overflow:hidden rail, so a frozen marquee shows
   the first few chips and clips the rest away — anyone who has asked for less
   motion silently loses more than half the industries. So instead of a stalled
   strip, the chips wrap into centred rows, the edge fade comes off (there is
   nothing running off the edge any more), and the duplicate set used to make
   the loop seamless is hidden so nothing reads twice. */
@media (prefers-reduced-motion:reduce){
  .ind-rail{overflow:visible;-webkit-mask-image:none;mask-image:none;padding:0 22px}
  .ind-track{animation:none;width:auto;flex-wrap:wrap;justify-content:center;row-gap:14px}
  .ind-track > .ind-chip[aria-hidden="true"]{display:none}
}

/* ---------- portal promo -----------------------------------------------------
   The headline promises "everything in one place, on any device", so the
   section shows two of them: the deliveries list as it looks in a browser, and
   one delivery as it looks on a phone. Behind both sits a photograph of the
   work the portal is reporting on, pushed well back under a navy scrim so the
   type stays the brightest thing on screen.
   -------------------------------------------------------------------- */
.promo{position:relative;background:var(--navy-9);color:#fff;overflow:hidden}
.promo .shot{position:absolute;inset:0;z-index:0}
.promo .shot img{width:100%;height:100%;object-fit:cover;object-position:50% 42%}
.promo .shot::after{content:"";position:absolute;inset:0;
  background:linear-gradient(102deg,rgba(5,15,46,.97) 0%,rgba(10,29,86,.95) 36%,
             rgba(10,29,86,.78) 66%,rgba(5,15,46,.91) 100%)}
/* stacked, the copy sits over the whole frame, so the scrim goes flat and dark */
@media (max-width:900px){
  .promo .shot::after{background:rgba(6,17,52,.93)}
}
.promo .grid{position:absolute;inset:0;z-index:1;opacity:.35;
  background-image:radial-gradient(rgba(255,255,255,.1) 1.3px,transparent 1.3px);background-size:26px 26px}
.promo .wrap{position:relative;z-index:2;padding:92px 24px;display:grid;grid-template-columns:1fr 1fr;
  gap:56px;align-items:center}
.promo h2{color:#fff;font-size:clamp(28px,3.5vw,42px)}
.promo p{color:rgba(255,255,255,.82);font-size:17.5px;margin-top:16px}
.promo ul{list-style:none;padding:0;margin:24px 0 0;display:grid;gap:12px}
.promo li{display:flex;gap:11px;color:rgba(255,255,255,.9);font-size:15.5px}
.promo li svg{width:19px;height:19px;color:var(--red-3);flex:0 0 auto;margin-top:2px}

/* the two devices, stood side by side on a shared baseline. They deliberately
   do not overlap: a phone laid over the list would cover the tracking numbers,
   which are the one thing this picture exists to show. */
.devices{display:flex;align-items:flex-end;gap:18px}
.win{flex:1 1 auto;min-width:0;background:linear-gradient(168deg,rgba(15,32,84,.92),rgba(8,21,65,.92));
  border:1px solid rgba(255,255,255,.17);border-radius:15px;overflow:hidden;
  backdrop-filter:blur(10px);box-shadow:var(--sh-lg)}
.win .chrome{display:flex;align-items:center;gap:7px;padding:11px 14px;
  background:rgba(255,255,255,.07);border-bottom:1px solid rgba(255,255,255,.11)}
.win .chrome i{width:9px;height:9px;border-radius:50%;background:rgba(255,255,255,.25);flex:0 0 auto}
.win .chrome .url{margin-left:8px;font-size:11.5px;color:rgba(255,255,255,.62);
  background:rgba(255,255,255,.08);border-radius:6px;padding:3px 11px;white-space:nowrap;
  overflow:hidden;text-overflow:ellipsis}
.mock{padding:16px}
.mock .mhead{display:flex;align-items:baseline;justify-content:space-between;gap:12px;
  margin:0 2px 12px}
.mock .mhead b{font-size:14.5px;letter-spacing:-.01em}
.mock .mhead span{font-size:11.5px;color:rgba(255,255,255,.58)}
.mock .row{display:flex;align-items:center;justify-content:space-between;gap:12px;
  padding:13px 14px;border-radius:11px;background:rgba(255,255,255,.07);margin-bottom:9px}
.mock .row:last-child{margin-bottom:0}
.mock .t{font-weight:700;font-variant-numeric:tabular-nums}
.mock .s{font-size:12px;color:rgba(255,255,255,.6);margin-top:2px}
.pill{font-size:11px;font-weight:700;padding:5px 11px;border-radius:20px;text-transform:uppercase;
  letter-spacing:.05em;white-space:nowrap;flex:0 0 auto}
.pill.a{background:rgba(46,204,113,.22);color:#7ff0b0}
.pill.b{background:rgba(227,6,19,.24);color:#ff9aa0}
.pill.c{background:rgba(255,255,255,.16);color:#fff}

.phone{flex:0 0 auto;width:158px;margin-bottom:-14px;
  background:#0a1740;border:1px solid rgba(255,255,255,.22);border-radius:24px;padding:8px 7px 10px;
  box-shadow:0 30px 70px rgba(0,0,0,.5)}
.phone .notch{width:52px;height:5px;border-radius:3px;background:rgba(255,255,255,.24);margin:1px auto 9px}
.phone .pbody{background:rgba(255,255,255,.07);border-radius:17px;padding:13px 12px 14px}
.phone .ptag{font-size:11.5px;font-weight:700;color:rgba(255,255,255,.6);
  font-variant-numeric:tabular-nums;letter-spacing:.03em}
.phone .ptitle{font-size:16px;font-weight:800;margin:3px 0 12px;letter-spacing:-.02em}
.phone .ptl{list-style:none;padding:0;margin:0;display:grid;gap:0}
.phone .ptl li{position:relative;padding:0 0 13px 20px;font-size:11.5px;color:rgba(255,255,255,.5);
  line-height:1.35}
.phone .ptl li:last-child{padding-bottom:0}
/* the rail runs between the dots, so it must stop at the last one */
.phone .ptl li::before{content:"";position:absolute;left:3.5px;top:11px;bottom:-2px;width:2px;
  background:rgba(255,255,255,.16)}
.phone .ptl li:last-child::before{display:none}
.phone .ptl li::after{content:"";position:absolute;left:0;top:3px;width:9px;height:9px;border-radius:50%;
  background:rgba(255,255,255,.22)}
.phone .ptl li.on{color:rgba(255,255,255,.78)}
.phone .ptl li.on::after{background:#7ff0b0}
.phone .ptl li.now{color:#fff;font-weight:700}
.phone .ptl li.now::after{background:var(--red);box-shadow:0 0 0 4px rgba(227,6,19,.26)}
.phone .ptl b{display:block;font-weight:inherit}
.phone .ptl em{font-style:normal;color:rgba(255,255,255,.45);font-variant-numeric:tabular-nums}

/* ---------- steps ---------- */
.steps{position:relative;display:grid;grid-template-columns:repeat(4,1fr);gap:26px}
.rail{position:absolute;top:9px;left:0;right:0;height:3px;background:var(--line);border-radius:2px;overflow:hidden}
.rail .fill{height:100%;width:0;background:linear-gradient(90deg,var(--red),var(--navy));
  transition:width 1.5s cubic-bezier(.3,0,.2,1)}
.hstep{position:relative;padding-top:32px}
.hstep .knob{position:absolute;top:2px;left:0;width:17px;height:17px;border-radius:50%;background:var(--surface);
  border:3.5px solid var(--line);transition:border-color .5s,transform .5s}
.hstep.lit .knob{border-color:var(--red);transform:scale(1.15)}
.hstep .num{font-weight:800;font-size:12.5px;letter-spacing:.1em;color:var(--red)}
.hstep h4{font-size:19px;margin:12px 0 9px}
.hstep p{color:var(--slate);font-size:15px}

/* ---------- counters ---------- */
.counters{background:var(--bg);padding:0 0 92px}
.counters .wrap{display:grid;grid-template-columns:repeat(4,1fr);gap:26px}
.counter{text-align:center;padding:8px 14px;position:relative}
.counter+.counter::before{content:"";position:absolute;left:0;top:12%;height:76%;width:1px;background:var(--line)}
.counter .n{font-weight:800;font-size:clamp(34px,4.2vw,52px);line-height:1;letter-spacing:-.03em;color:var(--heading);
  font-variant-numeric:tabular-nums}
.counter .n .u{color:var(--red)}
.counter .l{color:var(--slate);font-size:14.5px;margin-top:12px}

/* ---------- why -------------------------------------------------------------
   Six claims, each one carrying the artefact that proves it: the status rail a
   customer actually watches, the signature that actually gets captured, the
   rate line that actually prices a job. Every card is a link to the place on
   the site where you can do that thing, so the grid is navigation, not
   decoration.
   -------------------------------------------------------------------- */
.feat{display:grid;grid-template-columns:repeat(3,1fr);gap:22px}
.f{position:relative;isolation:isolate;overflow:hidden;background:var(--surface);
  border:1px solid rgba(10,29,86,.09);
  border-radius:22px;padding:30px 28px 26px;
  display:flex;flex-direction:column;
  box-shadow:0 1px 2px rgba(10,29,86,.05),0 10px 28px rgba(10,29,86,.055);
  transition:transform .38s cubic-bezier(.22,.9,.24,1),box-shadow .38s cubic-bezier(.22,.9,.24,1),
             border-color .3s ease}
/* a barely-there wash, revealed on hover â€” the resting state stays clean */
.f::before{content:"";position:absolute;inset:0;z-index:-1;opacity:0;
  background:linear-gradient(168deg,#fff 0%,#fbfcfe 46%,#f5f8fd 100%);transition:opacity .38s ease}
/* brand hairline drawn along the top edge on hover */
.f::after{content:"";position:absolute;left:26px;right:26px;top:0;height:2px;
  background:linear-gradient(90deg,var(--red),#ff8a90);border-radius:0 0 3px 3px;
  transform:scaleX(0);transform-origin:left;
  transition:transform .45s cubic-bezier(.22,.9,.24,1)}
.f:hover{transform:translateY(-6px);border-color:#d4dcec;
  box-shadow:0 2px 4px rgba(10,29,86,.04),0 18px 44px rgba(10,29,86,.13)}
.f:hover::before{opacity:1}
.f:hover::after{transform:scaleX(1)}
.f:focus-visible{outline:3px solid var(--red);outline-offset:3px}
.f .fh{display:flex;align-items:center;gap:11px;margin-bottom:11px}
.f .fi{width:24px;height:24px;color:var(--red);flex:0 0 auto;
  transition:transform .38s cubic-bezier(.3,1.3,.5,1)}
.f:hover .fi{transform:translateY(-2px) scale(1.06)}
.f h4{font-size:19px;letter-spacing:-.02em;margin:0}
.f p{color:var(--slate);font-size:15.5px;line-height:1.64}
.f .go{margin-top:18px;color:var(--red);font-weight:700;font-size:14px;
  display:inline-flex;gap:7px;align-items:center}
.f .go .arw{transition:transform .3s cubic-bezier(.22,.9,.24,1)}
.f:hover .go .arw{transform:translateX(5px)}

/* the proof strip: a fragment of the real thing, not an illustration of it */
.f .proof{margin-top:auto;padding-top:17px;border-top:1px solid var(--line)}
/* a) the status rail a customer watches */
.prail{display:flex}
.prail span{position:relative;flex:1;padding-top:17px;text-align:center;font-size:10px;font-weight:800;
  letter-spacing:.045em;text-transform:uppercase;color:var(--muted)}
.prail span::after{content:"";position:absolute;top:7px;left:50%;width:100%;height:2px;
  background:var(--line);z-index:0}
.prail span:last-child::after{display:none}
.prail span::before{content:"";position:absolute;top:3px;left:50%;transform:translateX(-50%);z-index:1;
  width:9px;height:9px;border-radius:50%;background:var(--line)}
.prail span.done{color:var(--slate)}
.prail span.done::before{background:#2ecc71}
.prail span.done::after{background:#2ecc71}
.prail span.live{color:var(--heading)}
.prail span.live::before{background:var(--red);box-shadow:0 0 0 4px rgba(227,6,19,.15)}
/* b) the signature that gets captured at the door */
.psig{display:flex;align-items:flex-end;justify-content:space-between;gap:14px}
.psig svg{width:112px;height:36px;color:var(--heading);flex:0 0 auto}
.psig .who{font-size:11px;color:var(--muted);text-align:right;line-height:1.45;
  font-variant-numeric:tabular-nums}
.psig .who b{display:block;color:var(--heading);font-size:12.5px}
/* c) + d) a priced job, and the invoice it lands on */
.prate{display:grid;gap:6px;font-variant-numeric:tabular-nums}
.prate div{display:flex;justify-content:space-between;align-items:baseline;gap:12px;font-size:12.5px;
  color:var(--heading)}
.prate div span:first-child{color:var(--slate)}
.prate div.tot{margin-top:3px;padding-top:7px;border-top:1px dashed var(--line);
  font-size:13.5px;font-weight:800}
.prate div.tot span:first-child{color:var(--heading)}
/* e) the label a driver scans */
.pscan{display:flex;align-items:center;gap:13px}
.pscan .bars{flex:0 0 auto;width:98px;height:36px;border-radius:5px;background-color:#fff;
  border:1px solid var(--line);
  background-image:repeating-linear-gradient(90deg,var(--navy) 0 2px,transparent 2px 5px,
    var(--navy) 5px 9px,transparent 9px 11px,var(--navy) 11px 12px,transparent 12px 16px);
  background-position:center;background-size:88% 62%;background-repeat:no-repeat}
.pscan .meta{font-size:11px;color:var(--muted);line-height:1.45;font-variant-numeric:tabular-nums}
.pscan .meta b{display:block;color:var(--heading);font-size:12.5px}
/* f) the named driver on the job */
.pbadge{display:flex;align-items:center;gap:11px}
.pbadge .av{flex:0 0 auto;width:34px;height:34px;border-radius:50%;background:var(--navy);color:#fff;
  display:flex;align-items:center;justify-content:center;font-weight:800;font-size:12px;letter-spacing:.02em}
.pbadge .nm{font-size:12.5px;color:var(--heading);font-weight:700;line-height:1.3}
.pbadge .nm small{display:block;font-weight:500;color:var(--muted);font-size:11px;
  font-variant-numeric:tabular-nums}
.pbadge .shift{margin-left:auto;flex:0 0 auto;font-size:10px;font-weight:800;letter-spacing:.05em;
  text-transform:uppercase;color:#12703f;background:rgba(46,204,113,.15);border-radius:20px;padding:4px 9px}
@media (prefers-reduced-motion:reduce){
  .f,.f .fi,.f::after,.f::before,.f .go .arw{transition:none}
  .f:hover,.f:hover .fi{transform:none}
}

/* ---------- mission, vision & values ---------- */
.mv{display:grid;grid-template-columns:1fr 1fr;gap:22px;margin-bottom:26px}
.mv .m{position:relative;isolation:isolate;overflow:hidden;background:var(--surface);
  border:1px solid rgba(10,29,86,.09);border-radius:22px;padding:36px 34px;
  box-shadow:0 1px 2px rgba(10,29,86,.05),0 10px 28px rgba(10,29,86,.055);
  transition:transform .38s cubic-bezier(.22,.9,.24,1),box-shadow .38s cubic-bezier(.22,.9,.24,1),
             border-color .3s ease}
.mv .m::after{content:"";position:absolute;left:0;top:34px;bottom:34px;width:3px;
  background:linear-gradient(180deg,var(--red),#ff8a90);border-radius:0 3px 3px 0;
  transform:scaleY(.35);transform-origin:top;
  transition:transform .5s cubic-bezier(.22,.9,.24,1)}
.mv .m:hover{transform:translateY(-5px);border-color:#d4dcec;
  box-shadow:0 2px 4px rgba(10,29,86,.04),0 18px 44px rgba(10,29,86,.13)}
.mv .m:hover::after{transform:scaleY(1)}
.mv .m .ic{width:52px;height:52px;border-radius:16px;display:flex;align-items:center;
  justify-content:center;margin-bottom:18px;
  background:linear-gradient(158deg,#fff5f5,#ffe9eb);
  box-shadow:inset 0 0 0 1px rgba(227,6,19,.11),0 4px 12px rgba(227,6,19,.09)}
.mv .m .ic svg{width:25px;height:25px;color:var(--red)}
.mv .m h3{font-size:22px;letter-spacing:-.02em;margin-bottom:11px}
.mv .m p{color:var(--slate);font-size:15.5px;line-height:1.68}

/* seven values into rows of four leaves a dead slot, so the last row is
   centred rather than left-aligned against an empty cell */
.vals{display:flex;flex-wrap:wrap;justify-content:center;gap:16px;margin-top:34px}
.val{flex:1 1 230px;max-width:calc(25% - 12px);
  position:relative;background:var(--surface);border:1px solid rgba(10,29,86,.08);border-radius:18px;
  padding:24px 22px 22px;box-shadow:0 1px 2px rgba(10,29,86,.04);
  transition:transform .32s cubic-bezier(.22,.9,.24,1),box-shadow .32s ease,border-color .28s ease}
.val:hover{transform:translateY(-4px);border-color:#d4dcec;
  box-shadow:0 2px 4px rgba(10,29,86,.04),0 14px 34px rgba(10,29,86,.11)}
.val .vic{width:40px;height:40px;border-radius:12px;display:flex;align-items:center;justify-content:center;
  margin-bottom:14px;background:linear-gradient(158deg,#f2f5fb,#e7ecf7);
  box-shadow:inset 0 0 0 1px rgba(10,29,86,.07);transition:background .3s ease,box-shadow .3s ease}
.val:hover .vic{background:linear-gradient(158deg,#fff1f2,#ffe2e4);
  box-shadow:inset 0 0 0 1px rgba(227,6,19,.16)}
.val .vic svg{width:20px;height:20px;color:var(--heading);transition:color .3s ease}
.val:hover .vic svg{color:var(--red)}
.val h4{font-size:16.5px;margin-bottom:7px;letter-spacing:-.015em}
.val p{color:var(--slate);font-size:14.5px;line-height:1.6}

.promise{margin-top:34px;position:relative;overflow:hidden;border-radius:22px;
  background:linear-gradient(150deg,#fff,#fbfcfe 55%,#f4f7fd);
  border:1px solid rgba(10,29,86,.09);padding:38px 40px;
  box-shadow:0 1px 2px rgba(10,29,86,.05),0 12px 32px rgba(10,29,86,.06)}
.promise::before{content:"";position:absolute;left:0;top:0;bottom:0;width:4px;
  background:linear-gradient(180deg,var(--red),#ff8a90)}
.promise .eyebrow{margin-bottom:12px}
.promise p{font-size:18.5px;line-height:1.62;color:var(--heading);font-weight:500;
  letter-spacing:-.012em;max-width:900px}
.promise p b{font-weight:700}

/* ---------- leadership ---------- */
.lead{display:grid;grid-template-columns:1fr 1fr;gap:26px}
.dir{position:relative;isolation:isolate;overflow:hidden;background:var(--surface);
  border:1px solid rgba(10,29,86,.09);border-radius:24px;padding:30px 30px 32px;
  box-shadow:0 1px 2px rgba(10,29,86,.05),0 10px 28px rgba(10,29,86,.055);
  transition:transform .38s cubic-bezier(.22,.9,.24,1),box-shadow .38s cubic-bezier(.22,.9,.24,1),
             border-color .3s ease}
.dir::after{content:"";position:absolute;left:30px;right:30px;top:0;height:2px;
  background:linear-gradient(90deg,var(--red),#ff8a90);border-radius:0 0 3px 3px;
  transform:scaleX(0);transform-origin:left;
  transition:transform .45s cubic-bezier(.22,.9,.24,1)}
.dir:hover{transform:translateY(-6px);border-color:#d4dcec;
  box-shadow:0 2px 4px rgba(10,29,86,.04),0 22px 52px rgba(10,29,86,.14)}
.dir:hover::after{transform:scaleX(1)}
.dir-top{display:flex;gap:22px;align-items:center;margin-bottom:24px}
/* height:auto is load-bearing - the width/height attributes are presentational
   hints, and without this the height attribute wins over aspect-ratio and the
   portrait renders stretched. The attributes stay so the box is reserved
   before the image decodes. */
.dir .shot{flex:0 0 auto;width:148px;height:auto;aspect-ratio:4/5;border-radius:18px;object-fit:cover;
  object-position:center top;background:var(--paper);
  box-shadow:0 6px 20px rgba(10,29,86,.16),inset 0 0 0 1px rgba(10,29,86,.06);
  transition:transform .4s cubic-bezier(.22,.9,.24,1),box-shadow .4s ease}
.dir:hover .shot{transform:scale(1.025);box-shadow:0 12px 30px rgba(10,29,86,.22),
  inset 0 0 0 1px rgba(10,29,86,.08)}
.dir-id{min-width:0}
.dir-id h3{font-size:21px;letter-spacing:-.02em;line-height:1.18}
.dir-id .cred{margin-top:7px;color:var(--slate);font-size:13.5px;font-weight:500;line-height:1.45}
.dir-id .role{display:inline-flex;align-items:center;gap:7px;margin-top:12px;
  padding:6px 13px;border-radius:999px;background:linear-gradient(158deg,#fff5f5,#ffe9eb);
  color:var(--red);font-size:12px;font-weight:700;letter-spacing:.07em;text-transform:uppercase;
  box-shadow:inset 0 0 0 1px rgba(227,6,19,.14)}
.dir-id .role .dot{width:5px;height:5px;border-radius:50%;background:var(--red)}
.dir-bio{max-width:660px}
.dir-bio p{color:var(--slate);font-size:15px;line-height:1.68}
.dir-bio p+p{margin-top:13px}

/* iPhone SE / Galaxy S-mini territory - drop the arrow and tighten further
   so the logo still never has to shrink */
@media (prefers-reduced-motion:reduce){
  .mv .m,.val,.dir,.dir .shot,.mv .m::after,.dir::after{transition:none}
  .mv .m:hover,.val:hover,.dir:hover,.dir:hover .shot{transform:none}
}

/* ---------- network ---------- */
.net{position:relative;background:linear-gradient(165deg,var(--navy),var(--navy-9));color:#fff;overflow:hidden}
.net .grid{position:absolute;inset:0;opacity:.4;
  background-image:radial-gradient(rgba(255,255,255,.1) 1.3px,transparent 1.3px);background-size:26px 26px}
.net .wrap{position:relative;z-index:1;padding:96px 24px}
.netg{display:grid;grid-template-columns:.9fr 1.1fr;gap:54px;align-items:center}
.net h2{color:#fff;font-size:clamp(29px,3.6vw,44px)}
.net p{color:rgba(255,255,255,.82);font-size:17.5px;margin-top:16px}
.nstats{display:flex;gap:36px;margin-top:30px;flex-wrap:wrap}
.nstats .n{font-weight:800;font-size:29px}
.nstats .l{color:rgba(255,255,255,.68);font-size:13.5px;margin-top:4px}
/* The decorative network map was removed: an abstract blob with dashed
   routes to nowhere read as neither a map nor a coverage area. network.html
   carries a photograph instead. */

/* ---------- swoosh / tagline ---------- */
.swoosh{display:block;width:100%;height:auto;line-height:0}
.tagband{background:var(--navy);color:#fff;text-align:center;padding:36px 24px}
.tagband .t{font-weight:800;font-size:clamp(21px,2.6vw,32px)}
.tagband .t .dot{color:var(--red)}

/* ---------- quote ---------- */
.quote{background:var(--paper);padding:96px 0;border-top:1px solid var(--line)}
.qcard{max-width:860px;margin:0 auto;background:var(--surface);border-radius:20px;box-shadow:var(--sh-lg);
  border:1px solid var(--line);overflow:hidden}
.qhead{padding:24px 34px;border-bottom:1px solid var(--line);display:flex;align-items:center;gap:14px}
.qhead img{height:32px;width:auto;max-width:none}
.qhead .tg{margin-left:auto;font-weight:700;font-size:11.5px;letter-spacing:.13em;color:var(--muted);text-transform:uppercase}
.qbody{padding:32px 34px 36px}
.frow{display:grid;grid-template-columns:1fr 1fr;gap:20px;margin-bottom:20px}
.field{display:flex;flex-direction:column;gap:8px}
.field.full{grid-column:1/-1}
.field label{font-weight:600;font-size:14px}
.field label .req{color:var(--red)}
.field input,.field select,.field textarea{font-family:inherit;font-size:15.5px;width:100%;padding:14px 15px;
  border:1.5px solid var(--line);border-radius:11px;background:var(--surface);transition:.15s}
.field textarea{resize:vertical;min-height:98px}
.field input:focus,.field select:focus,.field textarea:focus{outline:none;border-color:var(--heading);
  box-shadow:0 0 0 4px rgba(10,29,86,.1)}
.field .hint{font-size:12.5px;color:var(--muted)}
.svc-choice{display:grid;grid-template-columns:1fr 1fr 1fr;gap:12px}
.svc-opt{position:relative}
.svc-opt input{position:absolute;opacity:0;pointer-events:none}
.svc-opt label{display:flex;flex-direction:column;gap:5px;cursor:pointer;height:100%;border:1.5px solid var(--line);
  border-radius:12px;padding:16px 17px;transition:.18s}
.svc-opt label .o-t{font-weight:700;font-size:15px}
.svc-opt label .o-s{font-size:12.5px;color:var(--muted)}
.svc-opt input:checked+label{border-color:var(--red);background:#fdf2f3;box-shadow:0 0 0 3px rgba(227,6,19,.12)}
.qfoot{display:flex;align-items:center;justify-content:space-between;gap:18px;margin-top:8px;flex-wrap:wrap}
.qfoot .priv{font-size:12.5px;color:var(--muted);max-width:400px}
.qmsg{padding:13px 16px;border-radius:10px;font-size:14px;margin-bottom:18px;display:none}
.qmsg.show{display:block}
.qmsg.err{background:#fdecec;color:#a3141b;border:1px solid #f5c9cc}
.qok{display:none;text-align:center;padding:52px 34px}
.qok.show{display:block}
.qok .chk{width:78px;height:78px;border-radius:50%;background:#2ecc71;margin:0 auto 22px;display:flex;
  align-items:center;justify-content:center;box-shadow:0 0 0 9px rgba(46,204,113,.16)}
.qok h3{font-size:27px;margin-bottom:12px}
.qok p{color:var(--slate);max-width:440px;margin:0 auto}
.spinner{width:16px;height:16px;border:2.5px solid rgba(255,255,255,.35);border-top-color:#fff;border-radius:50%;
  animation:spin .7s linear infinite;display:inline-block}
@keyframes spin{to{transform:rotate(360deg)}}

/* ---------- footer ---------- */
footer.site{background:var(--navy-9);color:#fff;padding:72px 0 34px}
.fgrid{display:grid;grid-template-columns:1.6fr 1fr 1fr 1fr;gap:38px}
/* width:auto matters: the width="466" attribute on the tag is a
   presentational hint that sets CSS width, so setting only the height here
   left the logo stretched to 466px wide. Same reason .brand-logo has it. */
.flogo{height:46px;width:auto;max-width:none;margin-bottom:18px}
.fblurb{color:rgba(255,255,255,.68);font-size:15px;max-width:310px}
.ftag{margin-top:16px;font-weight:700;font-size:14.5px}
.ftag .dot{color:var(--red)}
.fcol h5{font-size:11.5px;letter-spacing:.15em;text-transform:uppercase;color:rgba(255,255,255,.5);
  margin:0 0 16px;font-weight:700}
.fcol a{display:block;color:rgba(255,255,255,.84);font-size:15px;padding:6px 0;transition:.15s}
.fcol a:hover{color:#fff;transform:translateX(3px)}
.fbar{border-top:1px solid rgba(255,255,255,.13);margin-top:50px;padding-top:24px;display:flex;
  justify-content:space-between;align-items:center;flex-wrap:wrap;gap:14px}
.fbar span{font-size:13.5px;color:rgba(255,255,255,.56)}

/* Reveal state. Scoped to html.js on purpose: if JavaScript never runs there
   is nothing to reveal these again, so without it they must simply be visible.
   The inline script in <head> adds .js before first paint, so there is no
   flash of un-hidden content on the way in either. */
html.js .io{opacity:0;transform:translateY(28px);
  transition:opacity .8s ease,transform .8s cubic-bezier(.2,.7,.2,1)}
html.js .io.in{opacity:1;transform:none}
html.js .io.d1{transition-delay:.09s}html.js .io.d2{transition-delay:.18s}html.js .io.d3{transition-delay:.27s}

@media (max-width:1180px){
  /* six pills, a logo and a CTA is a lot of bar - tighten before it wraps */
  nav.main a.lnk{padding:9px 11px;font-size:13.5px}
}
/* Below this the pill row genuinely cannot fit beside the logo and the CTA
   (it overflowed the bar by 209px at 768px), so the burger takes over here
   rather than at 700px. The pill itself is desktop-only from now on. */
@media (max-width:1024px){
  nav.main{position:fixed;inset:78px 0 auto 0;flex-direction:column;background:var(--surface);
    border:0;border-radius:0;border-bottom:1px solid var(--line);padding:18px 24px;gap:2px;
    transform:translateY(-150%);align-items:stretch;
    transition:transform .28s cubic-bezier(.2,.7,.2,1);box-shadow:var(--sh-md);z-index:40}
  nav.main.open{transform:none}
  nav.main .navcursor{display:none}
  nav.main a.lnk{padding:13px 0;width:100%;border-radius:0;font-size:15px;
    border-bottom:1px solid var(--line)}
  nav.main a.lnk.on{color:var(--heading)}
  .menu-btn{display:block}
}
@media (max-width:1080px){
  .quick .grid4{grid-template-columns:1fr 1fr}
  .sol{grid-template-columns:1fr 1fr}
  .feat{grid-template-columns:1fr 1fr}
  .val{max-width:calc(33.333% - 11px)}
  /* one bio column below this: two 600px columns no longer fit side by side */
  .lead{grid-template-columns:1fr}
  .dir-bio{max-width:none}
}
@media (max-width:900px){
  .mv{grid-template-columns:1fr}
  .val{max-width:calc(50% - 8px)}
  .promo .wrap{grid-template-columns:1fr;gap:38px}
  .netg{grid-template-columns:1fr;gap:38px}
  .steps{grid-template-columns:1fr 1fr}
  .rail{display:none}
  .counters .wrap{grid-template-columns:1fr 1fr;gap:34px 20px}
  .counter:nth-child(3)::before{display:none}
  .fgrid{grid-template-columns:1fr 1fr;gap:30px}
}
@media (max-width:700px){
  /* logo + CTA + burger must fit the narrowest phones without anything being
     compressed, so the bar tightens rather than the logo giving way */
  header.site .bar{gap:10px;height:68px}
  .brand-logo{height:38px}
  .nav-cta{gap:6px}
  .nav-cta .btn{padding:11px 15px;font-size:13.5px;border-radius:9px}
  nav.main{inset:68px 0 auto 0}
  .val{max-width:100%;flex-basis:100%}
  .mv .m{padding:28px 24px}
  .promise{padding:30px 24px}
  .promise p{font-size:16.5px}
  .dir{padding:24px 22px 26px;border-radius:20px}
  .dir::after{left:22px;right:22px}
  /* Stack the portrait above the name so neither gets squeezed, and centre
     that block - left-aligned it leaves a lopsided empty gap beside the
     photo. The biography stays left-aligned, because centred body copy is
     hard to read. */
  .dir-top{flex-direction:column;align-items:center;text-align:center;gap:16px;margin-bottom:22px}
  .dir .shot{width:152px}
  .dir-id{width:100%}
  .dir-id .cred{margin-top:8px}
  .dir-bio{text-align:left}
  .util{display:none}
  .hero{padding:56px 0 120px;min-height:auto}
  section.block,.quote{padding:66px 0}
  .quick{margin-top:-72px}
  .quick .grid4{grid-template-columns:1fr}
  .sol,.feat,.steps{grid-template-columns:1fr}
  .counters .wrap{grid-template-columns:1fr 1fr}
  .counter::before{display:none!important}
  .fgrid{grid-template-columns:1fr 1fr}
  .frow,.svc-choice{grid-template-columns:1fr}
  .qbody{padding:24px 20px 28px}.qhead{padding:18px 20px}
  .aud .wrap{padding:38px 24px}
  /* side by side there is no room for both on a phone, so the handset drops
     below the list and centres rather than shrinking to illegibility */
  .devices{flex-direction:column;align-items:center;gap:20px}
  .win{width:100%}
  .phone{width:168px;margin-bottom:0}
}
/* These must sit AFTER the 700px block: at equal specificity the later rule
   wins, so declaring them earlier let the 700px logo height override them. */
@media (max-width:430px){
  header.site .bar{gap:8px}
  .brand-logo{height:34px}
  .nav-cta .btn{padding:10px 12px;font-size:12.5px}
  .nav-cta .btn .arw{display:none}
  .menu-btn{padding:6px}
}
/* iPhone SE and similar: reclaim the gutter too, so the logo still never
   has to give way */
@media (max-width:360px){
  .wrap{padding:0 14px}
  header.site .bar{gap:6px}
  .brand-logo{height:31px}
  .nav-cta .btn{padding:9px 10px;font-size:11.5px}
  .menu-btn{padding:4px}
  .menu-btn span{width:21px}
}
/* Some phones report "reduced motion" simply because Low Power Mode is on.
   So we keep quiet opacity fades (which are fine) and switch off only the
   large, continuous movement. */
/* ---------- handover to the motion layer -------------------------------------
   assets/js/zdx-motion.js sets .has-motion on <html> once Motion is running.
   From that point it owns transform and opacity on these elements and drives
   them with springs. The CSS transitions below must get out of the way: a
   transition and a spring on the same property fight each other, and the
   result is the mush that looks like neither.

   Everything here is additive. Without the class - script blocked, old
   browser, reduced motion - the original CSS behaviour is exactly what it was.
   -------------------------------------------------------------------- */
html.has-motion .io{transition:none}
html.has-motion .tile,html.has-motion .f,html.has-motion .card,
html.has-motion .pick,html.has-motion .btn{
  transition:box-shadow .32s ease,border-color .3s ease,background .18s ease}
html.has-motion .tile:hover,html.has-motion .f:hover,html.has-motion .card:hover,
html.has-motion .pick:hover,html.has-motion .btn:hover,html.has-motion .btn:active,
html.has-motion .tile:hover .pic img{transform:none}
html.has-motion .tile .pic img{transition:none}

@media (prefers-reduced-motion:reduce){
  .hero .aurora{animation:none}
  /* The hero artwork stops, but it must stop somewhere that reads as a finished
     drawing: the van partway along its route, the signature signed, the record
     stamped. Switching the animations off alone would leave it half-drawn. */
  .heroart *{animation:none!important}
  .heroart .chip{opacity:1}
  .heroart .van{offset-distance:58%}
  .heroart .sig{stroke-dashoffset:0}
  .heroart .stamp{opacity:1}
  .heroart .rt-live{opacity:0}
  html.js .io{transform:none;transition:opacity .5s ease}
  .slide{transform:none;transition:opacity .45s ease}
  .tile:hover,.f:hover,.card:hover,.pick:hover{transform:none}
  html{scroll-behavior:auto}
}

/* ==========================================================================
   ADDED FOR THE RESTRUCTURE
   The landing page carries the offer and one call to action. Everything that
   used to sit below it now lives on its own page behind the nav, so the
   homepage converts and the depth is one deliberate click away.
   ========================================================================== */

/* ---------- dropdown navigation ---------------------------------------------
   Top-level items that own a submenu get a caret and a panel. Hover opens it
   on a pointer, click and Enter open it on a touchscreen or a keyboard, and
   Escape closes it - so the menu is reachable however someone is driving it.
   -------------------------------------------------------------------- */
nav.main .item{position:relative;display:flex;align-items:center}
nav.main .item > .lnk{display:inline-flex;align-items:center;gap:6px}
nav.main .caret{width:9px;height:9px;flex:0 0 auto;
  transition:transform .26s cubic-bezier(.22,.8,.2,1)}
nav.main .item.open > .lnk .caret{transform:rotate(180deg)}
.menu{position:absolute;top:calc(100% + 14px);left:50%;transform:translate(-50%,10px);
  min-width:292px;background:var(--surface);border:1px solid var(--line);border-radius:16px;
  box-shadow:0 3px 8px rgba(10,29,86,.07),0 26px 60px rgba(10,29,86,.19);
  padding:10px;z-index:70;opacity:0;visibility:hidden;pointer-events:none;
  transition:opacity .22s ease,transform .28s cubic-bezier(.22,.9,.24,1),visibility .22s}
.item.open .menu{opacity:1;visibility:visible;pointer-events:auto;transform:translate(-50%,0)}
/* a bridge across the gap, so the pointer can travel from link to panel */
.menu::before{content:"";position:absolute;left:0;right:0;top:-16px;height:16px}
.menu a{display:flex;gap:12px;align-items:flex-start;padding:11px 13px;border-radius:11px;
  transition:background .16s ease}
.menu a:hover{background:var(--paper)}
.menu a:focus-visible{background:var(--paper);outline:none;box-shadow:inset 0 0 0 2px var(--red)}
.menu .mi{flex:0 0 auto;width:34px;height:34px;border-radius:10px;display:flex;align-items:center;
  justify-content:center;background:var(--paper);border:1px solid var(--line)}
.menu .mi svg{width:17px;height:17px;color:var(--heading)}
.menu b{display:block;font-size:14.5px;color:var(--heading);letter-spacing:-.01em;line-height:1.35}
.menu small{display:block;font-size:12.5px;color:var(--muted);line-height:1.45;margin-top:2px}

/* ---------- the landing hero: one photograph, blended -----------------------
   The picture is the page. It runs full bleed and is pulled into the brand by
   a navy wash that is solid where the headline sits and clears to almost
   nothing over the van, plus a fade at the foot so the photograph dissolves
   into the section below instead of stopping at a hard edge.
   -------------------------------------------------------------------- */
.phero{position:relative;min-height:clamp(540px,80vh,780px);display:flex;align-items:center;
  background:var(--navy-9);color:#fff;overflow:hidden;padding:96px 0 104px}
.phero .shot{position:absolute;inset:0;z-index:0}
.phero .shot img{width:100%;height:100%;object-fit:cover;object-position:66% 50%}
.phero .shot::after{content:"";position:absolute;inset:0;
  background:linear-gradient(92deg,var(--navy-9) 0%,rgba(5,15,46,.96) 22%,rgba(5,15,46,.74) 42%,
             rgba(5,15,46,.34) 62%,rgba(5,15,46,.14) 80%,rgba(5,15,46,.34) 100%)}
.phero .fade{position:absolute;left:0;right:0;bottom:0;height:190px;z-index:1;pointer-events:none;
  background:linear-gradient(180deg,transparent 0%,rgba(5,15,46,.55) 55%,var(--navy-9) 100%)}
.phero .wrap{position:relative;z-index:2;width:100%}
.phero .inner{max-width:620px}
.phero h1{color:#fff;font-size:clamp(34px,5.2vw,60px);letter-spacing:-.03em;line-height:1.04;
  margin-top:20px}
.phero h1 .accent{color:var(--red-3)}
.phero .lede{font-size:18.5px;color:rgba(255,255,255,.86);margin-top:20px;max-width:46ch}
.phero .cta-row{display:flex;gap:14px;margin-top:34px;flex-wrap:wrap;align-items:center}
/* the credibility chip, the one thing allowed above the headline */
.trust{display:inline-flex;align-items:center;gap:11px;padding:8px 15px 8px 12px;border-radius:999px;
  background:rgba(255,255,255,.10);border:1px solid rgba(255,255,255,.22);
  backdrop-filter:blur(8px);font-size:13.5px;color:rgba(255,255,255,.92)}
.trust .stars{display:inline-flex;gap:2px;color:#ffc94d}
.trust .stars svg{width:14px;height:14px}
.trust b{font-weight:700}
.trust .sep{width:1px;height:14px;background:rgba(255,255,255,.28)}

/* ---------- subpage header --------------------------------------------------
   Every page behind the nav opens the same way, so arriving on one feels like
   arriving on the site rather than on a document bolted to it.
   -------------------------------------------------------------------- */
.phead{position:relative;background:linear-gradient(150deg,var(--navy),var(--navy-9));color:#fff;
  overflow:hidden;padding:74px 0 78px}
.phead .grid{position:absolute;inset:0;opacity:.3;
  background-image:radial-gradient(rgba(255,255,255,.11) 1.3px,transparent 1.3px);background-size:26px 26px}
.phead .wrap{position:relative;z-index:2}
.phead h1{color:#fff;font-size:clamp(31px,4.4vw,52px);margin-top:15px;max-width:19ch}
.phead .lede{color:rgba(255,255,255,.84);font-size:18px;margin-top:18px;max-width:60ch}
.phead .crumb{display:flex;gap:9px;align-items:center;font-size:13px;color:rgba(255,255,255,.6)}
.phead .crumb a:hover{color:#fff}
.phead .crumb svg{width:13px;height:13px;opacity:.6}

/* long-form copy on a subpage */
.prose{max-width:70ch}
.prose p{color:var(--slate);font-size:17px;margin-top:18px}
.prose p:first-child{margin-top:0}
.prose h3{font-size:23px;margin-top:38px}
.prose ul{list-style:none;padding:0;margin:20px 0 0;display:grid;gap:12px}
.prose li{display:flex;gap:12px;color:var(--slate);font-size:16px}
.prose li svg{width:19px;height:19px;color:var(--red);flex:0 0 auto;margin-top:4px}

/* a two-column split, used on most subpages */
.split{display:grid;grid-template-columns:minmax(0,1.05fr) minmax(0,.95fr);gap:56px;align-items:center}
.split .shot{border-radius:20px;overflow:hidden;border:1px solid var(--line);box-shadow:var(--sh-md);
  background:var(--navy-9)}
.split .shot img{width:100%;height:auto;object-fit:cover;aspect-ratio:4/3}

/* closing conversion band, shared by every subpage */
.endcta{position:relative;background:linear-gradient(140deg,var(--navy),var(--navy-9));color:#fff;
  overflow:hidden}
.endcta .grid{position:absolute;inset:0;opacity:.32;
  background-image:radial-gradient(rgba(255,255,255,.1) 1.3px,transparent 1.3px);background-size:26px 26px}
.endcta .wrap{position:relative;z-index:2;padding:74px 24px;text-align:center}
.endcta h2{color:#fff;font-size:clamp(26px,3.2vw,40px)}
.endcta p{color:rgba(255,255,255,.82);font-size:17.5px;margin:16px auto 0;max-width:56ch}
.endcta .cta-row{display:flex;gap:14px;margin-top:30px;justify-content:center;flex-wrap:wrap}

@media (max-width:1024px){
  /* in the stacked sheet a submenu is an indented list - no hover, no panel,
     nothing that needs a pointer to reach it */
  nav.main .item{display:block;width:100%}
  nav.main .item > .lnk{width:100%;justify-content:space-between}
  .menu{position:static;transform:none;opacity:1;visibility:visible;pointer-events:auto;
    min-width:0;border:0;border-radius:0;box-shadow:none;padding:0 0 8px 14px;background:transparent;
    display:none}
  .item.open .menu{display:block;transform:none}
  .menu::before{display:none}
  .menu a{padding:9px 0}
  .menu .mi{display:none}
  .menu b{font-size:14px}
  .menu small{display:none}
}
@media (max-width:900px){
  .split{grid-template-columns:1fr;gap:34px}
}
@media (max-width:700px){
  .phero{min-height:auto;padding:62px 0 76px}
  .phero .shot img{object-position:70% 50%}
  .phero .shot::after{background:linear-gradient(178deg,rgba(5,15,46,.86) 0%,rgba(5,15,46,.80) 40%,
    rgba(5,15,46,.93) 100%)}
  .phero .cta-row .btn{width:100%;justify-content:center}
  .phead{padding:52px 0 56px}
  .endcta .wrap{padding:56px 20px}
}

/* ==========================================================================
   MOBILE OPTIMISATION

   Every rule below sits inside a media query a desktop cannot match: a
   max-width ceiling of 1024px, a coarse-pointer / no-hover test, or a short
   landscape viewport that also requires a coarse pointer. There is not one
   bare selector in this section, so the desktop rendering is exactly the one
   that shipped - resizing a desktop window to phone width is the only way to
   see any of it.

   It sits at the end of the file on purpose. Several of these refine rules of
   equal specificity, so source order is what makes them win - the same reason
   the 430px block further up had to be placed after the 700px one.
   ========================================================================== */

/* ---------- the open nav sheet has to be able to scroll ----------------------
   nav.main goes position:fixed below 1024px with no height limit. Three
   top-level items plus an expanded submenu is ten links, which is taller than
   a phone held sideways - and the overflow was simply unreachable, because
   nothing scrolled it. Cap it to whatever is left under the bar and let it
   scroll inside itself. dvh so a collapsing iOS toolbar cannot clip the last
   item; the vh line above it is the fallback for browsers without dvh.
   -------------------------------------------------------------------- */
@media (max-width:1024px){
  nav.main{max-height:calc(100vh - 78px);max-height:calc(100dvh - 78px);
    overflow-y:auto;overscroll-behavior:contain;-webkit-overflow-scrolling:touch}
}

@media (max-width:1024px){
  /* Safari on iOS inflates body text when a phone is turned to landscape.
     Pinning the adjustment keeps the type at the size it was designed at. */
  html{-webkit-text-size-adjust:100%;text-size-adjust:100%}

  /* The header is sticky, so an in-page anchor otherwise lands with its
     heading hidden underneath it. */
  html{scroll-padding-top:88px}

  /* Form fields: stop iOS zooming the page on focus.
     Safari zooms the viewport whenever a focused control's text is under 16px,
     and it does not zoom back out afterwards - the visitor is left on a page
     they have to pinch to escape. 15.5px was just under the line. This is the
     quote form on the landing page and the contact form; track and signin use
     .tin input, already 19px, and were never affected. */
  .field input,.field select,.field textarea{font-size:16px}

  /* Tap targets up to the 44px the platforms ask for. Both of these were in
     the high thirties. */
  .fcol a{padding:10px 0}
  nav.main .menu a{padding:13px 0}
}

@media (max-width:700px){
  /* the bar is 68px tall from here down, so the sheet gets that much more */
  nav.main{max-height:calc(100vh - 68px);max-height:calc(100dvh - 68px)}
  html{scroll-padding-top:78px}
}

/* ---------- devices that cannot hover ---------------------------------------
   A tap fires :hover on a touchscreen and the state sticks after the finger
   lifts, so a card that rises 7px on hover stays risen until something else is
   tapped. On a device with no pointer the resting state is the design. :active
   is the honest signal there - it ends when the finger comes off.
   -------------------------------------------------------------------- */
@media (hover:none) and (pointer:coarse){
  .tile:hover,.tile:hover .ic,.tile:hover .pic img,
  .f:hover,.f:hover .fi,
  .mv .m:hover,.val:hover,.dir:hover,.dir:hover .shot,
  .pick:hover,.btn-red:hover,.btn-navy:hover,.fcol a:hover,
  .btn:hover .arw,.tile:hover .go .arw,.f:hover .go .arw{transform:none}
  a,button,.btn,.tile,.f,.card,.pick{-webkit-tap-highlight-color:rgba(10,29,86,.08)}
  .btn:active{transform:translateY(1px)}
}

/* ---------- very narrow phones ----------------------------------------------
   .btn is white-space:nowrap, so a long label could not wrap and ran past the
   edge - invisibly, because body carries overflow-x:hidden, which clips it
   rather than revealing it. Let the label wrap, and give the stacked
   call-to-action rows the full width they are already stacking into.
   -------------------------------------------------------------------- */
@media (max-width:430px){
  .btn{white-space:normal;text-align:center}
  .hero .cta-row .btn,.endcta .cta-row .btn{width:100%;justify-content:center}
  /* an email address or a tracking id has no break opportunity inside it */
  .fblurb,.prose p,.phead .lede,.phero .lede{overflow-wrap:anywhere}
  /* four figures in two columns - give the labels room */
  .counters .wrap{gap:28px 14px}
  .counter{padding:8px 4px}
  .counter .l{font-size:13.5px}
}

/* ---------- phones held sideways --------------------------------------------
   A landscape phone is roughly 740-930px wide, so none of the width
   breakpoints above reach it - but it is only about 390px tall. Both heroes
   carry a min-height floor (520px and 540px) taller than the entire viewport,
   which pushed the headline and its call to action off the bottom and made the
   first screen and a half nothing but artwork. The pointer test keeps this off
   any desktop window that merely happens to be short.
   -------------------------------------------------------------------- */
@media (max-height:560px) and (orientation:landscape) and (pointer:coarse){
  .hero{min-height:auto;padding:44px 0 72px}
  .phero{min-height:auto;padding:48px 0 56px}
  .phead{padding:44px 0 46px}
  .quick{margin-top:-56px}
  nav.main{max-height:calc(100vh - 68px);max-height:calc(100dvh - 68px)}
}

/* ==========================================================================
   THEME TOGGLE
   Sits in the header next to the call to action. Two icons in one button,
   only one shown at a time, so the control never changes size as it flips.
   ========================================================================== */
.theme-btn{display:inline-flex;align-items:center;justify-content:center;
  width:40px;height:40px;flex:0 0 auto;padding:0;cursor:pointer;
  background:transparent;border:1px solid var(--line);border-radius:10px;
  color:var(--heading);transition:background .18s,border-color .18s,color .18s}
.theme-btn:hover{border-color:var(--heading);background:var(--paper)}
.theme-btn:focus-visible{outline:none;box-shadow:0 0 0 3px rgba(227,6,19,.35)}
.theme-btn svg{width:19px;height:19px;display:block}
/* Show the sun in dark mode (what a click gets you) and the moon in light. */
.theme-btn .i-sun{display:none}
[data-theme="dark"] .theme-btn .i-sun{display:block}
[data-theme="dark"] .theme-btn .i-moon{display:none}
/* On a navy background the outline has to come from white, not the hairline. */
.theme-btn.on-navy{border-color:rgba(255,255,255,.32);color:#fff}
.theme-btn.on-navy:hover{border-color:#fff;background:rgba(255,255,255,.1)}
@media (max-width:430px){ .theme-btn{width:36px;height:36px} }
@media (max-width:360px){ .theme-btn{width:33px;height:33px} }

/* ============================================================================
   DARK THEME — LIGHT WASHES AND THE LOGO
   Two things the token pass could not reach.

   1. Several surfaces are painted with a light *gradient* rather than a flat
      colour, so swapping --surface never touched them. The worst was .f::before,
      a white wash revealed on hover: in dark mode the card turned white while
      its text stayed light, so hovering a card made it unreadable.

   2. The header logo is dark navy and red artwork on a transparent PNG. On a
      dark navy header it all but disappears. It gets a white pad in dark mode,
      drawn with a shadow spread rather than padding because *{box-sizing:
      border-box} is set globally — real padding would shrink the artwork
      inside its fixed height instead of growing the box around it.
   ========================================================================== */

/* ---- the hover wash on the feature cards (the reported one) ---- */
[data-theme="dark"] .f::before{
  background:linear-gradient(168deg,#202B4E 0%,#1C2647 46%,#19223F 100%)}

/* ---- other light gradients on light-mode surfaces ---- */
[data-theme="dark"] .promise{
  background:linear-gradient(150deg,#1C2647,#19223F 55%,#161E39);
  border-color:#2A3557}
[data-theme="dark"] .svc-opt input:checked+label{
  background:#38191F;border-color:var(--red)}
[data-theme="dark"] .qmsg.err{
  background:#38191F;color:#FFB3B8;border-color:#5A2830}

/* pale icon chips: keep the red/navy glyph, darken only what sits behind it */
[data-theme="dark"] .mv .m .ic,
[data-theme="dark"] .dir-id .role{
  background:linear-gradient(158deg,#38191F,#2C1319)}
[data-theme="dark"] .val .vic{
  background:linear-gradient(158deg,#232E52,#1D2745)}
[data-theme="dark"] .val:hover .vic{
  background:linear-gradient(158deg,#38191F,#2C1319)}

/* ---- the logo gets its own white card so the navy artwork still reads ----
   Both places the dark-artwork logo.png appears: the site header, and the
   masthead of the quote-request panel on contact.html. That second one carries
   no class of its own, so it has to be reached through .qhead. The footer
   already ships logo-white.png on navy and is deliberately left alone. */
[data-theme="dark"] .brand-logo,
[data-theme="dark"] .qhead img{
  background:#fff;border-radius:6px;
  box-shadow:0 0 0 6px #fff, 0 3px 12px rgba(0,0,0,.4)}

/* ---------------------------------------------------------------------------
   NATIVE BROWSER WIDGETS

   The list a <select> drops down is painted by the browser, not by this
   stylesheet — no CSS rule reaches inside it. Left alone it stays on the light
   palette, so the options rendered as near-black text on a dark navy page and
   became unreadable the moment the theme was switched. Same story for
   scrollbars, date pickers and number spinners.

   color-scheme is the one property that governs all of them at once. portal.html
   already declared it; site.css never did, so every marketing page had the
   problem. Setting it on the root while data-theme is dark hands the browser the
   dark palette for its own furniture.
   --------------------------------------------------------------------------- */
[data-theme="dark"]{color-scheme:dark}

/* Belt and braces: a few browsers still paint the popup from the page palette
   even with color-scheme set. Naming the colours costs nothing and matches the
   surface the closed control already uses. */
[data-theme="dark"] select option,
[data-theme="dark"] select optgroup{background:#17203C;color:#E6EAF3}

/* The proof-of-delivery badge sits inside a feature card, and those cards go
   dark. Its dark-green text on a faint green wash reads fine on white and
   disappears on navy. Lift the green rather than restyle the badge. */
[data-theme="dark"] .pbadge .shift{color:#5FD9A0;background:rgba(46,204,113,.18)}
