/* --------------------------------------------------------------- FONT
   Montserrat is self-hosted as a variable face (400-800 in one file) so the
   critical path holds no third-party request. The LCP element is the hero H1,
   so a render-blocking call to fonts.googleapis.com would gate first paint.
   Same two subsets the group portal ships. */
@font-face{
  font-family:'Montserrat';
  font-style:normal;
  font-weight:400 800;
  font-display:swap;
  src:url('/assets/fonts/montserrat-latin.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;
}
@font-face{
  font-family:'Montserrat';
  font-style:normal;
  font-weight:400 800;
  font-display:swap;
  src:url('/assets/fonts/montserrat-latin-ext.woff2') format('woff2');
  unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,
    U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,
    U+2113,U+2C60-2C7F,U+A720-A7FF;
}

/* ==========================================================================
   Jamaal's Industrial Transport & Construction Services Co. Ltd. — JITCS
   Operating-company site. Surface mode: Qualify.

   The structural system is inherited from the group portal so the two sites
   read as one family: Montserrat only, the fluid rem+vw scale, the 24/14/10/8
   radius set, one shared gutter, the five-step dark ramp, one hairline weight.

   What changes is the accent. The group leads with yellow; Industrial leads
   with orange and holds yellow secondary — the logo's own relationship, the
   orange outer J sitting behind the yellow inner J.
   ========================================================================== */

/* --------------------------------------------------------------- TOKENS */
:root{
  --paper:      #FFFFFF;
  --paper-2:    #F6F6F4;
  --ink:        #101318;
  --ink-2:      #4F555E;   /* 7.5:1 on paper — clears AAA */
  --ink-3:      #686E77;   /* 5.1:1 on paper, 4.75:1 on paper-2 */
  --rule:       #E4E4E0;   /* the hairline. One weight everywhere. */

  /* ACCENT — see the contrast rule below before using either of these. */
  --orange:     #F58309;
  --orange-2:   #D97207;   /* pressed / hover */
  /* The ONE sanctioned way to set orange as TEXT on paper. #F58309 is 2.60:1
     there and #D97207 only reaches 3.34:1 — both fail AA at small sizes. This
     is darkened until it clears 4.5:1 while still reading as the brand orange.
     Use it for small accent labels on light grounds and nothing else; it is
     too dark to work as a field colour. */
  --orange-ink: #B35F00;
  --yellow:     #FDBE06;
  --yellow-2:   #E8AD04;   /* pressed / hover */
  --on-accent:  #101318;   /* the ONLY text colour that clears AA on either */

  /* --------------------------------------------------------------------
     THE CONTRAST RULE — load-bearing, do not drift.

     Measured: #F58309 on #FFFFFF is 2.60:1 and #FDBE06 is worse. Both FAIL
     WCAG AA as text on paper. On --plate #101318, #F58309 measures 7.19:1
     and passes comfortably.

     Therefore:
       · On LIGHT ground both accents are FIELD colours only — button fills,
         badges, rails, seams, hover floods — always carrying --on-accent ink.
       · On DARK ground --orange is a legitimate TEXT colour, and is used for
         kickers, numerals and inline emphasis.
       · --yellow is NEVER a text colour on either ground. Fill, rule and
         brand device only.
     -------------------------------------------------------------------- */

  /* dark surface ramp — five near-blacks held in relation to each other */
  --plate:        #101318;   /* hero veil base, contact band */
  --d-bg-deep:    #0A0C0F;   /* deepest ground */
  --d-bg-foot:    #0B0D10;   /* footer */
  --d-card:       #14171B;   /* panel on dark */
  --d-panel:      #161A1F;   /* enquiry form */
  --d-field:      #0F1216;   /* form input at rest */
  --d-field-focus:#12161A;   /* form input focused */

  /* text on dark. The --ink-* / --d-text-* split is load-bearing: --ink-3 is
     legible on paper and fails on ink; --d-text-3 is the reverse. They are the
     same visual role on opposite grounds, NOT interchangeable. */
  --d-text:     #F4F5F6;
  --d-text-2:   #A2A8B0;
  --d-text-3:   #8C929B;
  --d-text-nav: #C7CCD2;
  --d-rule:     rgba(255,255,255,.16);

  /* Sector identity, shared with the group portal. Used in the footer's group
     strip and in the four-panel deck on About — never as general decoration.
     Each pair is the colour plus the text colour that clears AA on it. */
  --sector-industrial: #F58309;  --sector-industrial-on: #101318;
  --sector-rentals:    #0072E7;  --sector-rentals-on:    #FFFFFF;
  --sector-hardware:   #BC081E;  --sector-hardware-on:   #FFFFFF;
  --sector-realty:     #028139;  --sector-realty-on:     #FFFFFF;

  /* form state */
  --state-err:      #FF6B6B;
  --state-err-text: #FF9C9C;
  --state-ok:       #7BE0A5;
  --d-placeholder:  #7E858E;   /* 5.04:1 on --d-field */

  /* shape */
  --r-lg:  24px;
  --r-md:  14px;
  --r-sm:  10px;
  --r-xs:  8px;

  --gutter: clamp(40px, calc(5vw + 20px), 144px);
  --shell:  1320px;            /* text measure, never a container */
  --gap:    clamp(14px, 1.4vw, 24px);

  --ease:     cubic-bezier(.22,.61,.36,1);
  --header-h: 92px;

  /* fluid type scale — interpolates 360px → 1440px viewport.
     rem + vw, never bare vw: a pure-vw scale breaks browser zoom and user
     font-size preferences. */
  --fs-2xs:   clamp(0.656rem, 0.635rem + 0.09vw, 0.719rem);   /* 10.5 → 11.5 */
  --fs-xs:    clamp(0.719rem, 0.698rem + 0.09vw, 0.781rem);   /* 11.5 → 12.5 */
  --fs-sm:    clamp(0.781rem, 0.760rem + 0.09vw, 0.844rem);   /* 12.5 → 13.5 */
  --fs-base:  clamp(0.875rem, 0.844rem + 0.14vw, 0.969rem);   /* 14   → 15.5 */
  --fs-md:    clamp(0.938rem, 0.896rem + 0.19vw, 1.063rem);   /* 15   → 17   */
  --fs-lg:    clamp(1.031rem, 0.979rem + 0.23vw, 1.188rem);   /* 16.5 → 19   */
  --fs-xl:    clamp(1.188rem, 1.042rem + 0.65vw, 1.625rem);   /* 19   → 26   */
  --fs-2xl:   clamp(1.500rem, 1.292rem + 0.93vw, 2.125rem);   /* 24   → 34   */
  --fs-3xl:   clamp(1.750rem, 1.250rem + 2.22vw, 3.250rem);   /* 28   → 52   */
  --fs-hero:  clamp(2.250rem, 0.972rem + 5.68vw, 6.000rem);   /* 36   → 96   */
}

/* --------------------------------------------------------------- RESET */
*,*::before,*::after{ box-sizing:border-box; }
html{ -webkit-text-size-adjust:100%; scroll-behavior:smooth; }
body{
  margin:0;
  background:var(--paper);
  color:var(--ink);
  font-family:'Montserrat',system-ui,-apple-system,'Segoe UI',sans-serif;
  font-size:1rem;
  line-height:1.68;
  -webkit-font-smoothing:antialiased;
  overflow-x:hidden;
}
img,svg,picture{ max-width:100%; display:block; }
img{ height:auto; }
a{ color:inherit; }
button,input,select,textarea{ font:inherit; color:inherit; }
h1,h2,h3,h4{ margin:0; line-height:1.08; letter-spacing:-.02em; font-weight:800; }
p{ margin:0; }
ul,ol{ margin:0; padding:0; list-style:none; }

/* Visible focus ring on every control. */
:focus-visible{
  outline:2px solid var(--orange);
  outline-offset:3px;
  border-radius:2px;
}
/* On dark grounds the orange ring still clears 7.19:1 against --plate. */

.sr-only{
  position:absolute; width:1px; height:1px; padding:0; margin:-1px;
  overflow:hidden; clip:rect(0 0 0 0); white-space:nowrap; border:0;
}
.skip{
  position:absolute; left:-9999px; top:0; z-index:200;
  background:var(--orange); color:var(--on-accent);
  padding:12px 20px; font-size:var(--fs-sm); font-weight:700;
  border-radius:0 0 var(--r-sm) 0;
}
.skip:focus{ left:0; }

/* --------------------------------------------------------------- LAYOUT
   ONE shared gutter. All left/right padding equal site-wide, at every width
   from 320 to 1920. Full-bleed backgrounds are fine; gutter-aligned content
   is not negotiable. */
.shell{ padding-inline:var(--gutter); }
.section{ padding-block:clamp(56px, 7vw, 120px); }
.section--tight{ padding-block:clamp(40px, 5vw, 76px); }
.measure{ max-width:68ch; }

.band{ background:var(--paper-2); }
.band--dark{ background:var(--plate); color:var(--d-text); }
.band--deep{ background:var(--d-bg-deep); color:var(--d-text); }

/* section head ------------------------------------------------------- */
.head{ display:grid; gap:clamp(12px,1.4vw,20px); margin-bottom:clamp(28px,3.4vw,52px); }
.head--split{
  grid-template-columns:minmax(0,1fr);
}
@media (min-width:920px){
  .head--split{ grid-template-columns:minmax(0,1.05fr) minmax(0,.95fr); align-items:end; column-gap:clamp(32px,4vw,80px); }
}

/* KEEP the uppercase kicker labels above section headlines — explicit,
   repeated client preference, inherited from the group portal. */
.kicker{
  font-size:var(--fs-xs);
  font-weight:700;
  letter-spacing:.2em;
  text-transform:uppercase;
  color:var(--ink-2);
  display:flex; align-items:center; gap:12px;
}
.kicker::before{
  content:''; width:26px; height:3px; flex:none;
  background:var(--orange); border-radius:2px;
}
:is(.band--dark,.band--deep,.hero,.phero,.cta) .kicker{ color:var(--orange); }
:is(.band--dark,.band--deep,.hero,.phero,.cta) .kicker::before{ background:var(--yellow); }

.h-sec{ font-size:var(--fs-3xl); }
.lede{ font-size:var(--fs-md); color:var(--ink-2); }
:is(.band--dark,.band--deep,.hero,.phero,.cta) .lede{ color:var(--d-text-2); }

/* --------------------------------------------------------- SECTION NUMERAL
   A plain number. The offset device — an orange/yellow duplicate translated 5px
   on the diagonal behind the glyph — was retired at the client's request, so the
   numeral (and .offset-word) now stand flat. Ink on paper, --orange on the dark
   bands where orange is a legitimate text colour. (.pillars--cards recasts this
   into the large hollow corner numeral.) */
.numeral{
  display:inline-block;
  font-size:var(--fs-xl); font-weight:800; letter-spacing:-.03em;
  color:var(--ink);
}
:is(.band--dark,.band--deep,.hero,.phero,.cta) .numeral{ color:var(--orange); }

.offset-word{ color:var(--orange); }

/* --------------------------------------------------------------- BUTTONS */
.btn{
  display:inline-flex; align-items:center; justify-content:center; gap:10px;
  padding:14px 26px; min-height:48px;
  font-size:var(--fs-sm); font-weight:700; letter-spacing:.06em;
  text-transform:uppercase; text-decoration:none;
  border:1px solid transparent; border-radius:var(--r-sm);
  cursor:pointer; text-align:center;
  transition:background .28s var(--ease), color .28s var(--ease),
             border-color .28s var(--ease), transform .28s var(--ease);
}
.btn svg{ width:17px; height:17px; flex:none; fill:none; stroke:currentColor; stroke-width:2; }
.btn:hover{ transform:translateY(-2px); }
.btn:active{ transform:translateY(0); }

/* Accent as a FIELD, with ink text — the only AA-safe way to use it. */
.btn--primary{ background:var(--orange); color:var(--on-accent); }
.btn--primary:hover{ background:var(--orange-2); }
.btn--ghost{ background:transparent; color:var(--ink); border-color:var(--rule); }
.btn--ghost:hover{ border-color:var(--ink); background:var(--paper-2); }
:is(.band--dark,.band--deep,.hero,.phero,.cta) .btn--ghost{ color:var(--d-text); border-color:var(--d-rule); }
:is(.band--dark,.band--deep,.hero,.phero,.cta) .btn--ghost:hover{ border-color:var(--d-text); background:rgba(255,255,255,.06); }
.btn--wide{ width:100%; }

/* text link with a nudging arrow */
.tlink{
  display:inline-flex; align-items:center; gap:9px;
  font-size:var(--fs-sm); font-weight:700; letter-spacing:.08em;
  text-transform:uppercase; text-decoration:none; color:var(--ink);
}
.tlink svg{ width:15px; height:15px; fill:none; stroke:currentColor; stroke-width:2.2;
  transition:transform .28s var(--ease); }
.tlink:hover svg{ transform:translateX(4px); }
:is(.band--dark,.band--deep,.hero,.phero,.cta) .tlink{ color:var(--d-text); }

/* --------------------------------------------------------------- HEADER
   Zero-JavaScript navigation. The mobile drawer is a native <details>, the
   desktop services menu opens on :hover and :focus-within. Script only adds
   Escape-to-close and the scrolled state — it is never load-bearing. */
/* The group portal's header behaviour, 1:1: transparent over the hero, then a
   near-white bar with a hairline once you scroll, and the lockup crossfading
   from its on-dark version to its colour-on-light version.

   OPAQUE IS THE CSS DEFAULT and that is deliberate — the inverse of how the
   group wrote it. `js/main.js` only ever ADDS `.is-top`; it never adds the
   opaque state. A page whose script failed therefore keeps a readable white bar
   at every scroll position, instead of leaving pale nav links transparent over
   white content all the way down. */
.hdr{
  position:fixed; top:0; left:0; right:0; z-index:100;
  background:rgba(255,255,255,.94);
  -webkit-backdrop-filter:blur(14px) saturate(150%);
  backdrop-filter:blur(14px) saturate(150%);
  box-shadow:0 1px 0 var(--rule);
  transition:background .35s var(--ease), box-shadow .35s var(--ease);
}
.hdr.is-top{
  background:transparent;
  -webkit-backdrop-filter:none;
  backdrop-filter:none;
  box-shadow:none;
}
/* An open drawer must never sit on a transparent bar — the panel is opaque and
   the strip above it would read as a hole. */
.hdr:has(.drawer[open]){
  background:rgba(255,255,255,.98);
  box-shadow:0 1px 0 var(--rule);
}

/* The header is fixed, so it no longer occupies flow. Every page's first
   section owns the offset instead: .hero and .phero add it to their own
   padding (below), and .nf-band carries it on the 404. */
.nf-band{ padding-top:var(--header-h); }
.hdr__in{
  display:flex; align-items:center; gap:clamp(16px,2.4vw,40px);
  min-height:var(--header-h);
  padding-inline:var(--gutter);
}
/* The lockup crossfades rather than swaps: the on-dark version (white wordmark,
   colour mark) is in flow and sets the size; the colour-on-light version is
   stacked on top of it and fades in with the bar. */
.hdr__logo{ position:relative; display:block; line-height:0; flex:none; text-decoration:none; }
/* 54px flat, matching the group portal's .brand__logo — not a clamp. Both
   lockups share the same 380x144 artboard, so the two headers sit the mark at
   identical size. */
.hdr__logo img{
  height:54px; width:auto;
  transition:opacity .35s var(--ease);
}
.hdr__logo .is-ondark{ opacity:0; }
.hdr__logo .is-onlight{ position:absolute; left:0; top:0; opacity:1; }
.hdr.is-top .hdr__logo .is-ondark{ opacity:1; }
.hdr.is-top .hdr__logo .is-onlight{ opacity:0; }

.hdr__nav{ margin-left:auto; }
.hdr__list{ display:flex; align-items:center; gap:30px; }
.hdr__link{
  position:relative;
  display:inline-flex; align-items:center; gap:7px;
  padding:10px 2px;
  font-size:var(--fs-sm); font-weight:500; letter-spacing:.02em;
  text-decoration:none; color:var(--ink-2);
  transition:color .22s var(--ease);
  white-space:nowrap;
}
.hdr.is-top .hdr__link{ color:var(--d-text-nav); }
.hdr__link:hover{ color:var(--ink); }
.hdr.is-top .hdr__link:hover{ color:var(--d-text); }
.hdr__link[aria-current="page"]{ color:var(--ink); font-weight:700; }
.hdr.is-top .hdr__link[aria-current="page"]{ color:var(--d-text); }

/* The underline wipes in from the left on hover, and stays put for the current
   page. This replaces the accent dot that marked the current page before. */
.hdr__link::after{
  content:''; position:absolute; left:0; right:0; bottom:2px; height:2px;
  background:var(--orange);
  transform:scaleX(0); transform-origin:left;
  transition:transform .28s var(--ease);
}
.hdr__link:hover::after,
.hdr__link[aria-current="page"]::after{ transform:scaleX(1); }
/* Group portal's .nav__cta: a small button, 4px off the nav, held at the 44px
   tap floor. */
.hdr__cta{ flex:none; margin-left:34px; }
.hdr__cta .btn{ padding:10px 20px; min-height:44px; }

/* desktop services menu ---------------------------------------------- */
.menu{ position:relative; }
.menu__panel{
  position:absolute; top:calc(100% + 12px); left:50%; right:auto;
  transform:translateX(-50%) translateY(-6px);
  width:min(640px,92vw);
  padding:12px; border-radius:var(--r-lg);
  background:var(--paper); border:1px solid var(--rule);
  box-shadow:0 32px 72px -16px rgba(16,19,24,.28), 0 10px 24px -12px rgba(16,19,24,.16);
  opacity:0; visibility:hidden; pointer-events:none;
  transition:opacity .22s var(--ease), transform .22s var(--ease), visibility .22s;
}
/* Centred under the Services trigger. It stays on-screen because Services is
   never the rightmost item — the CTA and About/Contact sit to its right, so the
   panel has clearance on both sides at every width the nav is shown. */

/* Invisible bridge over the 12px gap between the trigger and the panel, so the
   pointer moving down from "Services" never leaves the hover region and closes
   the menu. Inherits the panel's pointer-events, so it is live only while open. */
.menu__panel::before{
  content:''; position:absolute; left:0; right:0; top:-16px; height:16px;
}
.menu:hover .menu__panel,
.menu:focus-within .menu__panel{
  opacity:1; visibility:visible; pointer-events:auto;
  transform:translateX(-50%) translateY(0);
}
.menu__grid{ display:grid; grid-template-columns:repeat(2,minmax(0,1fr)); gap:2px; }
.menu__item{
  display:flex; align-items:center; gap:12px;
  padding:11px 13px; border-radius:var(--r-sm);
  text-decoration:none; position:relative;
  transition:background .2s var(--ease);
}
.menu__body{ display:grid; gap:2px; min-width:0; }
.menu__name{
  font-size:var(--fs-sm); font-weight:700; letter-spacing:-.01em;
  color:var(--ink); line-height:1.2;
}
.menu__desc{
  font-size:var(--fs-2xs); color:var(--ink-3); line-height:1.35;
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
}
.menu__arrow{
  flex:none; width:16px; height:16px; margin-left:auto;
  fill:none; stroke:var(--orange); stroke-width:2.4;
  stroke-linecap:round; stroke-linejoin:round;
  opacity:0; transform:translateX(-5px);
  transition:opacity .2s var(--ease), transform .2s var(--ease);
}
.menu__item:hover{ background:var(--paper-2); }
.menu__item:hover .menu__arrow,
.menu__item:focus-visible .menu__arrow{ opacity:1; transform:translateX(0); }

/* footer strip — all-services link and the phone number */
.menu__foot{
  display:flex; align-items:center; justify-content:space-between; gap:16px;
  margin-top:8px; padding:14px 13px 5px;
  border-top:1px solid var(--rule);
}
.menu__all{
  display:inline-flex; align-items:center; gap:8px;
  font-size:var(--fs-xs); font-weight:700; letter-spacing:.08em; text-transform:uppercase;
  color:var(--ink); text-decoration:none; transition:gap .2s var(--ease);
}
.menu__all svg{ width:15px; height:15px; fill:none; stroke:var(--orange); stroke-width:2.4;
  stroke-linecap:round; stroke-linejoin:round; }
.menu__all:hover{ gap:12px; }
.menu__chev{ width:12px; height:12px; fill:none; stroke:currentColor; stroke-width:2.4;
  transition:transform .24s var(--ease); }
.menu:hover .menu__chev,.menu:focus-within .menu__chev{ transform:rotate(180deg); }

/* mobile drawer ------------------------------------------------------- */
.drawer{ display:none; margin-left:auto; }
.drawer__toggle{
  list-style:none; cursor:pointer;
  display:inline-flex; align-items:center; justify-content:center;
  width:46px; height:46px; border-radius:var(--r-sm);
  border:1px solid var(--rule); color:var(--ink);
  transition:border-color .3s var(--ease), color .3s var(--ease);
}
.hdr.is-top .drawer__toggle{ border-color:var(--d-rule); color:var(--d-text); }
.drawer__toggle::-webkit-details-marker{ display:none; }
.drawer__toggle svg{ width:20px; height:20px; fill:none; stroke:currentColor; stroke-width:2; }
.drawer__toggle .x{ display:none; }
.drawer[open] .drawer__toggle .x{ display:block; }
.drawer[open] .drawer__toggle .bars{ display:none; }
/* Off-canvas side sheet. The panel is a full-width scrim starting below the
   header bar (so the X toggle in the bar stays clickable); the sheet slides in
   from the right. It is a descendant of the fixed header (z-index:100), so it
   sits above page content and the group badge without a z-index of its own.

   Zero-JS: the native <details> shows/hides the panel, so the menu still works
   with the sheet appearing in place. .has-js keeps it rendered while closed so
   the slide can animate. */
.drawer__panel{
  position:fixed; left:0; right:0; top:var(--header-h); bottom:0;
  background:rgba(16,19,24,.5);
  opacity:0; visibility:hidden; pointer-events:none;
  transition:opacity .3s var(--ease), visibility .3s var(--ease);
}
.has-js .drawer > .drawer__panel{ display:block; }
.drawer[open] .drawer__panel{ opacity:1; visibility:visible; pointer-events:auto; }
.drawer__sheet{
  position:absolute; top:0; right:0; bottom:0;
  width:min(370px,88vw);
  display:flex; flex-direction:column;
  background:var(--paper); box-shadow:-24px 0 60px rgba(16,19,24,.24);
  padding:12px clamp(20px,6vw,30px) 28px; overflow-y:auto;
  transform:translateX(100%);
  transition:transform .34s var(--ease);
}
.drawer[open] .drawer__sheet{ transform:translateX(0); }

.drawer__link{
  display:block; padding:14px 2px; min-height:48px;
  font-size:var(--fs-md); font-weight:600; color:var(--ink); text-decoration:none;
  border-bottom:1px solid var(--rule);
}
.drawer__link[aria-current="page"]{ color:var(--orange-ink); }

/* Services accordion */
.drawer__acc{ border-bottom:1px solid var(--rule); }
.drawer__accsum{
  list-style:none; cursor:pointer;
  display:flex; align-items:center; justify-content:space-between;
  padding:14px 2px; min-height:48px;
  font-size:var(--fs-md); font-weight:600; color:var(--ink);
}
.drawer__accsum::-webkit-details-marker{ display:none; }
.drawer__chev{
  width:20px; height:20px; flex:none;
  fill:none; stroke:var(--orange); stroke-width:2.4;
  stroke-linecap:round; stroke-linejoin:round;
  transition:transform .28s var(--ease);
}
.drawer__acc[open] .drawer__chev{ transform:rotate(180deg); }
.drawer__sub{ display:flex; flex-direction:column; padding:4px 0 12px; }
.drawer__sublink{
  display:block; padding:11px 2px 11px 15px; min-height:44px;
  font-size:var(--fs-base); color:var(--ink-2); text-decoration:none;
  border-left:2px solid var(--rule); margin-left:2px;
  transition:color .18s var(--ease), border-color .18s var(--ease);
}
.drawer__sublink:hover{ color:var(--ink); border-color:var(--orange); }
.drawer__sublink--all{ font-weight:700; color:var(--ink); }
.drawer__cta{ margin-top:18px; }

@media (max-width:1080px){
  .hdr__nav,.hdr__cta{ display:none; }
  .drawer{ display:block; }
  /* The header stays position:fixed here. It used to be reset to sticky, which
     put it back in flow — so the hero was pushed down by the header height AND
     still added that height to its own top padding. Double offset, and the
     transparent-at-top treatment never appeared below 1080px at all. */
}

/* --------------------------------------------------------------- HERO
   One screen, always. Every vertical value is capped as min(<value>, N svh),
   tuned to be a no-op above ~1050px tall so large displays keep the roomy
   look, with a harder squeeze under max-height:800px. Below ~700px of height
   on a phone the compression needed would leave the headline cramped, so
   those viewports scroll instead.

   IF HERO COPY OR SPACING CHANGES, RE-MEASURE ACROSS THOSE HEIGHTS. */
.hero{
  position:relative; isolation:isolate;
  background:var(--plate); color:var(--d-text);
  display:flex; align-items:center;
  /* The header is fixed and transparent at the top of the page, so the hero
     runs the FULL viewport and the photograph shows through behind the bar.
     The header's height is added to the hero's own top padding instead, which
     keeps the content clear of the nav without reintroducing a solid strip. */
  min-height:min(845px, 100svh);
  padding-top:calc(var(--header-h) + min(clamp(40px,5vw,88px), 7.5svh));
  padding-bottom:min(clamp(40px,5vw,88px), 7.5svh);
  overflow:hidden;
}
.hero__media{ position:absolute; inset:0; z-index:-2; }
.hero__media img{ width:100%; height:100%; object-fit:cover; }
.hero__veil{
  position:absolute; inset:0; z-index:-1;
  background:
    linear-gradient(104deg, rgba(16,19,24,.96) 0%, rgba(16,19,24,.88) 42%, rgba(16,19,24,.62) 100%),
    linear-gradient(0deg, rgba(16,19,24,.9) 0%, rgba(16,19,24,.2) 46%);
}
.hero__in{ width:100%; }
.hero__grid{ display:grid; gap:min(clamp(20px,2.4vw,36px), 3.4svh); max-width:1180px; }
.hero h1{
  font-size:var(--fs-hero); letter-spacing:-.035em; line-height:.98;
  max-width:16ch; text-wrap:balance;
}
.hero__sub{
  font-size:var(--fs-lg); font-weight:600; color:var(--d-text);
  max-width:44ch; line-height:1.4;
}
.hero__lede{ font-size:var(--fs-md); color:var(--d-text-2); max-width:56ch; }
.hero__actions{ display:flex; flex-wrap:wrap; gap:12px; }
/* The hero's stat strip (established / service lines / group companies /
   nationwide) is gone at the client's request. Every figure in it is still on
   the page: the years count-up and the rest sit in the trust band directly
   below, and the group affiliation is in the footer and the group badge. */

/* Short desktop viewports — laptops at 1280x620 through 1440x800. Measured at
   1280x620 the hero ran 699px against 620px, because the 9svh / 3.4svh caps
   above are only generous enough at tall heights. Everything vertical tightens
   here: the headline drops a step, the padding and the grid gap take harder
   caps. Lands ~611px against 620px. */
@media (max-height:800px) and (min-width:900px){
  .hero{
    min-height:100svh;
    padding-top:calc(var(--header-h) + min(clamp(16px,2.4vw,40px), 3.2svh));
    padding-bottom:min(clamp(16px,2.4vw,40px), 3.2svh);
  }
  .hero h1{ font-size:clamp(2rem,4.4vw,3.4rem); }
  .hero__grid{ gap:min(clamp(12px,1.6vw,24px), 2.3svh); }
}

/* Phones. The hero is five elements now — kicker, headline, sub-line, lede,
   buttons — and fits comfortably. No group-tag clearance is needed here either:
   below 900px the badge leaves the corner for the footer band. */
@media (max-width:700px){
  .hero{
    padding-top:calc(var(--header-h) + clamp(28px,6vw,44px));
    padding-bottom:clamp(28px,6vw,44px);
  }
  .hero__grid{ gap:clamp(14px,3vw,20px); }
}

/* Under ~700px of viewport height the compression needed would leave the
   headline genuinely cramped, so these viewports scroll instead. Deliberate. */

/* ------------------------------------------------------- PAGE HERO (inner) */
.phero{
  position:relative; isolation:isolate;
  background:var(--plate); color:var(--d-text);
  /* absorbs the fixed header, same as .hero */
  padding-top:calc(var(--header-h) + clamp(40px,5vw,84px));
  padding-bottom:clamp(44px,5.6vw,92px);
  overflow:hidden;
}
.phero__media{ position:absolute; inset:0; z-index:-2; }
.phero__media img{ width:100%; height:100%; object-fit:cover; }
.phero__veil{
  position:absolute; inset:0; z-index:-1;
  background:linear-gradient(100deg, rgba(16,19,24,.96) 0%, rgba(16,19,24,.9) 50%, rgba(16,19,24,.7) 100%);
}
.phero__grid{ display:grid; gap:clamp(14px,1.8vw,24px); max-width:900px; }
.phero h1{ font-size:var(--fs-3xl); letter-spacing:-.03em; text-wrap:balance; }
.phero__lede{ font-size:var(--fs-md); color:var(--d-text-2); max-width:62ch; }

/* breadcrumb ---------------------------------------------------------- */
.crumb{ font-size:var(--fs-xs); color:var(--d-text-3); }
.crumb ol{ display:flex; flex-wrap:wrap; align-items:center; gap:8px; }
.crumb a{ color:var(--d-text-2); text-decoration:none; }
.crumb a:hover{ color:var(--orange); }
.crumb li+li::before{ content:'/'; margin-right:8px; color:var(--d-text-3); }
.crumb [aria-current]{ color:var(--d-text); }

/* --------------------------------------------------- TRUST / STAT BAND */
.trust{ border-bottom:1px solid var(--rule); }
.trust__stats{
  display:grid; grid-template-columns:repeat(auto-fit,minmax(160px,1fr));
  gap:clamp(20px,2.6vw,40px);
  padding-block:clamp(30px,3.4vw,52px);
}
.trust__stat{ display:grid; gap:4px; }
.trust__stat b{ font-size:var(--fs-2xl); font-weight:800; letter-spacing:-.03em; color:var(--ink); }
.trust__stat span{ font-size:var(--fs-xs); font-weight:600; letter-spacing:.12em;
  text-transform:uppercase; color:var(--ink-3); }

/* ================================================================= CLIENTS
   Ported 1:1 from the group portal, including the per-mark height factors.
   The two logo groups are identical, so translating the track by exactly half
   its width lands group two where group one started — a seamless loop.

   There is no pause/play control: the strip carries no information that is not
   also in the alt text, and the group's build weighed WCAG 2.2.2 against the
   control and dropped it. Hover pauses it. Reduced motion unwraps it into a
   static grid rather than freezing it, because a frozen strip leaves half the
   marks behind overflow.
   ========================================================================== */
.clients{
  padding-block:clamp(54px,6.5vw,84px) clamp(60px,7vw,92px);
  background:var(--paper-2);
  border-top:1px solid var(--rule);
}
.clients__head{ max-width:760px; margin-bottom:clamp(32px,4vw,48px); }
.clients__note{ margin:18px 0 0; font-size:var(--fs-md); color:var(--ink-2); max-width:56ch; }

.marquee{
  position:relative;
  overflow:hidden;
  border-block:1px solid var(--rule);
  background:var(--paper);
  /* one base height for the whole set; each mark scales off it by a factor */
  --logo-h:clamp(72px, 8vw, 120px);
  --logo-cell:clamp(190px, 21vw, 290px);
  --logo-gap:0px;
  mask-image:linear-gradient(90deg, transparent, #000 5%, #000 95%, transparent);
  -webkit-mask-image:linear-gradient(90deg, transparent, #000 5%, #000 95%, transparent);
}
.marquee__track{ display:flex; width:max-content; animation:scroll-x 46s linear infinite; }
.marquee__group{
  display:flex; align-items:center;
  list-style:none; margin:0; padding:0;
  gap:var(--logo-gap); padding-right:var(--logo-gap);
}
@keyframes scroll-x{ from{ transform:translateX(0); } to{ transform:translateX(-50%); } }
.marquee:hover .marquee__track{ animation-play-state:paused; }

.clogo{
  display:grid; place-items:center;
  flex:0 0 var(--logo-cell);
  padding:clamp(22px,2.6vw,34px) clamp(16px,2vw,28px);
  min-height:clamp(128px,15vw,190px);
  border-left:1px solid var(--rule);
}
.clogo__img{
  display:block;
  width:auto; max-width:100%;
  object-fit:contain;
  /* full colour at rest — these are real clients, and greying them to a house
     tone would be a design flourish at their expense */
  opacity:.88;
  transition:opacity .3s var(--ease);
}
.clogo:hover .clogo__img{ opacity:1; }

/* per-mark factors, set so every logo lands near the same sqrt(w*h) */
.clogo__img--sjl{        height:calc(var(--logo-h) * .78); }
.clogo__img--udecott{    height:calc(var(--logo-h) * .38); }
.clogo__img--tpcl{       height:calc(var(--logo-h) * 1);   }
.clogo__img--james{      height:calc(var(--logo-h) * .64); }
.clogo__img--ballantech{ height:calc(var(--logo-h) * .81); }
.clogo__img--colours{    height:calc(var(--logo-h) * .56); }
.clogo__img--abs{        height:calc(var(--logo-h) * .73); }
.clogo__img--epos{       height:calc(var(--logo-h) * .86); }

/* --------------------------------------------------------- SERVICE CARDS
   One component, two tiers, two scales. See DESIGN.md §6.

   The real link lives on the service name; a pseudo-element stretches it over
   the whole card so the entire card is clickable. "Read more" is a visual
   affordance INSIDE that same hit area, never a nested second link — nesting
   an anchor inside a clickable card produces a control screen readers
   announce twice and keyboards tab through twice. */
.cards{ display:grid; gap:var(--gap); }
.cards--t1{ grid-template-columns:repeat(3,minmax(0,1fr)); }

/* Tier 2 rides a SIX-column grid: the first three cards span two columns
   each, the last two span three each. Five cards, no orphan row — and the
   wider bottom pair goes horizontal, so the rhythm change reads as
   intentional rather than as leftovers. */
.cards--t2{ grid-template-columns:repeat(6,minmax(0,1fr)); }
.cards--t2 > *:nth-child(-n+3){ grid-column:span 2; }
.cards--t2 > *:nth-child(n+4){ grid-column:span 3; }

.card{
  position:relative;
  display:flex; flex-direction:column;
  background:var(--paper);
  border:1px solid var(--rule); border-radius:var(--r-md);
  overflow:hidden;
  transition:border-color .3s var(--ease), transform .3s var(--ease),
             box-shadow .3s var(--ease);
}
.card:hover,.card:focus-within{
  border-color:var(--orange);
  transform:translateY(-4px);
  box-shadow:0 18px 44px rgba(16,19,24,.09);
}
.card__media{ position:relative; overflow:hidden; background:var(--paper-2); flex:none; }
.card__media img{
  width:100%; height:100%; object-fit:cover;
  aspect-ratio:16/10;
  transition:transform .5s var(--ease);
}
.card:hover .card__media img{ transform:scale(1.04); }
.card__body{
  display:flex; flex-direction:column; gap:8px; flex:1;
  padding:clamp(16px,1.6vw,24px);
}
.card__n{
  font-size:var(--fs-2xs); font-weight:700; letter-spacing:.18em;
  color:var(--ink-3);
}
/* Explicit weight, not the <b> default. UA `bolder` against this element's own
   700 resolves to 900, which is outside the variable font's 400–800 range — the
   browser then synthesises a faux-bold rather than using a real master. */
.card__n b{ color:var(--ink); font-weight:800; }
.card__t{ font-size:var(--fs-lg); letter-spacing:-.02em; line-height:1.18; }
.card__t a{ text-decoration:none; }
/* the stretched hit area — one tab stop, whole card clickable */
.card__t a::after{ content:''; position:absolute; inset:0; z-index:1; }
.card__d{ font-size:var(--fs-base); color:var(--ink-2); }
.card__more{
  margin-top:auto; padding-top:14px;
  display:inline-flex; align-items:center; gap:9px;
  font-size:var(--fs-xs); font-weight:700; letter-spacing:.1em;
  text-transform:uppercase; color:var(--ink);
}
.card__more svg{ width:14px; height:14px; fill:none; stroke:currentColor; stroke-width:2.4;
  transition:transform .3s var(--ease); }
.card:hover .card__more{ color:var(--orange-2); }
.card:hover .card__more svg{ transform:translateX(4px); }

/* tier 1 sits at the larger step */
.cards--t1 .card__t{ font-size:var(--fs-xl); }
.cards--t1 .card__media img{ aspect-ratio:4/3; }

/* the wide pair goes horizontal above 1100 */
@media (min-width:1101px){
  .cards--t2 > *:nth-child(n+4){ flex-direction:row; }
  .cards--t2 > *:nth-child(n+4) .card__media{ width:40%; }
  .cards--t2 > *:nth-child(n+4) .card__media img{ aspect-ratio:auto; height:100%; min-height:210px; }
}
@media (max-width:1100px){
  .cards--t1{ grid-template-columns:repeat(2,minmax(0,1fr)); }
  .cards--t1 > *:last-child{ grid-column:span 2; }
  .cards--t2{ grid-template-columns:repeat(2,minmax(0,1fr)); }
  .cards--t2 > *:nth-child(-n+3),
  .cards--t2 > *:nth-child(n+4){ grid-column:span 1; }
  .cards--t2 > *:last-child{ grid-column:span 2; }
}
@media (max-width:700px){
  .cards--t1,.cards--t2{ grid-template-columns:minmax(0,1fr); }
  .cards--t1 > *:last-child,
  .cards--t2 > *:last-child,
  .cards--t2 > *:nth-child(-n+3),
  .cards--t2 > *:nth-child(n+4){ grid-column:span 1; }
}

/* --------------------------------------------------------------- PILLARS
   KEEP the section numerals — explicit client preference. */
.pillars{ display:grid; grid-template-columns:repeat(3,minmax(0,1fr)); gap:clamp(20px,2.6vw,44px); }
.pillar{ display:grid; gap:12px; align-content:start;
  padding-top:22px; border-top:2px solid var(--ink); }
.pillar__t{ font-size:var(--fs-lg); }
.pillar__d{ font-size:var(--fs-base); color:var(--ink-2); }
@media (max-width:880px){ .pillars{ grid-template-columns:minmax(0,1fr); } }

/* Boxed variant. White cards on a --paper-2 band: hairline + soft shadow to
   lift them, a short orange marker at the top, and a large HOLLOW numeral
   bleeding out of the top-right corner. The numeral here is a distinct
   treatment from the .numeral signature — outline, not the offset duplicate —
   so it does not dilute that mark. overflow:hidden is what clips the glyph to
   the card edge. */
.pillars--cards .pillar{
  position:relative; overflow:hidden; gap:16px;
  padding:clamp(26px,2.4vw,40px);
  background:var(--paper);
  border:1px solid var(--rule);
  border-radius:18px;
  box-shadow:0 1px 2px rgba(16,19,24,.04), 0 18px 40px rgba(16,19,24,.06);
}
/* the orange marker — a fill, never text, so no contrast concern */
.pillars--cards .pillar::before{
  content:''; width:34px; height:5px; border-radius:3px;
  background:var(--orange);
}
/* content sits above the ghost numeral */
.pillars--cards .pillar::before,
.pillars--cards .pillar__t,
.pillars--cards .pillar__d{ position:relative; z-index:1; }
/* re-cast the inline numeral into the big corner outline */
.pillars--cards .numeral{
  position:absolute; top:-6px; right:12px; z-index:0;
  isolation:auto; pointer-events:none;
  font-size:clamp(88px,9vw,136px); line-height:1; letter-spacing:-.04em;
  color:transparent;
  -webkit-text-stroke:1.6px var(--rule);
}
.pillars--cards .numeral::before{ content:none; }

/* ------------------------------------------------------------ ABOUT SPLIT
   Carries the two devices inherited from the group portal: the CHAMFER (a 45°
   corner cut, from the J mark's own cut) and the SEAM (a 6px accent bar down
   the photograph's left edge — the lockup's vertical rule, which divides the
   J from the wordmark). Both live here and only here. */
.split{ display:grid; gap:clamp(28px,4vw,72px); align-items:center; }
@media (min-width:920px){ .split{ grid-template-columns:minmax(0,.9fr) minmax(0,1.1fr); } }
.split--flip .split__media{ order:2; }
.portrait{
  position:relative; margin:0;
  border-radius:var(--r-lg);
  overflow:hidden;
  clip-path:polygon(0 0, calc(100% - 56px) 0, 100% 56px, 100% 100%, 0 100%);
}
.portrait img{ width:100%; height:auto; }
.portrait::after{
  content:''; position:absolute; left:0; top:0; bottom:0; width:6px;
  background:var(--orange);
}
/* Named portrait — a person, credited. The chamfer and the seam live on the
   FRAME rather than the figure, so the caption below sits outside the clip-path
   instead of being cut off by it. */
.nportrait{ margin:0; display:grid; gap:clamp(14px,1.6vw,20px); }
.nportrait__frame{
  position:relative; display:block;
  border-radius:var(--r-lg);
  overflow:hidden;
  clip-path:polygon(0 0, calc(100% - 56px) 0, 100% 56px, 100% 100%, 0 100%);
}
.nportrait__frame img{ width:100%; height:auto; display:block; }
.nportrait__frame::after{
  content:''; position:absolute; left:0; top:0; bottom:0; width:6px;
  background:var(--orange);
}
.nportrait__cap{ display:grid; gap:4px; }
.nportrait__name{
  font-size:var(--fs-lg); font-weight:800; letter-spacing:-.02em;
  color:var(--ink); line-height:1.15;
}
/* The role reads as brand orange. On paper that is --orange-ink (#B35F00,
   4.61:1) — the one sanctioned on-light exception; pure --orange is 2.6:1 and
   would fail. The dark-band override below can use --orange directly. */
.nportrait__role{
  font-size:var(--fs-xs); font-weight:700; letter-spacing:.14em;
  text-transform:uppercase; color:var(--orange-ink);
}
/* On the dark bands the caption follows the ground, and --orange is a
   legitimate text colour there (7.19:1) where it would fail on paper. */
:is(.band--dark,.band--deep,.hero,.phero,.cta) .nportrait__name{ color:var(--d-text); }
:is(.band--dark,.band--deep,.hero,.phero,.cta) .nportrait__role{ color:var(--orange); }

.split__body{ display:grid; gap:clamp(14px,1.6vw,22px); align-content:start; }
.split__body p{ font-size:var(--fs-md); color:var(--ink-2); }
:is(.band--dark,.band--deep,.hero,.phero,.cta) .split__body p{ color:var(--d-text-2); }

/* ------------------------------------------------------------ PROOF GRID */
/* Archive grid — all eight services in a uniform three-up that reflows to two,
   then one. Tier 1 still leads because SERVICES is ordered that way. */
.cards--all{ grid-template-columns:repeat(3,minmax(0,1fr)); }
@media (max-width:1100px){ .cards--all{ grid-template-columns:repeat(2,minmax(0,1fr)); } }
@media (max-width:640px){ .cards--all{ grid-template-columns:minmax(0,1fr); } }

/* ---------------------------------------------------------------- SLIDER
   Home services carousel. The track is a native horizontal scroller — snap +
   momentum, draggable on touch, keyboard-scrollable — so it works with no
   script. main.js adds the arrows and mouse-drag, and reveals .slider__nav only
   after it takes over (display:none until .has-js), so no control is ever dead.
   Cards keep their own width via flex-basis rather than a grid track. */
.slider__track{
  display:flex; gap:var(--gap);
  overflow-x:auto; scroll-snap-type:x mandatory; scroll-behavior:smooth;
  scrollbar-width:none;                 /* Firefox */
  padding:8px 0 30px;                   /* room so the card hover-lift and shadow are not clipped */
  -webkit-overflow-scrolling:touch;
}
.slider__track::-webkit-scrollbar{ display:none; }   /* WebKit */
.slider__track > .card{
  flex:0 0 calc((100% - var(--gap) * 2) / 3);
  scroll-snap-align:start;
}
/* while a mouse drag is in progress, snap and clicks are suspended */
.slider.is-dragging .slider__track{ scroll-snap-type:none; scroll-behavior:auto; cursor:grabbing; }
.slider.is-dragging .slider__track *{ pointer-events:none; }
.has-js .slider__track{ cursor:grab; }

/* Controls row directly under the cards: the "view all" button on the left,
   the arrows on the right. Keeps the button close to the slider instead of
   stranding it below a tall gap. */
.slider__foot{
  display:flex; align-items:center; justify-content:space-between;
  gap:16px 20px; flex-wrap:wrap;
  margin-top:clamp(16px,1.8vw,24px);
}
.slider__nav{ display:none; }
.has-js .slider__nav{ display:flex; gap:10px; }
.slider__arrow{
  width:48px; height:48px; flex:none; display:grid; place-items:center;
  border:1px solid var(--rule); border-radius:50%;
  background:var(--paper); color:var(--ink); cursor:pointer;
  transition:border-color .24s var(--ease), background .24s var(--ease),
             color .24s var(--ease), opacity .24s var(--ease);
}
.slider__arrow svg{ width:20px; height:20px; fill:none; stroke:currentColor;
  stroke-width:2.2; stroke-linecap:round; stroke-linejoin:round; }
.slider__arrow:hover{ border-color:var(--orange); background:var(--orange); color:var(--on-accent); }
.slider__arrow:disabled{ opacity:.32; cursor:default; }
.slider__arrow:disabled:hover{ border-color:var(--rule); background:var(--paper); color:var(--ink); }
/* The view-all button floods orange on hover — accent as a FIELD with ink text,
   the AA-safe way (orange text on white is 2.6:1). */
.slider__all{ margin:0; }
.slider__all:hover,
.slider__all:focus-visible{
  background:var(--orange); border-color:var(--orange); color:var(--on-accent);
}

@media (max-width:1100px){
  .slider__track > .card{ flex-basis:calc((100% - var(--gap)) / 2); }
}
@media (max-width:700px){
  .slider__track > .card{ flex-basis:86%; }   /* the next card peeks, signalling a swipe */
}

/* ---------------------------------------------------------------- LIGHTBOX
   Built entirely in main.js (created on first use). With JS off, a.lb is just a
   link to the full-size image, so the tiles still open. */
.proof .lb{ display:block; cursor:zoom-in; }
.lightbox{
  position:fixed; inset:0; z-index:200;
  display:grid; place-items:center; padding:clamp(16px,4vw,56px);
  background:rgba(16,19,24,.86); -webkit-backdrop-filter:blur(2px); backdrop-filter:blur(2px);
  opacity:0; visibility:hidden;
  transition:opacity .28s var(--ease), visibility .28s;
}
.lightbox.is-open{ opacity:1; visibility:visible; }
.lightbox__img{
  max-width:100%; max-height:82vh; display:block;
  border-radius:var(--r-md); box-shadow:0 30px 80px rgba(0,0,0,.5);
  transform:scale(.98); transition:transform .28s var(--ease);
}
.lightbox.is-open .lightbox__img{ transform:scale(1); }
.lightbox__close{
  position:absolute; top:clamp(12px,2vw,22px); right:clamp(12px,2vw,22px);
  width:46px; height:46px; display:grid; place-items:center;
  border:1px solid rgba(255,255,255,.28); border-radius:50%;
  background:rgba(16,19,24,.4); color:#fff; cursor:pointer;
  transition:background .2s var(--ease), border-color .2s var(--ease);
}
.lightbox__close:hover{ background:rgba(255,255,255,.15); border-color:rgba(255,255,255,.55); }
.lightbox__close svg{ width:22px; height:22px; fill:none; stroke:currentColor; stroke-width:2.2; }
.lightbox__cap{
  position:absolute; left:0; right:0; bottom:clamp(12px,3vw,26px);
  text-align:center; color:var(--d-text-2); font-size:var(--fs-xs); padding:0 20px;
}

.proof{ display:grid; grid-template-columns:repeat(4,minmax(0,1fr)); gap:var(--gap); }
.proof figure{ margin:0; position:relative; border-radius:var(--r-md); overflow:hidden; }
.proof img{ width:100%; height:100%; object-fit:cover; aspect-ratio:4/3;
  transition:transform .55s var(--ease); }
.proof figure:hover img{ transform:scale(1.05); }
/* Four equal tiles in a row. The old composition gave the first tile a 2x2
   span, which only resolved cleanly with five; at four it left a hole in the
   grid. See the note in build.mjs on why the fifth tile went. */
@media (max-width:900px){
  .proof{ grid-template-columns:repeat(2,minmax(0,1fr)); }
}
@media (max-width:560px){
  .proof{ grid-template-columns:minmax(0,1fr); }
}

/* ------------------------------------------------------ COVERS / INCLUDED */
.covers{ display:grid; gap:clamp(24px,3vw,56px); }
@media (min-width:920px){ .covers{ grid-template-columns:minmax(0,1fr) minmax(0,1fr); } }
.ilist{ display:grid; gap:2px; }
.ilist li{
  display:grid; grid-template-columns:24px minmax(0,1fr); gap:12px; align-items:start;
  padding:13px 0; border-bottom:1px solid var(--rule);
  font-size:var(--fs-base); color:var(--ink-2);
}
.ilist li:first-child{ border-top:1px solid var(--rule); }
.ilist svg{ width:18px; height:18px; margin-top:3px; fill:none;
  stroke:var(--orange-2); stroke-width:2.6; }

/* --------------------------------------------------------------- PROCESS */
.steps{ display:grid; grid-template-columns:repeat(4,minmax(0,1fr)); gap:var(--gap); }
.step{
  display:grid; gap:10px; align-content:start;
  padding:clamp(18px,2vw,28px);
  background:var(--paper); border:1px solid var(--rule); border-radius:var(--r-md);
}
:is(.band--dark,.band--deep,.hero,.phero,.cta) .step{ background:var(--d-card); border-color:var(--d-rule); }
.step__t{ font-size:var(--fs-md); }
.step__d{ font-size:var(--fs-base); color:var(--ink-2); }
:is(.band--dark,.band--deep,.hero,.phero,.cta) .step__d{ color:var(--d-text-2); }
@media (max-width:980px){ .steps{ grid-template-columns:repeat(2,minmax(0,1fr)); } }
@media (max-width:560px){ .steps{ grid-template-columns:minmax(0,1fr); } }

/* --------------------------------------------------------------- FAQ
   Native <details>. No JavaScript, by design. */
.faq{ display:grid; }
.faq details{ border-bottom:1px solid var(--rule); }
.faq details:first-of-type{ border-top:1px solid var(--rule); }
.faq summary{
  list-style:none; cursor:pointer;
  display:flex; align-items:center; justify-content:space-between; gap:20px;
  padding:20px 0; min-height:44px;
  font-size:var(--fs-md); font-weight:700; letter-spacing:-.01em;
}
.faq summary::-webkit-details-marker{ display:none; }
.faq summary::after{
  content:''; flex:none; width:13px; height:13px;
  border-right:2.4px solid var(--orange-2); border-bottom:2.4px solid var(--orange-2);
  transform:rotate(45deg) translateY(-3px);
  transition:transform .3s var(--ease);
}
.faq details[open] summary::after{ transform:rotate(-135deg) translateY(-3px); }
.faq__a{ padding:0 0 22px; font-size:var(--fs-base); color:var(--ink-2); max-width:74ch; }

/* --------------------------------------------------------------- CONTACT */
.contact{ display:grid; gap:clamp(28px,4vw,64px); align-items:start; }
@media (min-width:980px){ .contact{ grid-template-columns:minmax(0,.85fr) minmax(0,1.15fr); } }
/* Labelled rows, ported from the group portal's contact block so the two sites
   present the same information the same way: icon, small-caps label, value,
   hairline between. */
.cdetails{ margin:0; align-content:start; border-top:1px solid var(--d-rule); }
.cdetails > div{
  display:grid;
  /* wide enough first column that each label keeps its icon on one line */
  grid-template-columns:minmax(132px,auto) minmax(0,1fr);
  gap:20px;
  padding:16px 0;
  border-bottom:1px solid var(--d-rule);
}
.cdetails dt{
  display:flex; align-items:center; gap:9px;
  font-size:var(--fs-2xs); font-weight:700; letter-spacing:.16em; text-transform:uppercase;
  color:var(--d-text-3);
  padding-top:3px;
}
.cdetails dd{
  margin:0;
  font-size:var(--fs-base); font-weight:500;
  color:var(--d-text);
  word-break:break-word;
}
.cdetails address{ font-style:normal; }
.cdetails a{ text-decoration:none; transition:color .2s var(--ease); }
.cdetails a:hover{ color:var(--orange); }
.cdetails small{ display:block; font-size:var(--fs-xs); color:var(--d-text-3); margin-top:4px; }

/* One stroke weight across every icon on the site. Stroke follows currentColor
   so an icon picks up whatever state its link is in — except in the contact
   rows, where the icons carry the accent instead of the label colour. */
.ico{
  width:15px; height:15px; flex:0 0 15px;
  fill:none; stroke:currentColor; stroke-width:2;
  stroke-linecap:round; stroke-linejoin:round;
}
.cdetails .ico{ stroke:var(--orange); }

/* Under ~560px the two columns leave the value about 120px of measure, which
   breaks the email address across three lines. Stack instead. */
@media (max-width:560px){
  .cdetails > div{ grid-template-columns:minmax(0,1fr); gap:7px; }
  .cdetails dt{ padding-top:0; }
}

/* form ---------------------------------------------------------------- */
.cform{
  background:var(--d-panel); border:1px solid var(--d-rule);
  border-radius:var(--r-md); padding:clamp(20px,2.6vw,38px);
  display:grid; gap:16px;
}
.cform__title{ font-size:var(--fs-xl); font-weight:800; letter-spacing:-.02em; }
.cform__row{ display:grid; gap:16px; }
@media (min-width:620px){ .cform__row{ grid-template-columns:repeat(2,minmax(0,1fr)); } }
.field{ display:grid; gap:7px; }
.field label{ font-size:var(--fs-xs); font-weight:700; letter-spacing:.1em;
  text-transform:uppercase; color:var(--d-text-2); }
/* Only the telephone field is optional; naming it is quieter than starring the
   four required ones and tells sighted users the same thing the `required`
   attribute already tells assistive tech. */
.field__opt{ font-weight:400; text-transform:none; letter-spacing:0;
  color:var(--d-text-3); }
.field input,.field select,.field textarea{
  width:100%; padding:13px 15px; min-height:48px;
  background:var(--d-field); color:var(--d-text);
  border:1px solid var(--d-rule); border-radius:var(--r-sm);
  font-size:var(--fs-base);
  transition:border-color .24s var(--ease), background .24s var(--ease);
}
.field textarea{ min-height:132px; resize:vertical; }
.field input::placeholder,.field textarea::placeholder{ color:var(--d-placeholder); }
.field input:focus,.field select:focus,.field textarea:focus{
  background:var(--d-field-focus); border-color:var(--orange); outline-offset:1px;
}
.field.is-invalid input,.field.is-invalid select,.field.is-invalid textarea{ border-color:var(--state-err); }
.field__err{ font-size:var(--fs-xs); color:var(--state-err-text); min-height:0; }
.field:not(.is-invalid) .field__err{ display:none; }

/* Honeypot: bots fill it, people never see it. It keeps a real label and drops
   aria-hidden, because aria-hidden must never wrap a focusable control;
   tabindex="-1" plus the off-screen position is what keeps it from visitors. */
.cform__honey{
  position:absolute !important; left:-9999px !important;
  width:1px; height:1px; overflow:hidden;
}
.cform__status{ font-size:var(--fs-base); color:var(--d-text-2); }
.cform__status.is-ok{ color:var(--state-ok); }
.cform__status.is-err{ color:var(--state-err-text); }
.cform__submit{ justify-self:start; }

/* --------------------------------------------------------------- CTA BAND */
.cta{ background:var(--d-bg-deep); color:var(--d-text); }
.cta__in{
  display:grid; gap:clamp(18px,2.4vw,36px); align-items:center;
  padding-block:clamp(44px,5vw,84px);
}
@media (min-width:900px){ .cta__in{ grid-template-columns:minmax(0,1fr) auto; } }
.cta h2{ font-size:var(--fs-2xl); text-wrap:balance; }
.cta p{ font-size:var(--fs-md); color:var(--d-text-2); margin-top:10px; max-width:56ch; }
.cta__actions{ display:flex; flex-wrap:wrap; gap:12px; }

/* ============================================================== THE DECK
   The group portal's four-company panel, ported 1:1 so the two sites present
   the group identically. Used once, on About.

   Each panel sets --accent and --on-accent inline from the sector pair. When a
   sector colour is used as TEXT on the dark card, it is lightened with
   color-mix — the raw colours run 2.7–3.9:1 there and fail AA.
   ========================================================================== */
.deck{
  position:relative;
  display:grid;
  grid-template-columns:repeat(4,minmax(0,1fr));
  gap:clamp(12px,1.4vw,20px);
  /* room above so the numbered rail clears the cards entirely */
  padding-top:96px;
  align-items:stretch;
}
.deck__rail{
  /* runs the full viewport width, not just the content column, so the numbers
     sit on a continuous line with no indent at either end */
  position:absolute; top:40px;
  left:calc(var(--gutter) * -1);
  right:calc(var(--gutter) * -1);
  height:1px;
  background:linear-gradient(90deg, var(--sector-industrial), var(--sector-rentals),
    var(--sector-hardware), var(--sector-realty));
  opacity:.6;
}

.cpanel{
  position:relative;
  min-width:0;
  display:flex; flex-direction:column;
  border-radius:var(--r-lg);
  background:var(--d-card);
  overflow:visible;
  border:1px solid rgba(255,255,255,.09);
  transition:border-color .4s var(--ease), transform .4s var(--ease), box-shadow .4s var(--ease);
}
.cpanel:hover{
  transform:translateY(-5px);
  border-color:rgba(255,255,255,.2);
  box-shadow:0 26px 56px rgba(0,0,0,.46);
}
.cpanel__badge{
  position:absolute; z-index:4;
  top:-56px; left:50%;
  transform:translate(-50%,-50%);
  display:grid; place-items:center;
  width:52px; height:52px;
  border-radius:50%;
  background:var(--accent);
  /* white failed on the orange panel (2.58:1); --on-accent carries the right
     text colour for each sector and is set inline per panel */
  color:var(--on-accent,#fff);
  font-size:var(--fs-sm); font-weight:800; letter-spacing:.02em;
  box-shadow:0 0 0 6px var(--d-bg-deep), 0 0 0 8px color-mix(in srgb, var(--accent) 42%, transparent);
  pointer-events:none;
}
.cpanel__open{
  display:flex; flex-direction:column; flex:1;
  border-radius:inherit; overflow:hidden;
}
.cpanel__media{ position:relative; flex:0 0 auto; aspect-ratio:4/3; overflow:hidden; }
.cpanel__media img{ width:100%; height:100%; object-fit:cover; }
.cpanel__body{
  flex:1;
  display:flex; flex-direction:column; align-items:flex-start;
  padding:clamp(20px,1.6vw,26px);
  min-width:0;
}
.cpanel__logo{ height:clamp(39px,calc(2.6vw + 5px),47px); width:auto; margin-bottom:clamp(12px,1.2vw,15px); }
.cpanel__eyebrow{
  margin:0 0 clamp(9px,1vw,12px);
  font-size:var(--fs-2xs); font-weight:700; letter-spacing:.18em; text-transform:uppercase;
  color:var(--accent);
  color:color-mix(in srgb, var(--accent) 62%, #FFFFFF);
}
.cpanel__title{
  font-size:var(--fs-xl);
  font-weight:800; line-height:1.2; letter-spacing:-.02em;
  color:var(--d-text);
  margin-bottom:clamp(9px,1vw,12px);
  text-wrap:balance;
}
.cpanel__desc{
  margin:0 0 clamp(16px,1.8vw,22px);
  font-size:var(--fs-sm); line-height:1.55;
  color:var(--d-text-2);
}
.cpanel__cta{
  display:inline-flex; align-items:center; gap:14px;
  margin-top:auto;
  padding:5px 5px 5px 19px;
  border-radius:999px;
  background:transparent;
  border:1.5px solid color-mix(in srgb, var(--accent) 55%, transparent);
  color:var(--d-text);
  font-size:var(--fs-sm); font-weight:700; letter-spacing:-.005em;
  text-decoration:none;
  transition:background .28s var(--ease), border-color .28s var(--ease),
             color .28s var(--ease), transform .28s var(--ease);
}
.cpanel__cta:hover{
  background:var(--accent);
  border-color:var(--accent);
  color:var(--on-accent,#fff);
  transform:translateY(-2px);
}
.cpanel__arrow{
  display:grid; place-items:center;
  width:32px; height:32px;
  border-radius:50%;
  background:var(--accent);
  transition:background .28s var(--ease), transform .28s var(--ease);
}
.cpanel__cta:hover .cpanel__arrow{ background:rgba(255,255,255,.94); transform:rotate(45deg); }
.cpanel__arrow svg{
  width:14px; height:14px;
  fill:none; stroke:var(--on-accent,#fff); stroke-width:2.6;
  stroke-linecap:round; stroke-linejoin:round;
  transition:stroke .28s var(--ease);
}
.cpanel__cta:hover .cpanel__arrow svg{ stroke:var(--accent); }
/* This panel is the site you are already on, so it carries no outbound link. */
.cpanel__here{
  margin-top:auto;
  font-size:var(--fs-xs); font-weight:700; letter-spacing:.14em; text-transform:uppercase;
  color:color-mix(in srgb, var(--accent) 62%, #FFFFFF);
}

/* Between the 4-column break and ~1700 the columns sit near 265px, where the
   Industrial legal name ran to five lines against Realty's two. */
@media (min-width:1101px) and (max-width:1700px){
  .cpanel__title{ font-size:var(--fs-lg); }
  .cpanel__logo{ height:clamp(35px,2.4vw + 4px,42px); }
}
@media (max-width:1100px){
  .deck{ grid-template-columns:repeat(2,minmax(0,1fr)); row-gap:clamp(58px,7vw,76px); }
}
@media (max-width:680px){
  .deck{ grid-template-columns:minmax(0,1fr); }
}

/* ========================================================== THE GROUP TAG
   A stacked tile: the group lockup, a hairline, and the label beneath it.

   A FLOATING pill, clear of the corner on both axes — fully rounded, full
   border, an even shadow. It is not corner-anchored, so it lifts on hover the
   way every other card on the site does.

   At rest it shows the lockup alone; the rule and the label open on hover or
   keyboard focus. The pill is anchored by `bottom`, so that extra height grows
   UPWARD on its own and can never push itself off the bottom of the screen.

   On touch there is no hover to open it with — that case is not left broken,
   it is handled by the footer band further down. */
.gtag{
  position:fixed; z-index:90;
  right:clamp(12px,1.6vw,26px);
  bottom:clamp(12px,1.6vw,26px);
  display:inline-grid; justify-items:center; gap:0;
  padding:12px 18px;
  border-radius:14px;
  /* The white ground is load-bearing, not decoration. The badge is fixed over a
     page that is ~70% light and ~30% dark, so with no ground of its own the
     lockup inherits whatever it happens to float over: the #14181E wordmark
     measures 17.8:1 on paper but 1.04:1 on the hero and 1.09:1 on the footer,
     and the yellow mark inverts the problem at 1.67:1 on white. No single
     lockup variant survives both. Removing this makes the badge invisible on
     roughly a third of the page. */
  /* OPAQUE, not rgba(...,.96). At 4% translucency the pill picked up whatever
     was behind it: over the dark hero it composited to rgb(246,246,246) and the
     9px label fell from 4.61:1 to 4.27:1, under the AA threshold. An opaque
     ground makes the label's contrast a constant. The backdrop-filter went with
     it — it renders nothing behind an opaque fill and only costs a layer. */
  background:var(--paper);
  border:1px solid var(--rule);
  box-shadow:0 1px 2px rgba(16,19,24,.06), 0 14px 38px rgba(16,19,24,.16);
  text-decoration:none; white-space:nowrap;
  transition:border-color .28s var(--ease), transform .28s var(--ease),
             box-shadow .28s var(--ease);
}
.gtag:hover,
.gtag:focus-visible{
  border-color:var(--orange);
  transform:translateY(-2px);
  box-shadow:0 2px 4px rgba(16,19,24,.07), 0 20px 46px rgba(16,19,24,.22);
}

.gtag__logo{ display:grid; place-items:center; }
.gtag__logo img{ height:36px; width:auto; display:block; }
/* Two lockups — colour-on-light for the badge, colour-on-dark for the footer
   band. Both carry alt="", so hiding one costs nothing semantically. */
.gtag__logo .on-dark{ display:none; }

/* ONE element, ONE axis. The pill's width is fixed by the label at every state,
   so hover only opens the height — nothing moves sideways.

   The previous version animated `max-width` and `max-height` together, on two
   separate siblings. It read as a glitch for two reasons: expanding on both
   axes at once is inherently a compound motion, and `max-width` ran 0→240px
   against a real label width of ~138px, so the width finished at roughly 58%
   of the duration while the height carried on. Right, then under.

   Collapsed with max-height, NOT display:none, so the label stays in the
   accessibility tree and the link keeps its accessible name unhovered. */
.gtag__reveal{
  display:grid; justify-items:center; width:100%;
  max-height:0; opacity:0; padding-bottom:0; overflow:hidden;
  transition:max-height .34s var(--ease), padding-bottom .34s var(--ease),
             opacity .24s var(--ease);
}
/* 36px against 33px of real content. Overshooting the target — 40px was the
   first attempt — makes the easing curve finish while the box is still
   nominally growing, so the motion appears to stall before it ends. Keep this
   just above the content height, never comfortably above it. */
.gtag:hover .gtag__reveal,
.gtag:focus-visible .gtag__reveal{ max-height:36px; opacity:1; padding-bottom:11px; }

/* The rule sits BELOW the label, separating it from the lockup underneath. */
.gtag__sep{ height:1px; width:100%; background:var(--rule); margin-top:10px; }
.gtag__t{
  display:flex; align-items:center; gap:6px;
  font-size:.5rem; font-weight:800; letter-spacing:.11em; text-transform:uppercase;
  /* --orange-ink, not --orange: small text on paper. See the token. */
  color:var(--orange-ink); line-height:1;
}
.gtag__go{
  width:11px; height:11px; flex:none;
  fill:none; stroke:currentColor; stroke-width:2.6;
  stroke-linecap:round; stroke-linejoin:round;
  transition:transform .28s var(--ease);
}
.gtag:hover .gtag__go,
.gtag:focus-visible .gtag__go{ transform:translate(2px,-2px); }

/* ------------------------------------------------------- the footer band
   On a device without hover — or a viewport too narrow for a corner tile — the
   same element leaves the corner and becomes a full-width band above the
   footer, laid out as a row on the footer's own dark ground.

   The width clause matters as much as the hover one here: the tile runs ~175px,
   which is nearly half a 375px screen to give up permanently. One element
   either way; no duplicate markup. */
/* When the footer scrolls into view, the floating pill docks out of sight
   instead of overlapping it — the footer already carries the group links.
   main.js toggles .is-docked. Scoped to the fixed-pill context only; the
   footer-band form below is in normal flow and stays put. */
@media (hover:hover) and (min-width:901px){
  .gtag{
    transition:border-color .28s var(--ease), transform .28s var(--ease),
               box-shadow .28s var(--ease), opacity .3s var(--ease), visibility .3s var(--ease);
  }
  .gtag.is-docked{ opacity:0; visibility:hidden; pointer-events:none; transform:translateY(18px); }
}

@media (hover:none), (max-width:900px){
  .gtag{
    position:static;
    display:flex; align-items:center; justify-content:center; gap:0;
    width:100%;
    padding:20px var(--gutter);
    background:var(--d-bg-foot);
    -webkit-backdrop-filter:none; backdrop-filter:none;
    border:0; border-top:1px solid var(--d-rule);
    border-radius:0;
    box-shadow:none;
  }
  .gtag__logo .on-light{ display:none; }
  .gtag__logo .on-dark{ display:block; }
  .gtag__logo img{ height:42px; }
  /* Forced open and laid out as a row — there is no hover here to open it. */
  .gtag__reveal{
    display:flex; align-items:center; width:auto;
    max-height:none; opacity:1; padding-bottom:0; overflow:visible;
  }
  .gtag__sep{
    width:1px; height:auto; align-self:stretch; margin:0 18px;
    background:var(--d-rule);
  }
  .gtag__t{ color:var(--orange); font-size:.625rem; }
  .gtag:hover,.gtag:focus-visible{ border-color:var(--d-rule); transform:none; }
  .gtag:hover .gtag__t{ color:var(--yellow-2); }
}
@media (max-width:520px){
  .gtag{ padding:18px var(--gutter); }
  .gtag__sep{ margin:0 14px; }
  .gtag__logo img{ height:34px; }
}
/* The tile keeps the 44px floor only where it actually floats. */
@media (hover:hover) and (min-width:901px){
  .gtag{ min-height:44px; }
}

/* --------------------------------------------------------------- RELATED */
.related{ display:grid; grid-template-columns:repeat(3,minmax(0,1fr)); gap:var(--gap); }
@media (max-width:880px){ .related{ grid-template-columns:minmax(0,1fr); } }

/* --------------------------------------------------------------- FOOTER */
.foot{ background:var(--d-bg-foot); color:var(--d-text-2); }
.foot__top{
  display:grid; gap:clamp(28px,3vw,48px);
  padding-block:clamp(44px,5vw,76px);
  align-items:start;
}
/* Brand + four columns (Services, Quick links, The group, Get in touch). Balanced
   counts keep the row height tight — the old three-column layout left the short
   columns with dead space under the eight-item Services list. */
@media (min-width:1120px){ .foot__top{ grid-template-columns:minmax(0,1.5fr) repeat(4,minmax(0,1fr)); } }
@media (min-width:640px) and (max-width:1119px){
  .foot__top{ grid-template-columns:repeat(2,minmax(0,1fr)); }
  .foot__brand{ grid-column:1 / -1; }
}
.foot__brand{ display:grid; gap:16px; align-content:start; }
.foot__brand img{ height:46px; width:auto; }
.foot__brand p{ font-size:var(--fs-base); color:var(--d-text-3); max-width:38ch; }
.foot__h{
  font-size:var(--fs-2xs); font-weight:700; letter-spacing:.18em;
  text-transform:uppercase; color:var(--d-text); margin-bottom:14px;
}
.foot__list{ display:grid; gap:2px; }
.foot__list a{
  display:block; padding:6px 0; font-size:var(--fs-base);
  color:var(--d-text-2); text-decoration:none;
  transition:color .22s var(--ease);
}
.foot__list a:hover{ color:var(--orange); }
.foot__list li[style*="--sc"] a::before{
  content:''; display:inline-block; width:7px; height:7px; border-radius:2px;
  background:var(--sc); margin-right:9px; vertical-align:1px;
}
.foot__more{ color:var(--d-text-3) !important; }

/* Get in touch — address, phone, email. Icons carry the accent, matching the
   contact block elsewhere on the site; orange is a legitimate stroke colour on
   this dark ground. */
.foot__contact{ display:grid; gap:14px; align-content:start; }
.foot__addr{ font-style:normal; display:grid; gap:12px; }
.foot__cl{
  display:flex; align-items:flex-start; gap:11px;
  font-size:var(--fs-base); color:var(--d-text-2); text-decoration:none;
  transition:color .22s var(--ease);
}
a.foot__cl:hover{ color:var(--orange); }
.foot__ico{ flex:none; line-height:0; margin-top:2px; }
.foot__ico svg{ width:16px; height:16px; fill:none; stroke:var(--orange); stroke-width:2;
  stroke-linecap:round; stroke-linejoin:round; }

.foot__bot{
  display:flex; flex-wrap:wrap; gap:12px 28px; align-items:center;
  justify-content:space-between;
  padding:22px 0 clamp(26px,3vw,40px);
  border-top:1px solid var(--d-rule);
  font-size:var(--fs-xs); color:var(--d-text-3);
}
.foot__bot a{ color:var(--d-text-2); text-decoration:none; }
.foot__bot a:hover{ color:var(--orange); }

/* Build credit. The link floods orange on hover — 7.19:1 on this ground, so it
   is a legitimate text colour here where it would fail on paper. */
.foot__by a{
  color:var(--d-text-2); font-weight:700;
  transition:color .22s var(--ease);
}
.foot__by a:hover,
.foot__by a:focus-visible{ color:var(--orange); }
@media (pointer:coarse){
  .foot__by a{ display:inline-flex; align-items:center; min-height:44px; }
}

/* --------------------------------------------------------------- 404 */
.nf{ display:grid; place-items:center; text-align:center; gap:20px;
  padding-block:clamp(70px,10vw,150px); }
.nf__code{ font-size:var(--fs-hero); font-weight:800; letter-spacing:-.04em; color:var(--orange); }

/* --------------------------------------------------------------- REVEAL
   Opt-in: content is VISIBLE by default and only hides once the script has
   confirmed it can drive the observer, so a failed observer can never leave
   the page blank. A 1.2s safety net shows everything anyway. */
.js-reveal .reveal{ opacity:0; transform:translateY(20px); }
.js-reveal .reveal.is-in{
  opacity:1; transform:none;
  transition:opacity .7s var(--ease) var(--d,0ms), transform .7s var(--ease) var(--d,0ms);
}

/* --------------------------------------------------- TOUCH TARGETS
   On coarse pointers, link rows grow to the 44px floor. */
@media (pointer:coarse){
  .foot__list a,.menu__item{ min-height:44px; display:flex; align-items:center; }
  .tlink{ min-height:44px; }
}

/* --------------------------------------------------------- REDUCED MOTION
   Movement goes; feedback stays. Nothing translates, scales or rotates — but
   colour, background, border, shadow and opacity keep a 120ms transition, so
   hover, focus and form validation still register. A blanket
   transition:.01ms kill would strip the feedback people rely on to know a
   control responded.

   The marquee stops at its START frame, not its end, so the real logos stay
   on screen rather than the aria-hidden duplicate group. */
@media (prefers-reduced-motion:reduce){
  html{ scroll-behavior:auto; }
  *,*::before,*::after{
    animation-duration:.001ms !important;
    animation-iteration-count:1 !important;
    transition-property:color,background-color,border-color,box-shadow,opacity,outline-color !important;
    transition-duration:120ms !important;
  }
  .js-reveal .reveal{ opacity:1 !important; transform:none !important; }
  .card:hover,.btn:hover,.cpanel:hover,.gtag:hover{ transform:none !important; }
  .card:hover .card__media img,.proof figure:hover img{ transform:none !important; }
  .menu__panel{ transform:translateX(-50%) !important; }
  .cpanel__badge{ transform:translate(-50%,-50%) !important; }
  .cpanel__cta:hover .cpanel__arrow{ transform:none !important; }
  .gtag:hover .gtag__go,.gtag:focus-visible .gtag__go{ transform:none !important; }

  /* Freezing the track would leave most of the marks behind overflow, so unwrap
     the rail into a static grid instead. The aria-hidden duplicate goes with
     it — showing it would repeat every client twice for no reason. */
  .marquee{ mask-image:none; -webkit-mask-image:none; }
  .marquee__track{ animation:none !important; transform:none !important; width:auto; display:block; }
  .marquee__group{
    display:grid;
    grid-template-columns:repeat(auto-fit, minmax(var(--logo-cell), 1fr));
    width:100%; padding-right:0;
  }
  .marquee__group[aria-hidden="true"]{ display:none; }
  .clogo{ flex:none; }
}
