/* ==========================================================================
   Om Sai Tools and Technologies - design system
   --------------------------------------------------------------------------
   Built from the client's own two-page brand sheet. Every colour below is a
   hex printed in that sheet, except the three greys marked DERIVED, which are
   tints we had to invent because the sheet supplies no light-mode surface.

   Character: flat, hard-edged, high contrast. Charcoal grounds, white type,
   orange used sparingly. The angled "speed bar" from the logo is the one
   repeating graphic device. No gradients, no drop shadows, no soft corners.
   ========================================================================== */

@import url("fonts.css");
@import url("blocks.css");

/* ==========================================================================
   1. Tokens
   --------------------------------------------------------------------------
   MEASURED CONTRAST, DO NOT UNDO. #fd4f03 is the client's brand orange and it
   does not change. It simply cannot carry normal-size text on a light ground,
   so the site runs two oranges: --orange on dark, --orange-ink on light.

     white          on #fd4f03  = 3.34:1   FAILS  (4.5:1 needed)
     #fd4f03  text  on white    = 3.34:1   FAILS
     #fd4f03  text  on #f2f3f4  = 3.00:1   FAILS
     #fd4f03  text  on #171819  = 5.33:1   PASSES
     #171819  text  on #fd4f03  = 5.33:1   PASSES
     #171819  text  on #fe710e  = 6.42:1   PASSES  (.btn--primary hover)
     #fd4f03  text  on #202324  = 4.74:1   PASSES  (.stats, .machine-strip)
     #c23c00  text  on white    = 5.33:1   PASSES
     #c23c00  text  on #f2f3f4  = 4.80:1   PASSES

   The rule: any --orange used as TEXT on a light ground becomes --orange-ink,
   and the dark grounds (.section--dark, .hero, .cta, .page-banner, and the
   always-charcoal .stats / .machine-strip / .spec bands) keep --orange.
   Icons and rules are non-text graphics and only need 3:1, so .tile-icon and
   .contact-list svg stay --orange at 3.34:1 on white.
   ========================================================================== */

:root {
  /* --- Brand colour, straight off the brand sheet --- */
  --ink-900: #171819;        /* dark ground: header, footer, dark bands      */
  --ink-800: #202324;        /* raised surface on dark: cards, table rows    */
  --black:   #000000;        /* image overlays only                          */
  --white:   #ffffff;
  --orange:      #fd4f03;    /* primary accent                               */
  --orange-hi:   #fe710e;    /* hover only, never a resting state            */
  --orange-ink:  #c23c00;    /* orange TEXT on LIGHT grounds only            */

  /* --- DERIVED greys. Not in the brand sheet. --- */
  --ink-700: #2d3133;        /* hairlines and borders on dark                */
  --paper:   #ffffff;        /* light section ground                         */
  --paper-2: #f2f3f4;        /* alternating light section                    */
  --rule:    #dfe1e3;        /* hairlines on light                           */
  --muted:   #5d6467;        /* secondary body text on light                 */
  --muted-d: #9aa1a4;        /* secondary body text on dark                  */

  /* --- Type --- */
  --font-head: "Teko", "Oswald", "Arial Narrow", system-ui, sans-serif;
  --font-body: "Montserrat", system-ui, -apple-system, "Segoe UI", sans-serif;

  /* Fluid scale. Teko runs condensed and short, so headings are set larger
     than a Montserrat scale would be, with much tighter line-height. */
  --fs-display: clamp(2.9rem, 7vw, 5.25rem);
  --fs-h1:      clamp(2.5rem, 5.5vw, 4rem);
  --fs-h2:      clamp(2rem, 4vw, 3rem);
  --fs-h3:      clamp(1.5rem, 2.4vw, 2rem);
  --fs-h4:      clamp(1.2rem, 1.6vw, 1.4rem);
  --fs-body:    1rem;
  --fs-lead:    clamp(1.05rem, 1.4vw, 1.2rem);
  --fs-small:   0.875rem;
  --fs-micro:   0.75rem;

  /* --- Space. A 4px base, so everything lands on a grid. --- */
  --s-1: 0.25rem;  --s-2: 0.5rem;   --s-3: 0.75rem;  --s-4: 1rem;
  --s-5: 1.5rem;   --s-6: 2rem;     --s-7: 3rem;     --s-8: 4rem;
  --s-9: 6rem;     --s-10: 8rem;

  --section-y: clamp(3.5rem, 8vw, 7rem);   /* vertical rhythm per section */
  --container: 1200px;
  --gutter: clamp(1.25rem, 4vw, 2.5rem);

  /* --- Hard edges. 2px is the maximum radius anywhere on this site. --- */
  --radius: 2px;

  /* --- Motion. Short and mechanical, nothing floaty. --- */
  --t-fast: 120ms cubic-bezier(0.2, 0, 0.2, 1);
  --t-base: 200ms cubic-bezier(0.2, 0, 0.2, 1);

  --header-h: 76px;
  /* The header's own 1px bottom border counts toward the sticky block's real
     height. Leave it out and the mobile menu drops 1px high, overlapping that
     border, and in-page anchors land 1px under the bar. */
  --header-total: calc(var(--header-h) + 1px);
}

@media (max-width: 900px) {
  :root { --header-h: 64px; }
}

/* ==========================================================================
   2. Reset
   ========================================================================== */

*, *::before, *::after { box-sizing: border-box; }

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  scroll-padding-top: calc(var(--header-total) + 1rem);
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    transition-duration: 0.01ms !important;
  }
}

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink-900);
  font-family: var(--font-body);
  font-size: var(--fs-body);
  line-height: 1.7;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-x: hidden;           /* mobile viewport must never widen */
}

img, svg, video { display: block; max-width: 100%; height: auto; }

h1, h2, h3, h4 {
  font-family: var(--font-head);
  font-weight: 700;
  text-transform: uppercase;
  line-height: 0.95;
  letter-spacing: 0.01em;
  margin: 0 0 var(--s-4);
  text-wrap: balance;
}

h1 { font-size: var(--fs-h1); }
h2 { font-size: var(--fs-h2); }
h3 { font-size: var(--fs-h3); }
h4 { font-size: var(--fs-h4); letter-spacing: 0.03em; }

p { margin: 0 0 var(--s-4); text-wrap: pretty; }
p:last-child { margin-bottom: 0; }

a { color: inherit; text-decoration-thickness: 1px; text-underline-offset: 3px; }

ul, ol { margin: 0 0 var(--s-4); padding-left: 1.2em; }
li { margin-bottom: var(--s-2); }

:focus-visible {
  outline: 3px solid var(--orange);
  outline-offset: 3px;
}

.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-link {
  position: absolute; top: -100px; left: var(--s-4); z-index: 999;
  background: var(--orange); color: var(--ink-900);   /* 5.33:1, not 3.34:1 */
  padding: var(--s-3) var(--s-5); font-weight: 700;
}
.skip-link:focus { top: var(--s-3); }

/* ==========================================================================
   3. Layout
   ========================================================================== */

.container {
  width: 100%;
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

.container--narrow { max-width: 820px; }

.section { padding-block: var(--section-y); }
.section--tight { padding-block: clamp(2.5rem, 5vw, 4rem); }
.section--alt   { background: var(--paper-2); }
.section--dark  { background: var(--ink-900); color: var(--white); }
.section--dark h1, .section--dark h2, .section--dark h3 { color: var(--white); }
.section--dark p { color: var(--muted-d); }

.grid { display: grid; gap: var(--s-5); }
@media (min-width: 640px)  { .grid--2 { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 900px)  { .grid--3 { grid-template-columns: repeat(3, 1fr); } }
@media (min-width: 640px)  { .grid--4 { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1000px) { .grid--4 { grid-template-columns: repeat(4, 1fr); } }

/* ==========================================================================
   4. The chevron device
   --------------------------------------------------------------------------
   Lifted from the angled bars flanking the word TOOLS in the logo. This is
   the identity's only repeating graphic, so it carries section labels,
   buttons and dividers. A 10px horizontal shear, always leaning right.
   ========================================================================== */

.chev {
  --shear: 10px;
  clip-path: polygon(var(--shear) 0, 100% 0, calc(100% - var(--shear)) 100%, 0 100%);
}

/* Small orange eyebrow that sits above a section heading. */
.eyebrow {
  display: inline-block;
  font-family: var(--font-body);
  font-size: var(--fs-micro);
  font-weight: 700;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--orange-ink);
  margin-bottom: var(--s-3);
  padding-left: 2.25rem;
  position: relative;
}
.eyebrow::before {
  content: "";
  position: absolute; left: 0; top: 50%;
  width: 1.65rem; height: 3px;
  background: var(--orange);
  transform: translateY(-50%) skewX(-24deg);
}

/* On every charcoal ground the brand orange already clears 4.5:1, so the
   eyebrow goes back to it there. The ::before above is a decorative rule, not
   text, so it stays --orange on both grounds. */
.section--dark .eyebrow,
.hero .eyebrow,
.cta .eyebrow,
.page-banner .eyebrow { color: var(--orange); }

.section-head { max-width: 46rem; margin-bottom: var(--s-7); }
.section-head p { font-size: var(--fs-lead); color: var(--muted); }
.section--dark .section-head p { color: var(--muted-d); }

/* ==========================================================================
   5. Buttons
   ========================================================================== */

.btn {
  --shear: 9px;
  display: inline-flex; align-items: center; gap: var(--s-2);
  font-family: var(--font-body);
  font-size: var(--fs-small);
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  text-decoration: none;
  padding: 0.95rem 1.9rem;
  border: 0; cursor: pointer;
  /* A button must never be squeezed by its flex parent. Without these the
     header quote button shrank to 108px while its label needed ~170px, and
     the text spilled straight out of the sheared shape. */
  flex-shrink: 0;
  white-space: nowrap;
  transition: background var(--t-fast), color var(--t-fast), transform var(--t-fast);
  clip-path: polygon(var(--shear) 0, 100% 0, calc(100% - var(--shear)) 100%, 0 100%);
}

.btn:hover { transform: translateX(2px); }
.btn:active { transform: translateX(0); }

/* Charcoal on orange, not white on orange. White measured 3.34:1 on the
   resting fill and 2.77:1 on the hover fill; charcoal measures 5.33:1 and
   6.42:1. Icons inside the button are stroke="currentColor", so they follow
   the label colour; the rule below only makes that explicit. */
.btn--primary { background: var(--orange); color: var(--ink-900); }
.btn--primary:hover { background: var(--orange-hi); }
.btn--primary svg { color: currentColor; }

.btn--dark { background: var(--ink-900); color: var(--white); }
.btn--dark:hover { background: var(--ink-800); }

/* Ghost variant.
   Deliberately a translucent fill, not an outline. An inset border would be
   sliced open by the clip-path along both sheared edges, and a pseudo-element
   border sitting at z-index -1 disappears entirely inside any parent that
   creates a stacking context (which .hero does, via overflow:hidden). A flat
   translucent fill keeps the chevron silhouette exactly and cannot break. */
.btn--ghost {
  background: rgba(23, 24, 25, 0.08);
  color: var(--ink-900);
}
.btn--ghost:hover { background: rgba(23, 24, 25, 0.14); }

/* Every dark ground on the site, named explicitly. .section--dark alone was
   not enough: the hero, the CTA band and the interior page banners each carry
   their own class, and on those the button was rendering charcoal on charcoal. */
.section--dark .btn--ghost,
.hero .btn--ghost,
.cta .btn--ghost,
.page-banner .btn--ghost,
.site-header .btn--ghost,
.handoff .btn--ghost {
  background: rgba(255, 255, 255, 0.12);
  color: var(--white);
}
.section--dark .btn--ghost:hover,
.hero .btn--ghost:hover,
.cta .btn--ghost:hover,
.page-banner .btn--ghost:hover,
.site-header .btn--ghost:hover,
.handoff .btn--ghost:hover { background: rgba(255, 255, 255, 0.2); }

.btn--lg { font-size: var(--fs-body); padding: 1.15rem 2.4rem; }

.btn-row { display: flex; flex-wrap: wrap; gap: var(--s-4); }

/* Only ever one of these is displayed, so a screen reader never meets the
   button twice: display:none removes it from the accessibility tree. */
.header-cta { display: none; }
@media (min-width: 1201px) { .header-cta { display: inline-flex; } .nav-cta { display: none; } }

/* ==========================================================================
   6. Header
   ========================================================================== */

.site-header {
  position: sticky; top: 0; z-index: 100;
  background: var(--ink-900);
  border-bottom: 1px solid var(--ink-700);
  height: var(--header-h);
  display: flex; align-items: center;
}

/* One row: logo left, then navigation, the ISO badge, and the call to action.
   On a phone the navigation collapses to a panel, so the row reads
   logo, badge, hamburger, which is what puts the credential top right on the
   screen a buyer actually looks at first. */
.site-header > .container {
  display: flex; align-items: center; gap: var(--s-4);
  width: 100%;
}

/* min-height, not a bigger logo. At phone widths the mark renders 124x33, so
   the link around it was a 33px tap target. This gives it a comfortable hit
   area inside the 64px bar while the logo itself stays the size it should be. */
/* ---- Brand lockup ----
   The supplied logo reads OM SAI / TOOLS / DELIVERING EXCELLENCE. The company
   is Om Sai Tools and Technologies, so the name needed completing.

   The tagline was cut from the artwork rather than kept, because at header size
   it is 4.2px tall (45px of a 1833px file rendered at 180px) and is decoration
   rather than information. "and Technologies" then goes back in as real text,
   set in the brand's own Teko, so it stays crisp at any size, scales with the
   logo, and is readable by search engines rather than locked inside a PNG.

   SYMMETRY: in the source artwork the wordmark starts at x=532 of 1833, which
   is 29.02%, and the TOOLS line runs to the right edge. The text line is
   indented by exactly that 29.02% and tracked so it terminates flush right,
   so it sits in the same column as OM SAI and TOOLS rather than under the gear. */

.brand {
  --lockup: 180px;
  display: block;
  position: relative;
  flex-shrink: 0;
  margin-right: auto;
  min-height: 44px;
  width: var(--lockup);
}

/* The artwork is used at its FULL height. An earlier version cropped the
   canvas to drop the tagline, which silently sliced 71 rows off the bottom of
   the gear, because the gear spans all 489 rows while the wordmark only
   occupies the middle. The tagline is now erased from the file instead, which
   leaves an 18.8% free band at the bottom of the wordmark column. */
.brand-mark { display: block; width: 100%; height: auto; }

/* The completing line sits in that band. The negative top margin is a
   percentage, so it resolves against the brand's own width and the whole
   lockup scales as one piece at every breakpoint. */
/* Every value below is derived from --lockup, so setting one width scales the
   whole thing. The footer previously hard-coded its own font-size and margin
   and drifted: 21px of gap under TOOLS against the header's 1px, and the line
   overshot the right edge by 9px. */
.brand-ext {
  display: block;
  margin-left: 29.02%;                          /* the wordmark's left edge */
  margin-top: calc(var(--lockup) * -0.03);      /* lifts it into the free band */
  font-family: var(--font-head);
  font-weight: 700;
  font-size: calc(var(--lockup) * 0.07222);
  line-height: 1;
  letter-spacing: 0.152em;       /* tuned so the line ends flush right */
  text-transform: uppercase;
  color: var(--white);
  white-space: nowrap;
}

/* The whole lockup scales as one piece: .brand sets the width, the artwork is
   width:100%, and .brand-ext's offsets are percentages of that same width. */
@media (max-width: 1200px) { .brand { --lockup: 158px; } }

@media (max-width: 520px) {
  /* 120, not 128. Measured at 390: the row needed 355px in a 350px content
     box. The 8px it gains puts the lockup, badge and hamburger inside budget
     without leaning on the toggle's optical negative margin to hide it. */
  .brand { --lockup: 120px; }
  .brand-ext { letter-spacing: 0.167em; }
}


/* ==========================================================================
   6a. The ISO credential badge
   --------------------------------------------------------------------------
   Top right, inline with the logo, and the whole block is one clickable link
   through to the certificate. No arrow glyph: it reads as a credential, not a
   navigation control.

   Near black on the charcoal bar rather than orange, because it sits beside an
   orange call to action and two competing oranges in one row is noise.
   ========================================================================== */

.iso-badge {
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
  flex-shrink: 0;
  text-decoration: none;
  color: var(--white);
  background: rgba(255, 255, 255, 0.06);
  border: 1px solid var(--ink-700);
  border-radius: var(--radius);
  padding: 0.35rem 0.7rem;
  min-height: 44px;
  transition: background var(--t-fast), border-color var(--t-fast);
}
.iso-badge:hover { background: rgba(255, 255, 255, 0.12); border-color: var(--orange); }

.iso-badge-mark {
  width: 22px; height: 22px;
  color: var(--orange);
  flex-shrink: 0;
  transition: transform var(--t-base);
}
.iso-badge:hover .iso-badge-mark { transform: scale(1.08); }

.iso-badge-text { display: flex; flex-direction: column; line-height: 1.05; }

.iso-badge-std {
  font-size: var(--fs-micro);
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  white-space: nowrap;
}
.iso-badge-sub {
  font-size: 0.625rem;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--orange);
  white-space: nowrap;
  margin-top: 1px;
}

.nav { display: flex; align-items: center; gap: 1.25rem; }

/* Scoped off .btn and .header-tel. `.nav a` is specificity (0,1,1) and beats
   `.btn` (0,1,0), so an unscoped rule here silently strips the quote button's
   padding and colour. That bug shipped once already. */
.nav a:not(.btn):not(.header-tel) {
  font-size: 0.8125rem;
  font-weight: 600;
  letter-spacing: 0.045em;
  text-transform: uppercase;
  color: var(--white);
  text-decoration: none;
  padding: var(--s-2) 0;
  position: relative;
  white-space: nowrap;
  transition: color var(--t-fast);
}
.nav a:not(.btn):not(.header-tel):hover { color: var(--orange); }

.nav a:not(.btn)[aria-current="page"] { color: var(--orange); }
.nav a:not(.btn)[aria-current="page"]::after {
  content: "";
  position: absolute; left: 0; right: 0; bottom: -2px;
  height: 3px; background: var(--orange);
  transform: skewX(-24deg);
}

/* Hidden on desktop, where the number would crowd a row that already carries
   six links, the badge and the call to action. Shown inside the mobile menu. */
.header-tel {
  display: none; align-items: center; gap: var(--s-2);
  color: var(--white); text-decoration: none;
  font-weight: 700; font-size: var(--fs-small);
  white-space: nowrap;
}
.header-tel svg { color: var(--orange); flex-shrink: 0; }
.header-tel:hover { color: var(--orange); }


.nav-toggle {
  display: none;
  flex-shrink: 0;
  background: none; border: 0; cursor: pointer;
  padding: var(--s-2); margin-right: calc(var(--s-2) * -1);
  color: var(--white);
}

@media (max-width: 1200px) {
  .nav-toggle { display: block; }
  .header-tel { display: inline-flex; }

  .nav {
    position: fixed; inset: var(--header-total) 0 auto 0;
    flex-direction: column; align-items: stretch; gap: 0;
    background: var(--ink-900);
    border-bottom: 1px solid var(--ink-700);
    padding: var(--s-4) var(--gutter) var(--s-6);
    transform: translateY(-120%);
    /* translateY alone leaves the closed menu focusable: it is off screen but
       still visible, so a keyboard walked through all seven links on every
       page. visibility is discretely animatable, so listing it here flips to
       hidden only after the slide out finishes and back to visible at the
       start of the slide in. The transition still plays in full.
       js/site.js also sets inert while it is closed, which covers the 200ms
       window where visibility is still "visible" mid-close. */
    visibility: hidden;
    transition: transform var(--t-base), visibility var(--t-base);
    max-height: calc(100dvh - var(--header-total));
    overflow-y: auto;
  }
  .nav[data-open="true"] { transform: translateY(0); visibility: visible; }
  .nav a:not(.btn) { padding: var(--s-4) 0; border-bottom: 1px solid var(--ink-700); font-size: 1rem; letter-spacing: 0.06em; }
  .nav a:not(.btn)[aria-current="page"]::after { display: none; }
  .nav .btn { margin-top: var(--s-5); justify-content: center; }
}

/* ==========================================================================
   7. Hero
   --------------------------------------------------------------------------
   Deliberately a contained split, not a full-bleed banner. The client's best
   photograph is 1490px wide, which goes soft stretched across a wide monitor.
   Containing it keeps it sharp and gives the headline a dark ground to sit on.
   ========================================================================== */

.hero {
  background: var(--ink-900);
  color: var(--white);
  position: relative;
  overflow: hidden;
}

.hero .container {
  display: grid;
  gap: var(--s-7);
  padding-block: clamp(3rem, 7vw, 5.5rem);
  align-items: center;
}

@media (min-width: 900px) {
  /* 1.25fr, not 1.05fr. Measured: the two hero buttons need 598px side by
     side and the narrower column only gave 541px, so they wrapped into a
     ragged stack. This widens the text column to 595px without pushing the
     photo below its own sharpness budget (it still renders 1.6x at 2x DPR). */
  .hero .container { grid-template-columns: 1.25fr 1fr; gap: var(--s-8); }
}

.hero h1 {
  font-size: var(--fs-display);
  color: var(--white);
  margin-bottom: var(--s-5);
}
.hero h1 em { font-style: normal; color: var(--orange); }

.hero-lead {
  font-size: var(--fs-lead);
  color: var(--muted-d);
  max-width: 34rem;
  margin-bottom: var(--s-6);
}

/* The hero photograph changed on 15 Sep 26 to the door outer panel press
   tool, which is 1280x548 (2.34:1) where the old one was 1490x862 (1.73:1),
   so the old 3:2 box would now throw away a third of the tool. Two numbers
   set the new box, and both are measured rather than chosen.

   2.37:1 is very slightly TALLER in ratio than the file itself, which is a
   deliberate bottom crop. The supplied "-nomarks-" file still carries the
   customer's stamped part line along its bottom edge; the crop that was meant
   to remove it stopped about 31px short and the lettering is still legible at
   full size. At 2.37:1 with object-position top, the bottom 31px of the file
   is never painted. The file itself still needs re-cropping at source, which
   is flagged in the handover, because it remains readable if fetched direct.

   max-width 700px: under the 900px breakpoint the hero stacks and the photo
   would otherwise take the whole container, which is 827px wide at an 899px
   viewport. A 1280px file rendered 827px wide is 0.77 of the half-native
   sharpness budget. 700px holds it at 0.91. From 900px up the media column is
   469px at a 1440 viewport, so the cap never binds there. */
.hero-media { position: relative; max-width: 700px; margin-inline: auto; }
.hero-media img {
  width: 100%;
  aspect-ratio: 1280 / 548;
  object-fit: cover;
  object-position: center top;
  border: 1px solid var(--ink-700);
}

/* Orange corner bracket, echoing the logo's angled bars. */
.hero-media::after {
  content: "";
  position: absolute; right: -10px; bottom: -10px;
  width: 96px; height: 96px;
  border-right: 6px solid var(--orange);
  border-bottom: 6px solid var(--orange);
  pointer-events: none;
}

/* A single caption strip, used to label a photo honestly. */
.media-caption {
  font-size: var(--fs-micro);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--muted-d);
  margin-top: var(--s-3);
}

/* ==========================================================================
   8. Stats band
   --------------------------------------------------------------------------
   This does the job a client logo wall normally does. Every figure here is
   verifiable from the client's own machine specifications.
   ========================================================================== */

.stats {
  background: var(--ink-800);
  border-block: 1px solid var(--ink-700);
}

.stats .container {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 1px;
  padding-block: 0;
}

@media (min-width: 900px) { .stats .container { grid-template-columns: repeat(4, 1fr); } }

.stat {
  padding: var(--s-6) var(--s-4);
  text-align: center;
  position: relative;
}
.stat + .stat::before {
  content: "";
  position: absolute; left: 0; top: 20%; bottom: 20%;
  width: 1px; background: var(--ink-700);
}

.stat-num {
  font-family: var(--font-head);
  font-size: clamp(2.5rem, 5vw, 3.75rem);
  font-weight: 700;
  line-height: 0.9;
  /* .stats is always var(--ink-800), where orange measures 4.74:1, and this
     is 40px+ display type, so it stays the brand orange. */
  color: var(--orange);
  display: block;
}
.stat-num sup { font-size: 0.45em; vertical-align: super; letter-spacing: 0.02em; }

.stat-label {
  display: block;
  margin-top: var(--s-2);
  font-size: var(--fs-micro);
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--muted-d);
}

/* ==========================================================================
   9. Capability tiles
   ========================================================================== */

.tile {
  background: var(--white);
  border: 1px solid var(--rule);
  padding: var(--s-6);
  position: relative;
  transition: border-color var(--t-base), transform var(--t-base);
  text-decoration: none;
  display: block;
  color: inherit;
  height: 100%;
}

.tile::before {
  content: "";
  position: absolute; left: 0; top: 0; bottom: 0;
  width: 4px; background: var(--orange);
  transform: scaleY(0); transform-origin: top;
  transition: transform var(--t-base);
}
.tile:hover { border-color: var(--ink-900); transform: translateY(-3px); }
.tile:hover::before { transform: scaleY(1); }

/* A non-text graphic, so the bar is 3:1 and orange on white clears it at
   3.34:1. Left as the brand orange deliberately. */
.tile-icon {
  width: 44px; height: 44px;
  color: var(--orange);
  margin-bottom: var(--s-4);
}

/* /404.html runs its four quick links straight off the h1, so their headings
   are h2 there and h3 everywhere else. Both are pinned to the h3 size so a
   tile looks identical whichever level it carries. */
.tile h3, .tile h2 { font-size: var(--fs-h3); margin-bottom: var(--s-3); }
.tile p { color: var(--muted); font-size: var(--fs-small); margin: 0; }

.section--dark .tile { background: var(--ink-800); border-color: var(--ink-700); }
.section--dark .tile:hover { border-color: var(--orange); }
.section--dark .tile p { color: var(--muted-d); }

/* ==========================================================================
   11. Process steps  (spec table now lives in blocks.css)
   ========================================================================== */

.step { position: relative; padding-top: var(--s-6); }

.step::before {
  content: "";
  position: absolute; top: 0; left: 0; right: 0;
  height: 3px; background: var(--rule);
}
.step::after {
  content: "";
  position: absolute; top: 0; left: 0;
  width: 36px; height: 3px; background: var(--orange);
}
.section--dark .step::before { background: var(--ink-700); }

.step-num {
  font-family: var(--font-head);
  font-size: 1rem; font-weight: 700; letter-spacing: 0.14em;
  color: var(--orange-ink);
  display: block; margin-bottom: var(--s-2);
}
.section--dark .step-num,
.hero .step-num,
.cta .step-num,
.page-banner .step-num { color: var(--orange); }
.step h3 { font-size: var(--fs-h4); margin-bottom: var(--s-2); }
.step p { font-size: var(--fs-small); color: var(--muted); margin: 0; }
.section--dark .step p { color: var(--muted-d); }

/* ==========================================================================
   12. Work gallery
   ========================================================================== */

.gallery { display: grid; gap: var(--s-4); grid-template-columns: repeat(2, 1fr); }
@media (min-width: 900px) { .gallery { grid-template-columns: repeat(3, 1fr); gap: var(--s-5); } }

.gallery figure { margin: 0; position: relative; overflow: hidden; background: var(--ink-800); }

.gallery img {
  width: 100%; height: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  transition: transform var(--t-base), filter var(--t-base);
}
.gallery figure:hover img { transform: scale(1.04); }

.gallery figcaption {
  position: absolute; inset: auto 0 0 0;
  background: linear-gradient(to top, rgba(0,0,0,0.88), rgba(0,0,0,0));
  color: var(--white);
  padding: var(--s-6) var(--s-4) var(--s-3);
  font-size: var(--fs-micro);
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

/* A portrait-shaped tile, for the taller source photos. */
.gallery figure.is-tall img { aspect-ratio: 3 / 4; }

/* ==========================================================================
   13. Split content block
   ========================================================================== */

.split { display: grid; gap: var(--s-7); align-items: center; }
@media (min-width: 900px) {
  .split { grid-template-columns: 1fr 1fr; gap: var(--s-8); }
  .split--flip .split-media { order: -1; }
}
.split-media img { width: 100%; object-fit: cover; }

/* ==========================================================================
   14. CTA band
   ========================================================================== */

.cta {
  background: var(--ink-900);
  color: var(--white);
  text-align: center;
  position: relative;
  overflow: hidden;
}
.cta::before {
  content: "";
  position: absolute; left: 0; right: 0; top: 0; height: 4px;
  background: var(--orange);
}
.cta h2 { color: var(--white); margin-bottom: var(--s-4); }
.cta p { color: var(--muted-d); max-width: 44rem; margin-inline: auto; margin-bottom: var(--s-6); }
.cta .btn-row { justify-content: center; }

/* ==========================================================================
   15. Forms
   ========================================================================== */

.field { margin-bottom: var(--s-5); }

.field label {
  display: block;
  font-size: var(--fs-micro);
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  margin-bottom: var(--s-2);
  color: var(--muted);
}
.section--dark .field label { color: var(--muted-d); }

.field input, .field select, .field textarea {
  width: 100%;
  font-family: var(--font-body);
  font-size: var(--fs-body);
  padding: 0.85rem 1rem;
  background: var(--white);
  color: var(--ink-900);
  border: 1px solid var(--rule);
  border-radius: var(--radius);
  transition: border-color var(--t-fast), box-shadow var(--t-fast);
}
.field textarea { min-height: 9rem; resize: vertical; }

.field input:focus, .field select:focus, .field textarea:focus {
  outline: none;
  border-color: var(--orange);
  box-shadow: inset 0 -3px 0 var(--orange);
}

.field .req { color: var(--orange-ink); }
.section--dark .field .req,
.page-banner .field .req { color: var(--orange); }
.field-error { color: #c0392b; font-size: var(--fs-micro); margin-top: var(--s-2); display: none; }
.field[data-invalid="true"] input,
.field[data-invalid="true"] textarea { border-color: #c0392b; }
.field[data-invalid="true"] .field-error { display: block; }

.form-note { font-size: var(--fs-micro); color: var(--muted); }

/* ==========================================================================
   16. Contact details block
   ========================================================================== */

.contact-list { list-style: none; margin: 0; padding: 0; }
.contact-list li {
  display: flex; gap: var(--s-4);
  padding-block: var(--s-4);
  border-bottom: 1px solid var(--rule);
  margin: 0;
}
.section--dark .contact-list li { border-color: var(--ink-700); }
/* The icon is a non-text graphic at 3:1, so it keeps the brand orange. The
   link label is text, so its hover colour follows the light/dark split. */
.contact-list svg { width: 22px; height: 22px; color: var(--orange); flex-shrink: 0; margin-top: 3px; }
.contact-list a { text-decoration: none; font-weight: 600; }
.contact-list a:hover { color: var(--orange-ink); }
.section--dark .contact-list a:hover,
.page-banner .contact-list a:hover { color: var(--orange); }
.contact-list .label {
  display: block;
  font-size: var(--fs-micro); letter-spacing: 0.12em; text-transform: uppercase;
  color: var(--muted); font-weight: 600; margin-bottom: 2px;
}
.section--dark .contact-list .label { color: var(--muted-d); }

/* ==========================================================================
   17. Footer
   ========================================================================== */

.site-footer {
  background: var(--ink-900);
  color: var(--muted-d);
  font-size: var(--fs-small);
  border-top: 4px solid var(--orange);
}

.footer-main {
  display: grid; gap: var(--s-7);
  padding-block: var(--s-8);
}
@media (min-width: 700px)  { .footer-main { grid-template-columns: 1.4fr 1fr; } }
@media (min-width: 1000px) { .footer-main { grid-template-columns: 1.6fr 1fr 1fr 1.2fr; gap: var(--s-6); } }

/* No margin-bottom. This rule predates the lockup, and its 24px sat between
   the artwork and the completing text line, dropping it 24px too low: the
   header measured a 0.7px gap under TOOLS, the footer 24.7px. The spacing
   below the whole lockup now belongs to .footer-brand. Width comes from
   --lockup too, so this only exists for any legacy markup still using it. */
.site-footer img.footer-logo { width: 200px; }

/* These were h4 under an h2, which skipped a heading level on every page.
   They are h2 in the markup now; every declaration here is unchanged, so they
   render exactly as they did: 1.15rem Teko, 0.06em tracking, white. */
.site-footer h2 {
  color: var(--white);
  font-size: 1.15rem;
  letter-spacing: 0.06em;
  margin-bottom: var(--s-4);
}

.site-footer ul { list-style: none; margin: 0; padding: 0; }
.site-footer li { margin-bottom: var(--s-3); }
.site-footer a { color: var(--muted-d); text-decoration: none; transition: color var(--t-fast); }
.site-footer a:hover { color: var(--orange); }

.footer-bar {
  border-top: 1px solid var(--ink-700);
  padding-block: var(--s-5);
  display: flex; flex-wrap: wrap; gap: var(--s-3) var(--s-5);
  align-items: center; justify-content: space-between;
  font-size: var(--fs-micro);
  letter-spacing: 0.04em;
}

/* ==========================================================================
   18. Utilities
   ========================================================================== */

.u-orange { color: var(--orange-ink); }
.section--dark .u-orange,
.hero .u-orange,
.cta .u-orange,
.page-banner .u-orange { color: var(--orange); }
.u-center { text-align: center; }
.u-mb-0 { margin-bottom: 0; }
.u-lead { font-size: var(--fs-lead); }
.u-nowrap { white-space: nowrap; }

/* ==========================================================================
   19. Touch targets
   --------------------------------------------------------------------------
   Measured on a real 390px viewport: the footer links rendered 17px tall and
   the contact links 20px, against a 44px comfortable-tap guideline. Desktop
   keeps the compact spacing, because a mouse does not need the padding.
   ========================================================================== */

@media (max-width: 700px) {
  .site-footer li { margin-bottom: 0; }
  .site-footer li a,
  .contact-list a,
  .footer-credit a {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
  }
  .contact-list li { padding-block: var(--s-2); }
}
