/* --------------------------------------------------------------- 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 was gating first paint. */
@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 Group of Companies — group portal · v4 "Group Profile"
   The corporate profile of a serious holding company, set modern.
   White ground, one hairline rule, Montserrat only (the logo's own face),
   14/10px radius, sober grayscale photography. Yellow is the single accent
   field; sector colours appear only where they ARE the identity system.
   ========================================================================== */

/* --------------------------------------------------------------- TOKENS */
:root{
  --paper:      #FFFFFF;
  --paper-2:    #F6F6F4;
  --ink:        #101318;
  --ink-2:      #4F555E;
  /* muted text on LIGHT ground. 5.14:1 on paper, 4.75:1 on paper-2 — the old
     #8C929B sat at 3.13:1 and failed AA everywhere it touched white. */
  --ink-3:      #686E77;
  --rule:       #E4E4E0;

  --yellow:     #FDBE06;
  --yellow-2:   #E8AD04;

  /* dark surface ramp. These were five loose literals scattered through the
     file with nothing holding them in relation to each other. */
  --plate:        #101318;   /* hero + contact band */
  --d-bg-deep:    #0A0C0F;   /* companies band, the deepest ground */
  --d-bg-foot:    #0B0D10;   /* footer */
  --d-card:       #14171B;   /* company panel */
  --d-panel:      #161A1F;   /* enquiry form */
  --d-field:      #0F1216;   /* form input at rest */
  --d-field-focus:#12161A;   /* form input focused */

  /* sector identity. One pair per company: the colour and the text colour that
     clears AA on it. Previously repeated inline on eight elements. */
  --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;
  /* form placeholder — 5.04:1 on --d-field */
  --d-placeholder:  #7E858E;

  /* on dark bands */
  --d-text:     #F4F5F6;
  --d-text-2:   #A2A8B0;
  /* muted text on DARK ground, one step below --d-text-2. This is the old
     --ink-3 value, kept here so the dark bands look exactly as before. */
  --d-text-3:   #8C929B;
  /* nav links at rest, over the hero veil */
  --d-text-nav: #C7CCD2;
  --d-rule:     rgba(255,255,255,.16);

  /* shape — tighter than v3: modern, but boardroom-calm */
  --r-lg:       24px;
  --r-md:       14px;
  --r-sm:       10px;
  --r-xs:       8px;

  --gutter:     clamp(40px, calc(5vw + 20px), 144px);
  --shell:      1320px; /* used only as a text measure, never as a container */

  --ease:       cubic-bezier(.22,.61,.36,1);

  --header-h:   92px;

  /* fluid type scale — interpolates 360px → 1440px viewport.
     rem + vw keeps browser zoom and user font-size preferences working. */
  --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.833rem + 6.30vw, 6.500rem);   /* 36   → 104  */
}

/* --------------------------------------------------------------- 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{ display:block; max-width:100%; }
/* <picture> is inline by default, which breaks height:100% on the img inside
   it. Every picture here is a sizing wrapper, so make it behave like one. */
picture{ display:contents; }
svg{ display:block; }
a{ color:inherit; text-decoration:none; }
ul,ol{ margin:0; padding:0; list-style:none; }
dl,dd,figure{ margin:0; }
p{ margin:0 0 1.05em; }
h1,h2,h3,h4{ margin:0; line-height:1.1; font-weight:800; }
button{ font:inherit; color:inherit; background:none; border:0; cursor:pointer; }

::selection{ background:var(--yellow); color:var(--ink); }
:focus-visible{ outline:2px solid var(--yellow); outline-offset:3px; }

.skip-link{
  position:absolute; left:-9999px; top:0; z-index:999;
  background:var(--yellow); color:var(--ink); padding:12px 20px; font-weight:600;
}
.skip-link:focus{ left:0; }

/* --------------------------------------------------------------- LAYOUT */
.shell{
  width:100%;
  padding-inline:var(--gutter);
}
.section{ padding-block:clamp(76px,9.5vw,140px); }


/* --------------------------------------------------------------- TYPE */
.kicker{
  display:flex; align-items:center; gap:13px;
  margin:0 0 20px;
  font-size:var(--fs-2xs); font-weight:600; letter-spacing:.2em; text-transform:uppercase;
  color:var(--ink-3);
}
.kicker__rule{
  display:block; width:28px; height:2px; flex:0 0 28px;
  background:var(--yellow);
}
.kicker--onDark{ color:var(--d-text-2); }
/* only the hero kicker needs to give ground on short viewports */
.hero .kicker{ margin-bottom:min(20px, 2svh); }

.h2{
  font-size:var(--fs-3xl);
  font-weight:800;
  line-height:1.06;
  letter-spacing:-.028em;
}
.h2--onDark{ color:var(--d-text); }
.lead{
  font-size:var(--fs-lg);
  line-height:1.6;
  font-weight:500;
}

/* --------------------------------------------------------------- BUTTONS */
.btn{
  display:inline-flex; align-items:center; justify-content:center; gap:10px;
  padding:14px 26px;
  border:1.5px solid transparent;
  border-radius:var(--r-sm);
  font-size:var(--fs-sm); font-weight:600;
  /* was nowrap, which forced the page wider than the viewport once a user
     scaled text up; wrapping is the graceful failure */
  text-align:center;
  transition:background .25s var(--ease), color .25s var(--ease),
             border-color .25s var(--ease), transform .2s var(--ease);
}
.btn--yellow{ background:var(--yellow); color:var(--ink); }
.btn--yellow:hover{ background:var(--yellow-2); transform:translateY(-2px); }
.btn--outline{ border-color:var(--d-rule); color:var(--d-text); }
.btn--outline:hover{ border-color:var(--yellow); color:var(--yellow); transform:translateY(-2px); }
.btn:active{ transform:translateY(0) scale(.985); }
.btn--sm{ padding:10px 20px; font-size:var(--fs-sm); }
.btn--lg{ padding:16px 30px; font-size:var(--fs-base); }
.btn__arrow{
  width:17px; height:17px; fill:none; stroke:currentColor; stroke-width:2.2;
  stroke-linecap:round; stroke-linejoin:round;
  transition:transform .25s var(--ease);
}
.btn:hover .btn__arrow{ transform:translateX(4px); }

/* --------------------------------------------------------------- HEADER */
.site-header{
  position:fixed; inset:0 0 auto 0; z-index:100;
  height:var(--header-h);
  display:flex; align-items:center;
  transition:background .35s var(--ease), box-shadow .35s var(--ease);
}
.site-header.is-stuck{
  background:rgba(255,255,255,.94);
  backdrop-filter:blur(14px) saturate(150%);
  -webkit-backdrop-filter:blur(14px) saturate(150%);
  box-shadow:0 1px 0 var(--rule);
}
.site-header__inner{ display:flex; align-items:center; justify-content:space-between; gap:24px; }

.brand{ position:relative; display:block; line-height:0; }
.brand__logo{ height:54px; width:auto; transition:opacity .35s var(--ease); }
.brand__logo--colour{ position:absolute; left:0; top:0; height:54px; opacity:0; }
.site-header.is-stuck .brand__logo--white{ opacity:0; }
.site-header.is-stuck .brand__logo--colour{ opacity:1; }

.nav{ display:flex; align-items:center; gap:30px; }
.nav__link{
  position:relative; padding-block:6px;
  font-size:var(--fs-sm); font-weight:500;
  /* at rest these sit on the hero veil, whose lightest possible composite is
     ~#3B3E42. --d-text-2 only reached 4.46:1 against that worst case; this
     clears it at 6.69:1 whatever the photograph is doing underneath. */
  color:var(--d-text-nav);
  transition:color .2s var(--ease);
}
.nav__link::after{
  content:''; position:absolute; left:0; bottom:0; width:100%; height:2px;
  background:var(--yellow);
  transform:scaleX(0); transform-origin:left;
  transition:transform .28s var(--ease);
}
.nav__link:hover::after,
.nav__link.is-active::after{ transform:scaleX(1); }
.nav__link:hover{ color:var(--d-text); }
.site-header.is-stuck .nav__link{ color:var(--ink-2); }
.site-header.is-stuck .nav__link:hover{ color:var(--ink); }
.nav__link.is-active{ color:var(--d-text); font-weight:600; }
.site-header.is-stuck .nav__link.is-active{ color:var(--ink); }
/* was 43px tall — one pixel under the 44px minimum target */
.nav__cta{ margin-left:4px; min-height:44px; }

.burger{ display:none; width:44px; height:44px; position:relative; flex:0 0 44px; }
.burger span{
  position:absolute; left:11px; width:22px; height:2px;
  background:var(--d-text);
  transition:transform .3s var(--ease), opacity .2s var(--ease), background .3s var(--ease);
}
.site-header.is-stuck .burger span{ background:var(--ink); }
.burger span:nth-child(1){ top:15px; }
.burger span:nth-child(2){ top:21px; }
.burger span:nth-child(3){ top:27px; }
.burger[aria-expanded="true"] span:nth-child(1){ transform:translateY(6px) rotate(45deg); }
.burger[aria-expanded="true"] span:nth-child(2){ opacity:0; }
.burger[aria-expanded="true"] span:nth-child(3){ transform:translateY(-6px) rotate(-45deg); }

/* ==========================================================================
   HERO — full-bleed band
   One photograph carries the whole viewport. The four lockups sit centred
   along the base, evenly spaced, so the row reads dead-centre.
   ========================================================================== */
.hero{
  position:relative;
  display:flex; flex-direction:column;
  min-height:100svh;
  background:var(--plate);
  color:var(--d-text);
  overflow:hidden;
}
.hero__bg{
  position:absolute; inset:0;
  width:100%; height:100%;
  object-fit:cover;
  filter:contrast(1.06) saturate(.9);
}
.hero__veil{
  position:absolute; inset:0;
  background:
    linear-gradient(180deg, rgba(16,19,24,.82) 0%, rgba(16,19,24,.46) 34%, rgba(16,19,24,.72) 68%, rgba(16,19,24,.94) 100%),
    linear-gradient(90deg, rgba(16,19,24,.72) 0%, rgba(16,19,24,.24) 52%, transparent 100%);
}
.hero__main{
  position:relative; z-index:2;
  flex:1;
  display:flex; align-items:center;
  padding-top:var(--header-h);
}
/* Every vertical value in the hero is capped against the viewport HEIGHT as
   well as its width, so the header, the headline block and the four-company
   strip always land inside one screen. Each cap is a no-op above ~1050px tall,
   which leaves the roomy look on big displays untouched. */
.hero__content{ padding-block:min(clamp(44px,5vw,80px), 7.6svh); }
.hero__title{
  font-size:min(var(--fs-hero), 10svh);
  font-weight:800;
  line-height:.96;
  letter-spacing:-.034em;
  text-transform:uppercase;
  margin-bottom:min(clamp(22px,2.8vw,34px), 3.3svh);
}
/* the keyword line inside the H1: reads as a standfirst, not a second headline */
.hero__title-sub{
  display:block;
  margin-top:min(clamp(14px,1.6vw,20px), 1.95svh);
  font-size:min(var(--fs-lg), 2.6svh);
  font-weight:600;
  line-height:1.35;
  letter-spacing:-.01em;
  text-transform:none;
  color:var(--yellow);
  /* was 24ch, which forced this onto three short lines. 42ch lets it sit on
     two and lines its right edge up with the lede below it. */
  max-width:42ch;
}

.hero__lede{
  max-width:46ch; margin:0 0 min(clamp(28px,3.4vw,44px), 4.3svh);
  font-size:min(var(--fs-md), 2.4svh);
  line-height:1.62;
  color:var(--d-text-2);
  /* two sentences now, so the last line can strand a single word ("2010.");
     pretty pulls a word down rather than leaving the orphan */
  text-wrap:pretty;
}
.hero__actions{ display:flex; flex-wrap:wrap; gap:12px; }

/* the lockups: centred, evenly spaced, white at rest, brand colour on hover */
.hero__index{
  position:relative; z-index:2;
  border-top:1px solid rgba(255,255,255,.22);
  /* light veil only: the site photo still reads through the strip */
  background:rgba(16,19,24,.24);
  backdrop-filter:blur(3px);
  -webkit-backdrop-filter:blur(3px);
}
.hero__marks{
  display:grid;
  grid-template-columns:repeat(4,minmax(0,1fr));
}
.hero__marks li{
  position:relative;
  display:flex; align-items:center; justify-content:center;
  padding-block:min(clamp(24px,2.6vw,34px), 3.3svh);
  /* divider between each company; full strip height */
  border-left:1px solid rgba(255,255,255,.2);
}
/* a small ↗ in the top-right corner marks each logo as a link out */
.hero__marks li::after{
  content:''; position:absolute;
  top:clamp(12px,1.2vw,16px); right:clamp(12px,1.2vw,18px);
  width:20px; height:20px;
  background:rgba(255,255,255,.45);
  -webkit-mask:no-repeat center/contain url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M7 17 17 7M9 7h8v8'/%3E%3C/svg%3E");
          mask:no-repeat center/contain url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M7 17 17 7M9 7h8v8'/%3E%3C/svg%3E");
  transition:background .3s var(--ease), transform .3s var(--ease);
}
.hero__marks li:hover::after,
.hero__marks li:focus-within::after{
  background:var(--accent,var(--yellow));
  transform:translate(2px,-2px);
}
.hero__marks li:first-child{ border-left:0; }
.hero__marks a{
  position:relative; display:block;
  height:min(clamp(35px,calc(2.8vw + 5px),45px), 4.4svh);
  transition:transform .3s var(--ease);
}
.hero__marks a:hover{ transform:translateY(-2px); }
.hero__mark{
  height:100%; width:auto;
  transition:opacity .32s var(--ease);
}
.hero__mark--colour{ position:absolute; left:0; top:0; opacity:0; }
.hero__marks a:hover .hero__mark--white,
.hero__marks a:focus-visible .hero__mark--white{ opacity:0; }
.hero__marks a:hover .hero__mark--colour,
.hero__marks a:focus-visible .hero__mark--colour{ opacity:1; }

/* Short desktop viewports (small laptops, or a window with a bookmarks bar and
   a sidebar eating height). The caps above hold the hero to one screen down to
   about 790px; below that it needs a harder squeeze to keep the four-company
   strip above the fold. Width guard keeps this clear of the mobile layout,
   where the hero is natural height anyway. */
@media (min-width:901px) and (max-height:800px){
  .hero__content{ padding-block:min(clamp(44px,5vw,80px), 6svh); }
  .hero__title{
    font-size:min(var(--fs-hero), 9svh);
    margin-bottom:min(clamp(22px,2.8vw,34px), 2.6svh);
  }
  .hero__title-sub{
    margin-top:min(clamp(14px,1.6vw,20px), 1.5svh);
    font-size:min(var(--fs-lg), 2.3svh);
  }
  .hero__lede{
    margin-bottom:min(clamp(28px,3.4vw,44px), 3.4svh);
    font-size:min(var(--fs-md), 2.2svh);
  }
  .hero__actions .btn--lg{ padding-block:12px; }
  .hero__marks li{ padding-block:min(clamp(24px,2.6vw,34px), 2.8svh); }
  .hero__marks a{ height:min(clamp(35px,calc(2.8vw + 5px),45px), 3.9svh); }
}

/* ==========================================================================
   ABOUT — the group story
   ========================================================================== */
.about__top{
  max-width:900px;
  padding-bottom:clamp(34px,4.5vw,58px);
  margin-bottom:clamp(34px,4.5vw,58px);
  border-bottom:1px solid var(--rule);
}
.about__title{ font-size:clamp(2.125rem, 1.361rem + 3.40vw, 4.250rem); } /* 34 → 68 */

.about__body{
  display:grid;
  grid-template-columns:minmax(0,.86fr) minmax(0,1.14fr);
  gap:clamp(34px,5.5vw,84px);
  /* start, not center. With three people stacked the portrait column is the
     taller one, and centring pushed the first paragraph ~270px below the
     founder's head. Both columns now begin on the same line. */
  align-items:start;
  margin-bottom:clamp(46px,6vw,88px);
}

/* Portrait stack. start, not center: the story column is taller than the two
   photos together, and centring left ~200px of dead space above them. */
.about__people{ align-self:start; }

/* the founder / site portrait, carrying the J mark's chamfer + the yellow seam */
.about__portrait{
  position:relative;
  /* A vertical studio portrait needs a portrait frame. Stretching to the row
     height made a 690x560 landscape box at 1920, which left the subject
     stranded in dead white space. Fixed 4/5 everywhere instead. */
  aspect-ratio:4/5;
  width:100%;
  max-width:460px;
  overflow:hidden;
  /* Rounded, matching the Industrial site's .nportrait__frame one-to-one: the
     radius rounds three corners and the chamfer still cuts the top-right, since
     the polygon's other vertices sit on the box corners and leave the curves
     inside the clip. The seam follows the top- and bottom-left curves. */
  border-radius:var(--r-lg);
  clip-path:polygon(0 0, calc(100% - 46px) 0, 100% 46px, 100% 100%, 0 100%);
  background:var(--plate);
}
.about__portrait img{
  position:absolute; inset:0;
  width:100%; height:100%;
  object-fit:cover;
  /* The source is a tall studio portrait (0.678) in a much wider frame, so
     cover crops vertically. The subject's head starts 6.4% down, and a centred
     crop cut into it — biasing the crop upward keeps the head with air above. */
  object-position:50% 18%;
  filter:contrast(1.04) saturate(.96);
}
/* yellow seam down the left edge — the lockup's vertical rule */
.about__portrait::before{
  content:''; position:absolute; left:0; top:0; bottom:0; z-index:2;
  width:6px; background:var(--yellow);
}
.about__portrait::after{
  content:''; position:absolute; left:0; right:0; bottom:0; z-index:1;
  height:52%;
  background:linear-gradient(180deg,
    rgba(16,19,24,0),
    rgba(16,19,24,.62) 42%,
    rgba(16,19,24,.94) 78%);
  pointer-events:none;
}
/* The caption identifies the person now, so it stacks name over role rather
   than sitting on one baseline. Same treatment as the .about__team caption below,
   inverted for the dark image - both people get labelled the same way, the
   founder's photo is simply the larger one. */
.about__portrait figcaption{
  position:absolute; left:0; right:0; bottom:0; z-index:2;
  display:grid; justify-items:start; gap:5px;
  padding:clamp(20px,2.2vw,30px) clamp(20px,2.2vw,28px) clamp(18px,2vw,26px);
}
.about__portrait-name{
  font-size:var(--fs-lg); font-weight:800; letter-spacing:-.02em; line-height:1.2;
  color:#FFFFFF;
  text-wrap:balance;
}
.about__portrait-role{
  font-size:var(--fs-xs); font-weight:500; letter-spacing:.02em; line-height:1.45;
  color:var(--d-text-2);
  text-wrap:pretty;
}

/* A second person under the founder: the same object one size down, not a
   different one. Chamfer, yellow seam and an inset caption, so the two read as
   a pair. Left-aligned and narrower than the portrait above rather than
   matching its width, which keeps the founder primary. */
/* The officers sit side by side under the founder, held to his width so the
   pair lines up with the portrait above rather than overhanging it. */
.about__officers{
  display:grid;
  grid-template-columns:repeat(2, minmax(0,1fr));
  gap:clamp(12px,1.4vw,18px);
  align-items:start;
  width:100%;
  max-width:460px;
  margin:clamp(22px,2.6vw,30px) 0 0;
}
@media (max-width:600px){
  /* two-up would leave each card under ~160px on a phone */
  .about__officers{ grid-template-columns:minmax(0,1fr); }
}
.about__team{
  position:relative;
  width:100%;
  aspect-ratio:4/5;
  overflow:hidden;
  container-type:inline-size;   /* lets the caption size off the card width */
  /* same frame as the founder and as Industrial's .nportrait__frame */
  border-radius:var(--r-lg);
  clip-path:polygon(0 0, calc(100% - 46px) 0, 100% 46px, 100% 100%, 0 100%);
}
.about__team img{
  position:absolute; inset:0;
  width:100%; height:100%;
  object-fit:cover;
  /* a 0.945 source in a 4/5 frame crops horizontally; the head sits high, so
     bias the crop up to keep air above it rather than into the hair */
  object-position:50% 14%;
  filter:contrast(1.04) saturate(.96);
}
/* the lockup's vertical rule, a flat 6px as on the founder and on Industrial */
.about__team::before{
  content:''; position:absolute; left:0; top:0; bottom:0; z-index:3;
  width:6px;
  background:var(--yellow);
}
/* on the figure, not the figcaption - see .about__portrait::after */
.about__team::after{
  content:''; position:absolute; left:0; right:0; bottom:0; z-index:1;
  height:56%;
  background:linear-gradient(180deg,
    rgba(16,19,24,0),
    rgba(16,19,24,.64) 40%,
    rgba(16,19,24,.95) 76%);
  pointer-events:none;
}
.about__team figcaption{
  position:absolute; left:0; right:0; bottom:0; z-index:2;
  display:grid; justify-items:start; gap:4px;
  padding:clamp(16px,1.8vw,22px) clamp(16px,1.8vw,22px) clamp(14px,1.6vw,20px);
}
/* keeps a hyphenated surname on one line; a break after the hyphen
   strands the second half of the name alone */
.nobr{ white-space:nowrap; }
.about__team-name{
  /* Sized off the CARD, not the viewport. At the narrowest two-column width
     (~1100px) each card is 184px and "Mattadeen-George", held on one line by
     .nobr, came within 5px of the frame edge. 8cqi reaches --fs-md at ~220px
     cards, so from 1280 up and on phones nothing changes. The first
     declaration is the fallback where container units are unsupported. */
  font-size:var(--fs-md);
  font-size:min(var(--fs-md), 8cqi);
  font-weight:800; letter-spacing:-.02em; line-height:1.25;
  color:#FFFFFF;
  overflow-wrap:anywhere;
}
.about__team-role{
  display:grid; gap:1px;
  font-size:var(--fs-xs); line-height:1.45;
  color:var(--d-text-2);
  overflow-wrap:anywhere;
}

.about__story{
  /* The one long-form block on the page with no measure cap — every other one
     carries a `ch` limit (.faq__a 74ch, .hero__lede 46ch, .contact__note 44ch).
     This column just tracked the grid, so past 1920 it ran away: 85 characters
     a line from 844 up to 1920, then 128 at 2560 and 152 at 3440. 920px is the
     width the column already measures at 1920, so this is a no-op at and below
     the largest common display and only bites on ultrawide. */
  max-width:min(100%, 920px);
}
.about__story .lead{ color:var(--ink); }
.about__story p{ color:var(--ink-2); }
/* The column tracks the grid, which at 1920 ran the prose to 114 characters a
   line. Capping the text itself (not the column) holds a readable measure at
   every width without disturbing the layout. */
.about__story p,
.about__divisions{ max-width:62ch; }
/* long words break rather than widening the column under heavy zoom */
.about__story p,.faq__a,.promise__lede,.hero__lede,.codeck__sub{ overflow-wrap:break-word; }

/* the divisions list: the group's own trades, marked with the yellow rule
   rather than a bullet glyph, so it stays inside the type system */
.about__divisions{
  display:grid; gap:10px;
  margin:0 0 1.05em;
  padding-left:2px;
}
.about__divisions li{
  display:flex; align-items:baseline; gap:12px;
  font-size:var(--fs-base); font-weight:600;
  color:var(--ink);
}
.about__divisions li::before{
  content:''; flex:0 0 14px; height:2px;
  background:var(--yellow);
  transform:translateY(-.32em);
}

/* the creed states the slogan; the pillars below are its three terms */
.about__creed{
  max-width:820px;
  margin:0 0 clamp(30px,3.6vw,44px);
}
.about__creed-line{
  margin:0 0 12px;
  font-size:var(--fs-xl);
  font-weight:800; letter-spacing:-.02em; line-height:1.25;
  color:var(--ink);
  text-wrap:balance;
}
.about__creed-note{
  margin:0;
  font-size:var(--fs-base); line-height:1.7;
  color:var(--ink-2);
  max-width:66ch;
}

/* key figures, folded into the base of the story column */
.about__figures{
  display:grid;
  /* minmax(0,1fr) lets the columns go under min-content; repeat(4,1fr) pinned
     them to the widest label and overflowed the page at 200% text size */
  grid-template-columns:repeat(4,minmax(0,1fr));
  gap:clamp(16px,1.6vw,24px);
  margin:clamp(28px,3vw,40px) 0 0;
  padding-top:clamp(24px,2.6vw,32px);
  border-top:1px solid var(--rule);
}
.about__figures div{ display:flex; flex-direction:column; gap:4px; }
.about__figures dt{
  font-size:var(--fs-2xl);
  font-weight:800; line-height:1; letter-spacing:-.03em;
  color:var(--ink);
}
.about__figures dd{
  margin:0;
  font-size:var(--fs-2xs); font-weight:600; letter-spacing:.14em; text-transform:uppercase;
  color:var(--ink-3);
}

/* the three values as a numbered band across the base of About */
.pillars{
  display:grid;
  /* minmax(0,1fr), not a bare 1fr: at 768px with 200% text the min-content floor
     of each column pulled them to 220|237|194 instead of three equal tracks */
  grid-template-columns:repeat(3,minmax(0,1fr));
  border-top:1px solid var(--ink);
}
.pillars li{
  padding:clamp(24px,2.6vw,34px) clamp(20px,2vw,30px) 0 0;
  border-left:1px solid var(--rule);
}
.pillars li:first-child{ border-left:0; padding-left:0; }
.pillars li + li{ padding-left:clamp(20px,2vw,30px); }
/* The numeral used to be yellow-on-white at 2.02:1 — unreadable. The yellow
   moves into a rule (the same device as .kicker__rule) so the accent survives
   and the number itself reads at 18.6:1. */
.pillars__num{
  display:flex; align-items:center; gap:10px;
  font-size:var(--fs-sm); font-weight:800; letter-spacing:.06em;
  color:var(--ink);
  margin-bottom:clamp(16px,1.8vw,22px);
}
.pillars__num::before{
  content:''; flex:0 0 18px; width:18px; height:2px;
  background:var(--yellow);
}
.pillars h3{
  font-size:clamp(1.125rem, 1.021rem + 0.46vw, 1.438rem); /* 18 → 23 */
  font-weight:800; letter-spacing:-.02em; line-height:1.1;
  margin-bottom:9px;
  /* "Owned, not brokered" and "Local and accountable" dropped their last word
     onto a line of its own at 1280x620, and four of the five orphaned at 150%
     text. Same device already used on .cpanel__title. */
  text-wrap:balance;
}
.pillars p{
  margin:0;
  font-size:var(--fs-base); line-height:1.6;
  color:var(--ink-2);
}

/* ==========================================================================
   THE COMPANIES — operating deck
   A dark band. Four panels share a rail: the open one carries the photo,
   coloured logo, full legal name and visit link; the rest collapse to their
   lockups set vertically. Badges switch; the deck advances on its own.
   ========================================================================== */
.codeck{
  background:var(--d-bg-deep);
  color:var(--d-text);
}
.codeck__head{ max-width:760px; padding-bottom:clamp(46px,5vw,68px); }
.codeck .kicker{ color:var(--d-text-2); }
.codeck__sub{
  margin:20px 0 0;
  font-size:var(--fs-md); color:var(--d-text-2); max-width:52ch;
}

/* All four companies stay open: four equal columns, no accordion. */
.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;
}

/* the rail the badges sit on */
.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;
}

/* --- a panel --- */
.cpanel{
  position:relative;
  min-width:0;
  display:flex; flex-direction:column;
  border-radius:var(--r-lg,24px);
  background:var(--d-card);
  /* visible, so the badge can sit above the panel on the rail */
  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);
}

/* the numbered badge, centred on the rail at the panel's top */
.cpanel__badge{
  position:absolute; z-index:4;
  /* pulled up onto the rail, clear of the card below it */
  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 already 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;
}


/* --- open: photo above, content below --- */
.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;
  /* fallback for browsers without color-mix */
  color:var(--accent);
  /* the raw sector colours run 2.73–3.90:1 on this card; lightening them keeps
     the hue but clears AA (5.1–9.9:1) */
  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);
  max-width:none;
  /* the legal names differ wildly in length; balance evens the rag out */
  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);
  max-width:none;
}
.cpanel__cta{
  display:inline-flex; align-items:center; gap:14px;
  margin-top:auto;
  padding:5px 5px 5px 19px;
  border-radius:999px;
  /* transparent at rest so the card stays calm; the company colour arrives on hover */
  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;
  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);
}
/* the badge inverts on hover, so the colour reads either way */
.cpanel__cta:hover .cpanel__arrow{
  background:rgba(255,255,255,.94);
  transform:rotate(45deg);
}
.cpanel__arrow svg{
  width:14px; height:14px;
  fill:none; stroke:#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); }

/* Between the 4-column break and ~1400 the columns sit around 265px, where
   "Jamaal's Industrial Transport & Construction Services Co. Ltd." ran to five
   lines against Realty's two. Dropping a step evens the cards out. */
@media (min-width:1101px) and (max-width:1700px){
  .cpanel__title{ font-size:var(--fs-lg); }
  .cpanel__logo{ height:clamp(35px,2.4vw + 4px,42px); }
}

/* --- stacked below the tablet break: every company open and readable --- */
/* below 1100 the four columns get too narrow for a legal name, so the deck
   wraps to 2x2; the rail only reads across a single row, so it stands down
   and each badge moves into its own card corner. */
@media (max-width:1100px){
  .deck{
    grid-template-columns:repeat(2,minmax(0,1fr));
    padding-top:0;
    row-gap:clamp(16px,2vw,24px);
  }
  .deck__rail{ display:none; }
  .cpanel__media{ flex:0 0 auto; aspect-ratio:16/9; }
  .cpanel__badge{
    top:16px; left:16px;
    transform:none; opacity:1;
    width:44px; height:44px;
    box-shadow:0 4px 14px rgba(0,0,0,.4);
  }
  .cpanel__cta{ margin-top:0; }
}
@media (max-width:680px){
  .deck{ grid-template-columns:minmax(0,1fr); }
}

/* ==========================================================================
   THE STANDARD
   ========================================================================== */
.promise__head{ max-width:820px; margin-bottom:clamp(38px,5vw,60px); }
.promise__lede{ color:var(--ink-2); margin-top:20px; margin-bottom:0; }
/* the second paragraph steps down from the lead so the two read as one block
   rather than two competing statements */
.promise__lede-2{
  margin:14px 0 0;
  font-size:var(--fs-md); line-height:1.62;
  color:var(--ink-2);
  max-width:68ch;
}

.clauses{
  counter-reset:clause;
  display:grid;
  /* bare 1fr kept a min-content floor: at 1280 with 200% text the four cards
     measured 257|257|257|278 instead of four equal tracks */
  grid-template-columns:repeat(4,minmax(0,1fr));
  gap:clamp(14px,1.6vw,22px);
}
.clauses li{
  counter-increment:clause;
  padding:clamp(22px,2.6vw,30px);
  border-radius:var(--r-md);
  background:var(--paper-2);
  border:1px solid transparent;
  transition:border-color .3s var(--ease), background .3s var(--ease), transform .3s var(--ease);
}
.clauses li:hover{ background:var(--paper); border-color:var(--rule); transform:translateY(-3px); box-shadow:0 16px 36px rgba(16,19,24,.08); }
.clauses li::before{
  content:'0' counter(clause);
  display:block;
  font-size:var(--fs-xs); font-weight:700; letter-spacing:.14em;
  color:var(--yellow-2);
  margin-bottom:16px;
}
.clauses h3{
  font-size:var(--fs-lg); font-weight:700; line-height:1.3; letter-spacing:-.015em;
  margin-bottom:10px;
  /* "One point of contact" / "Safety as standard" orphaned their last word once
     the card narrowed or the text scaled */
  text-wrap:balance;
}
.clauses p{
  margin:0;
  font-size:var(--fs-sm); line-height:1.62;
  color:var(--ink-2);
}

/* ==========================================================================
   CLIENTS
   ========================================================================== */
.clients{
  padding-block:clamp(54px,6.5vw,84px) clamp(60px,7vw,92px);
  /* its own tray: .promise and .faq are both white, so a third white band in a
     row would let the logo rail dissolve into the FAQ above it */
  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;
}

/* --------------------------------------------------------- the logo rail */
.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 63s 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);
}
/* the two groups are identical, so translating the track by exactly half its
   width lands group two where group one started - a seamless loop */
@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); }
/* factors carried over from the Industrial site, where this set was eye-checked
   in the same rail - proactive sits a little above the formula on purpose */
.clogo__img--proactive{  height:calc(var(--logo-h) * .96); }
.clogo__img--ustek{      height:calc(var(--logo-h) * .60); }
.clogo__img--alja{       height:calc(var(--logo-h) * .66); }


/* ==========================================================================
   FAQ
   Native <details>/<summary>: keyboard-operable and openable with no JS, and
   the answers are real text on the page, which is what FAQPage schema needs.
   ========================================================================== */
.faq{ border-top:1px solid var(--rule); }
.faq__head{ max-width:760px; margin-bottom:clamp(30px,3.6vw,46px); }
.faq__sub{
  margin:18px 0 0;
  font-size:var(--fs-md); color:var(--ink-2); max-width:56ch;
}
.faq__list{ border-top:1px solid var(--rule); }
.faq__item{ border-bottom:1px solid var(--rule); }
.faq__q{
  position:relative;
  display:block; width:100%;
  padding:clamp(18px,2vw,24px) 56px clamp(18px,2vw,24px) 0;
  font-size:var(--fs-lg); font-weight:700; letter-spacing:-.015em; line-height:1.35;
  color:var(--ink);
  cursor:pointer;
  list-style:none;
  /* pretty, not balance: these are full questions, so the goal is only to keep
     the last word off a line of its own — three of the five did that at 390x844 */
  text-wrap:pretty;
  transition:color .22s var(--ease);
}
.faq__q::-webkit-details-marker{ display:none; }
.faq__q:hover{ color:var(--yellow-2); }
/* the +/- toggle */
.faq__q::after{
  content:''; position:absolute; right:0; top:50%;
  width:30px; height:30px; margin-top:-15px;
  border-radius:50%;
  border:1.5px solid var(--rule);
  background:
    linear-gradient(var(--ink),var(--ink)) center/11px 2px no-repeat,
    linear-gradient(var(--ink),var(--ink)) center/2px 11px no-repeat;
  transition:transform .3s var(--ease), border-color .3s var(--ease), background-color .3s var(--ease);
}
.faq__item[open] .faq__q::after{
  transform:rotate(135deg);
  border-color:var(--yellow);
  background:
    linear-gradient(var(--ink),var(--ink)) center/11px 2px no-repeat,
    linear-gradient(var(--ink),var(--ink)) center/2px 11px no-repeat,
    var(--yellow);
}
.faq__a{
  padding:0 clamp(40px,8vw,120px) clamp(20px,2.4vw,28px) 0;
  margin:0;
  font-size:var(--fs-base); line-height:1.7;
  color:var(--ink-2);
  max-width:74ch;
}
.faq__a a{ color:var(--ink); text-decoration:underline; text-underline-offset:3px; }
.faq__a a:hover{ color:var(--yellow-2); }

/* ==========================================================================
   CONTACT — pitch and details on the left, enquiry form on the right
   ========================================================================== */
.contact{
  background:var(--plate);
  color:var(--d-text);
}
.contact__inner{
  display:grid;
  grid-template-columns:minmax(0,.92fr) minmax(0,1.08fr);
  gap:clamp(40px,5vw,80px);
  align-items:start;
}
.contact__note{
  margin:20px 0 30px;
  color:var(--d-text-2);
  max-width:44ch;
}

.contact__details{
  margin-top:clamp(32px,4vw,48px);
  border-top:1px solid var(--d-rule);
}
.contact__details > div{
  display:grid;
  /* wider first column now that each label carries an icon */
  grid-template-columns:minmax(132px,auto) minmax(0,1fr);
  gap:20px;
  padding:16px 0;
  border-bottom:1px solid var(--d-rule);
}
.contact__details dt{
  display:flex; align-items:center; gap:9px;
  font-size:var(--fs-2xs); font-weight:600; letter-spacing:.16em; text-transform:uppercase;
  color:var(--d-text-3);
  padding-top:3px;
}
/* one stroke weight across every icon on the page. Stroke follows currentColor
   so an icon picks up whatever state its link is in. */
.ico{
  width:15px; height:15px; flex:0 0 15px;
  fill:none; stroke:currentColor; stroke-width:2;
  stroke-linecap:round; stroke-linejoin:round;
}
/* in the contact band the icons carry the accent rather than the text colour */
.contact__details .ico{ stroke:var(--yellow); }
.contact__details address{ font-style:normal; }
.contact__details dd{
  font-size:var(--fs-base); font-weight:500;
  color:var(--d-text);
  word-break:break-word;
}
/* the chips are taller than a text line, so this row loses the top nudge */
.contact__details dd:has(.social){ margin-top:-10px; }
.contact__details a{ transition:color .2s var(--ease); }
.contact__details a:hover{ color:var(--yellow); }

/* the social row: brand-mark chips, sized to the 44px tap floor so the
   coarse-pointer rule has nothing left to correct */
.social{ display:flex; flex-wrap:wrap; gap:10px; }
.social a{
  display:grid; place-items:center;
  width:44px; height:44px;
  border-radius:var(--r-sm);
  border:1px solid rgba(255,255,255,.14);
  color:var(--d-text-2);
  transition:background .25s var(--ease), border-color .25s var(--ease),
             color .25s var(--ease), transform .25s var(--ease);
}
.social a:hover{
  background:var(--yellow);
  border-color:var(--yellow);
  color:var(--ink);
  transform:translateY(-2px);
}
.social svg{
  width:19px; height:19px;
  fill:currentColor; stroke:none;
}

/* --------------------------------------------------------------- the form */
.cform{
  padding:clamp(24px,2.6vw,38px);
  border-radius:var(--r-md);
  background:var(--d-panel);
  border:1px solid rgba(255,255,255,.09);
}
.cform__title{
  margin:0 0 clamp(20px,2.2vw,26px);
  font-size:var(--fs-lg); font-weight:800; letter-spacing:-.02em;
  color:var(--d-text);
}
/* the honeypot must be reachable by bots but never by people */
.cform__honey{
  position:absolute; left:-9999px;
  width:1px; height:1px; opacity:0;
}

.cform__grid{
  display:grid;
  grid-template-columns:repeat(2,minmax(0,1fr));
  gap:clamp(14px,1.6vw,20px);
}
.field{ display:flex; flex-direction:column; gap:7px; }
.field--full{ grid-column:1 / -1; }

.field label{
  font-size:var(--fs-xs); font-weight:600; letter-spacing:.04em;
  /* AA on the field's own ground, not a dim grey */
  color:var(--d-text);
}
.field label span[aria-hidden]{ color:var(--yellow); }
.field__opt{
  font-weight:500; letter-spacing:0; text-transform:none;
  color:var(--d-text-3);
}

.field input,
.field select,
.field textarea{
  width:100%;
  padding:12px 14px;
  border-radius:var(--r-sm);
  background:var(--d-field);
  border:1px solid rgba(255,255,255,.14);
  color:var(--d-text);
  font-family:inherit;
  font-size:var(--fs-base);
  line-height:1.5;
  transition:border-color .25s var(--ease), background .25s var(--ease),
             box-shadow .25s var(--ease);
}
.field textarea{ resize:vertical; min-height:120px; }
/* placeholders stay legible rather than fading into the field */
.field input::placeholder,
.field textarea::placeholder{ color:var(--d-placeholder); opacity:1; }

.field input:hover,
.field select:hover,
.field textarea:hover{ border-color:rgba(255,255,255,.24); }

.field input:focus-visible,
.field select:focus-visible,
.field textarea:focus-visible{
  outline:none;
  border-color:var(--yellow);
  background:var(--d-field-focus);
  box-shadow:0 0 0 3px rgba(253,190,6,.22);
}

/* the select needs its own arrow once the native one is suppressed */
.field select{
  appearance:none;
  padding-right:40px;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23A2A8B0' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
  background-repeat:no-repeat;
  background-position:right 14px center;
  background-size:16px;
}
.field select option{ background:var(--d-field); color:var(--d-text); }

/* --- invalid + error text --- */
.field.is-invalid input,
.field.is-invalid select,
.field.is-invalid textarea{
  border-color:var(--state-err);
  box-shadow:0 0 0 3px rgba(255,107,107,.18);
}
.field__err{
  margin:0;
  font-size:var(--fs-xs); font-weight:500;
  color:var(--state-err-text);
}

.cform__submit{
  margin-top:clamp(18px,2vw,24px);
  width:100%;
}
.cform__status{
  margin:14px 0 0;
  font-size:var(--fs-sm);
  color:var(--d-text-2);
  min-height:1.4em;
}
.cform__status.is-ok{ color:var(--state-ok); }
.cform__status.is-err{ color:var(--state-err-text); }

/* .contact__inner stacks in the shared 1080px block further down */
@media (max-width:560px){
  .cform__grid{ grid-template-columns:minmax(0,1fr); }
}

/* ==========================================================================
   TOUCH TARGETS
   On a mouse these link rows are fine at their text height, and padding them
   out would wreck the footer's density. On a touch screen they are too small
   to hit confidently, so the tap area grows only where a coarse pointer is
   actually in use.
   ========================================================================== */
@media (pointer:coarse){
  .footer__col ul{ gap:0; }
  .footer__col li > a,
  .footer__col li > span,
  .contact__details dd a,
  .footer__by a{
    display:inline-flex; align-items:center;
    min-height:44px;
  }
  /* The lockups are the main route to each company's own site. The overlay
     expands the hit area past 44px without making the strip taller, which
     matters because the strip has to stay inside the first screen. */
  .hero__marks a::after{
    content:''; position:absolute; inset:-12px -20px;
  }
}

/* Where the burger stands down the horizontal nav shows — but a tablet
   (1024x768, 1080x810) is still a coarse pointer, and there the six link rows
   measured 41x34 with a 34px hit area. Same remedy as the lockups: a transparent
   overlay takes each to 46px without touching the 92px header. Held to the same
   980px threshold as the bar itself, so the drawer's own 49px rows — which sit
   0px apart — never grow hit areas that overlap each other. */
@media (pointer:coarse) and (min-width:980px){
  .nav__link::before{
    content:''; position:absolute; inset:-6px -8px;
  }
}

/* ==========================================================================
   FOOTER
   ========================================================================== */
.footer{
  background:var(--d-bg-foot);
  color:var(--d-text-2);
  padding-block:0 30px;
}
.footer__top{
  display:grid;
  /* the brand block only holds a 208px logo and one short line, so 1fr was
     over-allocating it and squeezing the contact column below the width of
     the email address */
  grid-template-columns:minmax(0,.8fr) minmax(0,2fr);
  gap:clamp(34px,5vw,70px);
  padding-block:clamp(44px,5.5vw,68px);
  border-top:1px solid var(--d-rule);
}
.footer__logo{ height:79px; width:auto; margin-bottom:18px; }
.footer__tag{
  margin:0;
  font-size:var(--fs-2xs); font-weight:500; letter-spacing:.18em; text-transform:uppercase;
  color:var(--d-text-3);
}
.footer__cols{
  display:grid;
  /* 230px is the width the longest line (the email address) needs. Below that
     the row drops to fewer columns rather than breaking the address mid-token.
     min(100%,...) keeps it from overflowing a narrow phone. */
  grid-template-columns:repeat(auto-fit,minmax(min(100%,230px),1fr));
  gap:30px;
}
.footer__col h3{
  font-size:var(--fs-2xs); font-weight:700; letter-spacing:.18em; text-transform:uppercase;
  color:var(--yellow);
  margin-bottom:16px;
}
.footer__col ul{ display:grid; gap:10px; }
/* the contact column pairs each line with its icon; the icon inherits the
   link colour, so it brightens with the text on hover for free */
.footer__contact li > a,
.footer__contact li > span{
  /* flex, not inline-flex: an inline box shrink-wraps to its content and the
     email address is one unbreakable token, so the row pushed past its own
     column. Block-level fills the track and cannot exceed it. */
  display:flex; align-items:flex-start; gap:9px;
}
.footer__contact .ico{ margin-top:.28em; }
/* the address is the longest string in the footer and must not force the
   column wider than its track */
/* <address> defaults to italic */
.footer__contact address{ font-style:normal; }
.footer__contact a > span,
.footer__contact span > span,
.footer__contact address{
  min-width:0;
  /* anywhere, not break-word: only this value lowers the min-content width,
     which is what actually lets the column shrink */
  overflow-wrap:anywhere;
  /* inherit, so the label follows its link through hover and focus. The
     blanket ".footer__col span" colour above would otherwise pin it and only
     the icon (stroke:currentColor) would react. */
  color:inherit;
}
.footer__col a,.footer__col span{
  font-size:var(--fs-base); color:var(--d-text-2);
  transition:color .2s var(--ease);
}
.footer__col a:hover{ color:var(--yellow); }

.footer__legal{ padding-top:26px; border-top:1px solid var(--d-rule); }
.footer__bottom{
  display:flex; justify-content:space-between; align-items:center;
  gap:16px; flex-wrap:wrap;
  font-size:var(--fs-xs); color:var(--d-text-3);
}
.footer__by a{ color:var(--d-text-2); }
.footer__by a:hover{ color:var(--yellow); }

/* ==========================================================================
   SCROLL REVEAL
   ========================================================================== */
/* Content is visible by default. Only once the script confirms it can drive the
   observer does it opt in to hiding, so a failed or unsupported observer can
   never leave the page blank. */
.js-reveal .reveal{
  opacity:0; transform:translateY(20px);
  transition:opacity .7s var(--ease) var(--d,0ms), transform .7s var(--ease) var(--d,0ms);
}
.js-reveal .reveal.in{ opacity:1; transform:none; }

/* ==========================================================================
   RESPONSIVE
   ========================================================================== */
@media (max-width:1080px){
  /* minmax(0,1fr), not 1fr: a bare 1fr keeps a min-content floor, so long
     words at large text sizes pushed the column past the viewport */
  .about__body{ grid-template-columns:minmax(0,1fr); gap:40px; }
  /* one column per row on tablet and below, so each list reads as its own
     block instead of two narrow columns competing side by side */
  .footer__cols{ grid-template-columns:minmax(0,1fr); gap:34px; }
  /* the frame is already 4/5; below the split it just gets a little more room */
  .about__portrait{ max-width:520px; }
  /* below the split it gets the same room as the portrait above it */
  .about__officers{ max-width:520px; }
  .contact__inner{ grid-template-columns:minmax(0,1fr); }
  .footer__top{ grid-template-columns:minmax(0,1fr); }
  .clauses{ grid-template-columns:repeat(2,minmax(0,1fr)); }
}

@media (max-width:900px){
  /* the hero drops its full-viewport floor and sits at content height, and the
     four lockups fall into a 2x2 grid */
  .hero{ min-height:0; }
  .hero__marks{ grid-template-columns:repeat(2,minmax(0,1fr)); }
}

/* Phones tall enough to hold it get the same one-screen treatment as desktop.
   Below 700px of height the compression needed would leave the headline and
   lede genuinely cramped, so those viewports scroll instead. */
@media (max-width:900px) and (min-height:700px){
  .hero{ min-height:100svh; }
  .hero__content{ padding-block:min(clamp(44px,5vw,80px), 3.4svh); }
  .hero .kicker{ margin-bottom:min(20px, 1.6svh); }
  .hero__title{ margin-bottom:min(clamp(22px,2.8vw,34px), 2.6svh); }
  .hero__lede{ margin-bottom:min(clamp(28px,3.4vw,44px), 2.4svh); }
  .hero__marks li{ padding-block:min(clamp(24px,2.6vw,34px), 1.9svh); }
  .hero__marks a{ height:min(clamp(35px,calc(2.8vw + 5px),45px), 3.8svh); }
}

@media (max-width:900px){
  .hero__marks{ grid-template-columns:repeat(2,minmax(0,1fr)); }
  .hero__marks li:nth-child(-n+2){ border-bottom:1px solid rgba(255,255,255,.16); }
  .hero__marks li:nth-child(odd){ border-left:0; }
}

/* Wide-but-short: a phone in landscape, or any window under 700px tall at this
   width. The rule above already drops `min-height` to 0 here, so the hero is at
   natural height and scrolls — the one-screen contract has been given up, and
   the svh caps are buying nothing. What they were costing: at 740x360 the four
   lockups measured 15.8px tall (against the 35px clamp floor) and their
   coarse-pointer hit area came out at 40px, under the 44px accessibility floor.
   Where there is no screen to fit into, the width-based clamps stand. */
@media (max-width:900px) and (max-height:699px){
  .hero__marks li{ padding-block:clamp(24px,2.6vw,34px); }
  .hero__marks a{ height:clamp(35px,calc(2.8vw + 5px),45px); }
}

/* And on the same viewports the strip goes back to one row. 2x2 spends an extra
   row of the axis that is scarcest in landscape: at 740x360 the content column
   is 626px, so four tracks of 156px still hold a 92px-wide lockup with room.
   Held above 660px so portrait phones keep the 2x2. */
@media (min-width:660px) and (max-width:900px) and (max-height:699px){
  .hero__marks{ grid-template-columns:repeat(4,minmax(0,1fr)); }
  .hero__marks li:nth-child(-n+2){ border-bottom:0; }
  .hero__marks li:nth-child(odd){ border-left:1px solid rgba(255,255,255,.2); }
  .hero__marks li:first-child{ border-left:0; }
}

/* The horizontal bar needs 671px of clear space beside the logo. Measured, it
   only gets that from 980px up (676px available); at 979 and below "The
   Standard" broke onto two lines and the phone CTA onto two — three at 861px,
   where the button alone measured 87px inside the 92px header. The burger was
   standing down at 860px, so every window from 861 to 979 (a landscape phone at
   896x414 among them) carried a visibly broken header. */
@media (max-width:979px){
  .burger{ display:block; }
  .nav{
    position:fixed; inset:var(--header-h) 0 auto 0;
    flex-direction:column; align-items:stretch; gap:0;
    padding:8px var(--gutter) 24px;
    background:var(--paper);
    border-bottom:1px solid var(--rule);
    box-shadow:0 24px 50px rgba(16,19,24,.14);
    transform:translateY(-14px);
    opacity:0; visibility:hidden;
    transition:opacity .28s var(--ease), transform .28s var(--ease), visibility .28s;
    max-height:calc(100dvh - var(--header-h));
    overflow-y:auto;
  }
  .nav.is-open{ opacity:1; visibility:visible; transform:none; }
  .nav__link,
  .site-header .nav__link{
    padding:15px 0; font-size:var(--fs-md);
    color:var(--ink);
    border-bottom:1px solid var(--rule);
  }
  .nav__link::after{ display:none; }
  .nav__cta{ margin:18px 0 0; }
}

@media (max-width:600px){
  /* 10px tighter than the desktop curve, everywhere at once */
  :root{ --gutter:clamp(30px, calc(5vw + 10px), 144px); }
  .about__figures{ grid-template-columns:repeat(2,minmax(0,1fr)); row-gap:22px; }
  .faq__q{ padding-right:44px; }
  .pillars{ grid-template-columns:minmax(0,1fr); }
  .pillars li{ border-left:0; padding:20px 0; border-top:1px solid var(--rule); }
  .pillars li:first-child{ border-top:0; padding-top:0; }
  .pillars li + li{ padding-left:0; }
  .clauses{ grid-template-columns:minmax(0,1fr); }
  .contact__details > div{ grid-template-columns:minmax(0,1fr); gap:6px; }
  .footer__bottom{ flex-direction:column; align-items:flex-start; gap:8px; }
}

/* ==========================================================================
   MOTION PREFERENCES
   ========================================================================== */
@media (prefers-reduced-motion:reduce){
  /* Movement goes; feedback stays. A blanket transition kill also removes the
     hover, focus and validation responses people rely on to know a control
     registered, so colour and opacity keep a short transition and only motion
     is suppressed. */
  *,*::before,*::after{
    animation-duration:.01ms !important;
    animation-iteration-count:1 !important;
    transition-duration:.12s !important;
    transition-property:color, background-color, border-color, box-shadow, opacity, outline-color !important;
    scroll-behavior:auto !important;
  }
  /* nothing translates, scales or rotates */
  .btn:hover, .btn:active, .cpanel:hover, .clauses li:hover, .clogo:hover,
  .hero__marks a:hover, .cpanel__cta:hover, .cpanel__cta:hover .cpanel__arrow,
  .btn:hover .btn__arrow, .nav__link::after{
    transform:none !important;
  }
  .nav__link:hover::after, .nav__link.is-active::after{ transform:scaleX(1) !important; }
  .reveal{ opacity:1; transform:none; }
  /* freezing the track would leave four of the seven marks behind overflow,
     so unwrap the rail into a static centred row instead */
  .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; }
}
