/* ══════════════════════════════════════════════════════════════════════
   Total Equipment Sales — site stylesheet
   Design Language III. Palette and type stack inherited from the shipped
   battery deliverables. Approved 4 Aug 2026.

   Principles enforced here:
     · Light weights at scale (200/300). Mass reads as sport, thin reads
       as precision.
     · Cyan appears on dark grounds only. 2.14:1 on white fails everything.
     · Zero radius, no shadows. Structure comes from hairlines.
     · Tabular numerals everywhere so columns compare down the page.

   TYPE. One family: Roboto, the official TES face, self-hosted as the
   variable weight (100–900) lifted straight from the battery deliverables'
   own embed. No third-party request and no layout shift, per the design
   foundation. There is no separate condensed face — the impact numbers use
   Roboto bold, so the site never depends on a font it does not ship.
   ══════════════════════════════════════════════════════════════════════ */

@font-face{
  font-family:'Roboto';
  font-style:normal;
  font-weight:100 900;
  font-stretch:100%;
  font-display:swap;
  src:url(/assets/fonts/roboto-var.woff2) format('woff2');
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}

:root{
  /* Official TES palette — deliverables/ */
  --navy:#096697;
  --navy-950:#063a56;
  --navy-900:#04283b;
  --cyan:#4bbded;
  --blue-soft:#e8f5fc;
  --ink:#080605;
  --ink-2:#605e5e;
  --muted:#8e8d8c;
  --line:#e6e5df;
  --paper:#ffffff;
  --bone:#f2f1ec;
  --line-d:rgba(255,255,255,.10);
  --line-dd:rgba(255,255,255,.18);
  --warn:#a8420f;
  --ok:#63c48a;      /* the lift check's "carries it" / recommended accent */

  --sans:'Roboto','Segoe UI',system-ui,-apple-system,'Helvetica Neue',Arial,sans-serif;
  --mono:ui-monospace,'SF Mono','Roboto Mono',Menlo,Consolas,monospace;

  --s1:4px;--s2:8px;--s3:12px;--s4:16px;--s5:24px;--s6:32px;--s7:48px;
  --s8:64px;--s9:80px;--s10:96px;--s11:128px;--s12:176px;

  --max:1440px;--gut:56px;--nav-h:88px;
  --proto-h:0px;    /* prototype banner retired 23 Aug 2026 */
  --ease:cubic-bezier(.22,.61,.36,1);
}

*,*::before,*::after{box-sizing:border-box;margin:0;padding:0}
html{-webkit-text-size-adjust:100%;scroll-behavior:smooth;scroll-padding-top:var(--nav-h)}
body{font-family:var(--sans);font-size:16px;font-weight:400;line-height:1.65;
  color:var(--ink);background:var(--bone);-webkit-font-smoothing:antialiased;
  font-variant-numeric:tabular-nums}
img{max-width:100%;display:block}
a{color:inherit}
:focus-visible{outline:1px solid var(--navy);outline-offset:3px}
.on-dark :focus-visible{outline-color:var(--cyan)}
.wrap{max-width:var(--max);margin-inline:auto;padding-inline:var(--gut);width:100%}
.skip{position:absolute;left:-9999px}
.skip:focus{left:var(--s5);top:var(--s3);z-index:200;background:#fff;color:var(--ink);
  padding:var(--s3) var(--s5);border:1px solid var(--navy)}

/* ══ TYPE ══ */
.d1{font-size:clamp(34px,4.6vw,68px);font-weight:300;letter-spacing:-.022em;line-height:1.12}
.d2{font-size:clamp(28px,3.4vw,46px);font-weight:300;letter-spacing:-.018em;line-height:1.16}
/* .d2 is weight 300 throughout, so a plain <b> inside one does nothing on
   its own — the browser's "bolder than inherited" default still has to
   compute off something, and this heading has no explicit rule making that
   land at a real bold. Used where one clause of a two-line heading needs
   to read as the headline and the rest as a quieter follow-on line. */
.d2 b{font-weight:700}
.d3{font-size:clamp(21px,2.1vw,31px);font-weight:300;letter-spacing:-.012em;line-height:1.28}
.d4{font-size:clamp(17px,1.4vw,21px);font-weight:400;letter-spacing:-.008em;line-height:1.4}
.fig{font-weight:200;letter-spacing:-.035em;line-height:.9;font-variant-numeric:tabular-nums}
.fig-u{font-weight:300;color:var(--cyan);letter-spacing:-.01em}
.zone{font-family:var(--mono);font-size:10px;letter-spacing:.2em;text-transform:uppercase;
  color:var(--muted)}
.on-dark .zone{color:rgba(255,255,255,.38)}
.lede{font-size:clamp(16px,1.2vw,18px);font-weight:300;line-height:1.75;color:var(--ink-2);
  max-width:58ch}
.on-dark .lede{color:rgba(255,255,255,.66)}
.sm{font-size:14px;line-height:1.7;color:var(--ink-2)}
.on-dark .sm{color:rgba(255,255,255,.58)}
.mono{font-family:var(--mono);font-variant-numeric:tabular-nums}

/* ══ GROUNDS & RHYTHM ══ */
/* ONE dark ground. There were three: a flat --navy-950 for .g-navy and .g-ink,
   a flat --navy-900 for .g-deep, and the range section's own gradient, so which
   navy you got depended on where you were on the page. They are all this ramp
   now, and flat: dark sections do stack (page head, then comparison table, then
   load chart on the crane pages), and any ramp restarts at each boundary and
   shows as a step where the two meet. */
.g-navy,.g-ink,.g-deep{background:var(--navy-950);color:#fff}
/* One exception, and it is structural rather than a one-off class: a DARK
   section following the hero starts at the hero plate's own navy, so the
   footage and the section under it meet without a seam. Scoped to the dark
   grounds by name — as `.heroS-photo + .sec` it also caught a light section
   put there later and painted navy under bone-coloured type. */
.heroS-photo + .g-navy,.heroS-photo + .g-ink,.heroS-photo + .g-deep{
  background:linear-gradient(180deg,#03202f 0%,
    var(--navy-900) 34%,var(--navy-950) 100%)}
/* Two grounds on the whole site and no more: bone for the light bands, the
   .g-navy gradient for the dark ones. White was a third, used by two sections
   and nothing else, and it read as a gap in the page rather than a section of
   it. --paper is still the card and input fill, which is where a true white
   earns its place. */
.g-bone,.g-paper{background:var(--bone)}
.sec{padding-block:var(--s11)}
.sec-sm{padding-block:var(--s9)}
.rule{height:1px;background:var(--line);border:0}
.on-dark .rule{background:var(--line-d)}
.two{display:grid;grid-template-columns:1fr 1fr;gap:var(--s10)}
.two-a{display:grid;grid-template-columns:1.15fr 1fr;gap:var(--s10)}
.stack{display:flex;flex-direction:column;gap:var(--s5)}
.row{display:flex;gap:var(--s4);flex-wrap:wrap;align-items:center}
.sec-head{margin-bottom:var(--s9)}
.sec-head h2{margin-top:var(--s4)}
.sec-head .lede{margin-top:var(--s5)}
/* The section kickers ("WHAT WE DO", "WHY IT MATTERS", "LIFT CHECK", …) read
   as slide furniture rather than as part of the page. The headline carries
   the section on its own. */
.sec-head > .zone,
.trk-head > .zone,
.lcx-kicker{display:none}
.sec-head > .zone + h2,
.trk-head > .zone + h2{margin-top:0}

/* ══ REVEAL ══ */
.rv{opacity:0;transform:translateY(18px);
  transition:opacity .9s var(--ease),transform .9s var(--ease)}
.rv.in{opacity:1;transform:none}
@media (prefers-reduced-motion:reduce){.rv{opacity:1;transform:none;transition:none}
  html{scroll-behavior:auto}}

/* ══ NAV ══ */
.nav{position:sticky;top:0;z-index:100;height:var(--nav-h);display:flex;align-items:center;
  background:rgba(6,58,86,.92);backdrop-filter:saturate(140%) blur(10px);
  border-bottom:1px solid var(--line-d);color:#fff;
  transition:transform .3s var(--ease);will-change:transform}
/* JS adds this on a downward scroll and removes it on an upward one */
.nav.nav-off{transform:translateY(-100%)}
@media(prefers-reduced-motion:reduce){.nav{transition:none}.nav.nav-off{transform:none}}
/* The bar runs the full width of the glass rather than sitting inside the
   content column, so the logo and the phone number hold the two edges of the
   screen instead of floating in from them. Gutters only, no max-width. */
.nav-in{display:flex;align-items:center;gap:var(--s7);width:100%;max-width:none}
.nav-logo img{height:58px;width:auto;display:block}
.nav-links{display:flex;align-items:center;gap:var(--s6);margin-left:auto}
.nav-link{display:inline-flex;align-items:center;gap:6px;white-space:nowrap;
  font-size:14px;font-weight:400;color:rgba(255,255,255,.72);text-decoration:none;
  transition:color .25s var(--ease);padding-block:var(--s2)}
.nav-link:hover{color:#fff}
.foot-links a span{white-space:nowrap}
@media(min-width:1001px) and (max-width:1200px){
  .nav-in{gap:var(--s5)}.nav-links{gap:var(--s4)}.nav-link{font-size:13px}}
.nav-link[aria-current=page]{color:#fff;box-shadow:inset 0 -1px 0 var(--cyan)}

/* ── nav dropdowns ───────────────────────────────────────────────
   Only Cranes, Hoists and Batteries carry one. The parent stays a real
   link to its section index; the menu is an addition to it, not a
   replacement — clicking "Cranes" still goes to /cranes/.

   Opened on hover for pointers and on focus-within for the keyboard. The
   panel is bridged to the bar by the item's own padding, so the pointer
   never crosses dead space on the way down and the menu cannot flicker
   shut mid-travel. */
.nav-item{position:relative;display:flex;align-items:center}
.nav-caret{width:9px;height:9px;opacity:.6;transition:transform .2s var(--ease)}
.nav-toggle{display:none}

.nav-menu{position:absolute;top:100%;left:calc(var(--s5) * -1);min-width:210px;
  display:flex;flex-direction:column;padding:var(--s3) 0;
  background:rgba(6,44,66,.97);backdrop-filter:saturate(140%) blur(12px);
  border:1px solid var(--line-d);border-top:2px solid var(--cyan);
  box-shadow:0 18px 40px rgba(2,16,26,.42);
  opacity:0;visibility:hidden;transform:translateY(-6px);
  transition:opacity .18s var(--ease),transform .18s var(--ease),visibility .18s;
  z-index:5}
.nav-menu a{display:block;padding:var(--s3) var(--s5);white-space:nowrap;
  font-size:13.5px;color:rgba(255,255,255,.76);text-decoration:none;
  border-left:2px solid transparent;transition:color .18s var(--ease),
  background .18s var(--ease),border-color .18s var(--ease)}
.nav-menu a:hover,.nav-menu a:focus-visible{color:#fff;
  background:rgba(255,255,255,.06);border-left-color:var(--cyan)}

.has-menu:hover .nav-menu,.has-menu:focus-within .nav-menu{
  opacity:1;visibility:visible;transform:translateY(0)}
.has-menu:hover .nav-caret,.has-menu:focus-within .nav-caret{transform:rotate(180deg)}
.has-menu:hover .nav-link,.has-menu:focus-within .nav-link{color:#fff}
/* the bridge: the menu starts flush against the bar, no gap to fall into */
.has-menu::after{content:'';position:absolute;top:100%;left:0;right:0;height:var(--s4)}
@media(prefers-reduced-motion:reduce){.nav-menu{transition:none}.nav-caret{transition:none}}
.nav-tel{font-family:var(--mono);font-size:13px;color:rgba(255,255,255,.72);text-decoration:none;
  white-space:nowrap;transition:color .25s var(--ease)}
.nav-tel:hover{color:#fff}
.nav-burger{display:none;background:none;border:1px solid var(--line-dd);color:#fff;
  padding:var(--s2) var(--s3);cursor:pointer;font-size:12px;font-family:var(--mono);
  letter-spacing:.12em;text-transform:uppercase}

/* ══ BUTTONS ══
   One system, two weights, defined together further down beside the hero they
   came from:
     .btn-fill   primary   — the cyan → navy gradient
     .btn-line   secondary — glass over a dark photo; a navy outline on a light
                             ground (see the .g-bone override by .btn-line)
   Icons: .btn-i leading (30px), .btn-a trailing arrow (19px, slides on hover).
   Every button on the site is emitted by button() in build.py, so no page
   rolls its own. `.lnk` below is the quiet text link — a different thing on
   purpose. */
.lnk{display:inline-flex;align-items:center;gap:var(--s2);font-size:14px;
  text-decoration:none;border-bottom:1px solid currentColor;padding-bottom:2px;
  transition:opacity .25s var(--ease)}
.lnk:hover{opacity:.6}

/* an inline link inside running body copy — inherits the sentence's size and
   leading, unlike .lnk which is a standalone inline-flex CTA */
.prose-lnk{color:var(--navy);text-decoration:underline;text-underline-offset:2px;
  transition:opacity .2s var(--ease)}
.prose-lnk:hover{opacity:.6}

/* ══ HERO — home. One viewport. The machine sits behind the copy, never
      above it, so the section can never grow past the fold. ══ */
.hero{position:relative;min-height:calc(100vh - var(--nav-h) - var(--proto-h));display:flex;
  align-items:flex-end;overflow:hidden;color:#fff;
  padding-block:var(--s9) var(--s6);
  background:
    radial-gradient(80% 55% at 62% 30%, rgba(75,189,237,.07) 0%, transparent 64%),
    var(--navy-950)}
.hero-media{position:absolute;inset:0;z-index:0}
.hero-media .ph{width:100%;height:100%;border:0;background:
    radial-gradient(70% 58% at 56% 40%, rgba(255,255,255,.055), transparent 68%),
    var(--navy-950)}
.hero-media .ph::after{left:22%;right:22%;bottom:26%}
/* Scrim. Target: body copy holds 4.5:1 over the darkest photograph we would
   realistically use, so the headline never depends on the image behind it. */
.hero-media::after{content:'';position:absolute;inset:0;pointer-events:none;
  background:linear-gradient(180deg,rgba(6,58,86,.15) 0%,rgba(6,58,86,.55) 52%,
    rgba(4,40,59,.92) 100%)}
.hero-inner{position:relative;z-index:1}
/* px, not ch. A ch max-width here would resolve against the container's 16px
   font-size rather than the 50px headline, collapsing the column. */
.hero-copy{max-width:660px}
.hero-copy h1{font-size:clamp(30px,3.4vw,50px)}
.hero-foot{display:flex;justify-content:space-between;gap:var(--s6);flex-wrap:wrap;
  border-top:1px solid var(--line-d);padding-top:var(--s5);margin-top:var(--s7)}

/* ══ PAGE HEAD — inner pages. Copy first, media beneath. ══ */
.pagehead{position:relative;padding-block:var(--s10) var(--s9);overflow:hidden;
  color:#fff;
  background:
    radial-gradient(80% 60% at 70% 20%, rgba(75,189,237,.06) 0%, transparent 62%),
    /* the shared dark ground, same as every .g-navy band */
    var(--navy-950)}

/* ══ REAL IMAGERY ══ */
.media{position:relative;overflow:hidden;background:var(--navy-900);display:block}
.media img{width:100%;height:100%;object-fit:cover;display:block}
/* A cutout PNG with real alpha (a product shot, not a photo) — no fill
   behind the transparent edges, and contain instead of cover so the whole
   product shows on the section's own ground rather than being cropped to
   fill a box it has no background to fill. */
.media-cutout{background:transparent}
.media-cutout img{object-fit:contain}
.media-sheet{background:#fff;padding:var(--s3)}
.media-sheet img{object-fit:contain}
.media-16-9{aspect-ratio:16/9}
.media-4-3{aspect-ratio:4/3}
.media-3-4{aspect-ratio:3/4}
.media-1-1{aspect-ratio:1/1}
.hero-media .media,.hero-media .media-hero{position:absolute;inset:0;aspect-ratio:auto}
.hero-media .media img{object-position:58% 42%}
.card .media,.seq-media .media{transition:transform .8s var(--ease)}
.card:hover .media img,.seq-media:hover .media img{transform:scale(1.015)}

/* cut-out product shot that sits on the section ground rather than in a
   cropped frame — used where the image already has a transparent alpha */
.ready-shot{display:flex;align-items:center;justify-content:center}
.ready-shot img{width:100%;height:auto;object-fit:contain;
  filter:drop-shadow(0 26px 34px rgba(4,40,59,.16))}

/* ══ VIDEO SLOT — carries a walkaround now, the configurator later ══ */
.videoslot{position:relative;aspect-ratio:1/1;width:100%;display:flex;flex-direction:column;
  align-items:center;justify-content:center;gap:var(--s4);cursor:pointer;
  background:radial-gradient(84% 62% at 50% 42%,rgba(75,189,237,.07),transparent 70%),var(--navy-900);
  border:1px solid var(--line-d);transition:border-color .3s var(--ease)}
.videoslot:hover{border-color:var(--line-dd)}
.videoslot-play{width:52px;height:52px;border:1px solid rgba(255,255,255,.34);border-radius:50%;
  display:flex;align-items:center;justify-content:center;transition:border-color .3s var(--ease)}
.videoslot-play::after{content:"";border-left:13px solid rgba(255,255,255,.72);
  border-top:8px solid transparent;border-bottom:8px solid transparent;margin-left:4px}
.videoslot:hover .videoslot-play{border-color:var(--cyan)}
.videoslot-cap{font-family:var(--mono);font-size:10px;letter-spacing:.2em;text-transform:uppercase;
  color:rgba(255,255,255,.4);text-align:center;padding-inline:var(--s5)}

/* ══ PLACEHOLDER IMAGERY ══ */
.ph{position:relative;display:flex;align-items:center;justify-content:center;
  background:
    radial-gradient(88% 66% at 50% 42%,rgba(75,189,237,.05),transparent 70%),
    var(--navy-900);
  border:1px solid var(--line-d);overflow:hidden}
.ph::after{content:'';position:absolute;left:16%;right:16%;bottom:8%;height:1px;
  background:linear-gradient(90deg,transparent,rgba(255,255,255,.14) 24%,
    rgba(255,255,255,.14) 76%,transparent)}
.ph-light{background:
    repeating-linear-gradient(135deg,rgba(0,0,0,.018) 0 14px,transparent 14px 28px),
    #e9e7e1;
  border:1px solid var(--line)}
.ph-light::after{display:none}
.ph span{font-family:var(--mono);font-size:10px;letter-spacing:.2em;text-transform:uppercase;
  color:rgba(255,255,255,.22);text-align:center;line-height:2;padding:var(--s5);
  position:relative;z-index:1}
.ph-light span{color:var(--muted)}
.ph-hero{width:100%;min-height:38vh}
.ph-16-9{aspect-ratio:16/9;width:100%}
.ph-4-3{aspect-ratio:4/3;width:100%}
.ph-3-4{aspect-ratio:3/4;width:100%}
.ph-1-1{aspect-ratio:1/1;width:100%}

/* ══ FIGURE BLOCK ══ */
.figblock{display:grid;grid-template-columns:1.05fr 1fr;gap:var(--s10);align-items:start}
.figbig{display:flex;align-items:flex-start;gap:var(--s3)}
.figbig .fig{font-size:clamp(88px,13vw,190px);color:var(--navy-950)}
.figbig .fig-u{font-size:clamp(22px,3vw,46px);padding-top:.52em}
.on-dark .figbig .fig{color:#fff}
.figcap{font-size:15px;color:var(--ink-2);margin-top:var(--s4)}
.on-dark .figcap{color:rgba(255,255,255,.6)}
.figlines{border-left:1px solid var(--line);padding-left:var(--s8)}
.on-dark .figlines{border-left-color:var(--line-d)}
.figlines p{font-size:clamp(17px,1.5vw,20px);font-weight:300;line-height:1.62;
  margin-bottom:var(--s5)}
.figlines p:last-child{margin-bottom:0;color:var(--ink-2);font-size:16px}
.on-dark .figlines p:last-child{color:rgba(255,255,255,.6)}

/* ══ METRICS ══ */
/* ══ STAT ROW — icon, big figure, label. Used on the model-page hero
   (.mstats-lg, four up) and the class-page crane cards (three up, in
   .seq-body). Own class names on purpose: a bare .k is a legend swatch
   elsewhere and used to crush these labels into an 8px box. The divider is a
   fixed-height pseudo-element so it spans only the icon + number, not down
   past the label. ══ */
.mstats{display:flex;flex-wrap:wrap;gap:var(--s6) 0;
  border-top:1px solid var(--line-d);border-bottom:1px solid var(--line-d);
  padding-block:var(--s6)}
.mstats-lg{max-width:840px}
.seq-body .mstats{max-width:440px;border:none;padding-block:0}
.mstat{flex:1 1 0;min-width:118px;position:relative;padding:0 var(--s6)}
.mstat:first-child{padding-left:0}
.mstat + .mstat::before{content:"";position:absolute;left:0;top:1px;width:1px;height:56px;
  background:rgba(255,255,255,.16)}
.mstat-i{width:22px;height:22px;stroke:var(--cyan);stroke-width:2.2;display:block;
  margin-bottom:var(--s3)}
.mstat-v{font-weight:200;letter-spacing:-.035em;line-height:1;font-variant-numeric:tabular-nums;
  font-size:clamp(30px,3.4vw,44px);color:#fff;white-space:nowrap}
.mstat-v .fig-u{font-weight:300;color:var(--cyan);font-size:.4em;letter-spacing:0;margin-left:.06em}
.mstat-none{font-size:15px;font-weight:400;color:rgba(255,255,255,.5);letter-spacing:0}
.mstat-k{font-family:var(--mono);font-size:9.5px;letter-spacing:.14em;text-transform:uppercase;
  color:rgba(255,255,255,.42);margin-top:var(--s4);white-space:nowrap}
@media(max-width:640px){
  .mstat{min-width:0;flex-basis:0;padding:0 var(--s3)}
  .mstat-i{width:19px;height:19px}
  .mstat-v{font-size:clamp(24px,7vw,32px)}
  .mstat-k{font-size:8.5px;letter-spacing:.08em}
  .mstat + .mstat::before{height:46px}
}

/* ══ MACROS — the three-up photo strip, e.g. "the parts that wear out" ══ */
.macros{display:grid;grid-template-columns:repeat(3,1fr);gap:1px;background:var(--line-d)}
.macro{aspect-ratio:3/4;position:relative;display:flex;align-items:flex-end;padding:var(--s6);
  background:radial-gradient(88% 66% at 50% 42%,rgba(75,189,237,.06),transparent 70%),
    var(--navy-900)}
.macro .media{position:absolute;inset:0;aspect-ratio:auto;background:none}
/* Label scrim, so the caption holds contrast over any photograph. */
.macro::after{content:"";position:absolute;inset:0;pointer-events:none;
  background:linear-gradient(180deg,transparent 52%,rgba(4,40,59,.88) 100%)}
.macro span{position:relative;z-index:1}

/* ══ RECENT WORK — real jobsites, capability page only (see
   recent_work_block() in build.py for why not the home page, and why a rail
   rather than the three-up grid this started as).

   The rail runs full-bleed out of .wrap and is padded to the gutter instead,
   so the first frame lines up with the heading above it and the last one
   runs off the right edge — which is the affordance: a card cut by the
   viewport says "there is more this way" without needing arrows or dots.
   A plain figure/figcaption, not a card — these don't link anywhere, so they
   don't borrow .trk-p's hover-and-arrow language and promise a click they
   can't deliver.

   No scroll-snap here. It was proximity snap that site.js toggled off during
   autoplay — but toggling scroll-snap-type on an already-scrolled container
   makes the browser re-snap, and near the start of the rail the nearest snap
   point is frame 1, so a mouse simply entering the rail yanked it back to the
   first photo. A free-scrolling photo strip doesn't need to land on a frame
   edge; drift, drag, wheel and arrow keys all still work. */
.work-rail{display:flex;gap:var(--s6);overflow-x:auto;
  padding-inline:max(var(--gut),calc((100vw - var(--max))/2 + var(--gut)));
  padding-bottom:var(--s5);
  scrollbar-width:thin;overscroll-behavior-x:contain}
.work-rail:focus-visible{outline:2px solid var(--cyan);outline-offset:4px}
.work-item{margin:0;flex:0 0 clamp(280px,32vw,420px)}
.work-media{aspect-ratio:4/3}
.work-item figcaption{margin-top:var(--s4);font-size:14.5px;line-height:1.6;
  color:var(--ink-2)}
.work-loc{display:block;font-family:var(--mono);font-size:11px;letter-spacing:.12em;
  text-transform:uppercase;color:var(--navy);margin-bottom:5px}
@media(max-width:700px){.work-rail{gap:var(--s5)}}

/* ══ CARD ROWS — the little ticked capability lists ══ */
.card-rows{display:flex;flex-direction:column;gap:2px;margin-top:var(--s2)}
.card-row{display:flex;justify-content:space-between;gap:var(--s4);font-size:13px;
  padding-block:var(--s3);border-bottom:1px solid var(--line)}
.card-row span:first-child{color:var(--ink-2)}
.card-row span:last-child{font-family:var(--mono)}
.on-dark .card-row{border-bottom-color:var(--line-d)}
.on-dark .card-row span:first-child{color:rgba(255,255,255,.55)}

/* ══ SPEC LIST ══ */
.spec{width:100%;border-collapse:collapse}
.spec td{padding:var(--s3) 0;border-bottom:1px solid var(--line);font-size:14px;
  vertical-align:baseline}
.spec td:first-child{color:var(--ink-2)}
.spec td:last-child{text-align:right;font-family:var(--mono);font-size:13px;color:var(--ink)}
.spec tr:last-child td{border-bottom:none}
.spec .grp td{border-bottom:none;padding-top:var(--s6);padding-bottom:var(--s2);
  font-family:var(--mono);font-size:10px;letter-spacing:.18em;text-transform:uppercase;
  color:var(--muted)}
.on-dark .spec td{border-bottom-color:var(--line-d);color:rgba(255,255,255,.62)}
.on-dark .spec td:last-child{color:#fff}
.on-dark .spec .grp td{color:rgba(255,255,255,.35)}
.pending-v{color:var(--muted)!important}
.on-dark .pending-v{color:rgba(255,255,255,.3)!important}

/* ══ CLOSE LINE ══
   The quiet replacement for the navy CTA band (removed step 07). One line of
   body copy, a hairline above it, a single arrow link. It offers the next
   step without a heading, a panel, or a second button competing with it. */
.close-line{padding-block:var(--s7);border-top:1px solid var(--line)}
.close-line p{font-size:1.02rem;line-height:1.7;color:var(--ink-2);max-width:64ch}
.close-line .lnk{white-space:nowrap}
/* the hoists / batteries "one quiet ask" line, in place of an inline form */
.bp-ask{font-size:1.04rem;line-height:1.75;color:var(--ink-2)}
.bp-ask .lnk{white-space:nowrap;margin-left:var(--s2)}
.on-dark .bp-ask{color:rgba(255,255,255,.66)}
.on-dark .close-line{border-top-color:var(--line-d)}
.on-dark .close-line p{color:rgba(255,255,255,.66)}
/* contact: the phone comes first, above the form */
.contact-lead{font-family:var(--sans);font-weight:300;font-size:clamp(19px,1.6vw,23px);
  line-height:1.4;letter-spacing:-.01em;color:var(--ink);margin-bottom:var(--s7)}
.contact-lead a{color:var(--navy);text-decoration:none;border-bottom:1px solid currentColor}
.contact-lead span{display:block;font-size:15px;font-weight:400;color:var(--ink-2);
  letter-spacing:0;margin-top:var(--s3)}

/* ══ PLAIN-ENGLISH KEY ══
   A quiet companion to a spec table or comparison: the trade terms on the
   page, each with one line a site manager can read. Same hairline-and-mono
   register as the table it sits under, so it reads as part of the same
   instrument rather than a marketing aside. */
.glo{margin-top:var(--s6);padding-top:var(--s5);border-top:1px solid var(--line);max-width:760px}
.glo-h{font-family:var(--mono);font-size:10px;letter-spacing:.18em;text-transform:uppercase;
  color:var(--muted);margin:0;display:inline-flex;align-items:center;gap:var(--s2);
  cursor:pointer;list-style:none;user-select:none}
.glo-h::-webkit-details-marker{display:none}
.glo-h:hover{color:var(--ink-2)}
.glo-i{width:14px;height:14px;flex:none}
.glo[open] .glo-h{margin-bottom:var(--s4)}
.glo dl{display:flex;flex-direction:column;gap:var(--s4);margin:0}
.glo dl>div{display:grid;grid-template-columns:132px 1fr;gap:var(--s2) var(--s5)}
.glo dt{font-family:var(--mono);font-size:12px;color:var(--ink-2);line-height:1.5}
.glo dd{margin:0;font-size:13.5px;line-height:1.62;color:var(--ink-2)}
.on-dark .glo{border-top-color:var(--line-d)}
.on-dark .glo-h{color:rgba(255,255,255,.4)}
.on-dark .glo-h:hover{color:rgba(255,255,255,.72)}
.on-dark .glo dt,.on-dark .glo dd{color:rgba(255,255,255,.6)}
@media(max-width:560px){.glo dl>div{grid-template-columns:1fr;gap:2px}}

/* ══ FAQ — a tight accordion, question and answer visibly paired ══ */
.faq{border-top:1px solid var(--line)}
.faq-i{border-bottom:1px solid var(--line)}
.faq-i>summary{list-style:none;cursor:pointer;display:flex;align-items:flex-start;
  gap:var(--s4);padding:var(--s4) 0;
  font-family:var(--sans);font-size:15.5px;font-weight:600;line-height:1.4;color:var(--ink);
  transition:color .18s var(--ease)}
.faq-i>summary::-webkit-details-marker{display:none}
.faq-i>summary::before{content:"+";flex:none;width:1em;font-weight:400;font-size:18px;
  line-height:1.35;color:var(--cyan);text-align:center}
.faq-i[open]>summary::before{content:"\2212"}
.faq-i>summary:hover{color:var(--navy)}
.faq-i>p{margin:calc(-1 * var(--s2)) 0 var(--s5);padding-left:calc(1em + var(--s4));
  max-width:62ch;font-size:14px;line-height:1.62;color:var(--ink-2)}

/* ══ COMPARISON TABLE ══ */
.cmp{width:100%;border-collapse:collapse}
.cmp th{font-family:var(--mono);font-size:10px;letter-spacing:.16em;text-transform:uppercase;
  color:rgba(255,255,255,.38);font-weight:400;text-align:right;padding:0 0 var(--s4);
  border-bottom:1px solid var(--line-dd)}
.cmp th:first-child{text-align:left}
.cmp td{padding:var(--s5) 0;border-bottom:1px solid var(--line-d);font-size:14px;
  text-align:right;font-family:var(--mono);color:rgba(255,255,255,.8)}
.cmp td:first-child{text-align:left;font-family:var(--sans);font-size:16px;font-weight:400;
  color:#fff;letter-spacing:-.01em}
.cmp td:first-child a{text-decoration:none;border-bottom:1px solid rgba(255,255,255,.25);
  padding-bottom:2px;transition:border-color .25s var(--ease)}
.cmp td:first-child a:hover{border-bottom-color:var(--cyan)}
.cmp tbody tr{transition:background .3s var(--ease)}
.cmp tbody tr:hover{background:rgba(255,255,255,.03)}
.cmp tr.pend td{color:rgba(255,255,255,.3)}
.cmp tr.pend td:first-child{color:rgba(255,255,255,.45)}
.tscroll{overflow-x:auto;-webkit-overflow-scrolling:touch}
.src{font-family:var(--mono);font-size:10px;letter-spacing:.12em;text-transform:uppercase;
  color:rgba(255,255,255,.35)}

/* ══ NUMBERED STEPS ══
   The battery page's mechanism column: a mono counter, a claim, a line of
   body. Hairlines tie the column the way rules tie the gband cells. */
.steps{display:flex;flex-direction:column}
.step{display:grid;grid-template-columns:56px 1fr;gap:var(--s5);
  padding-block:var(--s5);border-top:1px solid var(--line)}
.step:first-child{border-top:none;padding-top:0}
.step-n{font-family:var(--mono);font-size:13px;letter-spacing:.14em;
  color:var(--navy);padding-top:5px}
.step h3{font-size:18px;font-weight:600;letter-spacing:-.01em;color:var(--ink)}
.step p{font-size:15px;line-height:1.7;color:var(--ink-2);margin-top:var(--s2)}
.on-dark .step{border-top-color:var(--line-d)}
.on-dark .step-n{color:var(--cyan)}
.on-dark .step h3{color:#fff}
.on-dark .step p{color:rgba(255,255,255,.62)}
.step-fig{display:flex;align-items:baseline;gap:var(--s3);margin-top:var(--s4)}
.step-v{font-family:var(--sans);font-size:30px;
  font-weight:700;letter-spacing:-.02em;color:var(--navy);line-height:1}
.step-k{font-family:var(--mono);font-size:10px;letter-spacing:.14em;
  text-transform:uppercase;color:var(--muted)}
.on-dark .step-v{color:var(--cyan)}
.on-dark .step-k{color:rgba(255,255,255,.45)}

/* the icon-disc variant, and the tinted feature strip under it — the
   practical section's steps carry a filled navy disc and their number
   above the claim; the strip carries three quiet reassurances. */
.dot-a{color:var(--navy)}
.hiw-anim{border:1px solid var(--line);background:var(--paper);
  border-radius:12px;padding:var(--s6)}
.hiw-anim svg{display:block;width:100%;height:auto}
@media(prefers-reduced-motion:reduce){.hiw-dots{display:none}}
/* The diagram's source, promoted from a caption line to a proper callout —
   the same tinted-box-with-an-i language a spec table's "pending" note
   uses elsewhere, so a citation reads as one rather than fine print easy
   to skip past. The brochure name is a real link to the PDF now, not just
   a name. */
.hiw-note{display:flex;align-items:flex-start;gap:var(--s4);margin-top:var(--s5);
  padding:var(--s5) var(--s6);border-radius:10px;background:rgba(9,102,151,.06);
  border:1px solid rgba(9,102,151,.16)}
.hiw-note-i{flex:0 0 auto;width:20px;height:20px;color:var(--navy);margin-top:2px}
.hiw-note p{margin:0;font-size:13.5px;line-height:1.65;color:var(--ink-2)}
.hiw-note a{color:var(--navy);text-decoration:underline;text-underline-offset:2px}
/* The badged variant: a small number disc overlapping the corner of a
   pale icon circle, in the plain .step column (56px, not .steps-ico's
   96px) — this sits beside the diagram, not in its own full-width row, so
   it stays the size of a mechanism step, not a feature tile. Pale and
   outlined rather than .step-d's solid navy fill, so it doesn't compete
   with the diagram's own navy-on-paper linework directly beside it. */
.steps-badged .step{grid-template-columns:48px 1fr}
.step-ic{position:relative;width:44px;height:44px}
/* Compound selectors, not .step-d-light alone: a bare class here has the
   same specificity as .step-d's own background/width rule and lost to it
   on source order (declared earlier in the file) — the disc rendered as
   .step-d's solid navy-950 fill instead of this pale tint. .step-d.step-d-
   light wins outright regardless of where either rule sits. Same story for
   the icon: .step-d svg (a class + a type selector) outranks a bare
   .step-d-s, so the icon was staying at .step-d's 38px/white instead of
   this variant's 20px/navy. */
.step-d.step-d-light{width:44px;height:44px;background:rgba(9,102,151,.08);
  border:1px solid rgba(9,102,151,.22)}
.step-d.step-d-light svg{width:20px;height:20px;stroke:var(--navy);stroke-width:2}
.step-badge{position:absolute;z-index:1;top:-6px;left:-6px;display:grid;place-items:center;
  width:21px;height:21px;border-radius:50%;background:var(--navy-950);color:#fff;
  font-family:var(--mono);font-size:10px;font-weight:600}
.on-dark .step-d.step-d-light{background:rgba(255,255,255,.08);border-color:rgba(255,255,255,.2)}
.on-dark .step-d.step-d-light svg{stroke:#fff}
.on-dark .step-badge{background:var(--cyan);color:var(--navy-950)}
.steps-ico{height:100%}
.steps-ico .step{grid-template-columns:96px 1fr;gap:var(--s7);
  flex:1 1 0;align-items:center;padding-block:var(--s6)}
.step-d{display:grid;place-items:center;width:84px;height:84px;
  border-radius:50%;background:var(--navy-950)}
.step-d svg{width:38px;height:38px;stroke:#fff;stroke-width:2}
.step-no{font-family:var(--mono);font-size:12px;letter-spacing:.18em;
  color:var(--navy);margin-bottom:var(--s2)}
/* bigger, more legible body copy in the practical section */
.steps-ico .step h3{font-size:21px;letter-spacing:-.014em}
.steps-ico .step p{font-size:16px;line-height:1.72;margin-top:var(--s3)}

/* framer-style entrance: each step eases up on its own, gently staggered,
   the disc settling from a slightly smaller scale a beat behind it */
.steps-ico .step.rv{opacity:0;transform:translateY(30px);
  transition:opacity .74s cubic-bezier(.16,1,.3,1),
             transform .74s cubic-bezier(.16,1,.3,1)}
.steps-ico .step.rv.in{opacity:1;transform:none}
.steps-ico .step.rv:nth-of-type(1).in{transition-delay:60ms!important}
.steps-ico .step.rv:nth-of-type(2).in{transition-delay:180ms!important}
.steps-ico .step.rv:nth-of-type(3).in{transition-delay:300ms!important}
.steps-ico .step .step-d{transform:scale(.82);
  transition:transform .8s cubic-bezier(.16,1,.3,1) 90ms}
.steps-ico .step.in .step-d{transform:scale(1)}

@media(prefers-reduced-motion:reduce){
  .steps-ico .step.rv,.steps-ico .step .step-d{opacity:1;transform:none;transition:none}
}
@media(max-width:900px){
  .steps-ico .step{grid-template-columns:60px 1fr;gap:var(--s5);padding-block:var(--s5)}
  .step-d{width:52px;height:52px}
  .step-d svg{width:24px;height:24px}
  .steps-ico .step h3{font-size:19px}
  .steps-ico .step p{font-size:15.5px}
}

/* ══ MODEL SEQUENCE (range pages) ══ */
.seq{display:flex;flex-direction:column}
.seq-item{display:grid;grid-template-columns:1fr 1.1fr;gap:var(--s9);align-items:center;
  padding-block:var(--s10);border-top:1px solid var(--line-d)}
.seq-item:nth-child(even) .seq-media{order:2}
.seq-body{display:flex;flex-direction:column;gap:var(--s5)}


/* ══ OFFER CARDS — the two self-serve tools, home page only ══
   compare_tools_block() in build.py. Same "big number, label below, no
   icon" stat language as .seq-fig above (used on /cranes/), just recoloured
   for a card on paper instead of a dark section — .fig is the shared base
   (weight, tracking, tabular numerals), each context supplies its own
   colour and size. The illustration sits inside the same white card as the
   copy, rather than bleeding to the card's edge, so it reads as one object
   next to its sibling card, not a banner over a panel.

   contain, not the site-wide .media img cover: these two are trimmed,
   transparent PNGs (see compare_tools_block()'s docstring), not a
   rectangular photo — cover would zoom into the drawing and clip it.
   Background is --bone, not .media's own navy default, because the
   drawing is white/light-lined and drawn for a light ground, not the dark
   backdrop a product photo usually sits on. */
.offer-grid{display:grid;grid-template-columns:1fr 1fr;gap:var(--s7)}
/* A grid item's automatic minimum is its min-content, and a replaced image's
   min-content is its intrinsic width — max-width:100% does not reduce it. That
   made the card wider than a 320px screen and scrolled the page sideways. */
.offer-grid > *{min-width:0}
@media(max-width:800px){.offer-grid{grid-template-columns:1fr}}
.offer-card{background:var(--paper);border:1px solid var(--line);
  display:flex;flex-direction:column}
/* A bounded flex box, image sized by max-width/max-height only. No
   aspect-ratio, no padding-top hack, no absolute positioning, no percentage
   height on the <img> — every one of those made Safari/WebKit render the
   picture at intrinsic size and the card ran many screens tall. The image
   here simply cannot exceed the box. */
.offer-card .media{margin:var(--s5);background:var(--bone);padding:var(--s6);
  display:flex;align-items:center;justify-content:center;
  height:clamp(210px,56vw,264px);overflow:hidden}
.offer-card .media img{display:block;width:auto;height:auto;
  max-width:100%;max-height:100%;object-fit:contain}
.offer-body{padding:0 var(--s7) var(--s7);display:flex;flex-direction:column;
  gap:var(--s6);flex:1}
.offer-body p{margin:0;color:var(--ink-2);font-size:15px;line-height:1.65}
.offer-figs{display:flex;flex-wrap:wrap;gap:var(--s6)}
/* min-width, not the .k rule below alone: a flex row with no flex-grow/
   shrink sizes each column to its own content, which here means the width
   of the *number* above the label — .k is a <span>, and max-width does
   nothing on an inline element, so without a floor the label wrapped
   inside whatever few px the number left it, one word per line, tall
   enough to run into the button below it. */
.offer-fig{display:flex;flex-direction:column;min-width:100px}
.offer-fig .fig{font-size:clamp(23px,2.4vw,30px);color:var(--navy-950)}
.offer-fig .fig-u{font-size:14px;font-weight:400}
.offer-fig .k{display:block;font-family:var(--mono);font-size:9.5px;letter-spacing:.12em;
  text-transform:uppercase;color:var(--muted);margin-top:4px;max-width:15ch;
  line-height:1.4}
.offer-body .btn-line{margin-top:auto;align-self:flex-start}
/* 23 Sep 2026: on a 320px phone the card's own padding (48px a side) plus the
   button's minimum width pushed the card wider than the screen, which scrolled
   the whole page sideways. Both come in at the narrow end. */
@media(max-width:420px){
  .offer-card .media{margin:var(--s4)}
  .offer-body{padding:0 var(--s5) var(--s6);gap:var(--s5)}
  .offer-body .btn-line{font-size:15px;padding:var(--s4) var(--s5)}
}

/* ══ CARDS ══ */
.cards{display:grid;grid-template-columns:repeat(3,1fr);gap:var(--s6)}

/* ── related crane cards (model page "more in this class") ──
   Small image, name, one spec line. Deliberately light chrome so it does not
   compete with the hero above it. The whole card is the link — kill the
   default underline the <a> would push onto the text inside. */
.rel-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:var(--s5)}
.rel-card{display:flex;flex-direction:column;text-decoration:none;
  border:1px solid rgba(255,255,255,.12);border-radius:4px;overflow:hidden;
  transition:border-color .2s var(--ease)}
.rel-card:hover{border-color:var(--cyan)}
.rel-shot{display:block;aspect-ratio:16/9;background:var(--navy-900)}
.rel-shot .media,.rel-shot .ph{width:100%;height:100%;aspect-ratio:auto}
.rel-shot img{width:100%;height:100%;object-fit:cover;transition:transform .8s var(--ease)}
.rel-card:hover .rel-shot img{transform:scale(1.02)}
.rel-b{display:flex;flex-direction:column;gap:2px;padding:var(--s4) var(--s5) var(--s5)}
.rel-id{color:#fff;font-size:15.5px;font-weight:500}
.rel-sub{color:rgba(255,255,255,.5);font-family:var(--mono);font-size:11.5px;letter-spacing:.02em}
@media(max-width:640px){.rel-grid{grid-template-columns:1fr}}

/* ── type strip: the three crane types, a place marker + a jump ── */
.clsnav{display:grid;grid-template-columns:repeat(3,1fr);gap:var(--s3)}
.clsnav-i{display:flex;flex-direction:column;gap:3px;padding:var(--s5);
  border:1px solid rgba(255,255,255,.14);border-radius:5px;text-decoration:none;
  transition:border-color .2s var(--ease),background .2s var(--ease)}
a.clsnav-i:hover{border-color:var(--cyan);background:rgba(75,189,237,.06)}
.clsnav-i.is-cur{background:rgba(75,189,237,.12);border-color:rgba(75,189,237,.42)}
.clsnav-k{font-family:var(--mono);font-size:10px;letter-spacing:.16em;
  text-transform:uppercase;color:var(--cyan)}
.clsnav-b{color:#fff;font-size:14px;font-weight:500;line-height:1.3}
.clsnav-n{font-family:var(--mono);font-size:10px;color:rgba(255,255,255,.45);letter-spacing:.03em}
@media(max-width:640px){.clsnav{grid-template-columns:1fr}}

/* ── load curve chart on a model page: drawn by site.js from CHART_CURVE ──
   The SVG's classes had no rules, so the curve rendered as a black fill.
   Steps, not a smoothed line: it is drawn the way the lift check reads it. */
.chart-wrap{position:relative}
svg.chart{display:block;width:100%;height:auto;overflow:visible}
svg.chart .gl{stroke:rgba(255,255,255,.08);stroke-width:1}
svg.chart .gb{stroke:rgba(255,255,255,.35);stroke-width:1}
svg.chart .gt{fill:rgba(255,255,255,.5);font:12px var(--mono)}
svg.chart .gk{fill:rgba(255,255,255,.38);font:11px var(--mono);letter-spacing:.14em}
svg.chart .c-area{fill:url(#fade);stroke:none}
svg.chart .c-line{fill:none;stroke:var(--cyan);stroke-width:2.2;stroke-linejoin:round}
svg.chart .pt{fill:var(--cyan)}
svg.chart .dl{fill:#fff;font:600 15px var(--sans,inherit)}
svg.chart .dls{fill:rgba(255,255,255,.55);font:11px var(--mono)}
svg.chart .cross{stroke:rgba(255,255,255,.3);stroke-dasharray:3 4;opacity:0;pointer-events:none}
svg.chart .cursor{fill:#fff;stroke:var(--cyan);stroke-width:2;opacity:0;pointer-events:none}
.chart-wrap .tip{position:absolute;left:0;top:0;opacity:0;pointer-events:none;white-space:pre;
  padding:6px 10px;border-radius:4px;background:#fff;color:var(--ink);
  font:12px var(--mono);box-shadow:0 6px 18px rgba(0,0,0,.25);transition:opacity .12s}

/* ══ LIFT CHECK — a compact input card. Once both figures are in and the
   button is pressed it widens: inputs stay left, the ranked cranes appear on
   the right, and the elevation diagram sits inside the recommended card. ══ */
.lc3-sec{padding-block:var(--s9)}
.lc3{background:var(--navy-950);color:#fff;
  border:1px solid rgba(255,255,255,.1);border-radius:14px;overflow:hidden}
.lc3-in{display:flex;flex-wrap:wrap;align-items:flex-end;gap:var(--s5) var(--s5);
  padding:var(--s7)}
.lc3-head{flex:1 1 100%;display:flex;gap:var(--s4);align-items:flex-start}
.lc3-ico{flex:none;width:44px;height:44px;display:grid;place-items:center;
  border-radius:10px;background:rgba(75,189,237,.12);border:1px solid rgba(75,189,237,.22)}
.lc3-ico-s{width:24px;height:24px;stroke:var(--cyan);stroke-width:1.5}
.lc3-h{font-size:19px;font-weight:600;letter-spacing:-.01em}
.lc3-sub{font-size:12.5px;color:rgba(255,255,255,.6);margin-top:3px;line-height:1.45}

.lc3-field{flex:1 1 240px}
.lc3-field label{display:block;font-family:var(--mono);font-size:10px;
  letter-spacing:.16em;text-transform:uppercase;color:rgba(255,255,255,.45);
  margin-bottom:var(--s3)}
.lc3-row{display:flex;gap:var(--s3);align-items:stretch}
.lc3-box{flex:0 1 190px;min-width:150px;display:flex;align-items:stretch;
  border:1px solid rgba(255,255,255,.16);border-radius:10px;overflow:hidden;
  background:rgba(255,255,255,.03);transition:border-color .2s var(--ease)}
.lc3-box:focus-within{border-color:var(--cyan)}
.lc3-box-ic{flex:none;width:46px;display:grid;place-items:center;
  background:rgba(75,189,237,.10);border-right:1px solid rgba(255,255,255,.08)}
.lc3-box-ic-s{width:20px;height:20px;stroke:var(--cyan);stroke-width:1.5}
.lc3-box-v{flex:1;min-width:0;display:flex;flex-direction:column;justify-content:center;
  padding:var(--s3) var(--s4)}
.lc3-box-v input{width:100%;border:0;background:none;color:#fff;font-family:var(--sans);
  font-size:24px;font-weight:600;letter-spacing:-.02em;padding:0;
  font-variant-numeric:tabular-nums}
.lc3-box-v input:focus{outline:none}
.lc3-box-v input::placeholder{color:rgba(255,255,255,.25)}
.lc3-box-w{font-family:var(--mono);font-size:10px;letter-spacing:.08em;
  text-transform:uppercase;color:rgba(255,255,255,.4);margin-top:1px}
.lc3-box-u{flex:none;display:grid;place-items:center;width:34px;
  font-family:var(--mono);font-size:12px;color:rgba(255,255,255,.4);
  border-left:1px solid rgba(255,255,255,.08)}
.lc3-step{flex:none;display:flex;gap:var(--s3)}
.lc3-step-b{width:44px;border:1px solid rgba(255,255,255,.16);border-radius:10px;
  background:rgba(255,255,255,.03);color:#fff;font-size:19px;line-height:1;cursor:pointer;
  display:grid;place-items:center;transition:border-color .2s,background .2s}
.lc3-step-b:hover{border-color:var(--cyan);background:rgba(75,189,237,.10)}

.lc3-go{flex:0 0 auto;justify-content:center;padding-inline:var(--s7)}
.lc3-disc{display:flex;gap:var(--s4);align-items:center;margin:0;
  padding:var(--s5) var(--s7);border-top:1px solid rgba(255,255,255,.08);
  background:rgba(255,255,255,.02)}
.lc3-disc-ic{flex:none}
.lc3-disc-ic-s{width:20px;height:20px;stroke:var(--cyan);stroke-width:1.5}
.lc3-disc p{margin:0;font-size:12px;line-height:1.55;color:rgba(255,255,255,.55)}
.lc3-disc b{color:rgba(255,255,255,.85);font-weight:600}

/* results — a full-width band that opens below the input bar. The height
   animates via a 0fr → 1fr grid track (smoother than max-height), the inner
   content fades and lifts, and each crane card staggers in. */
.lc3-out{display:grid;grid-template-rows:0fr;
  transition:grid-template-rows .5s var(--ease)}
.lc3-out-in{overflow:hidden;min-height:0;padding:0 var(--s7);opacity:0;
  transform:translateY(8px);
  transition:opacity .4s var(--ease) .1s,transform .4s var(--ease) .1s,
    padding-block .3s var(--ease)}
.lc3[data-lc-state=ready] .lc3-out{grid-template-rows:1fr;
  border-top:1px solid rgba(255,255,255,.1)}
.lc3[data-lc-state=ready] .lc3-out-in{opacity:1;transform:none;
  padding-block:var(--s7)}
/* the busy beat between the click and the answer */
.lc3[data-lc-state=busy] .lc3-go{opacity:.75;pointer-events:none}
.lc3[data-lc-state=busy] .lc3-go .btn-a{animation:lc3-nudge .5s ease-in-out infinite}
@keyframes lc3-nudge{0%,100%{transform:translateX(0)}50%{transform:translateX(4px)}}
.lc3-out-head{display:flex;flex-wrap:wrap;gap:var(--s3) var(--s4);align-items:flex-start;
  margin-bottom:var(--s6)}
.lc3-out-head:focus{outline:none}
.lc3-out-head > div{flex:1 1 auto;min-width:0}
.lc3-check{flex:none}
.lc3-check-s{width:22px;height:22px;stroke:var(--ok);stroke-width:2}
.lc3-sum{font-size:15px;font-weight:600;letter-spacing:-.01em}
.lc3-out-sub{font-size:12px;color:rgba(255,255,255,.5);margin-top:2px}
.lc3[data-lc-none=yes] .lc3-check-s{stroke:rgba(255,255,255,.4)}
.lc3-reset{flex:none;align-self:center;display:inline-flex;align-items:center;gap:var(--s3);
  background:none;border:1px solid rgba(255,255,255,.18);border-radius:20px;
  padding:6px 14px;cursor:pointer;color:rgba(255,255,255,.7);
  font-family:var(--mono);font-size:10px;letter-spacing:.1em;text-transform:uppercase;
  transition:border-color .2s var(--ease),color .2s var(--ease)}
.lc3-reset:hover{border-color:var(--cyan);color:#fff}
.lc3-reset-s{width:14px;height:14px;stroke:currentColor;stroke-width:2.4}

.lc3-list{display:grid;grid-template-columns:minmax(0,1fr);gap:var(--s4)}
@media(min-width:760px){.lc3-list{grid-template-columns:minmax(0,1fr) minmax(0,1fr)}}
@media(min-width:1120px){.lc3-list{grid-template-columns:repeat(3,minmax(0,1fr))}}
.lc3-m{position:relative;display:block;min-width:0;padding:var(--s5);
  border:1px solid rgba(255,255,255,.13);border-radius:10px;
  transition:border-color .2s var(--ease),background .2s var(--ease)}
.lc3-m:hover{border-color:rgba(255,255,255,.3);background:rgba(255,255,255,.02)}
.lc3-m.is-rec{grid-column:1/-1;border-color:rgba(99,196,138,.5);
  background:rgba(99,196,138,.05)}
.lc3-m.is-out{opacity:.42}
/* the featured card: text, then the elevation, then the check chips — the
   diagram sits beside the text once there is room. */
@media(min-width:680px){
  .lc3-m.is-rec{display:grid;grid-template-columns:minmax(0,1fr) 280px;
    column-gap:var(--s8);row-gap:var(--s4)}
  .lc3-m.is-rec .lc3-m-top{grid-column:1;grid-row:1}
  .lc3-m.is-rec .lc3-m-why{grid-column:1;grid-row:2;margin:0}
  .lc3-m.is-rec .lc3-m-foot{grid-column:1;grid-row:3}
  .lc3-m.is-rec .lc3-m-dia{grid-column:2;grid-row:1/span 3;margin:0;align-self:center}
}
.lc3-m-top{display:flex;flex-wrap:wrap;align-items:baseline;gap:4px var(--s4);
  padding-right:26px}   /* room for the absolutely-placed arrow */
.lc3-m-id{flex:none;font-size:15.5px;font-weight:600;letter-spacing:-.01em;color:#fff;
  text-decoration:none}
a.lc3-m-id::after{content:'';position:absolute;inset:0}   /* whole card links */
.lc3-m:hover a.lc3-m-id{color:var(--cyan)}
.lc3-m-spec{flex:none;font-family:var(--mono);font-size:11px;color:rgba(255,255,255,.45);
  white-space:nowrap}
.lc3-m-badge{margin-left:auto;flex:none;font-family:var(--mono);font-size:8.5px;
  letter-spacing:.12em;text-transform:uppercase;color:var(--ok);
  border:1px solid rgba(99,196,138,.5);border-radius:20px;padding:3px 9px}
.lc3-m-go{position:absolute;top:var(--s5);right:var(--s5);
  width:18px;height:18px;color:rgba(255,255,255,.35)}
.lc3-m:hover .lc3-m-go{color:var(--cyan)}
.lc3-m-why{margin:var(--s3) 0 0;font-size:12.5px;line-height:1.55;
  color:rgba(255,255,255,.6);max-width:46ch}
.lc3-m-dia{margin:var(--s4) 0}
.lc3-m-dia .lcx-dia{width:100%;max-width:320px;height:auto}
.lc3-m-foot{display:flex;flex-wrap:wrap;gap:var(--s3) var(--s6);margin-top:var(--s4)}
.lc3-m-chip{display:inline-flex;align-items:center;gap:var(--s3);
  font-size:11.5px;color:rgba(255,255,255,.55)}
.lc3-m-chip svg{width:15px;height:15px;stroke:rgba(255,255,255,.45);stroke-width:1.6}
.lc3-m-chip.is-ok svg{stroke:var(--ok)}
a.lc3-m-chip{position:relative;z-index:1;text-decoration:none}
a.lc3-m-chip:hover{color:#fff}
a.lc3-m-chip:hover svg{stroke:var(--cyan)}

.lc3-list:not(.show-all) .lc3-m.is-extra{display:none}
.lc3-more{margin-top:var(--s5);display:inline-flex;align-items:center;gap:var(--s3);
  background:none;border:none;cursor:pointer;padding:0;
  font-family:var(--mono);font-size:10.5px;letter-spacing:.1em;text-transform:uppercase;
  color:var(--cyan)}
.lc3-more:hover{color:#fff}
.lc3-none{display:none;margin-top:var(--s5);font-size:13px;color:rgba(255,255,255,.65)}
.lc3[data-lc-none=yes] .lc3-none{display:block}
.lc3-none a{color:var(--cyan);text-decoration:none}

.lc3-note{margin:0;padding:var(--s5) var(--s7);
  display:flex;align-items:center;gap:var(--s3);
  border-top:1px solid rgba(255,255,255,.08);background:rgba(0,0,0,.16);
  font-size:12px;color:rgba(255,255,255,.45)}
.lc3-note-ic{flex:none}
.lc3-note-ic-s{width:16px;height:16px;stroke:rgba(255,255,255,.4);stroke-width:1.6}
.lc3-note a{color:rgba(255,255,255,.72)}
.lc3-dia-host{display:none}

@media(max-width:620px){
  .lc3-in{gap:var(--s5)}
  .lc3-head,.lc3-field,.lc3-go{flex:1 1 100%}
  .lc3-box{flex:1}
  .lc3-m.is-rec{display:block}
}
/* ── a page head that is a photograph ────────────────────────────
   Used where a page opens on a machine in place rather than on a block of
   type. Same plate as the home hero: heavy where the copy sits, clearing to
   the right so the picture survives. min-height, never height, so the copy
   can never be clipped. */
.pagehead-photo{position:relative;isolation:isolate;overflow:hidden;
  display:flex;align-items:center;
  min-height:max(600px, calc(100svh - var(--nav-h)));
  padding-block:var(--s9)}
.pagehead-bg{position:absolute;inset:0;z-index:-2}
.pagehead-bg img{width:100%;height:100%;object-fit:cover;display:block}
.pagehead-bg::after{content:'';position:absolute;inset:0;z-index:1;
  background:
    linear-gradient(90deg,rgba(3,24,38,.92) 0%,rgba(3,24,38,.78) 38%,
      rgba(3,24,38,.36) 62%,rgba(3,24,38,.12) 100%),
    linear-gradient(180deg,rgba(3,24,38,.55) 0%,transparent 30%)}
.pagehead-in{position:relative;z-index:1;width:100%}
@media(max-width:820px){
  .pagehead-photo{min-height:max(460px,calc(100svh - var(--nav-h)));padding-block:var(--s9)}
  .pagehead-bg::after{background:linear-gradient(180deg,rgba(3,24,38,.62),rgba(3,24,38,.90))}
}

/* ── machine picker ─────────────────────────────────────────────
   The comparison table's rows are the chooser: a battery disc, the fit
   line under the model name, a cyan ring and chevron on the chosen row.
   The card under the table pops with the machine on a lit stage — the
   same pooled-light device the panels on this site already use. With
   script off, every card renders and the rows are plain. */
.pick-cell{display:flex;align-items:center;gap:var(--s4)}
.pick-ico{flex:0 0 auto;display:grid;place-items:center;width:36px;height:36px;
  border-radius:50%;border:1px solid rgba(75,189,237,.30);
  background:rgba(75,189,237,.07)}
.pick-ico svg{width:18px;height:18px;stroke:var(--cyan);stroke-width:1.8}
.pick-b{appearance:none;background:none;border:0;padding:0;cursor:pointer;
  font:inherit;font-weight:600;color:inherit;text-align:left;
  display:inline-flex;align-items:center;gap:var(--s3)}
/* a chevron on every model name, dimmed until the row is hovered or open,
   so the rows read as controls and not a static spec table — including on
   touch, where the hover tint never fires */
.pick-b::after{content:'';flex:0 0 auto;width:7px;height:7px;
  border-top:2px solid var(--cyan);border-right:2px solid var(--cyan);
  transform:rotate(45deg);opacity:.55;
  transition:opacity .2s var(--ease),transform .2s var(--ease)}
.pick-b:focus-visible{outline:2px solid var(--cyan);outline-offset:3px;
  border-radius:2px}
.pick-r{cursor:pointer}
.pick-r:hover{background:rgba(75,189,237,.06)}
.pick-r:hover .pick-b{color:var(--cyan)}
.pick-r:hover .pick-b::after{opacity:1;transform:rotate(45deg) translate(1px,-1px)}
.pick-fit{display:block;font-size:12px;margin-top:4px;color:rgba(255,255,255,.45)}
.pick-r.is-on td{background:rgba(75,189,237,.07);
  border-top:1px solid var(--cyan);border-bottom:1px solid var(--cyan)}
.pick-r.is-on td:first-child{border-left:1px solid var(--cyan)}
.pick-r.is-on td:last-child{border-right:1px solid var(--cyan)}
.pick-r.is-on .pick-b{color:var(--cyan)}
.pick-r.is-on .pick-b::after{opacity:1}

/* the card: copy left, the machine on a lit stage right */
.pick-p{position:relative;display:grid;grid-template-columns:1.05fr .95fr;
  gap:var(--s7);margin-top:var(--s7);padding:var(--s7);
  border-radius:18px;overflow:hidden;
  border:1px solid rgba(255,255,255,.10);
  background:
    radial-gradient(80% 120% at 78% 45%, rgba(28,110,168,.38) 0%, transparent 65%),
    linear-gradient(158deg, #08324b 0%, var(--navy-950) 46%, #041e2e 100%)}
.pick-p[hidden]{display:none}
.pick-x{position:absolute;top:var(--s5);right:var(--s5);z-index:2;
  display:grid;place-items:center;width:36px;height:36px;border-radius:50%;
  appearance:none;cursor:pointer;border:1px solid rgba(255,255,255,.24);
  background:rgba(255,255,255,.06);color:#fff;
  transition:border-color .2s var(--ease),background .2s var(--ease)}
.pick-x svg{width:16px;height:16px;stroke:currentColor;stroke-width:2.4}
.pick-x:hover{border-color:var(--cyan);background:rgba(75,189,237,.12)}
.pick-id{font-family:var(--sans);
  font-size:clamp(38px,3.4vw,52px);font-weight:700;letter-spacing:-.02em;
  line-height:.95;color:#fff}
.pick-k{font-family:var(--mono);font-size:11px;letter-spacing:.22em;
  text-transform:uppercase;color:var(--cyan);margin-top:var(--s3)}
.pick-for{font-size:14.5px;line-height:1.7;color:rgba(255,255,255,.62);
  margin-top:var(--s4);max-width:46ch}
.pick-chips{display:flex;flex-wrap:wrap;gap:var(--s3);margin-top:var(--s6)}
.pick-chip{display:inline-flex;align-items:center;gap:var(--s3);
  padding:var(--s3) var(--s4);border:1px solid rgba(255,255,255,.13);
  border-radius:10px}
.pick-chip svg{width:18px;height:18px;stroke:var(--cyan);stroke-width:1.8;
  flex:0 0 auto}
.pick-chip b{display:block;font-size:14px;font-weight:600;color:#fff;
  white-space:nowrap;font-variant-numeric:tabular-nums}
.pick-chip i{display:block;font-style:normal;font-family:var(--mono);
  font-size:9px;letter-spacing:.12em;text-transform:uppercase;
  color:rgba(255,255,255,.45);margin-top:2px;white-space:nowrap}
.pick-acts{display:flex;flex-wrap:wrap;gap:var(--s4);margin-top:var(--s6);align-items:stretch}
/* The site button, sized to sit beside .pick-ask in the card rather than at
   its full pagehead size. Same style, smaller footprint. */
.pick-acts .btn-line{font-size:14px;font-weight:600;padding:var(--s4) var(--s6);
  border-radius:8px}
.pick-acts .btn-line .btn-i{width:18px;height:18px;filter:none}
.pick-ask{display:inline-flex;align-items:center;gap:var(--s3);
  padding:var(--s4) var(--s6);border-radius:8px;
  border:1px solid rgba(75,189,237,.45);color:#fff;font-size:14px;
  text-decoration:none;
  transition:border-color .2s var(--ease),background .2s var(--ease)}
.pick-ask svg{width:18px;height:18px;stroke:var(--cyan);stroke-width:2;
  transition:transform .2s var(--ease)}
.pick-ask:hover{border-color:var(--cyan);background:rgba(75,189,237,.12)}
.pick-ask:hover svg{transform:translateX(3px)}
.pick-stage{position:relative;display:flex;align-items:center;
  justify-content:center;min-height:300px}
.pick-stage img{max-width:100%;max-height:320px;width:auto;height:auto;
  transform:scale(var(--shot,1));object-fit:contain;
  filter:drop-shadow(0 30px 44px rgba(0,0,0,.55));
  animation:pick-in .34s var(--ease) both}
@keyframes pick-in{from{opacity:0;transform:translateY(10px) scale(.985)}}
@media(prefers-reduced-motion:reduce){.pick-stage img{animation:none}}
@media(max-width:900px){
  .pick-p{grid-template-columns:1fr;gap:var(--s5);padding:var(--s6)}
  .pick-stage{min-height:200px}
  .pick-stage img{max-height:200px}
}

/* ── the picker on a phone ──────────────────────────────────────────
   The comparison table is eight columns wide; on a phone that means a
   sideways scroll to read a single machine's line. Below 700px the
   table drops to the model and its headline rating, and the row still
   opens the overlay — which carries every figure in full. */
@media (max-width:700px){
  .tscroll .cmp.pick{min-width:0}
  .cmp.pick th:not(:first-child):not(:nth-child(2)),
  .cmp.pick td:not(:first-child):not(:nth-child(2)){display:none}
  .cmp.pick th:nth-child(2),
  .cmp.pick td:nth-child(2){white-space:nowrap;padding-left:var(--s3)}

  /* the overlay, rebuilt for a phone: the machine leads on its own glow,
     then the rated figure large, then the rest as a quiet two-column list
     — the boxed chips read as a form at this width. Desktop is untouched. */
  [data-picker].pick-ov{padding:0}
  [data-picker].pick-ov .pick-p{max-width:none;max-height:100dvh;
    min-height:100dvh;border-radius:0;padding:0 var(--s5) var(--s7);
    overflow-y:auto}

  .pick-p .pick-stage{order:-1;min-height:0;
    margin:0 calc(var(--s5) * -1) 0;padding:var(--s6) var(--s5) var(--s2);
    background:radial-gradient(72% 58% at 50% 40%,
      rgba(28,110,168,.34) 0%, transparent 70%)}
  .pick-p .pick-stage img{max-height:30vh;animation:none}

  .pick-p .pick-id{font-size:30px;margin-top:var(--s4)}
  .pick-p .pick-k{margin-top:var(--s1)}
  .pick-p .pick-for{display:none}

  .pick-chips{display:grid;grid-template-columns:1fr 1fr;
    column-gap:var(--s5);row-gap:0;margin-top:var(--s5)}
  .pick-chip{display:flex;flex-direction:column;gap:2px;width:auto;
    padding:var(--s3) 0;border:0;
    border-bottom:1px solid rgba(255,255,255,.09)}
  .pick-chip svg{display:none}
  .pick-chip b{font-size:15px;font-weight:600;white-space:nowrap}
  .pick-chip i{font-size:9.5px;letter-spacing:.1em;white-space:nowrap;
    color:rgba(255,255,255,.5)}
  /* the rated figure is the headline */
  .pick-chip:first-child{grid-column:1/-1;padding-bottom:var(--s4);
    border-bottom-color:rgba(255,255,255,.16)}
  .pick-chip:first-child b{font-size:38px;font-weight:300;
    letter-spacing:-.02em;line-height:1}
  .pick-chip:first-child i{font-size:11px;color:var(--cyan);
    margin-top:var(--s2)}

  .pick-acts{margin-top:var(--s5);gap:var(--s3)}
  .pick-acts .pick-ask,.pick-acts .btn-line,.pick-acts a{padding:var(--s3) var(--s5)}
}
@media (max-width:700px) and (max-height:680px){
  .pick-p .pick-stage img{max-height:22vh}
}

/* with script, the card floats over the page like the lift-check modal:
   scrim, centred panel, the page locked behind it. Without script the
   cards simply render in flow below the table. */
[data-picker].pick-ov{position:fixed;inset:0;z-index:300;display:flex;
  align-items:center;justify-content:center;padding:4vh var(--gut);
  max-width:none;margin:0;background:rgba(4,40,59,.86)}
[data-picker].pick-ov .pick-p{margin-top:0;width:100%;max-width:1160px;
  max-height:90vh;overflow-y:auto;
  box-shadow:0 40px 90px rgba(0,0,0,.5);
  animation:pick-pop .28s var(--ease) both}
@keyframes pick-pop{from{opacity:0;transform:translateY(14px) scale(.98)}}
@media(prefers-reduced-motion:reduce){
  [data-picker].pick-ov .pick-p{animation:none}}

/* ── the ask, as two panels ──────────────────────────────────────
   The page's two real paths, numbered the way the steps are numbered:
   hand it over, or run it yourself. The self-serve panel carries the
   pooled light, the same device the machine cards use, so the tool
   reads as the live thing on the screen. */
.ask-p{position:relative;padding:var(--s7);border-radius:18px;
  border:1px solid rgba(255,255,255,.10);background:rgba(255,255,255,.02)}
.ask-p-lit{border-color:rgba(75,189,237,.28);
  background:
    radial-gradient(90% 130% at 82% 0%, rgba(28,110,168,.40) 0%, transparent 62%),
    linear-gradient(158deg, #08324b 0%, var(--navy-950) 46%, #041e2e 100%)}
.ask-k{display:flex;align-items:baseline;gap:var(--s4);font-size:19px;
  font-weight:600;letter-spacing:-.01em;color:#fff;
  padding-bottom:var(--s5);margin-bottom:var(--s6);
  border-bottom:1px solid rgba(255,255,255,.10)}
.ask-k span{font-family:var(--mono);font-size:13px;letter-spacing:.14em;
  color:var(--cyan)}
.ask-p .form-note{font-size:12px}
button.btn-fill,button.btn-line{appearance:none}

/* fields with a pulse: lifted fill, a cyan ring that blooms on focus, and
   the label waking up with it — the same glow language as the buttons */
.ask-p .field input,.ask-p .field select{font-size:16px;
  padding:var(--s4) var(--s5);border-radius:12px;
  border:1px solid rgba(255,255,255,.16);
  background:linear-gradient(180deg,rgba(255,255,255,.09),rgba(255,255,255,.05));
  box-shadow:inset 0 1px 0 rgba(255,255,255,.10);
  transition:border-color .22s var(--ease),background .22s var(--ease),
    box-shadow .22s var(--ease)}
.ask-p .field input::placeholder{color:rgba(255,255,255,.32)}
.ask-p .field input:hover,.ask-p .field select:hover{
  border-color:rgba(75,189,237,.45)}
.ask-p .field input:focus,.ask-p .field select:focus{outline:none;
  border-color:var(--cyan);
  background:linear-gradient(180deg,rgba(75,189,237,.14),rgba(75,189,237,.05));
  box-shadow:inset 0 1px 0 rgba(255,255,255,.14),
    0 0 0 3px rgba(75,189,237,.18),0 10px 30px rgba(9,102,151,.30)}
.ask-p .field label{transition:color .22s var(--ease)}
.ask-p .field:focus-within label{color:var(--cyan)}
.ask-p .field input:not(:placeholder-shown){border-color:rgba(75,189,237,.35)}

@media(max-width:680px){.ask-p{padding:var(--s6)}}

/* ── battery selector ────────────────────────────────────────────
   The range as one machine at a time, chosen from a numbered rail. Four cards
   in a row read as a slide, and put an 11,000 kg container beside a 1,050 kg
   unit as though they were peers.

   Dark, with a light pooled behind the machine: on a flat ground these grey
   cut-outs sit dead, and the glow is what gives the panel depth. Numbering
   matches the home track; cyan marks the active tab as it does everywhere
   else on a dark section. */
.vh{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;
  clip:rect(0 0 0 0);white-space:nowrap;border:0}

.bsel{position:relative;display:grid;grid-template-columns:88px 1fr;
  margin-top:var(--s8);border-radius:18px;overflow:hidden;
  background:
    radial-gradient(120% 90% at 34% 62%, rgba(28,110,168,.42) 0%, transparent 62%),
    linear-gradient(158deg, #08324b 0%, var(--navy-950) 46%, #041e2e 100%);
  border:1px solid rgba(255,255,255,.10)}

.bsel-rail{display:flex;flex-direction:column;padding:var(--s5) 0;
  background:rgba(0,0,0,.22);border-right:1px solid rgba(255,255,255,.09)}
.bsel-t{position:relative;appearance:none;background:none;border:0;cursor:pointer;
  padding:var(--s5) 0;font-family:var(--sans);
  font-size:24px;font-weight:700;line-height:1;color:rgba(255,255,255,.34);
  transition:color .2s var(--ease),background .2s var(--ease)}
.bsel-t:hover{color:rgba(255,255,255,.78);background:rgba(255,255,255,.05)}
.bsel-t[aria-selected=true]{color:#fff;background:rgba(255,255,255,.07)}
.bsel-t[aria-selected=true]::after{content:'';position:absolute;right:-1px;
  top:18%;bottom:18%;width:3px;background:var(--cyan)}
.bsel-t:focus-visible{outline:2px solid var(--cyan);outline-offset:-4px}
/* the dwell runs down the tab, so the rotation is visible rather than sudden */
.bsel-t::before{content:'';position:absolute;left:0;right:0;bottom:0;height:2px;
  background:var(--cyan);opacity:.7;transform:scaleX(0);transform-origin:left}
.bsel[data-play=on] .bsel-t[aria-selected=true]::before{
  animation:bsel-fill var(--dwell,5.2s) linear forwards}
@keyframes bsel-fill{to{transform:scaleX(1)}}

/* align-items:start puts the model name at the top of the panel rather than
   floating it in the middle; the photograph then takes the height that
   leaves, which is most of it. */
.bsel-p{display:grid;grid-template-columns:1.32fr .68fr;gap:var(--s7);
  align-items:start;padding:var(--s7) var(--s7) var(--s7) var(--s6);
  min-height:680px}
.bsel-p[hidden]{display:none}

.bsel-main{display:flex;flex-direction:column;min-width:0;height:100%}
.bsel-k{font-family:var(--mono);font-size:11px;letter-spacing:.22em;
  text-transform:uppercase;color:var(--cyan)}
.bsel-id{font-family:var(--sans);
  font-size:clamp(46px,4.6vw,72px);font-weight:700;letter-spacing:-.025em;
  line-height:.95;color:#fff;margin-top:var(--s3)}
/* A fixed stage, not a flexing one. The four source files differ in size —
   PA375Pro is 964x734, PE500 only 375x276 — so letting the box follow the
   image made the panel jump every time the tab changed. The stage is constant
   and each machine sits inside it. */
.bsel-shot{flex:0 0 auto;display:flex;align-items:center;justify-content:center;
  height:440px;margin-top:var(--s5)}
/* contain, never cover: these are cut-outs, and cropping trims the machine */
/* --shot is the per-model optical nudge set in build.py; a transform, so
   the stage keeps its size and nothing reflows. */
.bsel-shot img{max-width:100%;max-height:100%;width:auto;height:auto;
  transform:scale(var(--shot,1));transform-origin:center;
  object-fit:contain;display:block;
  filter:drop-shadow(0 30px 44px rgba(0,0,0,.55));
  animation:bsel-in .34s var(--ease) both}
@keyframes bsel-in{from{opacity:0;transform:translateY(10px) scale(.985)}}

/* Datasheet link under the machine, as the proposal deck places it. Deep
   links to that model's page in the range brochure. */
.bsel-sheet{display:inline-flex;align-items:center;gap:var(--s3);align-self:center;
  margin-top:var(--s4);font-family:var(--mono);font-size:11px;letter-spacing:.1em;
  text-transform:uppercase;color:rgba(255,255,255,.62);text-decoration:none;
  padding:var(--s3) var(--s4);border-radius:6px;
  transition:color .2s var(--ease),background .2s var(--ease)}
.bsel-sheet svg{width:15px;height:15px;stroke:var(--cyan);stroke-width:1.8}
.bsel-sheet:hover{color:#fff;background:rgba(255,255,255,.07)}
.bsel[data-theme=light] .bsel-sheet{color:var(--ink-2)}
.bsel[data-theme=light] .bsel-sheet svg{stroke:var(--navy)}
.bsel[data-theme=light] .bsel-sheet:hover{color:var(--ink);background:rgba(6,44,66,.05)}

.bsel-spec{min-width:0}
.bsel-sh{font-family:var(--mono);font-size:11px;letter-spacing:.22em;
  text-transform:uppercase;color:var(--cyan);margin-bottom:var(--s5)}
.bsel-r{display:grid;grid-template-columns:auto 1fr auto;align-items:center;
  gap:var(--s5);padding:var(--s4) 0;border-bottom:1px solid rgba(255,255,255,.10)}
.bsel-ri{display:grid;place-items:center;width:42px;height:42px;border-radius:50%;
  border:1px solid rgba(255,255,255,.30);background:rgba(255,255,255,.07)}
.bsel-ri svg{width:20px;height:20px;stroke:#fff;stroke-width:1.7}
.bsel-rk{font-size:14.5px;color:rgba(255,255,255,.74)}
.bsel-rv{font-size:19px;font-weight:600;color:#fff;white-space:nowrap;
  font-variant-numeric:tabular-nums}
.bsel-cta{display:inline-flex;align-items:center;justify-content:space-between;
  gap:var(--s6);width:100%;margin-top:var(--s6);padding:var(--s5) var(--s6);
  border-radius:8px;border:1px solid rgba(75,189,237,.45);color:#fff;
  font-size:15.5px;text-decoration:none;
  transition:border-color .2s var(--ease),background .2s var(--ease)}
.bsel-cta:hover{border-color:var(--cyan);background:rgba(75,189,237,.12)}
.bsel-cta svg{width:20px;height:20px;stroke:var(--cyan);stroke-width:2;
  transition:transform .2s var(--ease)}
.bsel-cta:hover svg{transform:translateX(4px)}

/* the contrast switch, top right of the panel */
.bsel-theme{position:absolute;top:var(--s5);right:var(--s5);z-index:3;
  display:grid;place-items:center;width:38px;height:38px;border-radius:50%;
  appearance:none;cursor:pointer;
  border:1px solid rgba(255,255,255,.24);background:rgba(255,255,255,.06);
  color:#fff;
  transition:border-color .2s var(--ease),background .2s var(--ease),
    color .2s var(--ease),transform .3s var(--ease)}
.bsel-theme svg{width:19px;height:19px}
.bsel-theme:hover{border-color:var(--cyan);color:#fff;transform:rotate(180deg)}
.bsel-theme:focus-visible{outline:2px solid var(--cyan);outline-offset:2px}

/* ── the light panel ─────────────────────────────────────────────
   Same structure, the site's paper and bone instead of the navies. These are
   grey cut-outs, so on paper they read as product photography rather than as
   objects floating in a dark room. */
.bsel[data-theme=light]{
  background:radial-gradient(120% 90% at 34% 60%, #ffffff 0%, var(--bone) 68%);
  border-color:var(--line)}
.bsel[data-theme=light] .bsel-rail{background:rgba(6,44,66,.045);
  border-right-color:var(--line)}
.bsel[data-theme=light] .bsel-t{color:var(--muted)}
.bsel[data-theme=light] .bsel-t:hover{color:var(--ink);background:rgba(6,44,66,.05)}
.bsel[data-theme=light] .bsel-t[aria-selected=true]{color:var(--navy);
  background:var(--paper)}
.bsel[data-theme=light] .bsel-t[aria-selected=true]::after{background:var(--navy)}
.bsel[data-theme=light] .bsel-t::before{background:var(--navy);opacity:.55}
.bsel[data-theme=light] .bsel-k,
.bsel[data-theme=light] .bsel-sh{color:var(--navy)}
.bsel[data-theme=light] .bsel-id{color:var(--ink)}
.bsel[data-theme=light] .bsel-shot img{
  filter:drop-shadow(0 22px 34px rgba(6,44,66,.22))}
.bsel[data-theme=light] .bsel-r{border-bottom-color:var(--line)}
.bsel[data-theme=light] .bsel-ri{border-color:rgba(9,102,151,.28);
  background:rgba(9,102,151,.06)}
.bsel[data-theme=light] .bsel-ri svg{stroke:var(--navy)}
.bsel[data-theme=light] .bsel-rk{color:var(--ink-2)}
.bsel[data-theme=light] .bsel-rv{color:var(--ink)}
.bsel[data-theme=light] .bsel-cta{border-color:var(--line);color:var(--ink)}
.bsel[data-theme=light] .bsel-cta:hover{border-color:var(--navy);
  background:var(--blue-soft)}
.bsel[data-theme=light] .bsel-cta svg{stroke:var(--navy)}
/* On paper the switch keeps navy: a white glyph on a white panel is invisible. */
.bsel[data-theme=light] .bsel-theme{border-color:rgba(6,44,66,.22);
  background:rgba(6,44,66,.04);color:var(--navy)}
.bsel[data-theme=light] .bsel-theme:hover{border-color:var(--navy)}

@media(max-width:1000px){
  .bsel{grid-template-columns:1fr}
  .bsel-rail{flex-direction:row;justify-content:center;padding:0;
    border-right:none;border-bottom:1px solid rgba(255,255,255,.09)}
  .bsel-t{flex:1 1 auto;padding:var(--s5)}
  .bsel-t[aria-selected=true]::after{right:20%;left:20%;top:auto;bottom:-1px;
    width:auto;height:3px}
  .bsel-p{grid-template-columns:1fr;min-height:0;gap:var(--s7);
    padding:var(--s7) var(--s6)}
  .bsel-shot{height:280px}
}
@media(prefers-reduced-motion:reduce){
  .bsel-t::before{display:none}
  .bsel-shot img{animation:none}
}
/* ── the rail: what you tell us ─────────────────────────────────── */
.lcx-rail{background:var(--navy-950);color:#fff;padding:var(--s8) var(--s7)}
.lcx-kicker{font-family:var(--mono);font-size:10px;letter-spacing:.2em;
  text-transform:uppercase;color:var(--cyan)}
.lcx-h{font-size:23px;font-weight:600;letter-spacing:-.015em;line-height:1.25;
  margin-top:var(--s4);color:#fff}
.lcx-sub{font-size:13px;line-height:1.6;color:rgba(255,255,255,.6);margin-top:var(--s4)}
.lcx-f{margin-top:var(--s6)}
.lcx-f label{display:block;font-family:var(--mono);font-size:10px;letter-spacing:.16em;
  text-transform:uppercase;color:rgba(255,255,255,.5);margin-bottom:var(--s3)}
.lcx-box{display:flex;align-items:stretch;border-radius:11px;overflow:hidden;
  border:1px solid rgba(255,255,255,.18);background:rgba(255,255,255,.05);
  transition:border-color .2s var(--ease),box-shadow .2s var(--ease)}
.lcx-box:focus-within{border-color:var(--cyan);
  box-shadow:0 0 0 3px rgba(75,189,237,.18)}
.lcx-ic{flex:0 0 auto;display:grid;place-items:center;width:48px;
  border-right:1px solid rgba(255,255,255,.13)}
.lcx-ic-s{width:21px;height:21px;stroke:var(--cyan);stroke-width:1.5}
.lcx-box input{flex:1 1 auto;min-width:0;text-align:right;font-family:var(--sans);
  font-weight:500;font-size:25px;background:transparent;border:none;color:#fff;
  padding:var(--s4) var(--s4);font-variant-numeric:tabular-nums}
.lcx-box input::placeholder{color:rgba(255,255,255,.25)}
.lcx-box input:focus{outline:none}
.lcx-u{flex:0 0 auto;display:grid;place-items:center;width:44px;
  border-left:1px solid rgba(255,255,255,.13);
  font-family:var(--mono);font-size:12px;color:rgba(255,255,255,.55)}
.lcx-dia{width:100%;height:auto;display:block;margin-top:var(--s7);overflow:visible}

/* ── the canvas: what we tell you ───────────────────────────────── */
.lcx-out{padding:var(--s8) var(--s7);min-width:0}
.lcx-ans{display:flex;align-items:center;justify-content:space-between;gap:var(--s5);
  padding:var(--s6);border-radius:14px;background:var(--blue-soft)}
.lcx-ans-k{font-family:var(--mono);font-size:10px;letter-spacing:.16em;
  text-transform:uppercase;color:var(--navy);font-weight:500}
.lcx-ans-v{display:flex;align-items:baseline;gap:var(--s3);margin-top:var(--s3);
  font-size:38px;font-weight:700;letter-spacing:-.03em;color:var(--navy-950);
  line-height:1;font-variant-numeric:tabular-nums}
.lcx-ans-of{font-size:15px;font-weight:400;color:var(--ink-2)}
.lcx-ans-s{font-size:13px;color:var(--ink-2);margin-top:var(--s3)}

.lcx-key{display:flex;flex-wrap:wrap;gap:var(--s3) var(--s6);margin-top:var(--s6)}
.lcx-key span{display:inline-flex;align-items:center;gap:var(--s3);font-size:12.5px;
  color:var(--ink-2)}
/* element-qualified: the legend swatch is always an <i>. A bare .k used to
   leak into every "big number / .k label" block (metrics, offer cards, the
   class-page stat row) and crush the label into an 8px box. */
i.k{display:inline-block;width:8px;height:8px;border-radius:50%;flex:0 0 auto}
.k-in{background:var(--navy)}.k-cf{background:var(--muted)}
.k-no{background:var(--line)}

.lcx-list{display:flex;flex-direction:column;margin-top:var(--s4);
  border-top:1px solid var(--line)}
.match{position:relative;display:grid;grid-template-columns:1fr auto;gap:var(--s5);
  align-items:center;padding:var(--s5) var(--s4);border-bottom:1px solid var(--line);
  transition:background .16s var(--ease)}
.match:hover{background:var(--bone)}
/* The one machine that answers the question should not look like the five
   that cannot. A tinted band and a rule, not a coloured box. */
.match.best{background:var(--blue-soft);
  box-shadow:inset 3px 0 0 var(--navy)}
.match.best:hover{background:var(--blue-soft);box-shadow:inset 3px 0 0 var(--navy),
  inset 0 0 0 999px rgba(9,102,151,.05)}
.match.out{opacity:.55}
.m-id{font-size:16px;font-weight:500;color:var(--ink);letter-spacing:-.01em}
.m-id a{text-decoration:none;color:inherit}
.m-id a::after{content:'';position:absolute;inset:0}
.match:hover .m-id{color:var(--navy)}
.m-d{font-family:var(--mono);font-size:11px;color:var(--ink-2);margin-top:3px}
.m-r{display:inline-flex;align-items:center;gap:var(--s4)}
.m-s{font-family:var(--mono);font-size:10px;letter-spacing:.14em;text-transform:uppercase}
.s-in{color:var(--navy);font-weight:500}.s-cf{color:var(--muted)}.s-no{color:var(--muted)}
.m-mk{display:grid;place-items:center;width:24px;height:24px;border-radius:50%;flex:0 0 auto}
.m-mk svg{width:15px;height:15px;stroke-width:2.6}
.mk-in{background:var(--navy)}.mk-in svg{stroke:#fff}
.mk-no{background:var(--line)}.mk-no svg{stroke:var(--muted)}
.mk-cf{display:none}

.lcx-none{margin-top:var(--s5);font-size:13.5px;color:var(--ink-2)}
.lcx-none a{color:var(--navy);text-decoration:none}
.lcx-none a:hover{text-decoration:underline}
.lcx-note{margin-top:var(--s6);padding-top:var(--s5);border-top:1px solid var(--line);
  font-size:12px;line-height:1.6;color:var(--muted)}

/* ── states ──────────────────────────────────────────────────────
   Only the list and the two conditional lines come and go. The answer card,
   the key and the note are always there, holding the shape. */
.lcx-list,.lcx-none,.lcx-spin,.lcx-key{display:none}
.lcx[data-lc-state=ready] .lcx-list{display:flex}
.lcx[data-lc-state=ready] .lcx-key{display:flex}
.lcx[data-lc-state=ready][data-lc-none=yes] .lcx-none{display:block}
.lcx[data-lc-state=busy] .lcx-spin{display:block}

/* The only spinner on the site. One beat while the figures settle. */
.lcx-spin{width:20px;height:20px;flex:0 0 auto;border-radius:50%;
  border:2px solid rgba(9,102,151,.20);border-top-color:var(--navy);
  animation:lc-turn .7s linear infinite}
@keyframes lc-turn{to{transform:rotate(360deg)}}

/* Rows stagger in once, on first reveal. After that they are reordered with
   a FLIP in script and never re-animated. */
.match.is-new{animation:lc-rise .3s cubic-bezier(.22,.61,.36,1) backwards;
  animation-delay:calc(var(--i,0) * 35ms)}
.lc3-m.is-new{animation:lc-rise .34s cubic-bezier(.22,.61,.36,1) backwards;
  animation-delay:calc(var(--i,0) * 45ms + 240ms)}
@keyframes lc-rise{from{opacity:0;transform:translateY(10px)}}
.lc3[data-lc-state=ready] .lc3-check{animation:lc3-pop .4s var(--ease) .18s backwards}
@keyframes lc3-pop{from{opacity:0;transform:scale(.4)}60%{transform:scale(1.12)}to{opacity:1;transform:scale(1)}}
@media(prefers-reduced-motion:reduce){
  .lc3-m.is-new,.lc3[data-lc-state=ready] .lc3-check,
  .lc3[data-lc-state=busy] .lc3-go .btn-a{animation:none}
  .lc3-out,.lc3-out-in{transition:none}
}

/* The elevation is dormant until there is a radius to place a hook at. */
.lcx-dia .lc-d-crane{opacity:.4;transition:opacity .4s var(--ease)}
.lcx-dia.has-rad .lc-d-crane{opacity:1}
.lcx-dia .lc-d-fall,.lcx-dia .lc-d-hook,.lcx-dia [data-lc-tick]{opacity:0;
  transition:opacity .3s var(--ease),x1 .25s var(--ease),x2 .25s var(--ease),
    transform .25s var(--ease)}
.lcx-dia.has-rad .lc-d-fall,.lcx-dia.has-rad .lc-d-hook,
.lcx-dia.has-rad [data-lc-tick]{opacity:1}
.lc-d-crane path{stroke:rgba(255,255,255,.42);stroke-width:1.3}
.lc-d-crane .lc-d-lat{stroke:rgba(255,255,255,.20);stroke-width:.9}
.lc-d-crane .lc-d-gnd{stroke:rgba(255,255,255,.16);stroke-width:1}
.lc-d-crane .lc-d-cw{stroke:rgba(255,255,255,.42);fill:rgba(255,255,255,.10)}
.lc-d-fall{stroke:rgba(255,255,255,.32);stroke-width:1;stroke-dasharray:3 3}
.lc-d-hook{fill:var(--cyan);stroke:none}
.lc-d-dim line{stroke:rgba(255,255,255,.18);stroke-width:1}
.lc-d-dim [data-lc-tick]{stroke:var(--cyan);stroke-width:1.6}
.lc-d-far rect{fill:rgba(255,255,255,.06)}
.lc-d-t{fill:var(--cyan);font-family:var(--sans);font-size:16px;font-weight:600}
.lc-d-t2{fill:rgba(255,255,255,.6);font-family:var(--sans);font-size:11px}
.lc-d-s{fill:rgba(255,255,255,.3);font-family:var(--mono);font-size:9px;letter-spacing:.1em}

@media(max-width:960px){
  /* minmax(0,1fr), not 1fr, and min-width:0 on the children. A grid item's
     default minimum is its content, so the rail kept the width its widest
     child wanted — 482px inside a 375px phone — and .lcx's own overflow:hidden
     cropped 128px of the calculator off the right edge rather than letting the
     page scroll, which is why nothing showed up as a page overflow. */
  .lcx{grid-template-columns:minmax(0,1fr)}
  .lcx > *{min-width:0}
  .lcx-dia{max-width:400px}
}
@media(prefers-reduced-motion:reduce){
  .match.is-new{animation:none}
  .lcx-spin{animation:none;border-top-color:rgba(9,102,151,.2)}
  .lcx-dia *{transition:none}
}

/* ══ FORM ══ */
.form{display:grid;grid-template-columns:1fr 1fr;gap:var(--s5)}
.field{display:flex;flex-direction:column;gap:var(--s2);position:relative;
  padding-bottom:1.25em}
/* every field reserves the error line, whether or not it has an error to
   show, so required and optional fields keep the same rhythm */
.field.wide{grid-column:1/-1;padding-bottom:0}
.field label{font-family:var(--mono);font-size:10px;letter-spacing:.16em;text-transform:uppercase;
  color:var(--ink-2)}
.on-dark .field label{color:rgba(255,255,255,.45)}
.field input,.field select,.field textarea{font-family:var(--sans);font-size:15px;
  padding:var(--s3) var(--s4);border:1px solid var(--line);background:#fff;color:var(--ink);
  border-radius:0;transition:border-color .25s var(--ease)}
.field textarea{min-height:120px;resize:vertical}
.field input:focus,.field select:focus,.field textarea:focus{outline:none;border-color:var(--navy);
  box-shadow:inset 0 0 0 1px var(--navy)}
.on-dark .field input,.on-dark .field select,.on-dark .field textarea{
  background:rgba(255,255,255,.05);border-color:var(--line-dd);color:#fff}
.on-dark .field input:focus,.on-dark .field textarea:focus{border-color:var(--cyan);
  box-shadow:inset 0 0 0 1px var(--cyan)}
/* Error text reserves its space at all times. Toggling display here would
   reflow the form and move the submit button out from under the pointer
   between the click that revealed the error and the one that follows it. */
.field .err{position:absolute;left:0;bottom:0;font-size:12px;line-height:1.45;
  color:var(--warn);visibility:hidden}
.field.is-err input,.field.is-err textarea{border-color:var(--warn)}
.field.is-err .err{visibility:visible}
.form-note{font-size:13px;color:var(--ink-2)}
.on-dark .form-note{color:rgba(255,255,255,.5)}
.form-ok{display:none;padding:var(--s5);border:1px solid var(--cyan);
  background:rgba(75,189,237,.08);font-size:15px}
.form-ok.show{display:block}

/* ══ QUICK SIZE — the battery calculator, folded into the fleet header ══
   Used to be its own full "Size a system" screen further down the page,
   repeating an h2 that said "size" right after this one did. The fleet
   header had empty navy to the right of its lede on anything wider than a
   phone; this fills it instead. #fleet .sec-head goes two columns to make
   room, text left, widget right, stacking on tablet/phone where there is no
   spare width to give it. */
/* grid-template-columns is 1fr 380px, not 1fr auto: an auto track sizes to
   its item's intrinsic content width, and .quick-size's own width was
   min(380px,100%) — a percentage, which is ambiguous input to an intrinsic
   (auto) track size, since the track isn't resolved yet. Chromium fell back
   to sizing the track off the widget's unwrapped text instead, well past
   380px, and left the real ~290px gap between the card and the section
   edge that this comment is here because of. A fixed 380px track has no
   ambiguity to fall back from. */
.fleet-head{display:grid;grid-template-columns:1fr 380px;gap:var(--s8);
  align-items:start}
@media(max-width:860px){.fleet-head{grid-template-columns:1fr}}
/* Raised off the navy rather than blended into it — a hairline this faint
   on a solid navy ground read as barely a card at all. The shadow and the
   inset top highlight are the same device the lift-check tool (.lcx-box)
   already uses for "this sits above the page", not a new one. */
.quick-size{position:relative;overflow:hidden;width:100%;padding:var(--s6);
  border:1px solid rgba(255,255,255,.14);border-radius:12px;background:rgba(255,255,255,.045);
  box-shadow:0 24px 48px rgba(2,12,20,.4),inset 0 1px 0 rgba(255,255,255,.07)}
/* Ghosted, not illustrated: z-index -1 paints it over the card's own tint
   but under every actual child (those stay position:static, which the
   stacking order always draws above a negative-z sibling) — decoration,
   never competing with the numbers for attention.

   Small and pinned tight to the corner on purpose — the first cut ran it at
   62% of the card's width, which put it directly behind the header text
   instead of beside it, reading as an unexplained smudge rather than a
   corner flourish. This one sits clear of every line of copy. */
.quick-size-bg{position:absolute;z-index:-1;top:-14px;right:-14px;width:84px;
  height:auto;opacity:.14;pointer-events:none}
.quick-size-head{display:flex;align-items:flex-start;gap:var(--s4);margin-bottom:var(--s6)}
.quick-size-ico{flex:0 0 auto;display:grid;place-items:center;width:38px;height:38px;
  border-radius:8px;background:rgba(75,189,237,.14);border:1px solid rgba(75,189,237,.3)}
.quick-size-ico-s{width:18px;height:18px;stroke:var(--cyan);stroke-width:2}
.quick-size-h{margin:0;font-size:15px;font-weight:600;color:#fff;letter-spacing:-.005em}
.quick-size-sub{margin:2px 0 0;font-size:12.5px;color:rgba(255,255,255,.55)}
.quick-size-f{display:flex;gap:var(--s4)}
.quick-size-f .field{flex:1;min-width:0;padding-bottom:0}
/* The boxed input + unit suffix is .lcx-box's pattern, scaled down: a
   number typed next to its own unit reads as a purpose-built tool, not a
   generic two-box form the placeholder text has to explain on its own. */
.qs-box{display:flex;align-items:stretch;border-radius:8px;overflow:hidden;
  border:1px solid rgba(255,255,255,.16);background:rgba(255,255,255,.05);
  transition:border-color .2s var(--ease),box-shadow .2s var(--ease)}
.qs-box:focus-within{border-color:var(--cyan);box-shadow:0 0 0 3px rgba(75,189,237,.18)}
.qs-box input{flex:1 1 auto;min-width:0;background:transparent;border:none;color:#fff;
  font-family:var(--sans);font-weight:500;font-size:16px;padding:var(--s3) 0 var(--s3) var(--s4);
  font-variant-numeric:tabular-nums}
.qs-box input:focus{outline:none}
.qs-box input::placeholder{color:rgba(255,255,255,.3)}
.qs-u{flex:0 0 auto;display:flex;align-items:center;padding:0 var(--s4);
  font-family:var(--mono);font-size:10.5px;letter-spacing:.04em;
  color:rgba(255,255,255,.45);white-space:nowrap}
/* The live estimate: today's own generator numbers multiplied out, not a
   battery figure — see site.js for the arithmetic and why it's simple
   on purpose. Appears only once both fields hold a value ([hidden] by
   default in the markup). */
.qs-est{margin-top:var(--s5);padding:var(--s5);border-radius:9px;
  background:rgba(75,189,237,.08);border:1px solid rgba(75,189,237,.22)}
.qs-est-i{display:flex;align-items:center;gap:var(--s4)}
.qs-est-ico-s{width:20px;height:20px;stroke:var(--cyan);stroke-width:2;flex:0 0 auto}
.qs-est-k{display:block;font-family:var(--mono);font-size:9.5px;letter-spacing:.12em;
  text-transform:uppercase;color:rgba(255,255,255,.5)}
.qs-est-v{display:block;margin-top:2px;font-size:19px;font-weight:600;color:#fff;
  font-variant-numeric:tabular-nums}
.qs-est-note{margin:var(--s3) 0 0;padding-top:var(--s3);
  border-top:1px solid rgba(255,255,255,.1);font-size:12.5px;color:var(--cyan)}
.quick-size .btn-fill{width:100%;justify-content:center;margin-top:var(--s5);
  font-size:14px;padding:var(--s4) var(--s5);border-radius:8px}
.quick-size .btn-fill .btn-i{width:18px;height:18px}
.quick-size-note{margin:var(--s4) 0 0;font-size:12.5px;line-height:1.6;
  color:rgba(255,255,255,.5)}
.quick-size-note .lnk{color:rgba(255,255,255,.75)}
@media(max-width:400px){
  .quick-size-f{flex-direction:column}
}

/* ══ VALUE PROPS ══ */
.props{display:grid;grid-template-columns:repeat(4,1fr);gap:var(--s7)}
.props-3{grid-template-columns:repeat(3,1fr)}
.prop h3{font-size:16px;font-weight:400;margin-bottom:var(--s2)}
.prop p{font-size:13px;line-height:1.65;color:var(--ink-2)}
.on-dark .prop p{color:rgba(255,255,255,.55)}

/* ══ BREADCRUMB ══ */
.backlink{display:flex;width:fit-content;max-width:100%;align-items:center;gap:8px;margin-bottom:var(--s6);
  padding:9px 18px 9px 13px;border:1px solid rgba(255,255,255,.28);border-radius:999px;
  background:rgba(255,255,255,.05);color:#fff;text-decoration:none;
  font-family:var(--mono);font-size:12px;letter-spacing:.06em;text-transform:uppercase;
  transition:background .2s var(--ease),border-color .2s var(--ease)}
.backlink:hover{background:rgba(255,255,255,.13);border-color:rgba(255,255,255,.55)}
.backlink-i{width:15px;height:15px;stroke:currentColor;stroke-width:2.2;
  transition:transform .2s var(--ease)}
.backlink:hover .backlink-i{transform:translateX(-3px)}

/* ══ FOOTER ══ */
/* The jib imprint is a watermark, not a mark. It is already cropped on three
   edges, so it is drawn to bleed off a panel rather than sit inside one:
   anchored to the bottom-right corner, oversized, and low enough in opacity
   that the raster's soft lattice never reads as softness. Decorative, so it
   is a background image and never enters the accessibility tree. The nav
   logo is itself a crane, which is why this belongs here and not up there. */
/* ══ FOOTER ══ */
.foot{position:relative;overflow:hidden;isolation:isolate;color:#fff;
  background:linear-gradient(165deg,var(--navy-950) 0%,var(--navy-900) 60%,var(--navy-900) 100%);
  padding-top:var(--s10)}
.foot::before{content:'';position:absolute;z-index:-1;pointer-events:none;
  right:-4%;bottom:-26%;width:min(660px,58%);aspect-ratio:533/327;
  background:url('/assets/img/crane-imprint.png') no-repeat right bottom/contain;
  opacity:.07}

/* align-items:start keeps each column to its own content — stretch left a
   void under the short ones. The bottom padding was a full --s10 below
   columns that already end unevenly. */
.foot-grid{display:grid;grid-template-columns:minmax(130px,.6fr) 1.15fr 1.3fr .75fr 1.25fr;gap:var(--s6);
  align-items:start;padding-bottom:var(--s8)}

.foot-brand img{height:auto;width:130px;max-width:100%;display:block}
.foot-brand p{margin-top:var(--s6);max-width:34ch;font-size:14.5px;line-height:1.75;
  color:rgba(255,255,255,.62)}
/* pill, outlined, with the arrow leaving the corner */
.foot-cta{display:inline-flex;align-items:center;gap:var(--s5);margin-top:var(--s7);
  padding:var(--s4) var(--s6);border-radius:999px;
  border:1px solid rgba(75,189,237,.5);color:var(--cyan);
  font-family:var(--mono);font-size:11.5px;letter-spacing:.16em;text-transform:uppercase;
  text-decoration:none;transition:border-color .22s var(--ease),
    background .22s var(--ease),color .22s var(--ease)}
.foot-cta:hover{border-color:var(--cyan);background:rgba(75,189,237,.10);color:#fff}
.foot-cta-i{width:15px;height:15px;stroke:currentColor;stroke-width:2.4;
  transition:transform .22s var(--ease)}
.foot-cta:hover .foot-cta-i{transform:translate(2px,-2px)}

/* heading with its own short rule, as in the reference */
.foot h4{font-family:var(--mono);font-size:11px;letter-spacing:.2em;text-transform:uppercase;
  color:var(--cyan);font-weight:500;padding-bottom:var(--s4);margin-bottom:var(--s5);
  position:relative}
.foot h4::after{content:'';position:absolute;left:0;bottom:0;width:26px;height:2px;
  background:var(--cyan)}
.foot ul{list-style:none;display:flex;flex-direction:column}

/* Each link is a full row with a rule under it and an arrow that travels. */
.foot-links li + li{margin-top:0}
.foot-links a{display:flex;align-items:center;justify-content:space-between;gap:var(--s5);
  padding:var(--s4) 0;font-size:14.5px;color:rgba(255,255,255,.78);text-decoration:none;
  border-bottom:1px solid rgba(255,255,255,.08);
  transition:color .2s var(--ease),border-color .2s var(--ease)}
.foot-links a:hover{color:#fff;border-bottom-color:rgba(75,189,237,.45)}
.foot-go{width:17px;height:17px;flex:0 0 auto;stroke:var(--cyan);stroke-width:2;
  opacity:.75;transition:transform .22s var(--ease),opacity .22s var(--ease)}
.foot-links a:hover .foot-go{transform:translateX(4px);opacity:1}

/* the contact column is set off by a rule, as a separate kind of content */
.foot-contact{padding-left:var(--s8);border-left:1px solid rgba(255,255,255,.09);
  align-self:stretch}
.foot-contact ul{gap:var(--s5)}
.foot-contact li{display:flex;align-items:flex-start;gap:var(--s5);
  font-size:14.5px;line-height:1.55;color:rgba(255,255,255,.78)}
.foot-contact a{color:inherit;text-decoration:none;transition:color .2s var(--ease)}
.foot-contact a:hover{color:var(--cyan)}
.foot-chip{flex:0 0 auto;display:grid;place-items:center;width:34px;height:34px;
  border-radius:50%;border:1px solid rgba(255,255,255,.14);
  background:rgba(255,255,255,.04)}
.foot-i{width:16px;height:16px;stroke:var(--cyan);stroke-width:2}

.foot-base{border-top:1px solid rgba(255,255,255,.09);
  background:rgba(0,0,0,.16)}
.foot-base-in{display:flex;align-items:center;justify-content:space-between;
  gap:var(--s5);flex-wrap:wrap;padding-block:var(--s5)}
.foot-base span{font-family:var(--mono);font-size:10.5px;letter-spacing:.14em;
  text-transform:uppercase;color:rgba(255,255,255,.34)}
.foot-legal{display:flex;gap:var(--s5)}
.foot-legal a{color:inherit;text-decoration:none;transition:color .2s var(--ease)}
.foot-legal a:hover{color:rgba(255,255,255,.7)}

@media(max-width:1000px){
  .foot-grid{grid-template-columns:1fr 1fr;gap:var(--s8) var(--s7)}
  .foot-brand{grid-column:1/-1}
  .foot-contact{padding-left:0;border-left:none;grid-column:1/-1}
}
@media(max-width:640px){
  .foot-grid{grid-template-columns:1fr}
  .foot-base-in{justify-content:flex-start}
}

/* ══ DOCUMENT PAGES (legal, guide detail) — one centred reading column,
      pagehead and body on the same measure so nothing sits lopsided. ══ */
.p-doc .pagehead .wrap,
.p-doc .sec > .wrap{max-width:760px}
.p-doc .legal,
.p-doc .guide,
.p-doc .faq-page{max-width:none;margin-inline:auto}
.p-doc .pagehead{padding-bottom:var(--s7)}
.p-doc .legal h2,
.p-doc .guide h2{margin-top:var(--s7)}
.faq-page h2{font-family:var(--sans);font-size:16px;font-weight:600;
  letter-spacing:.01em;margin:var(--s8) 0 var(--s3);color:var(--ink);
  scroll-margin-top:calc(var(--nav-h) + var(--s6))}
.faq-page h2:first-child{margin-top:0}
.faq-page .faq{margin-bottom:var(--s5)}
.p-doc .legal .legal-foot{margin-top:var(--s7)}

/* ══ LEGAL PAGES ══ */
.legal{max-width:64ch;margin-inline:0}
.legal h2{font-size:19px;margin:var(--s8) 0 var(--s3)}
.legal h2:first-child{margin-top:0}
.legal p{margin:0 0 var(--s4);line-height:1.7;color:var(--ink-2)}
.legal ul{margin:0 0 var(--s4);padding-left:1.1em;color:var(--ink-2);line-height:1.7}
.legal li{margin-bottom:var(--s3)}
.legal a{color:var(--navy);text-decoration:underline;text-underline-offset:2px}
.legal .legal-foot{margin-top:var(--s8);padding-top:var(--s5);
  border-top:1px solid var(--line);font-size:13px;color:var(--muted)}

/* ══ GUIDES ══ */
.guide-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(300px,1fr));
  gap:var(--s5)}
.guide-card{display:flex;flex-direction:column;gap:var(--s3);padding:var(--s6);
  background:var(--paper);border:1px solid var(--line);border-radius:12px;
  text-decoration:none;color:var(--ink);transition:border-color .2s var(--ease),transform .2s var(--ease)}
.guide-card:hover{border-color:var(--navy);transform:translateY(-2px)}
.guide-card-k{font-family:var(--mono);font-size:10px;letter-spacing:.16em;
  text-transform:uppercase;color:var(--muted)}
.guide-card-h{font-family:var(--sans);font-size:19px;font-weight:600;line-height:1.2;
  letter-spacing:-.01em}
.guide-card-d{font-size:14px;line-height:1.55;color:var(--ink-2);flex:1}
.guide-card-go{display:inline-flex;align-items:center;gap:6px;margin-top:var(--s3);
  font-family:var(--mono);font-size:11px;letter-spacing:.1em;text-transform:uppercase;
  color:var(--navy)}
.guide-card-go svg{width:14px;height:14px;stroke:currentColor;stroke-width:2.5;fill:none}

.guide{max-width:66ch;margin-inline:0}
.guide h2{font-size:21px;margin:var(--s8) 0 var(--s3)}
.guide>*:first-child{margin-top:0}
.guide p{margin:0 0 var(--s4);line-height:1.72;color:var(--ink)}
.guide ul{margin:0 0 var(--s4);padding-left:1.15em;line-height:1.72;color:var(--ink)}
.guide li{margin-bottom:var(--s3)}
.guide li b{font-weight:600}
.guide a{color:var(--navy);text-decoration:underline;text-underline-offset:2px}
.guide .faq{margin-top:var(--s4)}
.guide-rel{list-style:none;margin:var(--s7) 0 0;padding:var(--s5) 0 0;
  border-top:1px solid var(--line);display:flex;flex-wrap:wrap;gap:var(--s3) var(--s6)}
.guide-rel a{font-family:var(--mono);font-size:12px;letter-spacing:.04em;color:var(--navy);
  text-decoration:none}
.guide-rel a:hover{text-decoration:underline}
.guide-cta{margin-top:var(--s7);font-size:15px}

.model-ctx{max-width:60ch}
.model-ctx p{margin:0 0 var(--s4);line-height:1.7;color:var(--ink-2)}
.model-ctx p:last-child{margin-bottom:0}
.model-ctx a{color:var(--navy);text-decoration:underline;text-underline-offset:2px}

/* ══ PROTOTYPE BANNER ══ */
.proto{background:var(--navy-900);color:rgba(255,255,255,.6);
  font-family:var(--mono);font-size:10px;letter-spacing:.14em;text-transform:uppercase;
  text-align:center;padding:var(--s2) var(--s5);border-bottom:1px solid var(--line-d)}

/* ══ RESPONSIVE ══ */
@media (max-width:1024px){
  :root{--gut:32px;--s12:120px;--s11:96px;--s10:72px}
  .two,.two-a,.figblock,.lc{grid-template-columns:1fr;gap:var(--s8)}
  .figlines{border-left:none;border-top:1px solid var(--line);padding-left:0;padding-top:var(--s6)}
  .on-dark .figlines{border-top-color:var(--line-d)}
  .metrics{grid-template-columns:1fr 1fr}
  .metric{border-bottom:1px solid var(--line-d);padding-right:var(--s5)}
  .cards{grid-template-columns:1fr 1fr}
  .props{grid-template-columns:1fr 1fr;gap:var(--s6)}
  .seq-item{grid-template-columns:1fr;gap:var(--s6)}
  .seq-item:nth-child(even) .seq-media{order:0}
  .foot-grid{grid-template-columns:1fr 1fr;gap:var(--s7)}
  .macros{grid-template-columns:1fr 1fr}
  .nav-logo img{height:44px}
  .nav-links{display:none}
  /* a full-height drawer, not a short panel — otherwise the page content
     shows through below it and the cut edge reads as a bug */
  .nav-links.open{display:flex;position:fixed;top:var(--nav-h);left:0;right:0;
    height:calc(100dvh - var(--nav-h));z-index:99;
    flex-direction:column;align-items:stretch;background:var(--navy-950);
    padding:var(--s5) var(--gut) calc(var(--s7) + env(safe-area-inset-bottom));
    gap:var(--s2);overflow-y:auto;overscroll-behavior:contain}
  /* full-width rows, label at the left, caret button at the right edge */
  .nav-links.open .nav-link{display:flex;width:100%;justify-content:flex-start;
    padding-block:var(--s3)}
  .nav-links.open .nav-item{width:100%}
  .nav-burger{display:block;margin-left:auto}
  .nav-tel{display:none}

  /* Touch has no hover, so the menus become accordions. The caret gets its
     own button: tapping the label still goes to the section index, tapping
     the caret opens the list. Without that split there is no way to reach
     /cranes/ itself from a phone. */
  .nav-item{display:block;position:relative}
  .nav-item .nav-link{padding-right:44px}
  .nav-caret{display:none}
  .nav-toggle{display:block;position:absolute;top:0;right:0;width:44px;height:38px;
    background:none;border:0;cursor:pointer;padding:0}
  .nav-toggle::after{content:'';position:absolute;top:50%;left:50%;width:8px;height:8px;
    margin:-5px 0 0 -4px;border-right:1.5px solid rgba(255,255,255,.8);
    border-bottom:1.5px solid rgba(255,255,255,.8);
    transform:rotate(45deg);transition:transform .2s var(--ease)}
  .nav-toggle[aria-expanded=true]::after{transform:rotate(-135deg);margin-top:-1px}

  .nav-menu{position:static;min-width:0;opacity:1;visibility:hidden;transform:none;
    transition:none;border:0;border-left:1px solid var(--line-d);
    background:none;box-shadow:none;backdrop-filter:none;
    margin:var(--s3) 0 var(--s2) var(--s3);padding:0;display:none}
  .nav-item.open .nav-menu{display:flex;visibility:visible}
  .nav-menu a{padding:var(--s3) var(--s5)}
  /* the pointer rules must not fire on touch */
  .has-menu:hover .nav-menu,.has-menu:focus-within .nav-menu{
    opacity:1;transform:none}
  .has-menu::after{display:none}
}
@media (max-width:640px){
  :root{--gut:20px;--s12:88px;--s11:72px;--s10:56px}
  .metrics{grid-template-columns:1fr}
  .cards,.props{grid-template-columns:1fr}
  .macros{grid-template-columns:1fr}
  .form{grid-template-columns:1fr}
  .foot-grid{grid-template-columns:1fr}
  .tscroll{overflow-x:auto;-webkit-overflow-scrolling:touch}
  .tscroll table{min-width:660px}
  .inp input{font-size:36px}
}

/* ══ PRINT ══ */
@media print{
  .nav,.proto,.foot,.btn-fill,.btn-line,.lnk{display:none!important}
  *{-webkit-print-color-adjust:exact;print-color-adjust:exact}
  .sec{padding-block:24px}
  .rv{opacity:1!important;transform:none!important}
}

/* ══════════════════════════════════════════════════════════════════════
   HOME v2 — direction approved 23 Aug 2026.
   Hero carries video and a lift-check launcher; the tool opens in a modal
   so the hero keeps its room and the tool gets space to work.
   ══════════════════════════════════════════════════════════════════════ */

/* native spinners on a dark ground read as a rendering fault */
input[type=number]{appearance:textfield;-moz-appearance:textfield}
input[type=number]::-webkit-outer-spin-button,
input[type=number]::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}

.hero2{background:var(--navy-950);color:#fff;padding-block:var(--s10) var(--s8)}
.hero2-grid{display:grid;grid-template-columns:1.05fr .95fr;gap:var(--s10);
  align-items:start}

.tool{border:1px solid var(--line-dd);padding:var(--s6)}
.tool-h{display:flex;justify-content:space-between;align-items:baseline;gap:var(--s4);
  border-bottom:1px solid var(--line-d);padding-bottom:var(--s3);margin-bottom:var(--s5)}
.tool-in{display:grid;grid-template-columns:1fr 1fr;gap:var(--s6);margin-bottom:var(--s5)}
.hero2-copy h1{text-wrap:balance}

.lc-card{display:flex;flex-direction:column;gap:var(--s4);text-align:left;width:100%;
  background:rgba(4,40,59,.55);border:1px solid var(--line-dd);color:#fff;
  padding:var(--s7) var(--s6);cursor:pointer;font-family:var(--sans);
  transition:border-color .25s var(--ease),background .25s var(--ease)}
.lc-card:hover{border-color:var(--cyan);background:rgba(4,40,59,.78)}
.lc-card-h{display:flex;justify-content:space-between;gap:var(--s4);
  border-bottom:1px solid var(--line-d);padding-bottom:var(--s3)}
.lc-card-b{font-size:clamp(20px,2vw,28px);font-weight:300;letter-spacing:-.015em;
  line-height:1.25}
.lc-card-f{font-family:var(--mono);font-size:11px;letter-spacing:.16em;
  text-transform:uppercase;color:var(--cyan)}

.cred{display:flex;gap:var(--s6);flex-wrap:wrap;
  align-items:center;border-top:1px solid var(--line-d);margin-top:var(--s8);
  padding-top:var(--s5)}
.cred div{font-family:var(--mono);font-size:10px;letter-spacing:.16em;
  text-transform:uppercase;color:rgba(255,255,255,.62)}
.cred b{color:var(--cyan);font-weight:400}

.fam{display:grid;grid-template-columns:repeat(3,1fr);border-top:1px solid var(--line-d)}
.fam-i{text-decoration:none;border-right:1px solid var(--line-d);display:flex;
  flex-direction:column}
.fam-i:last-child{border-right:none}
.fam-shot{height:340px;display:flex;align-items:center;justify-content:center;
  overflow:hidden;background:var(--navy-900);padding:var(--s5)}
.fam-shot img{max-height:100%;width:auto;object-fit:contain;
  transition:transform .8s var(--ease)}
.fam-shot.cover{padding:0}
.fam-shot.cover img{width:100%;height:100%;object-fit:cover;max-height:none}
.fam-i:hover .fam-shot img{transform:scale(1.02)}
.fam-cap{padding:var(--s5) var(--s5) var(--s6)}
.fam-n{font-size:19px;font-weight:400;color:#fff;margin-bottom:var(--s2)}
.fam-f{font-family:var(--mono);font-size:11px;color:var(--cyan)}
.fam-c{font-family:var(--mono);font-size:10px;letter-spacing:.16em;text-transform:uppercase;
  color:rgba(255,255,255,.38);margin-top:var(--s3)}

.proof{border:1px dashed var(--line);padding:var(--s9) var(--s6);text-align:center;
  background:var(--paper)}
.proof .lede{max-width:56ch;margin-inline:auto;text-align:left}

.svcs{display:grid;grid-template-columns:repeat(4,1fr);gap:1px;background:var(--line);
  border:1px solid var(--line)}
.svc{background:var(--paper);padding:var(--s6) var(--s5);text-decoration:none;
  display:flex;flex-direction:column;gap:var(--s2);transition:background .2s var(--ease)}
.svc:hover{background:var(--bone)}
.svc-u{font-family:var(--mono);font-size:10px;color:var(--muted);margin-top:auto;
  padding-top:var(--s4)}

/* ══ LIFT CHECK MODAL ══ */
.lc-modal{position:fixed;inset:0;z-index:300;display:none}
.lc-modal[open],.lc-modal.on{display:block}
.lc-scrim{position:absolute;inset:0;background:rgba(4,40,59,.86)}
.lc-panel{position:relative;max-width:820px;margin:6vh auto;background:var(--navy-950);
  border:1px solid var(--line-dd);color:#fff;max-height:88vh;overflow-y:auto;
  padding:var(--s7) var(--s7) var(--s6)}
.lc-top{display:flex;justify-content:space-between;align-items:baseline;gap:var(--s4);
  border-bottom:1px solid var(--line-d);padding-bottom:var(--s4);margin-bottom:var(--s6)}
.lc-close{background:none;border:1px solid var(--line-dd);color:#fff;cursor:pointer;
  font-family:var(--mono);font-size:10px;letter-spacing:.16em;text-transform:uppercase;
  padding:var(--s2) var(--s4)}
.lc-close:hover{border-color:var(--cyan);color:var(--cyan)}
.lc-in{display:grid;grid-template-columns:1fr 1fr;gap:var(--s7);margin-bottom:var(--s6)}
.lc-note{font-size:12px;line-height:1.6;color:rgba(255,255,255,.42);
  border-top:1px solid var(--line-d);padding-top:var(--s4);margin-top:var(--s5)}

@media(max-width:1000px){
  .hero2-grid{grid-template-columns:1fr;gap:var(--s8)}
  .tool-in{grid-template-columns:1fr 1fr}
  .fam{grid-template-columns:1fr}
  .fam-i{border-right:none;border-bottom:1px solid var(--line-d)}
  .fam-shot{height:280px}
  .svcs{grid-template-columns:1fr 1fr}
  .lc-panel{margin:0;max-height:100vh;min-height:100vh;padding:var(--s6) var(--s5)}
}
@media(max-width:600px){
  .svcs{grid-template-columns:1fr}
  .lc-in{grid-template-columns:1fr 1fr;gap:var(--s5)}
}

/* ══════════════════════════════════════════════════════════════════════
   HERO v3 — 23 Aug 2026.
   The machine is a cut-out over built atmosphere rather than a dark plate
   behind a scrim, which is what made the previous hero read as a black
   rectangle. Glow, horizon and skyline are drawn, not photographed, so the
   hero holds up before any TES footage arrives.
   ══════════════════════════════════════════════════════════════════════ */

.heroS{position:relative;overflow:hidden;color:#fff;isolation:isolate;
  background:
    radial-gradient(58% 46% at 66% 34%, rgba(75,189,237,.16) 0%, transparent 62%),
    radial-gradient(38% 30% at 88% 72%, rgba(75,189,237,.10) 0%, transparent 66%),
    linear-gradient(180deg, #04283b 0%, #063a56 46%, #052e44 100%);
  padding-block:var(--s9) 0}

/* horizon haze the machines stand on */
.heroS::after{content:'';position:absolute;left:0;right:0;bottom:180px;height:230px;
  z-index:0;pointer-events:none;
  background:linear-gradient(180deg,transparent 0%,rgba(75,189,237,.10) 58%,
    rgba(75,189,237,.16) 78%,transparent 100%)}

.heroS-sky{position:absolute;left:0;right:0;bottom:168px;height:150px;z-index:0;
  opacity:.32;pointer-events:none}
.heroS-sky svg{width:100%;height:100%;display:block}

.heroS-grid{position:relative;z-index:2;display:grid;
  grid-template-columns:1.12fr .88fr;gap:var(--s6);align-items:center;
  min-height:520px}

.heroS-eyebrow{font-family:var(--mono);font-size:12px;letter-spacing:.30em;
  text-transform:uppercase;color:var(--cyan)}
.heroS h1{font-size:clamp(34px,4vw,54px);font-weight:700;letter-spacing:-.03em;
  line-height:1.05;text-wrap:balance}
.heroS h1 em{font-style:normal;color:var(--cyan)}
.heroS .lede{margin-top:var(--s5);color:rgba(255,255,255,.72);max-width:44ch}

/* 23 Sep 2026: the buttons sat too close under the lede. */
.heroS-cta{display:flex;gap:var(--s5);flex-wrap:wrap;margin-top:var(--s7)}
@media(max-width:700px){.heroS-cta{margin-top:var(--s6)}}
.heroS-pick{position:relative;z-index:5}
.heroS-pick-b{cursor:pointer;font:inherit}
.heroS-pick-c{transform:rotate(90deg)}
.heroS-pick-b:hover .heroS-pick-c{transform:rotate(90deg)}
.heroS-pick-b[aria-expanded=true] .heroS-pick-c{transform:rotate(-90deg)}
.heroS-pick-l{position:absolute;left:0;bottom:calc(100% + var(--s3));min-width:320px;
  display:flex;flex-direction:column;padding:var(--s2);
  background:rgba(4,40,59,.94);border:1px solid rgba(255,255,255,.2);
  backdrop-filter:blur(10px);-webkit-backdrop-filter:blur(10px);
  box-shadow:0 18px 40px rgba(2,16,26,.45)}
.heroS-pick-l[hidden]{display:none}
.heroS-pick-l a{display:flex;align-items:center;gap:var(--s4);padding:var(--s3) var(--s4);
  color:#fff;text-decoration:none;font-size:15.5px;font-weight:500}
.heroS-pick-l a:hover,.heroS-pick-l a:focus-visible{background:rgba(75,189,237,.18)}
.heroS-pick-i{width:24px;height:24px;stroke:var(--cyan);stroke-width:1.7;flex:0 0 auto}
.heroS-pick-job{margin-top:var(--s2);border-top:1px solid rgba(255,255,255,.18)}
/* Glass secondary. The panel is genuinely translucent — backdrop-filter over
   the photograph — with a hairline that catches light at the top edge and
   fades toward the bottom, which is what sells glass over a flat tint. On a
   light section it can't be glass — nothing dark behind it — so there it
   becomes a solid navy outline (rule after :active below). */
.btn-line{position:relative;display:inline-flex;align-items:center;gap:var(--s4);
  font-family:var(--sans);font-size:17px;font-weight:600;padding:var(--s5) var(--s7);
  border-radius:12px;color:#fff;text-decoration:none;cursor:pointer;
  border:1px solid rgba(255,255,255,.22);
  background:linear-gradient(180deg,rgba(255,255,255,.10),rgba(255,255,255,.03));
  backdrop-filter:blur(14px) saturate(130%);
  -webkit-backdrop-filter:blur(14px) saturate(130%);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.18),0 8px 24px rgba(2,16,26,.28);
  transition:border-color .22s var(--ease),background .22s var(--ease),
    box-shadow .22s var(--ease),transform .22s var(--ease)}
.btn-line:hover{border-color:rgba(255,255,255,.42);transform:translateY(-1px);
  background:linear-gradient(180deg,rgba(255,255,255,.16),rgba(255,255,255,.06));
  box-shadow:inset 0 1px 0 rgba(255,255,255,.26),0 12px 30px rgba(2,16,26,.36)}
.btn-line:active{transform:translateY(0)}

/* Secondary on a light ground. Glass needs a dark photo behind it to read;
   on the bone sections it becomes a solid navy outline — same size, radius,
   gap and sliding arrow as the hero pair, so it still reads as one family.
   Scoped to the light grounds and to "not .on-dark" so every dark pagehead
   and the hero keep the glass. */
.g-bone .btn-line,.g-paper .btn-line,.accred .btn-line,
.sec:not(.on-dark) .btn-line,.close-line .btn-line,
.two-a .btn-line,.form .btn-line{
  color:var(--navy);border-color:var(--navy);background:none;
  -webkit-backdrop-filter:none;backdrop-filter:none;box-shadow:none}
.g-bone .btn-line:hover,.g-paper .btn-line:hover,.accred .btn-line:hover,
.sec:not(.on-dark) .btn-line:hover,.close-line .btn-line:hover,
.two-a .btn-line:hover,.form .btn-line:hover{
  background:var(--navy);color:#fff;border-color:var(--navy);transform:translateY(-1px);
  box-shadow:0 10px 24px rgba(9,102,151,.24)}
.g-bone .btn-line .btn-i,.g-paper .btn-line .btn-i,
.sec:not(.on-dark) .btn-line .btn-i{filter:none}
/* A button inside a form field is a flex child of a stretch column, so it
   would run the full width of the form. Size it to its label instead, like
   every other button on the site. */
.field .btn-fill,.field .btn-line{align-self:flex-start}

.heroS-shot{position:relative;justify-self:end;width:100%;max-width:660px}
.heroS-shot img{width:100%;height:auto;display:block;
  filter:drop-shadow(0 0 60px rgba(75,189,237,.18))}

/* three families, the strip along the base */
.heroS-fams{position:relative;z-index:2;display:grid;grid-template-columns:repeat(3,1fr);
  border:1px solid var(--line-d);background:rgba(4,40,59,.55);
  backdrop-filter:blur(2px);margin-top:var(--s8)}
.heroS-fam{display:flex;gap:var(--s5);align-items:center;padding:var(--s5) var(--s6);
  border-right:1px solid var(--line-d);text-decoration:none;color:#fff;
  transition:background .22s var(--ease)}
.heroS-fam:last-child{border-right:none}
.heroS-fam:hover{background:rgba(75,189,237,.07)}
.heroS-fam svg{flex:0 0 auto;width:42px;height:42px;stroke:var(--cyan);fill:none;
  stroke-width:1.2;opacity:.85}
.heroS-fam-t{flex:1}
.heroS-fam-t{display:block}
.heroS-fam-k{display:block;font-family:var(--mono);font-size:10px;letter-spacing:.2em;
  text-transform:uppercase;color:var(--cyan);margin-bottom:var(--s3)}
.heroS-fam-b{display:block;font-size:15px;line-height:1.35;color:rgba(255,255,255,.9)}
.heroS-fam-a{font-family:var(--mono);font-size:15px;color:rgba(255,255,255,.4);
  transition:transform .22s var(--ease),color .22s var(--ease)}
.heroS-fam:hover .heroS-fam-a{color:var(--cyan);transform:translateX(3px)}

@media(max-width:1000px){
  .heroS-grid{grid-template-columns:1fr;gap:var(--s7);min-height:0}
  .heroS-shot{justify-self:center;max-width:520px}
  .heroS-fams{grid-template-columns:1fr}
  .heroS-fam{border-right:none;border-bottom:1px solid var(--line-d)}
  .heroS::after,.heroS-sky{bottom:auto;top:auto;display:none}
}


/* ── hero carrying a photograph ───────────────────────────────────────── */
.heroS-bg{position:absolute;inset:0;z-index:0}
.heroS-bg img,.heroS-bg video{width:100%;height:100%;object-fit:cover;object-position:60% 45%;display:block}
/* the reel plays; the approved still is the poster underneath it and the
   fallback below. Only one is ever visible. */
/* Every one of these is written .heroS-bg .heroS-… on purpose. The rule above
   is `.heroS-bg img,.heroS-bg video`, which is class-plus-element and beats a
   bare class: written as `.heroS-vid{display:none}` these lost, and the video
   and the still both rendered, one on top of the other. */
.heroS-bg .heroS-still{display:none}
@media (prefers-reduced-motion: reduce){
  .heroS-bg .heroS-vid{display:none}
  .heroS-bg .heroS-still{display:block}}
/* The wrapper ships with `reel-off`: the still shows, the reel is hidden, and
   the still stays the LCP element. site.js removes the class the moment it
   commits to loading the reel — on any screen where motion is welcome and the
   connection has not asked to conserve data. No JS, a reduced-motion setting,
   or a metered connection therefore keeps the still. */
.heroS-bg.reel-off .heroS-vid{display:none}
.heroS-bg.reel-off .heroS-still{display:block}
/* readability plate: heavy on the left where the type sits, clear on the right
   so the machine and the sunset survive */
.heroS-photo::before{content:'';position:absolute;inset:0;z-index:1;pointer-events:none;
  background:
    radial-gradient(128% 168% at -20% 48%, rgba(3,24,38,.96) 0%, rgba(3,24,38,.93) 38%,
      rgba(3,24,38,.78) 52%, rgba(3,24,38,.42) 64%, rgba(3,24,38,.12) 76%, transparent 86%),
    linear-gradient(180deg, rgba(3,26,40,.60) 0%, transparent 18%),
    linear-gradient(0deg, rgba(3,26,40,.72) 0%, transparent 26%)}
.heroS-photo::after{display:none}
/* min-height, not height. A fixed height clipped whatever did not fit — the
   last row of the evidence panel was being cut off by the section edge. This
   still fills the first screen and now grows instead of hiding content. */
.heroS-photo{min-height:max(620px, calc(100svh - var(--nav-h) - var(--proto-h)));
  display:flex;flex-direction:column;justify-content:center;
  /* No block padding at all. The bar is the section's bottom edge now, and the
     grid centres itself in whatever is left, so 48px top and bottom bought
     nothing and pushed the bar 17px past the fold at 1440x900. */
  padding-block:0}
/* Two columns: copy left, evidence panel right. The photo hero used to force
   1fr back on, which put the panel under the copy and made the hero too tall
   for its own container. */
.heroS-photo .heroS-grid{grid-template-columns:minmax(0,1fr);
  gap:var(--s8);min-height:0;align-items:center}
.heroS-photo .lede{max-width:52ch}

/* Primary. A gradient rather than a flat fill, lit from the top-left, with a
   coloured glow beneath it so it reads as sitting above the photograph. The
   inset top highlight is the same trick as the glass button, which is what
   keeps the pair looking like one family. */
.btn-fill{position:relative;display:inline-flex;align-items:center;gap:var(--s4);
  font-family:var(--sans);font-size:17px;font-weight:600;letter-spacing:.005em;
  padding:var(--s5) var(--s7);border-radius:12px;color:#fff;text-decoration:none;
  cursor:pointer;border:1px solid rgba(75,189,237,.45);
  /* Every stop is mixed from --cyan and --navy, so the button carries no
     colour the palette does not already hold. The flat fallback runs first
     for anything without color-mix. */
  background:var(--navy);
  background:linear-gradient(158deg,
    color-mix(in srgb,var(--cyan) 34%,var(--navy)) 0%,
    var(--navy) 55%, var(--navy-950) 100%);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.30),
    0 10px 28px rgba(9,102,151,.38),0 2px 6px rgba(4,40,59,.30);
  transition:background .22s var(--ease),box-shadow .22s var(--ease),
    transform .22s var(--ease),border-color .22s var(--ease)}
.btn-fill:hover{transform:translateY(-1px);border-color:rgba(75,189,237,.62);
  background:linear-gradient(158deg,
    color-mix(in srgb,var(--cyan) 48%,var(--navy)) 0%,
    color-mix(in srgb,var(--cyan) 12%,var(--navy)) 55%, var(--navy) 100%);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.38),
    0 14px 34px rgba(9,102,151,.48),0 2px 8px rgba(4,40,59,.34)}
.btn-fill:active{transform:translateY(0)}

/* Keyboard users get a ring that survives both grounds. */
.btn-fill:focus-visible,.btn-line:focus-visible{outline:2px solid var(--cyan);
  outline-offset:3px}
@media(prefers-reduced-motion:reduce){
  .btn-fill,.btn-line{transition:background .22s ease,border-color .22s ease}
  .btn-fill:hover,.btn-line:hover{transform:none}
}

/* the strip floats over the photograph */
.heroS-photo .heroS-fams{background:rgba(4,32,47,.62);backdrop-filter:blur(6px);
  border-color:rgba(255,255,255,.14);margin-top:var(--s7)}
.heroS-photo .heroS-fam{border-right-color:rgba(255,255,255,.14)}

@media(max-width:1000px){
  .heroS-photo .heroS-grid{min-height:0}
  /* Was .80 to .96, which is very nearly opaque: on a phone the photograph
     had gone and the hero was a flat navy panel with type on it. The plate
     still has to carry white text over a dawn sky, so it stays heavy at the
     foot where the evidence bar sits and lifts at the top where the crane is. */
  .heroS-photo::before{background:linear-gradient(180deg,rgba(4,32,47,.52) 0%,
    rgba(4,32,47,.72) 46%,rgba(4,32,47,.90) 100%)}
}



/* ── hero v5: comp-matched feature row, evidence bar, icon buttons ───── */
.heroS-photo .heroS-grid{align-items:center;min-height:0;flex:1 1 auto;
  align-content:center}
.heroS-copy{max-width:none}
/* text-wrap:nowrap used to live here. It stopped the headline wrapping, so
   once the evidence panel took the second column the line simply overflowed
   and ran under the panel. Let it wrap; the size below keeps it to two lines
   at every width we care about. */
.heroS-photo h1{font-size:clamp(31px,4.35vw,66px);line-height:1.04;max-width:24ch;
  margin-top:var(--s6)}
.heroS-photo .lede{max-width:40ch;font-size:20px;line-height:1.65;
  color:rgba(255,255,255,.82);margin-top:var(--s6)}

.btn-fill,.btn-line{gap:var(--s3)}
/* The crane is the mark people recognise, so it is drawn at nearly the cap
   height of the label rather than as a small leading glyph. */
.btn-i{width:30px;height:30px;stroke:currentColor;stroke-width:2;flex:0 0 auto}
.btn-fill .btn-i{filter:drop-shadow(0 1px 2px rgba(2,16,26,.35))}
.btn-a{width:19px;height:19px;margin-left:var(--s3);stroke:currentColor;stroke-width:1.7;flex:0 0 auto;
  transition:transform .22s var(--ease)}
.btn-fill:hover .btn-a,.btn-line:hover .btn-a{transform:translateX(3px)}

.heroS-feats{display:grid;grid-template-columns:repeat(4,1fr);gap:var(--s6);
  margin-top:var(--s8);max-width:880px;hyphens:none}
.heroS-feat{display:flex;gap:var(--s3);align-items:flex-start}
.heroS-feat{gap:var(--s3)}
.heroS-feat svg{flex:0 0 auto;width:28px;height:28px;stroke:var(--cyan);
  stroke-width:1.5;margin-top:0}
.heroS-feat h3{font-size:13.5px;font-weight:600;letter-spacing:-.01em;margin-bottom:5px;
  color:#fff;white-space:nowrap}
.heroS-feat p{font-size:12.5px;line-height:1.5;color:rgba(255,255,255,.66)}

.heroS-stats{position:relative;z-index:2;flex:0 0 auto;display:grid;
  grid-template-columns:repeat(4,1fr) 1.5fr;
  border:1px solid rgba(255,255,255,.13);background:rgba(3,24,38,.50);
  backdrop-filter:blur(11px);margin-top:var(--s7)}
.heroS-stat{position:relative;display:flex;gap:var(--s4);align-items:center;
  padding:var(--s6) var(--s5)}
.heroS-stat + .heroS-stat::before,.heroS-quote::before{content:'';position:absolute;
  left:0;top:24%;bottom:24%;width:1px;background:rgba(255,255,255,.16)}
.heroS-stat-i{flex:0 0 auto;width:32px;height:32px;stroke:var(--cyan);stroke-width:1.4}
.heroS-stat-v{font-size:29px;font-weight:700;letter-spacing:-.025em;line-height:1;color:#fff}
.heroS-stat-v.sm{font-size:16px;font-weight:700;letter-spacing:.03em;line-height:1.25}
.heroS-stat-k{font-size:12.5px;line-height:1.35;color:rgba(255,255,255,.66);margin-top:6px;
  white-space:nowrap}
.heroS-quote{position:relative;display:flex;gap:var(--s3);align-items:center;
  padding:var(--s6) var(--s5)}
.heroS-quote-m{font-family:Georgia,serif;font-size:34px;line-height:.7;color:var(--cyan);
  opacity:.9;align-self:flex-start}
.heroS-quote-m.end{align-self:flex-end}
.heroS-quote p{font-size:13.5px;line-height:1.55;color:rgba(255,255,255,.80);flex:1}
.heroS-quote strong{color:#fff;font-weight:700}

@media(max-width:1100px){
  .heroS-feats{grid-template-columns:repeat(2,1fr);gap:var(--s5) var(--s6)}
  .heroS-stats{grid-template-columns:repeat(2,1fr)}
  .heroS-stat{border-bottom:1px solid rgba(255,255,255,.13)}
  /* …but not in the hero, where the whole point of the bar is that it carries
     no rules. This one only showed up on a phone, which is where nobody was
     looking when the lines came out. */
  .heroS-photo .heroS-stat{border-bottom:0}
  .heroS-quote{grid-column:1/-1}
}
@media(max-width:620px){
  .heroS-feats,.heroS-stats{grid-template-columns:1fr}
  .heroS-stat{border-right:none}
  .heroS-photo .heroS-grid{min-height:0}
}

@media(max-height:760px){
  .heroS-photo{height:auto;min-height:0;padding-block:var(--s7) var(--s7)}
}

/* The credentials themselves live in the strip below the hero, so the copy
   block carries only what the strip cannot: what to send us, and how fast an
   answer comes back. One line, under the buttons it qualifies. */
/* .heroS-note is gone — the line under the buttons that asked for the load,
   the radius and the timing. Dropped 29 Aug 2026. The same ask is made in full
   by the lift check further down and again by the closing call to action, and
   the one-business-day promise is on the contact page where it is acted on. */

/* ── factory accreditations ──────────────────────────────────────
   A continuous strip, not the static pair this was. With only two marks,
   standing still read as thin between two denser sections, so a slow,
   even scroll carries them instead. The list is the pair repeated LOOPS
   times per half (build.py) so a -50% translateX always has enough track
   left to loop with no seam or dry patch, however wide the screen. A mask
   fades each edge rather than cutting a logo off mid-shape. Paused on
   hover/focus, and off entirely under prefers-reduced-motion — a hard stop,
   not a slow one, matching every other motion rule on the site.

   Duration is tuned to the LOOPS=10 track, not a flat number: one half runs
   roughly 4600–6200px depending on viewport (the gap clamp tops out at
   --s11), and 130s over that is ~35-48px/s — a drift, not a ticker. If
   LOOPS changes, retune this against it.

   Light ground on purpose — Potain grey, AS Energy black, both captions dark
   type — and no caption of our own under them: the artwork already says
   "Authorised Service Provider" in each manufacturer's own lettering. */
.accred{padding-block:var(--s9);background:var(--bone);
  border-block:1px solid rgba(6,44,66,.10)}
.accred-band{margin-top:var(--s8);padding-block:var(--s7);
  background:var(--paper);border-block:1px solid var(--line);overflow:hidden;
  -webkit-mask-image:linear-gradient(90deg,transparent,#000 8%,#000 92%,transparent);
  mask-image:linear-gradient(90deg,transparent,#000 8%,#000 92%,transparent)}
.accred-run{display:flex;flex-wrap:nowrap;align-items:center;justify-content:flex-start;
  width:max-content;gap:clamp(var(--s7),9vw,var(--s11));list-style:none;margin:0;
  padding-inline:var(--gut);animation:accred-scroll 130s linear infinite}
.accred-band:hover .accred-run,.accred-band:focus-within .accred-run{
  animation-play-state:paused}
@keyframes accred-scroll{from{transform:translateX(0)}to{transform:translateX(-50%)}}
@media(prefers-reduced-motion:reduce){.accred-run{animation:none}}
.accred-i{display:flex;align-items:center;justify-content:center;flex:0 0 auto}
/* Sized on the mark, not the file: the Potain lockup sets its caption small
   inside a wide box, so at equal height it reads half the size of AS Energy. */
.accred-i img{width:auto;height:auto;display:block}
.accred-i.is-wide img{height:92px}
.accred-i.is-flat img{height:72px}
@media(max-width:820px){
  .accred-i.is-wide img{height:64px}
  .accred-i.is-flat img{height:50px}
}
/* ── capability: the intro and the photograph ─────────────────────────
   Third attempt at this row. Cut one: a 16:9 photo beside a four-row table,
   96px apart, the table finishing 200px above the foot of the photo —
   top-heavy, and neither half read as an object. Cut two: the table
   became a quote, stretched to the photo's height and centred in a card —
   fixed the emptiness, but stacking heading, photo and quote in one
   narrow column each fighting the next for vertical room was still the
   real problem underneath it.

   This cut splits the two jobs properly: .cap-head is the argument (the
   heading, the lede, the way in to the capability page) and never touches
   the photo's height at all — it just sits at its own natural size, top of
   the row. .cap-photo-wrap is the proof, one photograph doing one job,
   with the claim that used to be a stretched quote card now sitting
   directly on top of it instead of fighting it for column width. Nothing
   here is centred in a box sized by something else, so there is no gap
   left over to explain. */
.cap-row{display:grid;grid-template-columns:.86fr 1.14fr;gap:var(--s9);
  align-items:start}
.cap-head{display:flex;flex-direction:column;align-items:flex-start;
  gap:var(--s5);padding-top:var(--s4)}
/* The one heading on the site that colours part of itself — borrowed
   from the home hero's h1 em (see .heroS h1 em), used here because this
   row now carries a photograph and a floating card, i.e. it is doing a
   hero's job for this page in miniature. Kept off every other h2 so it
   stays a hero-register device, not a house style for all headings.

   var(--navy), not var(--cyan): the button right below it (.btn-fill) is a
   navy gradient with cyan only as a thin edge tint, so a pure-cyan word
   above a navy button read as two different accent colours in one row
   rather than one. Navy ties the two together. */
.cap-head h2 em{font-style:normal;color:var(--navy)}
.cap-photo-wrap{position:relative}
.cap-photo-wrap .media{width:100%}
/* The claim, on the photo rather than beside it. Same big-quote-mark
   device as .heroS-quote on the home hero, and — like that one —
   deliberately not attributed to a named person: it reads as something
   TES says about how it works, not a sentence put in a real, named
   individual's mouth without asking them first. */
.cap-card{position:absolute;left:var(--s6);right:var(--s6);bottom:var(--s6);
  max-width:360px;background:var(--paper);padding:var(--s6) var(--s7) var(--s7);
  box-shadow:0 24px 48px rgba(9,20,30,.16)}
.cap-card p{margin:0;font-size:16px;line-height:1.55;font-weight:500;color:var(--ink)}
.cap-q{font-family:Georgia,'Times New Roman',serif;font-weight:700;color:var(--cyan)}
@media(max-width:900px){
  .cap-row{grid-template-columns:1fr;gap:var(--s6)}
  .cap-card{position:static;max-width:none;box-shadow:none;
    border:1px solid var(--line);margin-top:var(--s5)}
}

/* ══ WHAT WE DO ═══════════════════════════════════════════════════════
   Five capability cards in a static grid. This was a self-scrolling
   marquee — the row walked left on its own and you could not read a card
   without it sliding out from under you. A grid shows all five at once,
   holds still, and needs no script. */

.trk{padding-block:var(--s10)}
.trk-head{margin-bottom:var(--s8)}
.trk-head h2{margin-top:var(--s4)}

.trk-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:var(--s5)}
@media(max-width:1000px){.trk-grid{grid-template-columns:repeat(2,1fr)}}
@media(max-width:600px){.trk-grid{grid-template-columns:1fr}}

/* image on top, a white panel beneath carrying the label and the line.
   Hairline border, square corners, no shadow — the house style. */
.trk-p{display:flex;flex-direction:column;text-decoration:none;color:inherit;
  background:var(--paper);border:1px solid var(--line);
  transition:border-color .25s var(--ease)}
.trk-p:hover{border-color:var(--navy)}
.trk-shot{position:relative;display:block;aspect-ratio:4/3;overflow:hidden;
  background:var(--navy-900)}
.trk-shot img{width:100%;height:100%;object-fit:cover;display:block;
  transition:transform .8s var(--ease)}
.trk-p:hover .trk-shot img{transform:scale(1.04)}
/* icon tile in place of the photograph (21 Sep 2026) */
.trk-icon{aspect-ratio:auto;height:150px;display:flex;align-items:center;justify-content:center;
  background:linear-gradient(160deg,var(--navy-900),var(--navy))}
.trk-icon::after{display:none}
.trk-svg{width:64px;height:64px;stroke:var(--cyan);stroke-width:1.25;transition:transform .4s var(--ease)}
.trk-p:hover .trk-svg{transform:scale(1.08)}
.trk-icon .trk-ix{font-size:clamp(28px,2.4vw,40px)}
.trk-b{position:relative;flex:1;display:flex;flex-direction:column;padding:var(--s5)}
/* the index sits on the photograph, top left, set large */
.trk-ix{position:absolute;top:var(--s4);left:var(--s5);z-index:1;font-family:var(--sans);
  font-size:clamp(44px,4.4vw,72px);font-weight:800;line-height:.86;letter-spacing:-.03em;
  color:#fff;text-shadow:0 2px 24px rgba(2,16,26,.45)}
.trk-shot::after{content:'';position:absolute;inset:0 0 auto 0;height:46%;
  background:linear-gradient(180deg,rgba(4,32,47,.42),transparent);pointer-events:none}
.trk-n{font-size:clamp(19px,1.5vw,23px);font-weight:300;letter-spacing:-.012em;
  line-height:1.3;color:var(--ink)}
.trk-d{font-size:14.5px;line-height:1.65;color:var(--ink-2);margin-top:var(--s3);
  max-width:40ch}


/* ── the three pillars ───────────────────────────────────────────
   Deliberately the one type-only block on the page. The track, the capability
   panel and the accreditation strip are all image-led, so a fourth row of
   picture-over-caption would read as more of the same. Three columns standing
   between full-height rules, numeral set large and low-contrast above the
   heading — the verticality is the point. */
/* ── the three pillars ───────────────────────────────────────────
   Each column stands on its own photograph with the copy set over it. The
   scrim is heavy at the foot where the text sits and clears toward the top so
   the picture still reads — the same plate the hero uses, turned vertical.
   Columns are exactly 1fr with the rules in the gap, so all three are equal. */
.pils{display:grid;grid-template-columns:repeat(3,1fr);gap:var(--s6);
  margin-top:var(--s9)}
/* photo at the head, claim below, one takeaway on a tag at the foot */
.pil{container-type:inline-size;display:flex;flex-direction:column;padding:var(--s6);
  background:rgba(255,255,255,.03);border:1px solid var(--line-d);
  transition:border-color .25s var(--ease)}
.pil:hover{border-color:rgba(75,189,237,.4)}
.pil-n{font-family:var(--sans);
  font-size:32px;font-weight:700;line-height:1;letter-spacing:-.02em;
  color:var(--cyan)}
.pil-n::after{content:'';display:block;width:32px;height:2px;
  background:var(--cyan);margin-top:var(--s3)}
.pil-shot{display:block;aspect-ratio:3/2;overflow:hidden;margin:var(--s5) 0;
  background:var(--navy-900)}
.pil-shot img{width:100%;height:100%;object-fit:cover;display:block;
  transition:transform .8s var(--ease)}
.pil:hover .pil-shot img{transform:scale(1.04)}
/* one line each at every width (client, 22-23 Sep 2026). The size follows the
   card's own width, so the title still fits on a 320px phone, where the cards
   are one per row rather than three. */
.pil h3{font-size:clamp(13px,1.45vw,19px);font-weight:600;letter-spacing:-.015em;line-height:1.3;
  color:#fff;white-space:nowrap}
@supports (font-size:1cqi){
  .pil h3{font-size:clamp(12px,5.6cqi,20px)}
}
.pil p{font-size:14.5px;line-height:1.7;color:rgba(255,255,255,.78);
  margin-top:var(--s3);flex:1}
.pil-tag{display:inline-flex;align-items:center;gap:var(--s2);margin-top:var(--s5);
  font-family:var(--mono);font-size:10px;letter-spacing:.14em;text-transform:uppercase;
  color:var(--cyan)}
.pil-tag svg{width:15px;height:15px;flex:0 0 auto}
@media(max-width:900px){
  .pils{grid-template-columns:1fr;gap:var(--s5)}
}

/* ───────────────────────────────────────── how we work
   The service argument, on a bone ground. Copy on the left — heading, lede,
   then three numbered points in a row — with the yard photograph on the
   right, framed by a hairline and a navy block so it reads as a placed
   print rather than a plain rectangle.                                   */

.process{display:grid;grid-template-columns:1fr 1fr;gap:var(--s10);align-items:center}

.process-copy .lede{margin-top:var(--s5);max-width:52ch}

.process-items{display:grid;grid-template-columns:repeat(3,1fr);
  gap:var(--s6);margin-top:var(--s8)}
.process-i{display:flex;flex-direction:column}
.process-n{font-size:34px;font-weight:700;letter-spacing:-.02em;line-height:1;
  color:var(--navy);font-variant-numeric:tabular-nums}
.process-i h3{margin:var(--s4) 0 0;font-size:16px;font-weight:600;
  letter-spacing:-.01em;color:var(--ink)}
.process-i h3::after{content:"";display:block;width:28px;height:1px;
  background:var(--navy);margin:var(--s3) 0}
.process-i p{margin:0;font-size:14px;line-height:1.65;color:var(--ink-2)}

.process-fig{position:relative;margin:var(--s5) var(--s5) var(--s5) var(--s6)}
.process-fig img{position:relative;z-index:1;width:100%;display:block;
  aspect-ratio:4/3;object-fit:cover}
.process-fig::before{content:"";position:absolute;z-index:0;
  top:calc(-1 * var(--s5));right:calc(-1 * var(--s5));
  width:44%;height:62%;background:var(--navy-950)}
.process-fig::after{content:"";position:absolute;z-index:0;
  left:calc(-1 * var(--s5));bottom:calc(-1 * var(--s5));
  width:78%;height:82%;border:1px solid var(--navy)}
.process-fig figcaption{position:relative;z-index:1;margin-top:var(--s4);
  text-align:right;font-family:var(--mono);font-size:11px;
  letter-spacing:.13em;text-transform:uppercase;color:var(--navy)}

@media (max-width:900px){
  .process{grid-template-columns:1fr;gap:var(--s7)}
  .process-fig{margin:0;order:-1}
  .process-fig::before,.process-fig::after{display:none}
}
@media (max-width:560px){
  .process-items{grid-template-columns:1fr;gap:var(--s5)}
}

/* ═══════════════════════════════════════════ hero, v6
   Reference: the Falcon Cranes homepage AJ sent 27 Aug. What we took from it
   is the *structure* — a condensed uppercase display line doing the work, and
   the evidence bar as a discrete panel sitting on the photograph rather than a
   full-width slab cutting it in half.

   What we deliberately did NOT take: the greyscale image treatment. Falcon's
   photography is dark factory interiors, so desaturating costs them nothing.
   Ours is a dawn seascape, and the colour is the entire reason that frame beat
   the other 125. Darkening it would buy a generic dark hero and throw away the
   best asset in the pack. The scrim already there is enough.              */

.heroS-photo .heroS-grid{min-height:600px;align-items:center}

.heroS-photo h1{
  font-family:var(--sans);
  font-size:clamp(38px,5vw,104px);
  font-weight:800;
  text-transform:uppercase;
  letter-spacing:-.012em;
  line-height:.90;
  margin-top:var(--s4);
  max-width:none;
  text-shadow:0 2px 40px rgba(2,18,28,.45);
}
.heroS-photo h1 em{display:block;font-style:normal;color:var(--cyan)}

/* .heroS-eyebrow is unused on the photo hero now; the base rule stays for
   any other hero that wants one. */
.heroS-photo .lede{font-size:17.5px;max-width:56ch;color:rgba(255,255,255,.82);
  margin-top:var(--s6);text-wrap:pretty}

/* Evidence bar. It has been three things: a floating bar under the copy, then
   a glass panel in the grid's second column, and now a strip along the foot of
   the hero. The panel was right while the background was one still: it filled
   a column that was otherwise empty. Once the background became footage it was
   covering the half of the frame the reel plays in, so it moved to the foot,
   where it still sits above the fold and the crane stays visible.

   No card chrome down here. The section's own base gradient already darkens
   this band, and a bordered, blurred panel spanning the full width would read
   as a second navigation bar. A hairline over the top and dividers between the
   four is enough to hold them together. */
/* No rule over it, no tint, no dividers between the four. Every one of those
   was a hard edge drawn across a moving picture, and the band they enclosed
   read as a second navigation bar sitting on the footage. The section's own
   base gradient already darkens this strip enough to carry white type, so the
   facts simply sit on the frame and the spacing separates them. */
/* 16 above the row and 64 below it, where it was 48 above and 32 below: the
   same 96px in total, so the split moved and the footprint did not. The row
   sits 32px higher off the section edge and the bar still lands exactly on the
   fold at 1440x900. */
.heroS-bar{position:relative;z-index:2;margin-top:var(--s4);
  padding-block:var(--s4) var(--s8)}
.heroS-photo .heroS-stats{
  grid-template-columns:repeat(4,1fr);
  width:100%;max-width:var(--max);
  margin-top:0;
  border:0;background:none;backdrop-filter:none;-webkit-backdrop-filter:none;
  border-radius:0;box-shadow:none}
/* The icons used to sit in glass discs. That worked while this was a panel —
   a badge per row — but along the foot four bordered circles in a line read as
   chrome stacked on chrome, over a moving background. The line-art stands on
   its own in cyan. */
.heroS-photo .heroS-stat-c{flex:0 0 auto;display:grid;place-items:center;
  width:32px;height:32px}
.heroS-photo .heroS-stat-c .heroS-stat-i{width:32px;height:32px;stroke-width:1.3}
.heroS-photo .heroS-quote{display:none}
.heroS-photo .heroS-stat{padding:var(--s4) var(--s4) var(--s4) 0;gap:var(--s4)}
.heroS-photo .heroS-stat:first-child{padding-left:0}
/* Up from 31/19/10.5 and .6 alpha. The bar carries the four facts the whole
   page rests on and it sits at the foot of a photograph, where thin mono at
   ten and a half pixels in 60% white is a texture rather than a sentence. */
.heroS-photo .heroS-stat-v{font-family:var(--sans);
  font-size:34px;font-weight:700;letter-spacing:.005em}
.heroS-photo .heroS-stat-v.sm{font-size:21px;letter-spacing:.04em}
/* white-space:normal, always. The base rule is nowrap, which is right for the
   panel this used to be and wrong for a bar of four columns: at 1180px —
   an iPad Pro in landscape — "WORKSHOP, PARTS, TECHNICIANS" is 215px of
   unbreakable mono in a 211px column, and it ran straight out of the section. */
/* .07em, not .13em. Mono uppercase at wide tracking is a label style, and it
   was costing about 40px a line — enough that three of the four keys wrapped
   to two lines and the row went ragged. The size went up and the tracking came
   down; it reads larger and still fits on one line at 1440. */
.heroS-photo .heroS-stat-k{font-family:var(--mono);font-size:12px;letter-spacing:.07em;
  text-transform:uppercase;color:rgba(255,255,255,.74);white-space:normal;margin-top:7px}
.heroS-photo .heroS-stat + .heroS-stat::before{display:none}

/* Four across stops fitting before the hero does: the keys are set in mono at
   .13em, so they are wide for their word count. Two rows of two, then the
   discs come off so a phone spends its width on the words. */
@media(max-width:1080px){
  .heroS-photo .heroS-grid{grid-template-columns:1fr;align-items:start}
  .heroS-photo .heroS-stats{grid-template-columns:repeat(2,1fr)}
  .heroS-photo .heroS-stat{padding-left:0}
}
@media(max-width:620px){
  .heroS-photo .heroS-stats{gap:0 var(--s5)}
  .heroS-photo .heroS-stat{padding:var(--s4) 0;gap:var(--s3)}
  .heroS-photo .heroS-stat-c,
  .heroS-photo .heroS-stat-c .heroS-stat-i{width:21px;height:21px}
  .heroS-photo .heroS-stat-v.sm{font-size:15px}
  .heroS-photo .heroS-stat-k{letter-spacing:.1em;white-space:normal}
}
@media(max-width:620px){
  .heroS-photo h1{line-height:.94;max-width:none}
}

/* ═══════════════════════════════════════════ wide displays
   --max was a flat 1440px, so every viewport past that just grew the side
   margins and the layout stayed the same size in the middle of the screen.
   On a large external monitor that reads as a narrow column stranded in
   space. These steps let the grid keep using the glass, while the gutter
   grows with it so the content never runs to the bezel.                  */

@media (min-width:1700px){
  :root{--max:1580px;--gut:72px}
  .heroS-photo h1{font-size:clamp(44px,5.6vw,110px)}
}
@media (min-width:2100px){
  :root{--max:1900px;--gut:88px}
  body{font-size:17px}
  .heroS-photo h1{font-size:clamp(44px,5.6vw,138px)}
  .heroS-photo .lede{font-size:19px}
  .heroS-photo .heroS-grid{min-height:680px}
}
/* Past this width a fixed cap always loses: the monitor keeps growing and the
   layout does not. Switch to a share of the viewport so the grid scales with
   the glass. Prose stays readable because .lede and h1 carry their own ch
   measures — only the grid gets wider, not the line length.              */
@media (min-width:2600px){
  :root{--max:94vw;--gut:clamp(104px,3.4vw,160px)}
  body{font-size:18px}
  .heroS-photo h1{font-size:clamp(44px,5.4vw,168px)}
  .heroS-photo .heroS-grid{min-height:780px}
  .heroS-photo .heroS-stat{padding:var(--s5) var(--s7)}
  .heroS-photo .heroS-stat-v{font-size:38px}
}

/* ══════════════════════════════════════════════════════════════════════
   TOUCH AND SMALL SCREENS
   ══════════════════════════════════════════════════════════════════════
   Audited 29 Aug 2026 across iPhone SE (375), iPhone 14 (393), iPhone Pro
   Max (430), iPad mini and iPad Pro portrait (744, 1024) and iPad Pro
   landscape (1180), on all eight page types. No page overflowed its
   viewport at any of them, so nothing structural is fixed here. What is
   fixed is everything that only goes wrong when the pointer is a finger.
   ══════════════════════════════════════════════════════════════════════ */

/* iOS Safari zooms the whole page when a form field under 16px takes focus,
   and it does not zoom back out. Every field on the contact form was 15px,
   which is one pixel of design costing the entire layout the moment someone
   taps Name. 16px is the threshold, not a preference. */
/* The width half of this matters as much as the pointer half: a desktop
   browser narrowed to a phone width is how this gets checked, and the rule
   has to be visible there too. */
@media (max-width:900px),(pointer:coarse){
  /* Named the same way the 15px rule is (.field input, not input), because a
     bare element selector loses to a class-plus-element one no matter how far
     down the file it sits. The first version of this rule was written as
     `input,select,textarea` and changed nothing at all. */
  input,select,textarea,
  .field input,.field select,.field textarea{font-size:16px}
}

/* Hover states on a touch screen fire on tap and then stay: a card that
   lifts stays lifted, a photograph that scales stays scaled, until you
   touch something else. Everything that moves on hover stops moving where
   there is no hover to speak of. The colour changes are left alone — those
   read as feedback on a tap rather than a stuck state. */
@media (hover:none){
  .trk-p:hover .trk-shot img,
  .card:hover .media img,.seq-media:hover .media img{transform:none}
  .btn-fill:hover,.btn-line:hover{transform:none}
  .lnk:hover{transform:none}
}

/* A 17px-high link is a 17px-high target. These are the ones the audit
   found: the phone number in the header, and the phone and email in the
   footer — exactly the three a person on a phone is most likely to be
   reaching for. The type does not change size, only the box around it. */
@media (pointer:coarse){
  .foot-contact a,.lnk{display:inline-flex;align-items:center;min-height:44px}
  .foot-contact a{min-height:40px}
}
/* The header phone number is hidden below 1024px (it lives in the burger menu
   there). Only grow its tap target where it is actually on the bar — otherwise
   this rule un-hides it on every phone and shoves the Menu button off-centre. */
@media (pointer:coarse) and (min-width:1025px){
  .nav-tel{display:inline-flex;align-items:center;min-height:44px}
}

/* Safari paints a grey box over anything tappable. Ours is the site's own
   cyan at low opacity, so a tap reads as the page responding rather than
   as a rendering artefact. */
a,button,summary,input,select,textarea,label{
  -webkit-tap-highlight-color:rgba(75,189,237,.16)}

/* 9.5px was too small to be read at arm's length, and it was mine: it came
   in when the evidence bar went to two columns on a phone. The keys are
   mono and uppercase at 10px everywhere else on the site, which is the
   floor, not a target to shave. */
@media(max-width:620px){
  .heroS-photo .heroS-stat-k{font-size:10px}
}

/* ══ HOISTS PAGE — technical drawing register ═════════════════════════
   Deliberately not the battery page's system: no dark bands, no
   icon-disc steps, no glowing pill buttons. A dimensioned grid, dashed
   measurement lines, mono labels, and the OEM's own line drawings
   standing in for a photograph. Scoped under .bp-sec so nothing here
   touches the battery page's .pick-*/.ask-p/.step-* components. */
.bp-sec .sec-head{margin-bottom:var(--s7)}

.bp-panel{position:relative}

/* comparison: one container, two mirrored halves. SC220 render sits outboard
   left with its spec card inboard; SC300 mirrors it. A pill on the centre
   seam carries the one figure both machines share. */
.bp-container{position:relative;display:grid;grid-template-columns:1fr 1fr;
  background:var(--paper);border:1px solid var(--line);border-radius:10px;
  box-shadow:0 1px 3px rgba(4,40,59,.05),0 30px 60px -20px rgba(4,40,59,.14)}
.bp-half{position:relative;padding:var(--s7) var(--s5) var(--s6);
  transition:background .35s var(--ease)}
.bp-half-r{border-left:1px dashed var(--line)}
.bp-half:hover{background:linear-gradient(180deg,rgba(9,102,151,.045),transparent 60%)}

.bp-model-head{text-align:center;margin-bottom:var(--s6)}
.bp-model-k{display:block;font-family:var(--mono);font-size:10px;letter-spacing:.22em;
  text-transform:uppercase;color:var(--muted);margin-bottom:var(--s2)}
.bp-model-h{display:block;font-size:clamp(38px,4.6vw,58px);font-weight:700;
  letter-spacing:.04em;line-height:1;color:var(--navy)}
.bp-model-head::after{content:"";display:block;width:44px;height:3px;
  background:var(--navy);opacity:.32;margin:var(--s4) auto 0}

.bp-half-in{display:flex;align-items:center;gap:var(--s6)}
.bp-card{flex:1 1 auto;min-width:0}
/* two lines reserved so the spec rows line up across the three cards */
.bp-card > .sm{min-height:3.4em;text-align:center}
.bp-desig{font-family:var(--mono);font-size:10px;letter-spacing:.12em;
  color:var(--ink-2);padding-bottom:var(--s3);text-align:center}

.bp-frame{flex:0 0 auto;width:264px;height:520px;
  display:flex;align-items:flex-end;justify-content:center}
.bp-shot{display:block;width:auto;height:100%;max-width:100%;object-fit:contain;
  filter:drop-shadow(0 24px 30px rgba(4,40,59,.16));
  transition:transform .6s var(--ease),filter .6s var(--ease)}
.bp-half:hover .bp-shot{transform:scale(1.04) translateY(-4px);
  filter:drop-shadow(0 34px 40px rgba(4,40,59,.22))}

.bp-spec{display:flex;align-items:center;gap:var(--s4);padding:var(--s3) 0;
  border-top:1px dotted var(--line)}
.bp-spec > div{display:flex;flex-direction:column;gap:2px;min-width:0}
.bp-spec span{font-family:var(--mono);font-size:9.5px;letter-spacing:.13em;
  text-transform:uppercase;color:var(--ink-2)}
.bp-spec b{font-size:15px;font-weight:600;font-variant-numeric:tabular-nums}
.bp-ico{flex:0 0 auto;width:22px;height:22px;stroke:var(--navy);fill:none;
  stroke-width:1.4;stroke-linejoin:round;stroke-linecap:round}

/* datasheet peek */
.bp-sheet{display:flex;align-items:center;gap:var(--s4);margin-top:var(--s5);
  padding:var(--s3) var(--s5);border:1px solid var(--line);border-radius:7px;
  color:var(--navy);text-decoration:none;background:var(--paper);
  transition:background .22s var(--ease),border-color .22s var(--ease),
    color .22s var(--ease),box-shadow .22s var(--ease),transform .22s var(--ease)}
.bp-sheet span{flex:1 1 auto;min-width:0;display:flex;flex-direction:column;gap:1px;
  font-size:13px;font-weight:600}
.bp-sheet i{font-style:normal;font-weight:400;font-size:9.5px;letter-spacing:.04em;
  color:var(--ink-2);font-family:var(--mono)}
.bp-sheet-i{flex:0 0 auto;width:17px;height:17px;stroke:currentColor;fill:none;
  stroke-width:1.5;stroke-linejoin:round;stroke-linecap:round}
.bp-sheet-a{flex:0 0 auto;width:16px;height:16px;stroke:currentColor;fill:none;
  stroke-width:1.7;stroke-linejoin:round;stroke-linecap:round;
  transition:transform .22s var(--ease)}
.bp-sheet:hover{background:var(--navy);border-color:var(--navy);color:#fff;
  box-shadow:0 10px 24px -8px rgba(9,102,151,.5);transform:translateY(-1px)}
.bp-sheet:hover i{color:rgba(255,255,255,.72)}
.bp-sheet:hover .bp-sheet-a{transform:translateX(3px)}
.bp-sheet:focus-visible{outline:2px solid var(--navy);outline-offset:2px}

@media(prefers-reduced-motion:reduce){
  .bp-half:hover .bp-shot{transform:none}
  .bp-sheet:hover{transform:none}
}

/* THE RANGE: the two hoists side by side, each drawn to scale with its
   spec rows beneath. bp-in is the pair; bp-col is one machine. */
.bp-in{display:grid;grid-template-columns:1fr 1fr;gap:var(--s8);align-items:start}
.bp-col{display:flex;flex-direction:column;min-width:0}
.bp-id{font-family:var(--mono);font-size:10px;letter-spacing:.22em;text-transform:uppercase;
  color:var(--muted);margin-bottom:var(--s4)}
.bp-col .bp-shot{width:auto;height:clamp(300px,42vh,460px);max-width:100%;
  object-fit:contain;object-position:center top;align-self:center;margin-bottom:var(--s5)}
.bp-name{font-size:clamp(24px,3vw,34px);font-weight:700;letter-spacing:-.01em;
  padding-bottom:var(--s3);border-bottom:2px solid var(--navy);margin-bottom:var(--s1)}
.bp-row{display:flex;justify-content:space-between;align-items:baseline;gap:var(--s4);
  padding:var(--s3) 0;border-bottom:1px solid var(--line)}
.bp-row span{font-family:var(--mono);font-size:10px;letter-spacing:.12em;
  text-transform:uppercase;color:var(--ink-2)}
.bp-row b{font-size:15px;font-weight:600;font-variant-numeric:tabular-nums;
  white-space:nowrap}
.bp-callout{margin-top:var(--s7);padding:var(--s5) var(--s6);background:var(--paper);
  border-left:3px solid var(--navy);font-size:14.5px;line-height:1.7;color:var(--ink-2)}
@media (max-width:760px){
  .bp-in{grid-template-columns:1fr;gap:var(--s9)}
  .bp-col .bp-shot{height:min(56vh,420px)}
}

/* dimension call-outs: a number, the claim, the figure — read like a
   drawing's own dimension line rather than a numbered "step" */
.bp-dims{display:flex;flex-direction:column}
.bp-dim{display:grid;grid-template-columns:40px 1fr auto;align-items:start;gap:var(--s6);
  padding:var(--s6) 0;border-top:1px dashed var(--line)}
.bp-dim:first-child{border-top:1px solid var(--line)}
.bp-dim-no{font-family:var(--mono);font-size:12px;color:var(--navy);padding-top:3px}
.bp-dim h3{font-size:17px;font-weight:600;letter-spacing:-.005em}
.bp-dim p{font-size:14.5px;line-height:1.65;color:var(--ink-2);margin-top:var(--s2);max-width:64ch}
.bp-dim-v{font-family:var(--mono);font-size:15px;font-weight:600;color:var(--navy);
  white-space:nowrap;padding-top:3px}

.bp-form{padding:var(--s7)}

/* three machines (SC300 XL added 16 Sep 2026): each column stacks its
   drawing above its spec card, since a card beside a drawing won't fit a third */
.bp-three{grid-template-columns:repeat(3,1fr)}
.bp-three .bp-half-in{flex-direction:column;align-items:stretch}
.bp-three .bp-frame{width:100%;height:380px}
.bp-three .bp-model-h{font-size:clamp(30px,3.2vw,44px)}

/* tablet: the container stacks to one half above the other */
@media(max-width:1000px){
  .bp-container,.bp-three{grid-template-columns:1fr}
  .bp-half-r{border-left:0;border-top:1px dashed var(--line)}
  .bp-half-in{gap:var(--s7);max-width:560px;margin-inline:auto}
  .bp-frame{width:240px;height:440px}
}

@media(max-width:560px){
  .bp-half{padding:var(--s6) var(--s5)}
  .bp-half-in,.bp-half-r .bp-half-in{flex-direction:column;align-items:center}
  .bp-frame{width:100%;max-width:270px;height:380px;order:-1}
  .bp-card{width:100%}
  .bp-sheet{width:100%;justify-content:center}
  .bp-dim{grid-template-columns:32px 1fr;grid-template-areas:"no title" ". val"}
  .bp-dim-no{grid-area:no}
  .bp-dim > div{grid-area:title}
  .bp-dim-v{grid-area:val;padding-top:var(--s2)}
  .bp-form{padding:var(--s6)}
}

/* ══════════════════════════════════════════════════════════════════════
   CAPABILITY — premium layer. Scoped to body.p-capability so no other
   page is touched. Every motion has a prefers-reduced-motion off-switch.
   ══════════════════════════════════════════════════════════════════════ */

/* Tighter, springier reveal travel for this page, so the staggered
   cascade reads as one motion rather than a set of slow fades. */
body.p-capability .rv{transform:translateY(14px);transition-duration:.66s}

/* ── Hero: a gentle parallax on scroll (JS feeds --par), and a film grain
      over the photograph so it reads as graded, not sourced. */
body.p-capability .pagehead-bg{will-change:transform}
body.p-capability .pagehead-bg img{
  transform:scale(1.14) translateY(var(--par,0px))}
body.p-capability .pagehead-photo::before{
  content:"";position:absolute;inset:0;z-index:0;pointer-events:none;
  opacity:.5;mix-blend-mode:soft-light;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E")}
@media(prefers-reduced-motion:reduce){
  body.p-capability .pagehead-bg img{transform:none}}

/* ── The four service blocks. They sit on the light ground, so the page
      alternates navy / bone / navy / bone / navy. Each lifts its photograph
      on hover and draws a short spec-sheet rule beside its heading. */
body.p-capability .cap-services .seq-item{border-top-color:var(--line);
  scroll-margin-top:calc(var(--nav-h) + var(--s6))}
/* the linked block gets a brief cyan edge so a deep link lands somewhere obvious */
body.p-capability .cap-services .seq-item:target{
  animation:cap-target 2.4s var(--ease) 1}
@keyframes cap-target{
  0%,55%{box-shadow:-3px 0 0 var(--cyan)}
  100%{box-shadow:-3px 0 0 transparent}}
@media(prefers-reduced-motion:reduce){
  body.p-capability .cap-services .seq-item:target{animation:none}}
body.p-capability .seq-media .media{border-radius:5px;
  transition:transform .55s var(--ease),box-shadow .55s var(--ease)}
body.p-capability .seq-media .media img{transition:transform .8s var(--ease)}
body.p-capability .seq-item:hover .seq-media .media{
  transform:translateY(-6px);
  box-shadow:0 40px 80px -34px rgba(6,26,40,.4)}
body.p-capability .seq-item:hover .seq-media .media img{transform:scale(1.045)}
body.p-capability .seq-item .d3::before{content:"";display:block;height:2px;width:0;
  background:var(--cyan);margin-bottom:var(--s4);
  transition:width .6s var(--ease) .15s}
body.p-capability .seq-item.in .d3::before{width:34px}
@media(prefers-reduced-motion:reduce){
  body.p-capability .seq-item:hover .seq-media .media{transform:none;box-shadow:none}
  body.p-capability .seq-item:hover .seq-media .media img{transform:none}
  body.p-capability .seq-item .d3::before{width:34px;transition:none}}

/* ── "What we do": each point opens under a plus to say what that means.
      Native <details>, so it works and is keyboard-navigable with no JS. */
body.p-capability .cap-do{max-width:430px;margin-top:var(--s5);
  border-top:1px solid var(--line)}
body.p-capability .cap-do-i{border-bottom:1px solid var(--line)}
body.p-capability .cap-do-i summary{list-style:none;display:flex;align-items:center;
  justify-content:space-between;gap:var(--s5);cursor:pointer;padding-block:var(--s3);
  font-size:14px;color:var(--ink);transition:color .2s var(--ease)}
body.p-capability .cap-do-i summary::-webkit-details-marker{display:none}
body.p-capability .cap-do-i summary:hover{color:#0d6f96}
body.p-capability .cap-do-i summary:focus-visible{outline:2px solid var(--cyan);
  outline-offset:3px;border-radius:2px}
body.p-capability .cap-do-x{position:relative;flex:0 0 auto;width:12px;height:12px;
  transition:transform .25s var(--ease)}
body.p-capability .cap-do-x::before,body.p-capability .cap-do-x::after{content:"";
  position:absolute;background:#0d6f96;border-radius:1px}
body.p-capability .cap-do-x::before{left:0;right:0;top:50%;height:1.6px;
  transform:translateY(-50%)}
body.p-capability .cap-do-x::after{top:0;bottom:0;left:50%;width:1.6px;
  transform:translateX(-50%)}
body.p-capability .cap-do-i[open] .cap-do-x{transform:rotate(45deg)}
body.p-capability .cap-do-i > p{margin:0;padding:0 0 var(--s4);
  font-size:12.5px;line-height:1.65;color:var(--ink-2);max-width:40ch}
body.p-capability .cap-do-i[open] > p{animation:cap-do-in .28s var(--ease) both}
@keyframes cap-do-in{from{opacity:0;transform:translateY(-4px)}}
@media(prefers-reduced-motion:reduce){
  body.p-capability .cap-do-x,
  body.p-capability .cap-do-i[open] .cap-do-x{transition:none}
  body.p-capability .cap-do-i[open] > p{animation:none}}

/* ── The macro strip: image push-in, the label scrim deepens, and the
      caption rises with a cyan rule drawing in ahead of it. */
body.p-capability .macro .media img{transition:transform .7s var(--ease)}
body.p-capability .macro::after{transition:background .45s var(--ease)}
body.p-capability .macro span{display:inline-flex;align-items:center;
  transition:transform .4s var(--ease),color .4s var(--ease)}
body.p-capability .macro span::before{content:"";width:0;height:1px;flex:0 0 auto;
  background:var(--cyan);transition:width .45s var(--ease),margin .45s var(--ease)}
body.p-capability .macro:hover .media img{transform:scale(1.06)}
body.p-capability .macro:hover::after{
  background:linear-gradient(180deg,transparent 38%,rgba(4,40,59,.95) 100%)}
body.p-capability .macro:hover span{transform:translateY(-4px);color:#fff}
body.p-capability .macro:hover span::before{width:20px;margin-right:10px}
@media(prefers-reduced-motion:reduce){
  body.p-capability .macro:hover .media img{transform:none}
  body.p-capability .macro:hover span{transform:none}
  body.p-capability .macro span::before{display:none}}

/* ── Value props: a hairline draws across the top of each as it enters. */
body.p-capability .props .prop{position:relative;padding-top:var(--s5)}
body.p-capability .props .prop::before{content:"";position:absolute;top:0;left:0;
  width:0;height:2px;background:var(--cyan);opacity:.55;
  transition:width .7s var(--ease)}
body.p-capability .props .prop.in::before{width:100%}
@media(prefers-reduced-motion:reduce){
  body.p-capability .props .prop.in::before{width:100%;transition:none}}

/* ══ CRANE MODEL PAGE (17 Sep 2026 rework) ═════════════════════════════
   Head: copy, figures and both actions left; the crane right (its photo, or
   page 1 of its Potain datasheet on white). Body: spec + how it fits, beside
   a sticky column with the datasheet and the ask. */
.model-head{padding-block:var(--s9) var(--s10)}
.model-head-grid{display:grid;grid-template-columns:1.1fr .9fr;gap:var(--s10);align-items:center}
.model-head-copy .mstats{max-width:560px}
.model-head-copy .mstat-v{font-size:clamp(34px,3.6vw,48px)}
.model-head-visual .media{border-radius:8px;overflow:hidden}
.sheet-card{position:relative;display:block;background:#fff;border-radius:8px;overflow:hidden;
  padding:var(--s5) var(--s5) var(--s8);text-decoration:none;
  box-shadow:0 30px 60px -24px rgba(0,0,0,.55);transition:transform .35s var(--ease)}
.sheet-card img{display:block;width:100%;height:auto;max-height:560px;object-fit:contain}
.sheet-card:hover{transform:translateY(-3px)}
.sheet-card-cap{position:absolute;left:0;right:0;bottom:0;padding:var(--s3) var(--s5);
  font-family:var(--mono);font-size:10.5px;letter-spacing:.12em;text-transform:uppercase;
  color:var(--navy);background:linear-gradient(0deg,#fff 60%,rgba(255,255,255,0))}

.model-body{display:grid;grid-template-columns:1.35fr .65fr;gap:var(--s10);align-items:start}
.model-aside{position:sticky;top:calc(var(--nav-h, 88px) + var(--s6));display:flex;
  flex-direction:column;gap:var(--s5)}
.aside-card{background:var(--paper);border:1px solid var(--line);border-radius:8px;
  padding:var(--s6);display:flex;flex-direction:column;gap:var(--s4);align-items:flex-start}
.aside-card p{font-size:14.5px;line-height:1.7;color:var(--ink-2)}
.model-body .model-ctx p{font-size:15.5px;line-height:1.75;color:var(--ink-2);max-width:62ch}
.model-body .model-ctx p + p{margin-top:var(--s4)}

/* card thumbnail when the image is a datasheet page, not a photo */
.sheet-thumb{display:flex;align-items:center;justify-content:center;width:100%;height:100%;
  background:#fff;padding:var(--s3)}
.rel-shot .sheet-thumb img{width:100%;height:100%;object-fit:contain;object-position:center top}

@media(max-width:1000px){
  .model-head-grid,.model-body{grid-template-columns:1fr;gap:var(--s8)}
  .model-aside{position:static}
  .sheet-card img{max-height:440px}
}
.model-head .btn-fill,.model-head .btn-line,.aside-card .btn-fill,.aside-card .btn-line{
  font-size:15px;padding:var(--s4) var(--s6);min-width:0}
.aside-card .btn-fill,.aside-card .btn-line{align-self:stretch;justify-content:space-between}
.rel-shot{overflow:hidden}
.rel-shot .sheet-thumb{padding:0}
.rel-shot .sheet-thumb img{object-fit:cover;object-position:center 2%}
.model-head + .sec .spec{margin-bottom:var(--s2)}
#load-curve{padding-bottom:var(--s9)}

/* ══ GUIDES (17 Sep 2026 desktop rework) ══════════════════════════════
   Index: a wide feature card, then a three-up grid, each with a photo.
   Detail: the article at a comfortable measure beside a sticky rail. */
.guide-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:var(--s6)}
.guide-card{padding:0;overflow:hidden;gap:0}
.guide-card-img{display:block}
.guide-card-img .media,.guide-card-img .ph{aspect-ratio:16/10;border-radius:0}
.guide-card-img img{transition:transform .8s var(--ease)}
.guide-card:hover .guide-card-img img{transform:scale(1.03)}
.guide-card-b{display:flex;flex-direction:column;gap:var(--s3);padding:var(--s6);flex:1}
.guide-card.is-feature{grid-column:1 / -1;display:grid;grid-template-columns:1.2fr 1fr}
.guide-card.is-feature .guide-card-img .media,
.guide-card.is-feature .guide-card-img .ph{aspect-ratio:auto;height:100%;min-height:340px}
.guide-card.is-feature .guide-card-b{padding:var(--s8);justify-content:center}
.guide-card.is-feature .guide-card-h{font-size:clamp(24px,2.4vw,32px);font-weight:500}
.guide-card.is-feature .guide-card-d{flex:0;font-size:16px}

.p-guide .guide-head{padding-block:var(--s10) var(--s9)}
.guide-layout{display:grid;grid-template-columns:minmax(0,1fr) 320px;gap:var(--s10);align-items:start}
.guide-layout .guide{max-width:70ch}
.guide-layout .guide p,.guide-layout .guide ul{font-size:17px;line-height:1.78}
.guide-layout .guide h2{font-size:26px;font-weight:500;margin:var(--s9) 0 var(--s4);
  scroll-margin-top:calc(var(--nav-h, 88px) + var(--s6))}
.guide-layout .guide h2:first-child{margin-top:0}
.guide-rail{position:sticky;top:calc(var(--nav-h, 88px) + var(--s6));display:flex;
  flex-direction:column;gap:var(--s5)}
.guide-toc{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:var(--s2);
  align-self:stretch}
.guide-toc a{display:block;font-size:14px;line-height:1.45;color:var(--ink);text-decoration:none;
  padding:var(--s2) 0;border-bottom:1px solid var(--line)}
.guide-toc li:last-child a{border-bottom:0}
.guide-toc a:hover{color:var(--navy)}

@media(max-width:1000px){
  .guide-grid{grid-template-columns:1fr 1fr}
  .guide-card.is-feature{grid-template-columns:1fr}
  .guide-card.is-feature .guide-card-img .media{min-height:0;aspect-ratio:16/10}
  .guide-layout{grid-template-columns:1fr}
  .guide-rail{position:static}
}
@media(max-width:640px){.guide-grid{grid-template-columns:1fr}}
/* feature card full width, then the other four as one row */
.guide-grid{grid-template-columns:repeat(4,1fr)}
@media(max-width:1200px){.guide-grid{grid-template-columns:1fr 1fr}}
@media(max-width:640px){.guide-grid{grid-template-columns:1fr}}
/* article + rail as one centred block, with the head on the same edge */
.guide-layout{grid-template-columns:minmax(0,740px) 300px;justify-content:center;gap:var(--s10)}
.guide-layout .guide{max-width:none}
.p-guide .guide-head .pagehead-in{max-width:calc(740px + 300px + var(--s10));margin-inline:auto}
@media(max-width:1000px){.guide-layout{grid-template-columns:1fr}}
.p-guide .guide-head .wrap.pagehead-in,
.p-guide .wrap.guide-layout{max-width:calc(740px + 300px + var(--s10) + 2 * var(--gut))}
.p-guide .wrap.guide-layout{justify-content:stretch;grid-template-columns:minmax(0,1fr) 300px}
@media(max-width:1000px){.p-guide .wrap.guide-layout{grid-template-columns:1fr}}

/* ══ MOBILE PASS (17 Sep 2026) ════════════════════════════════════════
   From an audit of every page at 360, 390 and 768 px: no sideways scroll,
   nothing under 11px, touch targets at least 40px. Up to 1000px, which is
   where the menu turns into the burger. */
@media(max-width:1000px){
  .zone,.glo-h,.clsnav-k,.clsnav-n,.step-k,.bp-model-k,.bp-desig,.offer-fig .k,.bp-spec span,.bp-sheet i,
  .field label,.form label{font-size:11px}
  .mstat-k{font-size:10.5px;letter-spacing:.1em}
  .nav-burger{min-height:44px;min-width:64px}
  .lc3-reset{min-height:40px;padding-inline:var(--s4)}
  .pick-b{min-height:40px}
}
@media(max-width:760px){
  .lnk,.close-line .lnk{display:inline;white-space:normal;max-width:100%;overflow-wrap:anywhere}
  .lnk svg{display:inline-block;vertical-align:middle}
  .model-head-copy .row,.pagehead-in .row{gap:var(--s3)}
  .model-head .btn-fill,.model-head .btn-line,.pagehead .btn-fill,.pagehead .btn-line{
    width:100%;justify-content:space-between}
  .guide-layout .guide p,.guide-layout .guide ul{font-size:16px}
  .guide-layout .guide h2{font-size:22px;margin-top:var(--s8)}
}
@media(max-width:600px){
  /* home grid: nine full-height photo cards made the phone scroll forever —
     a compact row each (photo left, words right) instead */
  .trk-grid{gap:var(--s3)}
  .trk-p{display:grid;grid-template-columns:112px 1fr;align-items:stretch}
  .trk-shot{aspect-ratio:auto;height:100%;min-height:104px}
  .trk-ix{font-size:26px;top:var(--s2);left:var(--s3)}
  .trk-b{padding:var(--s4)}
  .trk-n{font-size:17px}
  .trk-d{font-size:13.5px;line-height:1.5}

  /* footer: two link columns side by side, tighter rows */
  .foot-grid{grid-template-columns:1fr 1fr;gap:var(--s7) var(--s5)}
  .foot-brand,.foot-contact{grid-column:1 / -1}
  .foot-contact{padding-left:0;border-left:0}
  .foot-grid > .foot-col:nth-child(3){grid-column:1 / -1;order:3}
  .foot-grid > .foot-col:nth-child(4){order:2}
  .foot-grid > .foot-contact{order:4}
  .foot-links a{padding:var(--s3) 0;font-size:14px}
  .foot-links a span{white-space:normal}
}
/* Buttons on phones and small tablets: 80px tall at desktop padding was
   bigger than the headings around them. ~52px keeps a comfortable thumb
   target (over the 44px minimum) at a size that fits the screen. */
@media(max-width:760px){
  .btn-fill,.btn-line{font-size:16px;padding:14px var(--s5);border-radius:10px;gap:var(--s3)}
  .btn-fill .btn-a,.btn-line .btn-a{width:18px;height:18px}
}
@media(max-width:760px){
  /* full-width buttons: label on the left edge, arrow pushed right */
  .model-head .btn-fill,.model-head .btn-line,.pagehead .btn-fill,.pagehead .btn-line,
  .aside-card .btn-fill,.aside-card .btn-line{justify-content:flex-start}
  .model-head .btn-a,.pagehead .btn-a,.aside-card .btn-a{margin-left:auto}
}

/* ── horizontal-scroll table affordance ──────────────────────────────
   .tscroll tables (crane "side by side", battery picker) silently ran off
   the right edge on a phone with nothing to say more columns existed —
   found 17 Sep 2026. A fade + "swipe" label appears only while there is
   real overflow to scroll to (site.js toggles .has-more / .has-start). */
.tscroll{position:relative}
/* No edge-fade gradient here on purpose (removed 17 Sep 2026) — it dimmed
   numbers that were still fully on screen (the tail of "54.9" et al) and
   left a broken-looking sliver of the next column peeking out past it.
   The "Swipe for more" label below is the unambiguous version of the same
   hint, and it can't mis-render depending on where a column happens to
   fall. has-more / has-start (set by site.js) still drive that label. */
.tscroll-hint{display:none;align-items:center;gap:6px;margin-top:var(--s3);
  padding-inline:var(--gut);max-width:var(--max);margin-inline:auto;
  font-family:var(--mono);font-size:10.5px;letter-spacing:.1em;text-transform:uppercase;
  color:rgba(255,255,255,.4)}
.tscroll-hint-arrow{display:inline-block;animation:tscroll-nudge 1.6s ease-in-out infinite}
@keyframes tscroll-nudge{0%,100%{transform:translateX(0)}50%{transform:translateX(4px)}}
@media(max-width:900px){.tscroll.has-more ~ .tscroll-hint{display:flex}}
@media(min-width:901px){.tscroll-hint{display:none!important}}

/* ══ GUIDES: brochure-grade detail (17 Sep 2026) ══════════════════════
   Three guides are written from the TES product brochures. They carry a
   figure strip under the lede and a brochure card in the rail; guides
   without those keys render exactly as before. */
.guide-stats{list-style:none;display:flex;flex-wrap:wrap;gap:var(--s5) var(--s8);
  margin:var(--s7) 0 0;padding:var(--s6) 0 0;border-top:1px solid var(--line-d)}
.guide-stats li{display:flex;flex-direction:column;gap:2px}
.guide-stats b{font-family:var(--sans);font-size:clamp(22px,2.2vw,30px);font-weight:500;
  line-height:1;letter-spacing:-.02em;color:#fff}
.guide-stats span{font-family:var(--mono);font-size:11px;letter-spacing:.14em;
  text-transform:uppercase;color:rgba(255,255,255,.55)}
.guide-sheet{margin-top:var(--s7);padding-top:var(--s5);border-top:1px solid var(--line);
  font-size:15px}
.guide-sheet + .guide-rel{margin-top:var(--s5);padding-top:0;border-top:0}
.guide-grid.is-three{grid-template-columns:repeat(3,1fr)}
@media(max-width:1200px){.guide-grid.is-three{grid-template-columns:1fr 1fr}}
@media(max-width:640px){
  .guide-grid.is-three{grid-template-columns:1fr}
  .guide-stats{gap:var(--s5) var(--s6)}
  .guide-stats li{min-width:calc(50% - var(--s6))}
}
