/* ============================================================================
   RANCO — IMMERSIVE, LIGHT
   The client asked for the immersive design "in a light theme, in the RANCO
   logo colours". This is that: the same machinery — curtain intro, cinematic
   full-bleed hero, masked line-rise headline, marquee, an equipment gallery
   that pins and drag-scrolls, the seven services as a pinned cross-fade — with
   the shell inverted to paper and the palette reduced to RANCO's own two
   colours plus ink.

   Provenance and the full build record: `clients/ranco/STATUS.md`.

   THE ONE PROBLEM A LIGHT CINEMATIC PAGE HAS, and how it is solved.
   Cinematic layouts put type on top of photographs, and on a dark page a black
   scrim makes white text safe anywhere. On a LIGHT page the equivalent — a
   pale wash under dark text — is only safe if the wash is near-opaque, because
   over a photograph the contrast behind a caption is whatever that crop happens
   to contain. Guessing is how the last build shipped a 1.2:1 caption.
   So every text-over-photo zone here sits under a scrim whose alpha in the text
   column is 0.97. The worst case is a pure-black photograph, which composites
   to #ECEEF1, and every foreground below is measured against THAT, not against
   the bare paper:

       ink  #14171C on #ECEEF1 = 15.45:1     navy #223566 on #ECEEF1 = 10.21:1
       link #1F6FA8 on #ECEEF1 =  4.64:1

   In other words the type is safe over any photograph that could ever be
   dropped in, not just over the ones currently there. The scrim then falls away
   across the rest of the frame so the picture still reads as a picture.

   THE LOGO. RANCO's mark is navy #223566 + blue #328FCE and is NEVER
   recoloured. On a light ground it needs no handling at all: no paper band, no
   chip, no plate, no mat. Every other dark concept in the set had to solve that
   problem; this one does not have it, which is the quiet argument for going
   light in the first place.

   THE PALETTE IS TWO COLOURS AND INK. Navy carries everything that is read at
   size — headlines, numerals, the solid CTA. Brand blue is decoration only
   (3.23:1 on paper: rules, bars, the progress bar, the outline numerals) and
   never carries body text; where blue has to be read at small sizes it becomes
   #1F6FA8, which clears 4.5:1. Nothing else is introduced — no fifth colour, no
   borrowed accent.
   ========================================================================= */

:root{
  --paper:#F3F5F8;           /* the shell */
  --paper-2:#E9EDF2;         /* alternate band — gallery, trust wall, footer */
  --paper-3:#FFFFFF;         /* cards, photo mats, logo tiles */
  --scrim:243,245,248;       /* --paper as rgb, for the photo scrims */

  --ink-txt:#14171C;         /* body ink */ /* @contrast --paper >=4.5 = 16.45:1 */
  --ink-dim:#5A6472;         /* muted body */ /* @contrast --paper >=4.5 = 5.49:1 */

  --navy:#223566;            /* logo — road swoosh, truck, wordmark. NEVER edited. */ /* @contrast --paper >=4.5 = 10.87:1 */
  --blue:#328FCE;            /* logo — bar motif, Arabic رانكو. NEVER edited. */
  --blue-link:#1F6FA8;       /* brand blue wherever it must be READ */ /* @contrast --paper >=4.5 = 4.93:1 */

  --accent:#328FCE;          /* DECORATION ONLY — rules, bars, outline numerals */ /* @contrast --paper >=3.0 = 3.23:1 */
  --accent-hi:#1F6FA8;       /* the small-text shade of the accent */ /* @contrast --paper >=4.5 = 4.93:1 */
  --accent-btn:#223566;      /* solid CTA ground */ /* @contrast white >=4.5 = 11.87:1 */

  /* the shared skeleton expects an on-dark set even where the page never goes
     dark — declared so no component falls back to an undefined token */
  --ink:#223566; --ink-2:#2B4179; --ink-3:#33508F;
  --txt:#FFFFFF; --txt-dim:#C9D2DE;   /* @contrast --ink >=4.5 = 7.78:1 */
  --txt-faint:#9FAFC8;

  --line:rgba(34,53,102,.16);        /* hairline on paper — navy-tinted, not grey */
  --line-2:rgba(34,53,102,.09);
  --line-ink:rgba(34,53,102,.16);

  --ease-expo:cubic-bezier(.19,1,.22,1);
}

body{ background:var(--paper); color:var(--ink-txt) }

/* --- <picture> is INLINE, and that quietly breaks every cover-fit image ----
   `<img style="height:100%">` inside a `<picture>` resolves its percentage
   against the PICTURE's height, which is `auto` — so the declaration does
   nothing, `object-fit:cover` never gets a box to fill, and the photo renders
   at its natural aspect and is simply clipped by the parent's overflow. It
   looks almost right at one viewport size and letterboxes or over-crops at
   every other, which is why it survives a screenshot check. Blockify every
   picture that wraps a cover-fit image. */
.hero-media picture, .capband-media picture, .qhse-media picture,
.h-panel picture, .plate picture, .chapter-figure picture, .bleed picture,
.split-fig picture, .logo-tile picture{
  display:block; width:100%; height:100%;
}
h1,h2,h3{ color:var(--navy) }

/* ---------------------------------------------------------------- chrome -- */
/* No band, no chip, no treatment — the header IS paper, which is the mark's
   own ground. This is the whole point of the light build. */
#top-bar{ --header-bg:rgba(243,245,248,.92); --header-line:var(--line);
  --nav-txt:var(--ink-dim); --nav-txt-hover:var(--navy); --line-btn:var(--line);
  --header-accent:var(--navy);
  -webkit-backdrop-filter:blur(12px); backdrop-filter:blur(12px) }
@media (max-width:720px){
  /* glass needs something behind it to read as glass, and costs real frames on
     a mid-range phone */
  #top-bar{ --header-bg:var(--paper); -webkit-backdrop-filter:none; backdrop-filter:none }
}
.mobile-menu{ background:var(--paper) }
#site-footer{ --footer-line:var(--line); --footer-muted:var(--ink-dim); --footer-accent:var(--navy);
  background:var(--paper-2); color:var(--ink-txt); border-top:1px solid var(--line) }
#site-footer .ibix-credit{ color:var(--footer-muted) }
#site-footer .foot-legal-row{ border-top-color:var(--line) }
#site-footer .foot-h{ color:var(--navy) }

/* --------------------------------------------------------- section grounds */
#statement, #services, #qhse, #careers, #contact{ background:var(--paper) }
#fleet, #stats, #trust{ background:var(--paper-2) }

.kicker{ color:var(--accent-hi) }
.kicker::after{ background:var(--accent); opacity:1 }
.chip{ background:var(--paper-3) }

/* ============================================================== 1 · PRELOADER
   Paper curtain, navy wordmark, brand-blue progress. Only ever rendered when
   JS is on AND motion is allowed: `html.js` comes from js/js-flag.js and
   `html.anim` from js/motion-gate.js, which refuses to set it under
   prefers-reduced-motion. With JS off, with the scripts blocked, or with
   reduced motion asked for, the curtain is display:none and the page is just
   the page. The gate also carries a 5s failsafe, because a curtain that never
   lifts is a blank site. */
#preloader{ display:none }
html.js.anim #preloader{
  display:flex; position:fixed; inset:0; z-index:1000; background:var(--paper);
  flex-direction:column; align-items:center; justify-content:center; gap:28px;
  transform:translateY(0); transition:transform 1s var(--ease-expo);
}
html.js.anim.intro-done #preloader{ transform:translateY(-101%) }
html.intro-done #preloader{ pointer-events:none }
.pl-brand{ font-family:var(--display); font-weight:800; text-transform:uppercase;
  line-height:.94; text-align:center; letter-spacing:-.025em; color:var(--navy);
  font-size:clamp(2.2rem,8vw,5rem) }
.pl-brand .mask{ display:block; overflow:hidden }
.pl-brand .mask > span{ display:block; transform:translateY(105%) }
html.js.anim #preloader.kick .pl-brand .mask:nth-child(1) > span{ transform:none; transition:transform .9s var(--ease) .05s }
html.js.anim #preloader.kick .pl-brand .mask:nth-child(2) > span{ transform:none; transition:transform .9s var(--ease) .16s }
.pl-brand .b{ color:var(--blue-link) }
.pl-track{ width:min(320px,64vw); height:2px; background:var(--line); position:relative; overflow:hidden }
.pl-bar{ position:absolute; inset:0; transform-origin:0 50%; transform:scaleX(0);
  background:linear-gradient(90deg,var(--navy),var(--accent)) }
.pl-meta{ display:flex; justify-content:space-between; width:min(320px,64vw);
  font-family:var(--mono); font-size:.68rem; letter-spacing:.14em; text-transform:uppercase;
  color:var(--ink-dim) }
.pl-meta .n b{ color:var(--navy); font-weight:600; font-variant-numeric:tabular-nums }

#progress{ position:fixed; top:0; inset-inline:0; height:2px; z-index:70; pointer-events:none;
  transform-origin:0 50%; transform:scaleX(0); opacity:0;
  background:linear-gradient(90deg,var(--navy),var(--accent)); transition:opacity .4s var(--ease) }
html.js.anim #progress.on{ opacity:1 }

/* ================================================================== 2 · HERO
   Full-bleed photograph with the paper scrim described at the top of this
   file. Two gradients: a horizontal one that holds the text column at 0.97
   alpha and releases the picture to the right, and a vertical one that lands
   the foot of the frame back on paper so the fact strip has a real surface. */
#hero{ position:relative; isolation:isolate; overflow:hidden; background:var(--paper);
  min-height:calc(100svh - 76px); display:flex; align-items:flex-end }
.hero-media{ position:absolute; inset:0; z-index:-2 }
.hero-media img{ width:100%; height:100%; object-fit:cover; object-position:center 52% }
html.js.anim .hero-media img{ transform:scale(1.12); transition:transform 2s var(--ease-expo) }
html.js.anim.intro-done .hero-media img{ transform:scale(1) }
.hero-scrim{ position:absolute; inset:0; z-index:-1; pointer-events:none;
  background:
    linear-gradient(90deg, rgba(var(--scrim),.97) 0%, rgba(var(--scrim),.94) 38%,
                           rgba(var(--scrim),.55) 66%, rgba(var(--scrim),.06) 100%),
    linear-gradient(180deg, rgba(var(--scrim),.55) 0%, rgba(var(--scrim),0) 26%,
                            rgba(var(--scrim),0) 58%, rgba(var(--scrim),.92) 100%) }
@media (max-width:900px){
  /* stacked layout: the text sits over the TOP of the frame, so the scrim has
     to run vertically instead — same 0.97 in the text zone */
  .hero-scrim{ background:
    linear-gradient(180deg, rgba(var(--scrim),.97) 0%, rgba(var(--scrim),.95) 46%,
                            rgba(var(--scrim),.62) 74%, rgba(var(--scrim),.9) 100%) }
  .hero-media img{ object-position:center 62% }
}
.hero-in{ position:relative; z-index:2; width:100%;
  padding-block-start:clamp(96px,14vh,150px); padding-block-end:clamp(120px,17vh,180px) }
.hero-eyebrow{ display:inline-flex; align-items:center; gap:14px; margin-bottom:clamp(16px,3vh,26px);
  font-family:var(--mono); font-size:.72rem; letter-spacing:.18em; text-transform:uppercase;
  color:var(--accent-hi) }
.hero-eyebrow::before{ content:""; width:34px; height:1px; background:var(--accent) }
.hero-h{ color:var(--navy); font-weight:800; letter-spacing:-.035em; text-transform:uppercase;
  /* sized by the SMALLER of width and height, so a three-line headline can
     never push the lede + CTAs below the fold on a wide-but-short laptop */
  font-size:clamp(2.6rem, min(11.5vw,14.5vh), 8rem); line-height:.9; margin:0;
  max-width:16ch }
.hero-h .line{ display:block; overflow:hidden; padding-bottom:.03em }
.hero-h .line > span{ display:block }
.hero-h .b{ color:var(--blue-link) }
html.js.anim:not(.anim-busted) .hero-h .line > span{ transform:translateY(108%) }
html.js.anim.intro-done .hero-h .line > span{ transform:none; transition:transform 1.05s var(--ease-expo) }
html.js.anim.intro-done .hero-h .line:nth-child(1) > span{ transition-delay:.06s }
html.js.anim.intro-done .hero-h .line:nth-child(2) > span{ transition-delay:.17s }
html.js.anim.intro-done .hero-h .line:nth-child(3) > span{ transition-delay:.28s }

/* The lede and the CTAs stay together in the LEFT column rather than being
   pushed to opposite edges the way the dark build does it. On a dark shell the
   whole width is a legible surface, so a split row reads as composition; here
   the right-hand third is the photograph at full strength, and a button
   floating over a crew's faces reads as a mistake. Capping the row keeps every
   piece of type inside the part of the frame the scrim actually holds. */
.hero-foot-in{ display:flex; align-items:flex-end; justify-content:flex-start;
  gap:20px 36px; flex-wrap:wrap; margin-top:clamp(24px,4vh,38px);
  max-width:min(860px, 66%) }
@media (max-width:900px){ .hero-foot-in{ max-width:none } }
.hero-lede{ max-width:46ch; color:var(--ink-txt); font-size:clamp(1rem,1.4vw,1.16rem); line-height:1.65 }
.hero-cta{ display:flex; align-items:center; gap:16px; flex-wrap:wrap }
html.js.anim:not(.anim-busted) .hero-fade{ opacity:0; transform:translateY(24px) }
html.js.anim.intro-done .hero-fade{ opacity:1; transform:none;
  transition:opacity 1s var(--ease) .5s, transform 1s var(--ease) .5s }

.hero-strip{ position:absolute; inset-inline:0; inset-block-end:0; z-index:3;
  border-top:1px solid var(--line); background:rgba(var(--scrim),.94);
  -webkit-backdrop-filter:blur(6px); backdrop-filter:blur(6px) }
.hero-strip ul{ list-style:none; display:flex; flex-wrap:wrap;
  font-family:var(--mono); font-size:.68rem; letter-spacing:.14em; text-transform:uppercase;
  color:var(--ink-dim) }
.hero-strip li{ padding-block:13px; display:inline-flex; align-items:center }
.hero-strip li:not(:last-child)::after{ content:""; width:1px; height:11px; background:var(--line);
  margin-inline:clamp(12px,2.6vw,28px) }
.hero-strip li b{ color:var(--navy); font-weight:700 }
@media (max-width:760px), (max-height:720px){
  /* `#hero` is `display:flex; align-items:flex-end`, so the moment the strip
     stops being `position:absolute` it becomes a flex ITEM and lands in the
     SAME ROW as the hero copy — a narrow column of facts pinned to the right
     of the headline. Taking it out of flow hid this at every desktop width,
     and it produces no overflow and no contrast fault, so qa.py reports the
     page clean. The strip only works in flow if the hero stacks. */
  #hero{ flex-direction:column; align-items:stretch; justify-content:flex-end }
  .hero-strip{ width:100%; position:static; background:var(--paper); -webkit-backdrop-filter:none; backdrop-filter:none }
  #hero{ min-height:0 }
  .hero-in{ padding-block-end:clamp(28px,5vh,44px) }
  /* once the strip wraps, the between-items rule stops separating anything and
     becomes a dangling pipe at the end of each line — gap does the job instead */
  .hero-strip ul{ gap:4px 18px }
  .hero-strip li{ padding-block:7px }
  .hero-strip li:not(:last-child)::after{ display:none }
}

.btn-line{ border:1px solid var(--line); color:var(--navy); background:var(--paper-3) }
.btn-line:hover{ border-color:var(--navy); background:var(--paper-3) }

/* --- hero fit tiers. LAST in the hero block on purpose: a media query adds no
   specificity, so written before `.hero-h` these would be silently outranked
   by it and change nothing. Both tiers were measured, not assumed. */
@media (max-height:800px){
  .hero-in{ padding-block-start:clamp(36px,5vh,56px); padding-block-end:clamp(64px,9vh,88px) }
  .hero-h{ font-size:clamp(1.9rem, min(8.6vw,9.2vh), 5rem) }
  .hero-eyebrow{ margin-bottom:12px }
  .hero-foot-in{ margin-top:16px }
  .hero-lede{ font-size:.98rem; line-height:1.5; max-width:42ch }
}
@media (max-width:560px){
  .hero-h{ font-size:clamp(1.9rem, min(10vw,8.6vh), 3.1rem) }
  .hero-lede{ font-size:.95rem; max-width:none }
}

/* ============================================================= 3 · STATEMENT */
#statement{ padding-block:var(--pad-section-lg) }
.stmt-h{ font-weight:800; text-transform:uppercase; letter-spacing:-.035em; line-height:.92;
  color:var(--navy); font-size:clamp(2.4rem,7.6vw,6.4rem); max-width:15ch }
.stmt-h .b{ color:var(--blue-link) }
.stmt-grid{ display:grid; grid-template-columns:1fr; gap:clamp(28px,4vw,60px);
  margin-top:clamp(30px,4.5vw,56px); align-items:end }
@media (min-width:900px){ .stmt-grid{ grid-template-columns:1.35fr .65fr } }
.stmt-lede{ color:var(--ink-txt); font-size:clamp(1.05rem,1.5vw,1.3rem); line-height:1.68; max-width:54ch }
.stmt-lede b{ font-weight:700; color:var(--navy) }
.stmt-aside{ border-inline-start:2px solid var(--accent); padding-inline-start:22px }
.stmt-aside p{ font-family:var(--mono); font-size:.76rem; letter-spacing:.04em; line-height:2;
  text-transform:uppercase; color:var(--ink-dim) }
.stmt-aside b{ color:var(--navy); font-weight:700 }

.marquee{ margin-top:clamp(44px,7vw,88px); overflow:hidden; padding-block:clamp(16px,2.4vw,26px);
  border-block:1px solid var(--line-2);
  -webkit-mask-image:linear-gradient(90deg,transparent,#000 8%,#000 92%,transparent);
          mask-image:linear-gradient(90deg,transparent,#000 8%,#000 92%,transparent) }
.marquee-track{ display:flex; align-items:center; width:max-content;
  animation:il-marquee 42s linear infinite }
.marquee:hover .marquee-track{ animation-play-state:paused }
/* The alternating "quiet" words were first set as navy at 26% alpha, which
   measured 1.62:1 — a word you can see but cannot comfortably read. The strip
   is aria-hidden and every word in it also appears as real text elsewhere on
   the page, so it is decorative; that is an argument for excluding it from a
   checker, not an argument for leaving it illegible. Solid #7682A0 instead:
   still clearly the recessive half of the pair, and it clears the 3:1 large-
   text floor with headroom. */
.marquee-track span{ font-family:var(--display); font-weight:800; text-transform:uppercase;
  letter-spacing:-.02em; font-size:clamp(1.4rem,3.6vw,3rem); color:#7682A0; /* @contrast --paper >=3.0 = 3.51:1 */
  padding-inline:clamp(18px,3vw,40px); display:inline-flex; align-items:center;
  gap:clamp(18px,3vw,40px) }
.marquee-track span::before{ content:""; width:9px; height:9px; border-radius:50%;
  background:var(--accent); flex:none }
.marquee-track span.on{ color:var(--navy) }
@keyframes il-marquee{ to{ transform:translateX(-50%) } }
@media (prefers-reduced-motion:reduce){ .marquee-track{ animation:none } }

/* ============================================== 4 · HORIZONTAL FLEET GALLERY
   SIGNATURE MOVE. On >=1024px the section pins and the track is dragged
   sideways by scroll. Below that — and with JS off, with GSAP missing, or under
   reduced motion — it is a plain native horizontal scroller with snap points
   and a visible hint, which needs no script at all. Every panel is one of
   RANCO's OWN photographs; there is no stand-in in this gallery.
   On paper the panels get a white mat and a hairline instead of the dark
   build's borderless bleed — a print in a frame, not a window into the night. */
#fleet{ padding-block-start:var(--pad-section); padding-block-end:var(--pad-section) }
.fleet-head{ display:flex; align-items:flex-end; justify-content:space-between; gap:24px;
  flex-wrap:wrap; margin-bottom:clamp(26px,4vw,46px) }
.fleet-head h2{ font-weight:800; text-transform:uppercase; letter-spacing:-.03em; line-height:.94;
  font-size:clamp(2.2rem,6vw,4.8rem) }
.fleet-head .fh-note{ max-width:36ch; color:var(--ink-dim); font-size:.95rem; line-height:1.6 }
.h-pin{ overflow:visible }
.h-track{ display:flex; gap:clamp(14px,2vw,28px); overflow-x:auto; overflow-y:hidden;
  scroll-snap-type:x mandatory; -webkit-overflow-scrolling:touch; padding-bottom:10px;
  scrollbar-width:thin; scrollbar-color:var(--accent) transparent }
.h-track::-webkit-scrollbar{ height:8px }
.h-track::-webkit-scrollbar-track{ background:rgba(34,53,102,.08) }
.h-track::-webkit-scrollbar-thumb{ background:var(--accent); border-radius:8px }
#fleet.is-pinned .h-pin{ overflow:hidden; height:100vh; display:flex; flex-direction:column; justify-content:center }
#fleet.is-pinned .h-track{ overflow:visible; scroll-snap-type:none; padding-bottom:0; scrollbar-width:none }
#fleet.is-pinned .h-track::-webkit-scrollbar{ display:none }
.h-panel{ position:relative; flex:0 0 auto; width:min(80vw,620px); scroll-snap-align:center;
  background:var(--paper-3); border:1px solid var(--line); padding:12px;
  display:flex; flex-direction:column }
.h-panel .h-shot{ display:block; height:min(54vh,440px); overflow:hidden; background:var(--paper-2) }
.h-panel img{ width:100%; height:100%; object-fit:cover }
.h-panel figcaption{ display:flex; justify-content:space-between; align-items:baseline; gap:12px;
  padding-top:12px; font-family:var(--mono); font-size:.68rem; letter-spacing:.1em;
  text-transform:uppercase }
.h-panel figcaption .t{ color:var(--navy) }
.h-panel figcaption .fig{ color:var(--accent-hi) }
@media (hover:hover) and (pointer:fine){
  .h-panel img{ transition:transform .8s var(--ease) }
  .h-panel:hover img{ transform:scale(1.05) }
}
/* the hint swaps wording rather than disappearing when the section pins: the
   two modes need two different instructions, and an affordance that vanishes in
   the mode that needs it most is worse than no affordance */
.h-hint{ margin-top:18px; font-family:var(--mono); font-size:.68rem; letter-spacing:.14em;
  text-transform:uppercase; color:var(--ink-dim) }
.h-hint .on-pin{ display:none }
#fleet.is-pinned .h-hint .off-pin{ display:none }
#fleet.is-pinned .h-hint .on-pin{ display:inline }

/* ======================================================= 5 · PINNED SERVICES
   SIGNATURE MOVE, second. RANCO's own seven lines of work, one screen at a
   time — not a staged "how a move runs" method, because RANCO publishes none
   and inventing one would be inventing a fact. No photograph is attached to
   any of the seven, deliberately: four of them have no image at all, and
   pairing three with a picture and four with a blank would say something
   untrue about which parts of the business are real.
   Below 1024px and in every degraded state this is an ordinary vertical list,
   complete and numbered, readable with no script. */
#services{ padding-block-start:var(--pad-section); padding-block-end:var(--pad-section) }
.svc-head{ margin-bottom:clamp(28px,4vw,52px) }
.svc-head h2{ font-weight:800; text-transform:uppercase; letter-spacing:-.03em; line-height:.94;
  font-size:clamp(2.2rem,6vw,4.8rem) }
.svc-seq{ display:flex; flex-direction:column; gap:clamp(40px,6vw,72px) }
.svc-cell{ display:grid; grid-template-columns:1fr; gap:clamp(14px,2vw,26px); align-items:start }
.svc-cell .svc-ix{ font-family:var(--mono); font-size:.8rem; letter-spacing:.2em; color:var(--accent-hi) }
.svc-cell h3{ font-weight:800; text-transform:uppercase; letter-spacing:-.03em; line-height:.98;
  font-size:clamp(1.9rem,4.6vw,3.6rem); max-width:16ch }
.svc-cell p{ color:var(--ink-dim); font-size:1.02rem; line-height:1.68; max-width:52ch }
.svc-ghost{ display:none }
#services.is-pinned .svc-seq{ display:block; position:relative; height:100vh }
#services.is-pinned .svc-cell{ position:absolute; inset:0; height:100vh; align-content:center;
  opacity:0; pointer-events:none; transform:translateY(22px) scale(.995);
  transition:opacity .6s var(--ease), transform .8s var(--ease) }
#services.is-pinned .svc-cell.active{ opacity:1; pointer-events:auto; transform:none }
/* The oversized numeral behind each service. `z-index:-1` is load-bearing and
   is not decoration: z-index:0 on an absolutely-positioned element still paints
   ABOVE its static in-flow siblings, so at 0 this would sit on top of the
   heading. Stroke-only where the browser supports it, a low-opacity solid fill
   where it does not — never invisible, never a blank rectangle. */
#services.is-pinned .svc-ghost{ display:block; position:absolute; z-index:-1;
  inset-block-start:2%; inset-inline-start:-.04em; pointer-events:none; user-select:none;
  font-family:var(--display); font-weight:800; letter-spacing:-.04em; line-height:1;
  font-size:clamp(9rem,26vw,26rem); color:var(--accent); opacity:.14 }
@supports (-webkit-text-stroke:1px black){
  #services.is-pinned .svc-ghost{ color:transparent; -webkit-text-stroke:2px var(--accent); opacity:.45 }
}
.svc-rail{ display:none }
#services.is-pinned .svc-rail{ display:flex; gap:10px; position:absolute;
  inset-inline-start:0; inset-block-end:44px; z-index:3 }
.svc-rail .dot{ width:30px; height:3px; background:var(--line); overflow:hidden }
.svc-rail .dot > b{ display:block; height:100%; width:100%; background:var(--accent);
  transform:scaleX(0); transform-origin:0 50%; transition:transform .4s var(--ease) }
.svc-rail .dot.on > b{ transform:scaleX(1) }

/* ============================================================= 6 · STAT BAND
   Four facts, and only four. There is no "Established" cell: RANCO has never
   supplied a founding year, and nothing here is invented to fill a grid. */
#stats{ padding-block:clamp(52px,7vh,80px); border-block:1px solid var(--line-2) }
.stats-g{ display:grid; grid-template-columns:1fr 1fr }
@media (min-width:860px){ .stats-g{ grid-template-columns:repeat(4,1fr) } }
.stat-g{ padding:clamp(20px,3vw,38px) clamp(14px,2vw,28px); border-top:1px solid var(--line-2) }
.stat-g:nth-child(odd){ border-inline-end:1px solid var(--line-2) }
@media (min-width:860px){
  .stat-g{ border-top:0 }
  .stat-g:not(:last-child){ border-inline-end:1px solid var(--line-2) }
}
.stat-g > b{ display:block; font-family:var(--display); font-weight:800; letter-spacing:-.03em;
  line-height:.92; color:var(--navy); font-size:clamp(2.6rem,6vw,5rem);
  font-variant-numeric:tabular-nums }
.stat-g > b .u{ color:var(--blue-link) }
.stat-g.is-list > b{ font-size:clamp(1.05rem,1.9vw,1.5rem); line-height:1.5; letter-spacing:0 }
.stat-g.is-word > b{ font-size:clamp(1.8rem,3.6vw,2.8rem) }
.stat-g > span{ display:block; margin-top:14px; font-family:var(--mono); font-size:.7rem;
  letter-spacing:.14em; text-transform:uppercase; color:var(--ink-dim) }

/* ========================================================= 7 · CAPABILITIES
   Full-bleed photographic bands, under the same measured paper scrim as the
   hero — so they stay part of a LIGHT page rather than becoming two dark
   interruptions in it. Only TWO exist, and only because RANCO photographed
   both: the excavator line in their own yard, and their own bus fleet. */
.capband{ position:relative; isolation:isolate; overflow:hidden; background:var(--paper);
  min-height:min(84vh,740px); display:flex; align-items:flex-end }
.capband-media{ position:absolute; inset:0; z-index:-2 }
.capband-media img{ width:100%; height:100%; object-fit:cover }
.capband-scrim{ position:absolute; inset:0; z-index:-1; pointer-events:none;
  background:
    linear-gradient(90deg, rgba(var(--scrim),.97) 0%, rgba(var(--scrim),.93) 40%,
                           rgba(var(--scrim),.5) 70%, rgba(var(--scrim),.05) 100%),
    linear-gradient(180deg, rgba(var(--scrim),.5) 0%, rgba(var(--scrim),0) 30%,
                            rgba(var(--scrim),.85) 100%) }
@media (max-width:900px){
  .capband-scrim{ background:
    linear-gradient(180deg, rgba(var(--scrim),.9) 0%, rgba(var(--scrim),.55) 34%,
                            rgba(var(--scrim),.95) 62%, rgba(var(--scrim),.97) 100%) }
}
.capband-in{ position:relative; z-index:2; width:100%;
  padding-block-start:clamp(60px,10vw,120px); padding-block-end:clamp(44px,7vw,86px) }
.capband-ix{ font-family:var(--mono); font-size:.76rem; letter-spacing:.2em; text-transform:uppercase;
  color:var(--accent-hi) }
.capband h2{ font-weight:800; text-transform:uppercase; letter-spacing:-.035em; line-height:.92;
  font-size:clamp(2.2rem,6.6vw,5.4rem); margin:16px 0 clamp(16px,2.4vw,24px); max-width:15ch }
.capband p{ max-width:54ch; color:var(--ink-txt); font-size:clamp(1rem,1.3vw,1.16rem); line-height:1.64 }
.capband ul{ list-style:none; display:flex; flex-wrap:wrap; gap:8px; margin-top:clamp(20px,3vw,28px);
  max-width:60ch }
.capband ul li{ font-family:var(--mono); font-size:.7rem; letter-spacing:.06em; text-transform:uppercase;
  color:var(--navy); border:1px solid var(--line); padding:9px 13px; background:var(--paper-3) }
.capband-note{ margin-top:18px; font-family:var(--mono); font-size:.66rem; letter-spacing:.12em;
  text-transform:uppercase; color:var(--ink-dim) }

/* ================================================================= 8 · TRUST */
#trust{ padding-block-start:var(--pad-section); padding-block-end:var(--pad-section) }
#trust .trust-head h2{ color:var(--navy) }
.logo-tile{ border:1px solid var(--line) }

/* ================================================================== 9 · QHSE
   The dark build dims a photograph behind this whole section. On a light page
   that would be the one place the shell went dark, so the photograph becomes a
   framed plate beside the copy instead — same picture, same evidence, no
   inverted band. */
#qhse{ padding-block-start:var(--pad-section-lg); padding-block-end:var(--pad-section-lg) }
.qhse-grid{ display:grid; grid-template-columns:1fr; gap:clamp(30px,5vw,72px); align-items:start }
@media (min-width:960px){ .qhse-grid{ grid-template-columns:minmax(0,6.2fr) minmax(0,5.8fr) } }
#qhse h2{ font-weight:800; text-transform:uppercase; letter-spacing:-.035em; line-height:.94;
  font-size:clamp(2rem,5.4vw,4rem); margin:0 0 clamp(20px,3vw,32px); max-width:17ch }
#qhse h2 .b{ color:var(--blue-link) }
.qhse-list{ display:grid; grid-template-columns:1fr; border-top:1px solid var(--line) }
.qhse-item{ padding-block:clamp(18px,2.4vw,26px); border-bottom:1px solid var(--line-2) }
.qhse-item .qi-k{ font-family:var(--mono); font-size:.68rem; letter-spacing:.16em;
  text-transform:uppercase; color:var(--accent-hi) }
.qhse-item .qi-v{ margin-top:8px; font-weight:600; font-size:clamp(1rem,1.5vw,1.2rem);
  color:var(--ink-txt); line-height:1.4 }
.qhse-foot{ margin-top:clamp(22px,3vw,32px); max-width:60ch; color:var(--ink-dim);
  font-size:.95rem; line-height:1.65 }
.plate{ background:var(--paper-3); border:1px solid var(--line); padding:14px }
.plate figure{ overflow:hidden; background:var(--paper-2); aspect-ratio:4/3 }
.plate img{ width:100%; height:100%; object-fit:cover }
.plate-cap{ margin-top:14px; display:flex; justify-content:space-between; gap:8px 20px;
  font-family:var(--mono); font-size:.66rem; letter-spacing:.12em; text-transform:uppercase;
  color:var(--ink-dim) }
.plate-cap b{ color:var(--navy); font-weight:600 }

/* =============================================================== 10 · CAREERS */
#careers{ padding-block-start:var(--pad-section); padding-block-end:var(--pad-section) }
#careers h2{ font-weight:800; text-transform:uppercase; letter-spacing:-.03em; line-height:.96;
  font-size:clamp(1.9rem,5vw,3.6rem); max-width:18ch }
#careers .careers-lead{ color:var(--ink-dim) }

/* =============================================================== 11 · CONTACT */
#contact{ padding-block-start:var(--pad-section); padding-block-end:var(--pad-section) }
.con-top{ display:grid; grid-template-columns:1fr; gap:clamp(22px,4vw,52px); align-items:end }
@media (min-width:900px){ .con-top{ grid-template-columns:1.2fr .8fr } }
.con-h{ font-weight:800; text-transform:uppercase; letter-spacing:-.035em; line-height:.9;
  font-size:clamp(2.6rem,8vw,6.4rem) }
.con-h .b{ color:var(--blue-link) }
.con-intro{ color:var(--ink-txt); font-size:clamp(1rem,1.3vw,1.16rem); line-height:1.64; max-width:44ch }
.dsp-grid{ display:grid; grid-template-columns:1fr; gap:clamp(16px,2vw,22px);
  margin-top:clamp(32px,5vw,56px) }
@media (min-width:680px){ .dsp-grid{ grid-template-columns:1fr 1fr } }
.dsp{ border:1px solid var(--line); background:var(--paper-3); padding:clamp(24px,3vw,34px);
  transition:border-color .35s var(--ease), transform .35s var(--ease) }
@media (hover:hover) and (pointer:fine){
  .dsp:hover{ border-color:var(--navy); transform:translateY(-4px) }
}
.dsp .dsp-role{ font-family:var(--mono); font-size:.68rem; letter-spacing:.14em;
  text-transform:uppercase; color:var(--accent-hi) }
.dsp .dsp-name{ font-family:var(--display); font-weight:700; font-size:1.3rem; color:var(--navy);
  margin-top:12px }
.dsp-tel{ display:inline-block; font-family:var(--display); font-weight:700;
  font-size:clamp(1.2rem,2.2vw,1.62rem); color:var(--navy); font-variant-numeric:tabular-nums;
  margin:10px 0 20px; min-height:24px }
.dsp-tel:hover{ color:var(--blue-link) }
.dsp-mail{ display:inline-block; margin-top:10px; color:var(--ink-txt); word-break:break-word;
  min-height:24px }
.dsp-mail:hover{ color:var(--blue-link) }
.dsp-acts{ display:flex; gap:10px; flex-wrap:wrap }
.dsp-acts .btn{ flex:1 1 auto }
@media (max-width:420px){ .dsp-acts .btn{ flex:1 1 100% } }
.loc-dl{ margin-top:clamp(32px,5vw,54px); border-top:1px solid var(--line);
  display:grid; grid-template-columns:1fr }
@media (min-width:760px){ .loc-dl{ grid-template-columns:repeat(3,1fr) } }
.loc-dl .row{ padding-block:clamp(18px,2.4vw,26px); border-bottom:1px solid var(--line-2) }
@media (min-width:760px){
  .loc-dl .row:not(:last-child){ border-inline-end:1px solid var(--line-2); padding-inline-end:26px }
  .loc-dl .row:not(:first-child){ padding-inline-start:26px }
}
.loc-dl dt{ font-family:var(--mono); font-size:.66rem; letter-spacing:.16em; text-transform:uppercase;
  color:var(--accent-hi) }
.loc-dl dd{ margin-top:10px; color:var(--ink-txt); font-size:1rem; line-height:1.55 }

/* ------------------------------------------------------------- reduced motion
   The gate is primarily in JS (`html.anim` is never set), which makes the
   curtain display:none and leaves every masked line at its natural position.
   These are the belt to those braces. */
@media (prefers-reduced-motion:reduce){
  html.js.anim #preloader{ display:none }
  html.js.anim .hero-h .line > span,
  html.js.anim .hero-fade{ opacity:1 !important; transform:none !important; transition:none }
  html.js.anim .hero-media img{ transform:none !important }
  #services.is-pinned .svc-cell{ transition:none }
}
