/* ============================================================================
   RANCO — Concept G · IMMERSIVE
   The cinematic showstopper of the eight-concept set: a curtain intro, a
   full-bleed photographic hero with a masked line-rise headline and a fact
   strip welded to its foot, a marquee, an equipment gallery that pins and
   scrolls sideways on wide screens, and the seven services delivered as a
   pinned cross-fade, one per screen.

   Provenance, sourcing and the full record of what was stripped out and why:
   `clients/ranco/STATUS.md`, entry 2026-08-07. Nothing about this page's
   origin belongs in a file the client can view-source.

   EVERY FACT ON THIS PAGE IS RANCO'S OWN, from CLIENT-FACTS.md. RANCO has
   supplied no founding year, no headcount, no registration number, no fleet
   counts, no safety statistics and no named projects, so this concept carries
   none — the stat band has four cells rather than five for exactly that
   reason, and there is no staged "method" section, because RANCO publishes no
   staged method. The pinned sequence carries RANCO's own seven-service
   taxonomy instead.

   NOT REPRODUCED: a custom cursor. The playbook records two separate bugs
   from that pattern (z-index over overlays; JS stamping `cursor:none!important`
   and defeating every stylesheet override), and it buys nothing on a page
   whose drag affordance is already labelled in words.

   THE LOGO CONSTRAINT. RANCO's mark is navy #223566 + blue #328FCE and is
   NEVER recoloured (owner, 2026-07-31), so on this dark shell it gets the
   paper-band treatment already solved in Concept F: header and footer are
   light paper, top and bottom, undecorated. F's token block was the STARTING
   point only — every pair below was re-solved with
   design/snippets/contrast-check.py against THIS shell (#070C16, darker than
   F's #0C1730), because a value that passes on one dark ground can fail on
   another. F's --txt-dim #7E848C, for instance, is fine here, but the shell
   change moves every ratio and the numbers below are computed, not inherited.

   ========================================================================= */

:root{
  /* Shell — RANCO's navy taken to full night. Deliberately not a neutral
     near-black (which is Concept E's ground): the blue cast is the brand's
     own, so the photography — orange machines against a hard blue sky — sits
     on a ground that belongs to RANCO. */
  --ink:#070C16;             /* cinematic shell */
  --ink-2:#0E1729;           /* raised band — stat band, gallery, contact */
  --ink-3:#16223A;           /* card / panel step on the raised band */
  --paper:#F2F4F6;           /* header + footer bands — the logo's own ground */
  --paper-2:#E7EBEE;

  --txt:#ECEEF1;             /* on --ink */    /* @contrast --ink >=4.5 = 16.83:1 */
  --txt-dim:#7B818A;         /* on --ink, muted body */ /* @contrast --ink >=4.5 = 4.98:1 */
  --txt-faint:#606670;       /* on --ink, DECORATION ONLY — never body or legal text */ /* @contrast --ink >=3.0 = 3.38:1 */
  --ink-txt:#14171C;         /* on --paper */  /* @contrast --paper >=4.5 = 16.29:1 */
  --ink-dim:#636F80;         /* on --paper, muted */ /* @contrast --paper >=4.5 = 4.63:1 */

  --navy:#223566;            /* logo — road swoosh, truck, wordmark. NEVER edited. */
  --blue:#328FCE;            /* logo — bar motif, Arabic رانكو. NEVER edited. */
  --blue-link:#1F6FA8;       /* brand blue where small text must carry it on paper */ /* @contrast --paper >=4.5 = 4.89:1 */

  /* THE accent. RANCO's own brand blue — the only signal colour on the page,
     in two shades because one value cannot serve both roles on this shell:
     full strength for anything large or decorative, the lifted shade wherever
     it has to carry small text. */
  --accent:#328FCE;          /* large / decorative — rules, bars, progress, numerals */ /* @contrast --ink >=3.0 = 5.55:1 */
  --accent-hi:#5CB3EF;       /* small text on ink — kickers, mono labels, indices */ /* @contrast --ink >=4.5 = 8.53:1 */
  --accent-btn:#223566;      /* solid CTA ground — navy, white-text-safe */ /* @contrast white >=4.5 = 11.87:1 */
  --accent-link:#1F6FA8;     /* accent on the PAPER bands */ /* @contrast --paper >=4.5 = 4.89:1 */

  --line:rgba(255,255,255,.13);
  --line-2:rgba(255,255,255,.07);
  --line-ink:rgba(20,23,28,.14);

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

body{ background:var(--ink) }

/* --- <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-g 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%;
}

/* ---------------------------------------------------------------- chrome -- */
/* Header and footer are the only paper on the page — the mark's own ground,
   top and bottom, exactly as Concept A and Concept F do it. No chip, no
   shadow, no recolour; a single hairline edge is the whole treatment. */
#top-bar{ --header-bg:var(--paper); --header-line:var(--line-ink);
  --nav-txt:var(--ink-dim); --nav-txt-hover:var(--ink-txt); --line-btn:var(--line-ink);
  --header-accent:var(--navy) }
#site-footer{ --footer-line:var(--line-ink); --footer-muted:var(--ink-dim); --footer-accent:var(--navy);
  background:var(--paper); color:var(--ink-txt) }
#site-footer .ibix-credit{ color:var(--footer-muted) }
#site-footer .foot-legal-row{ border-top-color:var(--accent-link) }

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

/* ============================================================== 1 · PRELOADER
   The curtain. Only ever rendered when JS is on AND motion is allowed —
   `html.js` comes from js/js-flag.js and `html.gmotion` is set by
   js/g-immersive.js, which refuses to set it under prefers-reduced-motion. So
   with JS off, with the script blocked, or with reduced motion asked for, the
   curtain is display:none and the page is simply the page. There is no state
   in which a visitor can be left staring at it: the script also carries a
   hard failsafe that lifts it after 5s whatever else has gone wrong. */
#preloader{ display:none }
html.js.gmotion #preloader{
  display:flex; position:fixed; inset:0; z-index:1000; background:var(--ink);
  flex-direction:column; align-items:center; justify-content:center; gap:28px;
  transform:translateY(0); transition:transform 1s var(--ease-expo);
}
html.js.gmotion.g-loaded #preloader{ transform:translateY(-101%) }
html.g-loaded #preloader{ pointer-events:none }
.pl-brand{ font-family:var(--display); font-weight:800; text-transform:uppercase;
  line-height:.94; text-align:center; letter-spacing:-.02em; color:var(--txt);
  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.gmotion #preloader.kick .pl-brand .mask:nth-child(1) > span{ transform:none; transition:transform .9s var(--ease) .05s }
html.js.gmotion #preloader.kick .pl-brand .mask:nth-child(2) > span{ transform:none; transition:transform .9s var(--ease) .16s }
.pl-brand .b{ color:var(--accent-hi) }
.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(--txt-dim) }
.pl-meta .n b{ color:var(--txt); font-weight:600; font-variant-numeric:tabular-nums }

/* scroll progress bar — decorative, hidden until the motion layer arms it */
#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.gmotion #progress.on{ opacity:1 }

/* ================================================================== 2 · HERO
   Cinematic full-bleed: photo + double scrim, the headline set in masked
   lines that rise once, a lede/CTA row that fades in behind it, and a fact
   strip welded to the bottom edge.

   The strip is `position:absolute` on wide/tall viewports so it can hang off
   the hero without pushing the CTAs down — and switches to `position:static`
   below 760px wide OR 720px tall, which is the fix already proven on Concepts
   A/B/C (the strip's own height GROWS as the viewport narrows, so on a phone
   the absolute version covered both CTAs and clipped the lede). */
#hero{ position:relative; isolation:isolate; overflow:hidden;
  min-height:calc(100svh - 76px); display:flex; align-items:flex-end }
.hero-media-g{ position:absolute; inset:0; z-index:-2 }
.hero-media-g img{ width:100%; height:100%; object-fit:cover; object-position:center 55% }
html.js.gmotion .hero-media-g img{ transform:scale(1.14); transition:transform 2s var(--ease-expo) }
html.js.gmotion.g-loaded .hero-media-g img{ transform:scale(1) }
.hero-scrim-g{ position:absolute; inset:0; z-index:-1; pointer-events:none;
  background:
    linear-gradient(180deg, rgba(7,12,22,.72) 0%, rgba(7,12,22,.34) 34%, rgba(7,12,22,.62) 70%, rgba(7,12,22,.97) 100%),
    linear-gradient(90deg, rgba(7,12,22,.78) 0%, rgba(7,12,22,.20) 62%, rgba(7,12,22,0) 100%) }
.hero-in-g{ position:relative; z-index:2; width:100%;
  padding-block-start:clamp(96px,14vh,150px); padding-block-end:clamp(120px,17vh,180px) }
/* Short-laptop ladder. The headline is sized by min(vw,vh) so it shrinks with
   the viewport's HEIGHT, not just its width — but on a 1366x700 or 1024x700
   laptop that alone was not enough and the CTA row measured ~100px below the
   fold. Measured, not guessed: the fix is a second tier that cuts the
   headline's vh cap and both hero paddings together. */
@media (max-height:860px){
  .hero-in-g{ padding-block-start:clamp(64px,9vh,96px); padding-block-end:clamp(96px,13vh,128px) }
}
.hero-eyebrow-g{ 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-g::before{ content:""; width:34px; height:1px; background:var(--accent) }
.hero-h-g{ color:var(--txt); 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 —
     min(vw,vh) guard, which is load-bearing here and not decoration */
  font-size:clamp(2.6rem, min(12vw,15vh), 8.4rem); line-height:.9; margin:0 }
.hero-h-g .line{ display:block; overflow:hidden; padding-bottom:.03em }
.hero-h-g .line > span{ display:block }
.hero-h-g .b{ color:var(--accent-hi) }
html.js.gmotion:not(.g-busted) .hero-h-g .line > span{ transform:translateY(108%) }
html.js.gmotion.g-loaded .hero-h-g .line > span{ transform:none; transition:transform 1.05s var(--ease-expo) }
html.js.gmotion.g-loaded .hero-h-g .line:nth-child(1) > span{ transition-delay:.06s }
html.js.gmotion.g-loaded .hero-h-g .line:nth-child(2) > span{ transition-delay:.17s }
html.js.gmotion.g-loaded .hero-h-g .line:nth-child(3) > span{ transition-delay:.28s }

.hero-foot-g{ display:flex; align-items:flex-end; justify-content:space-between; gap:26px;
  flex-wrap:wrap; margin-top:clamp(24px,4vh,38px) }
.hero-lede-g{ max-width:48ch; color:var(--txt); font-size:clamp(1rem,1.4vw,1.16rem); line-height:1.65 }
.hero-cta-g{ display:flex; align-items:center; gap:16px; flex-wrap:wrap }
html.js.gmotion:not(.g-busted) .hero-fade{ opacity:0; transform:translateY(24px) }
html.js.gmotion.g-loaded .hero-fade{ opacity:1; transform:none;
  transition:opacity 1s var(--ease) .5s, transform 1s var(--ease) .5s }

.hero-strip-g{ position:absolute; inset-inline:0; inset-block-end:0; z-index:3;
  border-top:1px solid var(--line-2); background:linear-gradient(180deg,transparent,rgba(7,12,22,.72)) }
.hero-strip-g ul{ list-style:none; display:flex; flex-wrap:wrap;
  font-family:var(--mono); font-size:.68rem; letter-spacing:.14em; text-transform:uppercase;
  color:var(--txt-dim) }
.hero-strip-g li{ padding-block:13px; display:inline-flex; align-items:center }
.hero-strip-g li:not(:last-child)::after{ content:""; width:1px; height:11px; background:var(--line);
  margin-inline:clamp(12px,2.6vw,28px) }
.hero-strip-g li b{ color:var(--txt); font-weight:600 }
@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-g{ width:100%; position:static; background:none; border-top:1px solid var(--line-2) }
  #hero{ min-height:0 }
  .hero-in-g{ padding-block-end:clamp(28px,5vh,44px) }
  /* Once the strip wraps, the between-items rule stops being a separator and
     becomes a dangling pipe at the end of every wrapped line — visible in the
     first og capture. Below this tier the items are spaced by gap instead. */
  .hero-strip-g ul{ gap:4px 18px }
  .hero-strip-g li{ padding-block:7px }
  .hero-strip-g li:not(:last-child)::after{ display:none }
}

/* --- hero fit tiers -----------------------------------------------------
   These come LAST in the hero block on purpose. A media query adds no
   specificity, so the same rules written before `.hero-h-g` / `.hero-lede-g`
   were silently outranked by those plain declarations and changed nothing —
   the exact trap the playbook records for inline styles, in its media-query
   form. Written here, they win.

   Both tiers exist because they were MEASURED: before them the CTA row
   finished ~100px below the fold at 1366x700 and 1024x700, and ~38px below at
   375x667. The headline is already capped by min(vw,vh); on a short laptop
   that alone is not enough. */
@media (max-height:800px){
  .hero-in-g{ padding-block-start:clamp(36px,5vh,56px); padding-block-end:clamp(64px,9vh,88px) }
  .hero-h-g{ font-size:clamp(1.9rem, min(9vw,9.5vh), 5rem) }
  .hero-eyebrow-g{ margin-bottom:12px }
  .hero-foot-g{ margin-top:16px }
  .hero-lede-g{ font-size:.98rem; line-height:1.5; max-width:42ch }
}
/* Phones. The house pattern here is to responsive-hide the lede so eyebrow +
   headline + CTA clear the fold — but once the short-viewport tier above was
   applied correctly, the whole block fits at 375x667 with ~90px to spare and
   the lede visible. Measured before deciding: hiding real copy that nothing
   forces you to hide is a cost with no benefit. */
@media (max-width:560px){
  .hero-h-g{ font-size:clamp(1.9rem, min(10.5vw,9vh), 3.2rem) }
  .hero-lede-g{ font-size:.95rem; max-width:none }
}

/* buttons — a solid navy primary (white-text-safe) and a hairline ghost. */
.btn-ghost{ border-color:rgba(255,255,255,.4); color:#fff }

/* ============================================================= 3 · STATEMENT
   A full-width statement slab, set on RANCO's own positioning line from the
   client's supplied website copy: "a trusted Saudi Arabian engineering and
   industrial services company". */
#statement{ padding-block:var(--pad-section-lg) }
.stmt-h{ font-family:var(--display); font-weight:800; text-transform:uppercase;
  letter-spacing:-.035em; line-height:.92; color:var(--txt);
  font-size:clamp(2.4rem,7.6vw,6.4rem); max-width:15ch }
.stmt-h .b{ color:var(--accent-hi) }
.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(--txt); font-size:clamp(1.05rem,1.5vw,1.3rem); line-height:1.68; max-width:54ch }
.stmt-lede b{ font-weight:700 }
.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(--txt-dim) }
.stmt-aside b{ color:var(--txt); font-weight:600 }

/* marquee — RANCO's own seven lines of work plus the standards they publish.
   RANCO has published no fleet brands and no equipment makes, so the strip
   scrolls what they DO rather than what they own. Decorative and aria-hidden:
   every word in it is also real text elsewhere on the page. */
.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:g-marquee 42s linear infinite }
.marquee:hover .marquee-track{ animation-play-state:paused }
.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:var(--txt-faint);
  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(--txt) }
@keyframes g-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 (GSAP ScrollTrigger). 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 is the house filmstrip
   pattern and needs no script at all. Every panel is one of RANCO's OWN
   photographs; there is no stand-in anywhere in this gallery. */
#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-family:var(--display); font-weight:800; text-transform:uppercase;
  letter-spacing:-.03em; line-height:.94; color:var(--txt); font-size:clamp(2.2rem,6vw,4.8rem) }
.fleet-head .fh-note{ max-width:36ch; color:var(--txt-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(255,255,255,.06) }
.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); height:min(62vh,520px);
  scroll-snap-align:center; overflow:hidden; background:var(--ink-3); border:1px solid var(--line-2) }
.h-panel img{ width:100%; height:100%; object-fit:cover }
.h-panel figcaption{ position:absolute; inset-inline:0; inset-block-end:0; padding:18px 20px;
  display:flex; justify-content:space-between; align-items:flex-end; gap:12px;
  background:linear-gradient(180deg,transparent,rgba(7,12,22,.9));
  font-family:var(--mono); font-size:.7rem; letter-spacing:.1em; text-transform:uppercase }
.h-panel figcaption .t{ color:var(--txt) }
.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 (you drag a native scroller, you
   scroll a pinned one), 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(--txt-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. A cross-fade carrying RANCO's own seven lines of
   work, one per screen, type-led — and not a staged "how a move runs" method,
   because RANCO publishes none. No photograph is attached to any of the seven,
   deliberately: RANCO has supplied no rig-move and no crane photograph, and
   four of the seven services have no image at all, so pairing three of them
   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 of seven services — complete, numbered, and readable with no script.
   The pinned mode is added by class from JS, never assumed. */
#services{ padding-block-start:var(--pad-section); padding-block-end:var(--pad-section) }
.svc-head-g{ margin-bottom:clamp(28px,4vw,52px) }
.svc-head-g h2{ font-family:var(--display); font-weight:800; text-transform:uppercase;
  letter-spacing:-.03em; line-height:.94; color:var(--txt); 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-family:var(--display); font-weight:800; text-transform:uppercase;
  letter-spacing:-.03em; line-height:.98; color:var(--txt);
  font-size:clamp(1.9rem,4.6vw,3.6rem); max-width:16ch }
.svc-cell p{ color:var(--txt-dim); font-size:1.02rem; line-height:1.68; max-width:52ch }
.svc-ghost{ display:none }
/* pinned cross-fade mode (desktop only, class added by js/g-immersive.js) */
#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 }
#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:.09 }
@supports (-webkit-text-stroke:1px black){
  #services.is-pinned .svc-ghost{ color:transparent; -webkit-text-stroke:2px var(--accent); opacity:.3 }
}
.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
   Same four facts as every other concept in the set, in a display-numeral
   treatment. The count-up runs on the one value that is genuinely a number.
   There is no "Established" cell: RANCO has never supplied a founding year,
   and Concept A is the demo that argues that gap on purpose — running the
   same device twice in one set would blunt it. */
#stats{ padding-block:clamp(52px,7vh,80px); border-block:1px solid var(--line-2) }
.stats-g{ display:grid; grid-template-columns:1fr 1fr; gap:0 }
@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(--txt); font-size:clamp(2.6rem,6vw,5rem);
  font-variant-numeric:tabular-nums }
.stat-g > b .u{ color:var(--accent-hi) }
.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(--txt-dim) }

/* ========================================================= 7 · CAPABILITIES
   Full-bleed capability bands. Only TWO exist, and only
   because RANCO photographed both of them: the excavator line in their own
   yard, and their own passenger-bus fleet. The other five services are
   covered in the pinned sequence above rather than given a picture that is
   not theirs. */
.capband{ position:relative; isolation:isolate; overflow:hidden;
  min-height:min(88vh,780px); 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(180deg, rgba(7,12,22,.55) 0%, rgba(7,12,22,.18) 38%, rgba(7,12,22,.94) 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-family:var(--display); font-weight:800; text-transform:uppercase;
  letter-spacing:-.035em; line-height:.92; color:var(--txt);
  font-size:clamp(2.2rem,6.6vw,5.4rem); margin:16px 0 clamp(16px,2.4vw,24px); max-width:15ch }
.capband p{ max-width:56ch; color:var(--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) }
.capband ul li{ font-family:var(--mono); font-size:.7rem; letter-spacing:.06em; text-transform:uppercase;
  color:var(--txt); border:1px solid var(--line); padding:9px 13px; background:rgba(7,12,22,.42);
  -webkit-backdrop-filter:blur(4px); backdrop-filter:blur(4px) }
@media (max-width:720px){
  /* glass needs a photo behind it to read as glass, and costs real frames on
     a mid-range Saudi phone — solid tint below 720px, per the playbook */
  .capband ul li{ -webkit-backdrop-filter:none; backdrop-filter:none; background:rgba(7,12,22,.78) }
}
.capband-note{ margin-top:18px; font-family:var(--mono); font-size:.66rem; letter-spacing:.12em;
  text-transform:uppercase; color:var(--txt-dim) }

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

/* ================================================================== 9 · QHSE
   A dimmed-photo band. The photo is RANCO's own toolbox talk, which
   is genuinely on-message for this section, at low opacity behind a scrim. */
#qhse{ position:relative; overflow:hidden; padding-block:var(--pad-section-lg);
  border-top:1px solid var(--line-2) }
.qhse-media{ position:absolute; inset:0; z-index:0; opacity:.2 }
.qhse-media img{ width:100%; height:100%; object-fit:cover }
.qhse-media::after{ content:""; position:absolute; inset:0;
  background:linear-gradient(180deg, rgba(7,12,22,.74), rgba(7,12,22,.95)) }
#qhse .wrap{ position:relative; z-index:1 }
#qhse h2{ font-family:var(--display); font-weight:800; text-transform:uppercase;
  letter-spacing:-.035em; line-height:.94; color:var(--txt);
  font-size:clamp(2.1rem,6.2vw,5rem); margin:18px 0 clamp(24px,3.4vw,38px); max-width:17ch }
#qhse h2 .b{ color:var(--accent-hi) }
.qhse-list{ display:grid; grid-template-columns:1fr; border-top:1px solid var(--line); max-width:960px }
@media (min-width:700px){ .qhse-list{ grid-template-columns:1fr 1fr } }
.qhse-item{ padding-block:clamp(20px,2.6vw,30px); border-bottom:1px solid var(--line-2) }
@media (min-width:700px){
  .qhse-item:nth-child(odd){ padding-inline-end:34px; border-inline-end:1px solid var(--line-2) }
  .qhse-item:nth-child(even){ padding-inline-start:34px }
}
.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:10px; font-weight:600; font-size:clamp(1.05rem,1.7vw,1.32rem);
  color:var(--txt); line-height:1.35 }
.qhse-foot{ margin-top:clamp(26px,3.4vw,36px); max-width:62ch; color:var(--txt-dim);
  font-size:.95rem; line-height:1.65 }

/* =============================================================== 10 · CAREERS */
#careers{ padding-block-start:var(--pad-section); padding-block-end:var(--pad-section) }
#careers h2{ font-family:var(--display); font-weight:800; text-transform:uppercase;
  letter-spacing:-.03em; line-height:.96; color:var(--txt); font-size:clamp(1.9rem,5vw,3.6rem);
  max-width:18ch }
#careers .careers-lead{ color:var(--txt-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-g{ font-family:var(--display); font-weight:800; text-transform:uppercase;
  letter-spacing:-.035em; line-height:.9; color:var(--txt); font-size:clamp(2.6rem,8vw,6.4rem) }
.con-h-g .b{ color:var(--accent-hi) }
.con-intro-g{ color:var(--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(--ink-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(--accent); 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(--txt);
  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(--txt); font-variant-numeric:tabular-nums;
  margin:10px 0 20px; min-height:24px }
.dsp-tel:hover{ color:var(--accent-hi) }
.dsp-mail{ display:inline-block; margin:10px 0 0; color:var(--txt); word-break:break-word;
  min-height:24px }
.dsp-mail:hover{ color:var(--accent-hi) }
.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(--txt); font-size:1rem; line-height:1.55 }

/* ------------------------------------------------------------- reduced motion
   The gate is primarily in JS (`html.gmotion` is never set), which makes the
   preloader display:none and leaves every masked line at its natural
   position. These rules are the belt to that braces: if the class ever gets
   set and the preference changes mid-session, nothing stays hidden. */
@media (prefers-reduced-motion:reduce){
  html.js.gmotion #preloader{ display:none }
  html.js.gmotion .hero-h-g .line > span,
  html.js.gmotion .hero-fade{ opacity:1 !important; transform:none !important; transition:none }
  html.js.gmotion .hero-media-g img{ transform:none !important }
  #services.is-pinned .svc-cell{ transition:none }
}
