/* Nthalpix Technologies — complete stylesheet for every page.
   One file, cached once by the browser. Page-specific selectors are
   namespaced (.biz-*, .mv2-*, .cat-*, .ex-*) so nothing collides. */

/* ============================================================
   1. TOKENS
   ============================================================ */
:root{
  /* colour */
  --navy:        #0e2039;
  --navy-deep:   #081525;
  --navy-line:   rgba(255,255,255,.14);
  /* sampled from the warm end of the mark's own gradient, so every
     accent on the page is literally the gold in the N */
  /* Brand gold. Reads 9.9:1 on navy — perfect on the dark bands. */
  --gold:        #f7c144;
  --gold-lift:   #f9d175;
  /* same hue, darkened only where gold has to sit on white — the
     brand gold reads 9.8:1 on navy but just 1.7:1 on paper */
  /* kept as an alias so call sites still resolve; same value as brand */
  --gold-deep:   #f7c144;
  /* the mark reads cool -> warm along its diagonal; these are its
     three stops, used for the rule beneath the nav */
  /* brightest genuinely-saturated green in the mark (edge pixels
     blended toward white read brighter but aren't brand colour) */
  --mark-green:  #63cd94;
  /* same hues, darkened only for type on white — the bright cuts sit
     at 1.7-2.0:1 there, well under the 3:1 large-text floor */
  --green-deep:  #2f9e6b;
  --mark-cool:   #37c9b0;
  /* The edge of a form control is the only thing that says where the
     control is: the fields are white on a white plate. It was #d3dae1,
     which is 1.41:1 against that plate, and the consent box #aab3bc at
     2.12:1 -- both under the 3:1 a control's boundary is meant to meet,
     and both genuinely hard to make out on a phone in daylight. This is
     3.16:1, the same cool grey stepped down until it clears with a
     little to spare. */
  --field-edge:#87929f;
  --mark-mid:    #71cb8e;
  --mark-warm:   #e0c557;
  --ink:         #16202c;
  --ink-soft:    #5c6b7d;
  --line:        #e2e6eb;
  --paper:       #ffffff;
  /* Section ground. A cool grey reads as "unstyled default"; a cream
     would pull warm and fight the cool green in the mark. This is white
     carrying about 3% of the mark's own green — reads as white, but
     belongs to the palette. */
  --paper-alt:   #f4f8f5;
  /* Sampled from the reference sites: body copy sits near #1E1E1E,
     never pure #000 — full black on off-white glares. */
  --ink-black:   #1a1d20;
  --ink-body:    #3d444c;

  /* type */
  --font-display:"Playfair Display", "Playfair Fallback", Georgia, "Times New Roman", serif;
  --font-ui:     "Jost", "Jost Fallback", "Helvetica Neue", Arial, sans-serif;
  --font-mono:   "JetBrains Mono", "JetBrains Fallback", "SFMono-Regular", Consolas, monospace;

  /* type scale — fluid, ratio ~1.28 */
  --t-hero: clamp(1.9rem, 5.1vw, 4.6rem);
  --t-h2:    clamp(2.1rem, 4.4vw, 3.75rem);
  --t-h3:    clamp(1.75rem, 3.2vw, 2.7rem);
  --t-lead:  clamp(1.55rem, 3.2vw, 2.85rem);
  --t-body:  1.0125rem;
  --t-small: .875rem;
  --t-micro: .72rem;

  /* motion — one shared vocabulary, so nothing feels ad hoc */
  --mark-src:  url("data:image/png;base64,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");
  --ease-out:  cubic-bezier(.22,.68,.28,1);
  --ease-mask: cubic-bezier(.76,0,.24,1);
  --ease-soft: cubic-bezier(.4,0,.2,1);
  --dur-fast:  .32s;
  --dur-mid:   .7s;
  --dur-slow:  1.15s;

  /* layout */
  --shell:  1380px;
  --gutter: 76px;
}


/* ============================================================
   2. BASE
   ============================================================ */
*,*::before,*::after{ box-sizing:border-box; }

/* The browser's own [hidden]{display:none} is the weakest rule there
   is: any author `display` on the same element silently defeats it,
   and the element stays on the page while every script that set the
   attribute believes it is gone. This makes the attribute mean what
   it says. */
[hidden]{ display:none !important; }

/* Native smooth scrolling is off. Every anchor on this site is already
   intercepted in JavaScript, which scrolls through Lenis on a pointer
   device and jumps instantly elsewhere. Leaving CSS smooth on top of
   that made a page change glide from wherever the reader had been,
   which looked like the old page racing away. */
html{ scroll-behavior:auto; -webkit-text-size-adjust:100%; }

body{
  margin:0;
  font-family:var(--font-ui);
  font-weight:300;
  font-size:var(--t-body);
  line-height:1.72;
  color:var(--ink);
  background:var(--paper);
  -webkit-font-smoothing:antialiased;
  text-rendering:optimizeLegibility;
  overflow-x:hidden;
}

img{ max-width:100%; display:block; }

a{ color:inherit; text-decoration:none; }

ul{ list-style:none; margin:0; padding:0; }

button{ font:inherit; color:inherit; background:none; border:0; cursor:pointer; }

:focus-visible{ outline:2px solid var(--gold-lift); outline-offset:3px; }


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


/* --- type utilities ------------------------------------------------ */
.display{
  font-family:var(--font-display);
  font-weight:600;
  letter-spacing:-.018em;   /* large serif needs negative tracking */
  line-height:1.04;
  margin:0;
}

.display em{ font-style:italic; font-weight:600; }


h2.display{ font-size:var(--t-h2); }

h3.display{ font-size:var(--t-h3); line-height:1.1; }


.eyebrow{
  font-size:.8rem;
  /* was .34em — the widest tracking on the page, on the lowest-contrast
     words on the page. Wide tracking suits an eyebrow, but not at that
     extreme when it also has to survive gold on paper. */
  letter-spacing:.2em;
  text-transform:uppercase;
  font-weight:600;
  color:var(--gold);
  margin:0 0 18px;
  display:flex;
  align-items:center;
  gap:14px;
}

.eyebrow::before{
  content:"";
  width:34px; height:1px;
  background:currentColor;
  flex:none;
  transform:scaleX(0);
  transform-origin:left;
  transition:transform var(--dur-mid) var(--ease-out) .15s;
}

.is-in .eyebrow::before,
.eyebrow.is-in::before{ transform:scaleX(1); }


/* Site default is weight 300, which goes thin and grey in long
   paragraphs on a light ground. Body copy steps to 400 on a darker
   ink so it reads as text rather than as a caption. */
.prose{
  color:var(--ink-body);
  font-weight:400;
  font-size:1.05rem;
  line-height:1.75;
  max-width:58ch;
}

.prose p{ margin:0 0 1.1em; }

.prose p:last-child{ margin-bottom:0; }


/* --- placeholders --------------------------------------------------- */
.ph{
  position:relative;
  background:
    repeating-linear-gradient(45deg, rgba(255,255,255,.035) 0 12px, transparent 12px 24px),
    linear-gradient(140deg,#26405f,#0f2038 58%,#1d3050);
  border:1px dashed rgba(255,255,255,.26);
  display:grid;
  place-items:center;
  overflow:hidden;
}

.ph span{
  font-size:var(--t-micro);
  letter-spacing:.26em;
  text-transform:uppercase;
  color:rgba(255,255,255,.7);
}

.ph--light{
  background:
    repeating-linear-gradient(45deg, rgba(14,32,57,.05) 0 12px, transparent 12px 24px),
    linear-gradient(140deg,#eef1f5,#dce2ea);
  border-color:rgba(14,32,57,.2);
}

.ph--light span{ color:rgba(14,32,57,.55); }


/* --- controls -------------------------------------------------------- */
.pill{
  position:relative;
  display:inline-flex;
  align-items:center;
  justify-content:center;
  gap:14px;
  /* The outline used to break up: patchy along the straight edges and
     thin through the arcs, which is what "blurred in places and dotted
     in others" was. Two causes, both about landing on whole pixels.
     The height came out at 59.52px because it was driven by the line
     box, so the top and bottom strokes straddled a device-pixel
     boundary and were drawn as two half-intensity rows. And 1.5px is
     not a whole number of device pixels at 1x or 3x, so the browser
     antialiased the stroke differently around the curve.
     A fixed even height and a whole-pixel border fix both. */
  padding:0 32px;
  min-height:58px;
  line-height:1;
  border:2px solid currentColor;
  border-radius:999px;
  font-size:1rem;
  font-weight:400;
  letter-spacing:.04em;
  background-color:transparent;
  /* No pseudo-element, no clip, no transform. The fill is the
     element's own background changing value, so there is no
     direction to it and nothing to play in reverse on mouse-out. */
  transition:background-color var(--dur-fast) var(--ease-soft),
             border-color     var(--dur-fast) var(--ease-soft),
             color            var(--dur-fast) var(--ease-soft);
}

/* The arrow moves by transform, not by growing the gap. Animating gap
   changed the button's WIDTH, which pushed the neighbouring button
   sideways — that was the "both buttons react" behaviour. */
.pill:focus-visible{
  background-color:var(--gold);
  border-color:var(--gold);      /* or the navy ring would outline the fill */
  color:var(--navy);
}
@media (hover:hover){ .pill:hover{
  background-color:var(--gold);
  border-color:var(--gold);      /* or the navy ring would outline the fill */
  color:var(--navy);
} }

.pill svg{
  width:19px; height:10px; flex:none;
  transition:transform var(--dur-fast) var(--ease-out);
}

@media (hover:hover){ .pill:hover svg{ transform:translateX(6px); } }


/* The Explore links used a one-pixel underline. They are the same
   invitation as "Request a Consultation", so they get the same bordered
   plate that fills with gold on hover. */
.readmore{
  display:inline-flex;
  align-items:center;
  gap:12px;
  font-family:var(--font-ui);
  font-size:.86rem;
  font-weight:600;
  letter-spacing:.09em;
  text-transform:uppercase;
  color:var(--ink-black);
  padding:14px 28px;
  border:2px solid var(--ink-black);
  background-color:transparent;
  position:relative;
  transition:background-color var(--dur-fast) var(--ease-soft),
             border-color     var(--dur-fast) var(--ease-soft),
             color            var(--dur-fast) var(--ease-soft);
}
.readmore:focus-visible{
  background-color:var(--gold);
  border-color:var(--gold);
  color:var(--navy);
}
@media (hover:hover){ .readmore:hover{
  background-color:var(--gold);
  border-color:var(--gold);
  color:var(--navy);
} }
.readmore .arw{ transition:transform var(--dur-fast) var(--ease-out); }
@media (hover:hover){ .readmore:hover .arw{ transform:translateX(6px); } }
@media (prefers-reduced-motion: reduce){
  .readmore,.readmore .arw{ transition:none; }
}

@media (hover:hover){ .readmore:hover::after{ transform:scaleX(1); transform-origin:left; } }

.readmore .arw{ transition:transform var(--dur-fast) var(--ease-out); }

@media (hover:hover){ .readmore:hover .arw{ transform:translateX(7px); } }


/* ============================================================
   3. MOTION PRIMITIVES
   Four reusable animation classes, driven by one observer.
   ============================================================ */

/* (a) word-by-word mask reveal — for display headings */
.mask{ display:inline-block; overflow:hidden; vertical-align:bottom;
       padding-bottom:.14em; margin-bottom:-.14em; }

.mask > i{
  display:inline-block;
  font-style:inherit;
  transform:translateY(115%);
  transition:transform var(--dur-slow) var(--ease-mask);
  transition-delay:calc(var(--i, 0) * 90ms);
}

.is-in .mask > i,
.mask.is-in > i{ transform:translateY(0); }


/* (b) fade + rise — for body copy, cards, buttons */
.rise{
  opacity:0;
  transform:translateY(30px);
  transition:opacity var(--dur-mid) var(--ease-out), transform var(--dur-mid) var(--ease-out);
  transition-delay:calc(var(--i, 0) * 110ms);
}

.is-in .rise,
.rise.is-in{ opacity:1; transform:none; }


/* (c) clip wipe — for images; the frame opens left-to-right */
.wipe{
  clip-path:inset(0 100% 0 0);
  transition:clip-path 1.25s var(--ease-mask);
  transition-delay:calc(var(--i, 0) * 120ms);
}

.is-in .wipe,
.wipe.is-in{ clip-path:inset(0 0 0 0); }


/* (e) the reference site's three scroll entrances. Values are read
   off its live stylesheet, not guessed: [data-aos="fade-up"] is
   translate3d(0,100px,0), fade-right is (-100px,0,0), fade-left is
   (100px,0,0), all on a 1s `ease` transition.
   These are a longer, slower gesture than our own .rise (30px on
   --dur-mid); they are for whole editorial blocks moving as one.
   The stagger step stays at 110ms so it matches the rest of the
   site — that lands on ~220/330/440/550ms against the reference's
   hand-written 250/300/400/500. */
/* Speed re-measured against the reference: its 43 animated elements
   run 0.5s-2s (1s most common) on `ease`, with hand-written delays of
   250/300/400/500ms. Our duration already matched at 1s. What made
   ours read as faster is that the reference moves its whole text
   column as ONE wrapper with a couple of coarse delays, where we
   animate five separate elements only 110ms apart -- so the block
   arrived as a burst instead of unfolding. Duration raised, stagger
   widened. Both are variables: change --f-dur / --f-step here and
   every block follows. */
.f-up,.f-right,.f-left{
  --f-dur:  1.15s;   /* 1.0s read as a burst, 1.4s dragged; this is the
                        midpoint of both judgements, and it happens to
                        equal the file's existing --dur-slow token. */
  --f-step: 140ms;   /* delays 0/280/420/560/700 -- block resolves in
                        1.85s, against 1.55s (too fast) and 2.25s (too
                        slow). Reference resolves in ~1.5s. */
  opacity:0;
  transition:opacity var(--f-dur) ease, transform var(--f-dur) ease;
  transition-delay:calc(var(--i, 0) * var(--f-step));
  will-change:opacity, transform;
}

.f-up{    transform:translate3d(0,100px,0); }

.f-right{ transform:translate3d(-100px,0,0); }
   /* enters from the left  */
.f-left{  transform:translate3d(100px,0,0); }
    /* enters from the right */
.is-in .f-up,    .f-up.is-in,
.is-in .f-right, .f-right.is-in,
.is-in .f-left,  .f-left.is-in{
  opacity:1; transform:translate3d(0,0,0);
}


/* (d) rule draw — for the gold hairlines */
.draw{
  transform:scaleX(0);
  transform-origin:left;
  transition:transform var(--dur-slow) var(--ease-mask);
  transition-delay:calc(var(--i, 0) * 110ms);
}

.is-in .draw,
.draw.is-in{ transform:scaleX(1); }


/* --- Lenis smooth scroll requirements ---
   Lenis drives the REAL native scrollbar, so sticky, anchors and
   find-in-page keep working. It only needs CSS smooth-scroll turned
   off (they would fight) and a couple of container rules. */
html.lenis, html.lenis body{ height:auto; }

.lenis.lenis-smooth{ scroll-behavior:auto !important; }

.lenis.lenis-smooth [data-lenis-prevent]{ overscroll-behavior:contain; }

.lenis.lenis-stopped{ overflow:hidden; }


/* ============================================================
   4. HEADER
   ============================================================ */
.site-header{
  position:fixed;
  inset:0 0 auto 0;
  z-index:120;
  transform:translateY(-100%);
  transition:transform .55s var(--ease-soft),
             background .4s var(--ease-soft),
             box-shadow .4s var(--ease-soft);
}

.site-header.is-ready{ transform:none; }
               /* slides in on load */
.site-header::before{
  content:"";
  position:absolute; inset:0;
  background:linear-gradient(180deg, rgba(4,10,20,.8), rgba(4,10,20,0));
  pointer-events:none;
  transition:opacity .4s var(--ease-soft);
}

/* Past the hero the bar flips to a light theme: white ground, dark
   type. Colour is transitioned (not swapped) so the words appear to
   fade from white to black rather than blink. */
.site-header.is-stuck{
  background:#fff;
  box-shadow:0 1px 24px rgba(8,21,37,.12);
}

.header-inner{ transition:color .4s var(--ease-soft); }

.site-header.is-stuck .header-inner{ color:var(--ink); }

.site-header.is-stuck .nav-link{ color:#141c26; }

.site-header.is-stuck .icon-btn{ color:#141c26; }

@media (hover:hover){ .site-header.is-stuck .icon-btn:hover{ background:rgba(14,32,57,.07); } }

/* brand gold is too pale on white — the deeper cut of the same hue */
.site-header.is-stuck .nav-link::after{ background:var(--gold-deep); }

.site-header.is-stuck .logo-mark{ border-color:transparent; }

.site-header.is-stuck::before{ opacity:0; }

.header-inner{ position:relative; z-index:2; color:#fff; }


/* --- upper row: retires once you scroll past the hero --------------
   Only the lower row is meant to follow you down the page, so the
   whole top strip collapses its own height rather than the header
   translating away. max-height animates; height:auto cannot. */
.topbar{
  display:flex; align-items:center; gap:40px;
  padding-top:12px;
  max-height:112px; opacity:1; overflow:hidden;
  transition:max-height .5s var(--ease-mask),
             opacity .3s var(--ease-soft),
             padding-top .5s var(--ease-mask);
}

.site-header.is-stuck .topbar{
  max-height:0; opacity:0; padding-top:0;
  pointer-events:none;
}


/* full lockup — lives in the row that retires.
   The wordmark is real text in the site's own faces, not part of the
   image: it stays razor sharp at any size, is selectable, readable by
   screen readers, and indexable by search. Only the mark is a bitmap. */
.logo-slot{
  display:flex; align-items:center; gap:15px;
  flex:none;
  padding:2px 0;
}

/* One copy of the mark, held in --mark-src and reused by both lockups.
   It was previously embedded twice — 33 KB of identical base64. */
.logo-slot .mark,
.footer-logo .mark{
  display:block; flex:none;
  background:var(--mark-src) center/contain no-repeat;
}

.logo-slot .mark{ height:56px; width:38px; }


/* The reference lockup sets the company name in a high-contrast serif
   with the descriptor letterspaced beneath it to the same measure, then
   a hairline rule. Playfair Display is already the site's display face,
   so the wordmark speaks in the same voice as the hero headline. */
.wordmark{
  display:flex; flex-direction:column;
  align-items:stretch;
  line-height:1;
}

.wordmark b{
  font-family:var(--font-display);
  font-weight:600;
  font-size:1.85rem;
  letter-spacing:-.005em;
  line-height:1.02;
  color:#fff;
  white-space:nowrap;
}

/* tracked out so the descriptor sits to roughly the same width as the
   name above it — the detail that makes a stacked lockup look composed
   rather than merely stacked */
.wordmark i{
  font-family:var(--font-display);
  font-style:normal;
  font-weight:600;
  font-size:.78rem;
  letter-spacing:.185em;
  text-indent:.185em;          /* offsets the trailing letter-space, keeps it optically centred */
  text-align:center;
  white-space:nowrap;
  color:rgba(255,255,255,.9);
  margin-top:4px;
  padding-bottom:5px;
  border-bottom:1px solid #fff;
}

/* the lockup is a link, but stays visually fixed — no tint, no shift */

/* compact mark — hidden at rest, takes over when the top row retires.
   Animating width (not display) lets the nav slide across smoothly. */
.logo-mark{
  flex:none;
  width:0; height:44px;
  margin-right:0;
  opacity:0;
  overflow:hidden;
  display:flex; align-items:center;
  transition:width .5s var(--ease-mask),
             opacity .35s var(--ease-soft) .1s,
             margin-right .5s var(--ease-mask);
}

.logo-mark img{ height:44px; width:auto; display:block; }

.site-header.is-stuck .logo-mark{ width:31px; margin-right:26px; opacity:1; }


/* The top row was set two steps below the nav beneath it -- .88rem
   against 1.09 -- which read as small rather than secondary. It is
   still the quieter of the two rows, but by a single step now. */
.utility{ display:flex; align-items:center; gap:30px; margin-left:auto; font-size:1.01rem; }

/* utility links warm to gold on hover rather than just brightening */
.utility a{
  position:relative;
  color:rgba(255,255,255,.88);
  font-weight:400;
  transition:color var(--dur-fast) var(--ease-soft);
}

.utility a:focus-visible{ color:var(--gold-lift); }
@media (hover:hover){ .utility a:hover{ color:var(--gold-lift); } }


/* email affordance — icon carries the meaning, label reinforces it */
/* icon-only: the label is carried by aria-label + title, not visible text */
.mail-btn{ display:inline-flex; align-items:center; }

.mail-btn svg{
  width:19px; height:19px; flex:none;
  stroke-width:1.6;
  transition:transform var(--dur-fast) var(--ease-out), color var(--dur-fast) var(--ease-soft);
}

@media (hover:hover){ .mail-btn:hover svg{ transform:translateY(-2px); } }


.caret{ display:inline-block; margin-left:7px; font-size:.55rem; vertical-align:middle;
        transition:transform var(--dur-fast) var(--ease-out); }

@media (hover:hover){ .nav-item:hover .caret{ transform:translateY(3px); } }


.navrow{ display:flex; align-items:center; }

/* 24px of padding under the nav put 43px of dead air between the last
   nav glyph and the bottom of the bar, on a row whose left half is
   already empty below the logo. Reliance's header content stops ~6px
   after its nav. Trimmed to 16 — enough to clear the .nav-link::after
   marker, not enough to leave the row floating. */
/* Nav placement, measured off the reference.
   On Reliance the nav neither hugs the right edge nor starts under the
   logo: it begins clear of the lockup -- about an 8.5% gutter past it --
   and the items are then spread evenly across the whole remaining width,
   ending at the icon cluster. That even spread is what makes the row
   read as full rather than as a cluster pushed to one side.

   Two things were wrong here in turn. Originally margin-left:auto pinned
   the nav right, leaving 341px of dead air after the logo. Correcting
   that by starting the nav at the shell's left edge put it directly
   under the logo, which is not what the reference does either.

   So: an explicit indent that clears the lockup, and space-between on
   the list so the items distribute across what is left. The reference
   carries three icons at the right and this site carries one, so the
   spread absorbs that difference on its own rather than needing the
   gaps hand-tuned. */
.mainnav{
  display:flex; align-items:center;
  /* With the search icon gone the row has no right-hand anchor, so the
     nav is given air on both sides rather than running to the edge:
     clear of the logo on the left, inset from the shell on the right,
     and the items spread across what is between. */
  padding:10px var(--nav-inset, 100px) 16px 0;
  margin-left:var(--nav-indent, 272px);
  flex:1 1 auto; min-width:0;
}

/* flex:1 + space-between is what fills the row: the first item sits at
   the indent, the last at the inset, and the gap is whatever is left
   over. `gap` is only the floor, for narrow viewports. */
.nav-list{ display:flex; flex:1 1 auto; justify-content:space-between; gap:26px; }

.nav-item{ position:relative; }

.nav-link{
  display:inline-block; padding:10px 0;
  font-size:1.09rem; font-weight:400; letter-spacing:.005em;
  color:#fff;
  transition:color .4s var(--ease-soft);
}

/* single active marker: a short weighted bar sitting under the item,
   the way the reference site does it */
.nav-link::after{
  content:""; display:block;
  height:3px; margin-top:6px;
  background:var(--gold);
  transform:scaleX(0); transform-origin:right;
  transition:transform var(--dur-mid) var(--ease-mask);
}

.nav-item:focus-within .nav-link::after{ transform:scaleX(1); transform-origin:left; }
@media (hover:hover){ .nav-item:hover .nav-link::after{ transform:scaleX(1); transform-origin:left; } }


/* --- the whole bar is a hover target ---------------------------------
   space-between spreads the six items across the row, which leaves a
   dead strip of 42-63px between each pair -- between a quarter and a
   third of the entire sweep, measured. Moving the cursor along the
   header, the menu dropped out in every one of those strips and only
   came back when the pointer happened to land on a label. That is what
   "it does not always open" was.

   Each item's hover area is extended across the gap to its right, and up
   to the top of the bar, by an out-of-flow pseudo-element. Nothing
   moves: the pseudo takes no space, and the panel is positioned from the
   item's own box, which is untouched.

   The extension is generous rather than exact, because space-between
   makes the real gap depend on the window width. Where it overruns, the
   next item's own box paints on top and takes the hover back, so the
   boundary lands at the next label rather than in the middle of nowhere
   -- which also means the menu you are on stays open until you actually
   reach the next one.

   Only where the horizontal bar exists, which is 981px and up --
   measured, not assumed: at 980px .mainnav becomes a fixed drawer and
   every item is a full-width row with no gap to bridge. */
@media (min-width:981px) and (hover:hover){
  .nav-item::before{
    content:"";
    position:absolute;
    top:-12px; bottom:0; left:0; right:0;
  }
  .nav-item:not(:last-child)::before{ right:-72px; }
  /* the label keeps its clicks: an absolutely positioned pseudo paints
     over static in-flow content, so the link is raised above it */
  .nav-link{ position:relative; }
}

/* dropdown: panel fades, then its links stagger in */
/* ---------------------------------------------------------------
   DROPDOWN CARD
   A panel that hangs beneath its own nav item -- not a full-width
   band. Width is driven by content: items never wrap (nowrap), so
   the card sizes itself and long labels stay on one line.
   --------------------------------------------------------------- */
.dropdown{
  position:absolute;
  top:100%; left:-26px;
  background:#fff;
  color:var(--ink);
  padding:30px 36px 30px;
  box-shadow:0 24px 50px rgba(8,21,37,.18);
  opacity:0; visibility:hidden;
  transform:translateY(12px);
  transition:opacity .28s var(--ease-soft), transform .38s var(--ease-out), visibility .38s;
}

/* the last menu opens inward so it can't run off the right edge */
.nav-item:last-child .dropdown{ left:auto; right:-26px; }


.dd-inner{ display:block; }

.dd-cols{ display:flex; gap:64px; }

.dd-col{ min-width:0; }


.nav-item:focus-within .dropdown{ opacity:1; visibility:visible; transform:translateY(0); }
@media (hover:hover){ .nav-item:hover .dropdown{ opacity:1; visibility:visible; transform:translateY(0); } }


/* group label — heading, not a link: not tabbable, no marker, no hover */
.dd-head{
  margin:0 0 10px;
  /* group labels were plain text and deliberately not clickable; the
     marketplace ones are now links to their category pages, so the
     no-clicks rule is scoped to the labels that are still labels */
  pointer-events:none;
  padding:0;
  font-family:var(--font-ui);
  font-size:.9375rem;
  font-weight:600;
  letter-spacing:.005em;
  color:#101820;
  white-space:nowrap;
}

.dd-head--top{ margin-bottom:20px; }

.dropdown a + .dd-head{ margin-top:26px; }


/* Body copy is weight 300 site-wide, which goes grey and fuzzy at menu
   sizes on white, so items step up on the page's darkest ink: at 15px,
   geometric letterforms with generous counters read lighter than their
   nominal weight, and a menu is scanned rather than read.

   500, not 600. At 600 the items sat at the same weight as the group
   label above them, so a panel of fourteen links read as one solid
   block of bold. 500 is a real Jost weight -- the file is already
   loaded -- so nothing is synthesised and nothing extra is fetched, and
   the label keeps its 600 and so still leads its group. */
.dropdown a{
  position:relative;
  display:block;
  padding:6px 0;
  font-size:.95rem;
  font-weight:500;
  line-height:1.55;
  color:var(--ink-black);
  white-space:nowrap;
  opacity:0;
  transform:translateX(-10px);
  transition:color .25s var(--ease-soft),
             opacity .4s var(--ease-out),
             transform .4s var(--ease-out);
  transition-delay:calc(var(--d, 0) * 28ms);
}

.dropdown a::before{
  content:"";
  position:absolute;
  left:0; top:50%;
  width:12px; height:1px;
  background:var(--gold-deep);
  transform:translateY(-50%) scaleX(0);
  transform-origin:left center;
  opacity:0;
  transition:transform .35s var(--ease-mask), opacity .25s var(--ease-soft);
}

.dropdown .dd-head{
  opacity:0; transform:translateX(-10px);
  transition:opacity .4s var(--ease-out), transform .4s var(--ease-out);
  transition-delay:calc(var(--d, 0) * 28ms);
}


/* Entrance animates the <a>; the hover shift animates the <span>
   inside it. Two different elements, so the rules can never fight
   over one property -- which is what silently killed the hover. */
.nav-item:focus-within .dropdown a, .nav-item:focus-within .dropdown .dd-head{ opacity:1; transform:none; }
@media (hover:hover){ .nav-item:hover .dropdown a, .nav-item:hover .dropdown .dd-head{ opacity:1; transform:none; } }


.dropdown a > span{
  display:inline-block;
  transition:transform .34s var(--ease-out);
}

.dropdown a:focus-visible{ color:#0b1219; }
@media (hover:hover){ .dropdown a:hover{ color:#0b1219; } }

.dropdown a:focus-visible > span{ transform:translateX(22px); }
@media (hover:hover){ .dropdown a:hover > span{ transform:translateX(22px); } }

.dropdown a:focus-visible::before{ transform:translateY(-50%) scaleX(1); opacity:1; }
@media (hover:hover){ .dropdown a:hover::before{ transform:translateY(-50%) scaleX(1); opacity:1; } }


.icon-btn{
  width:38px; height:38px;
  color:#fff;
  transition:color .4s var(--ease-soft), background var(--dur-fast) var(--ease-soft), transform var(--dur-fast) var(--ease-out);
  display:grid; place-items:center;
  border-radius:50%;
}

@media (hover:hover){ .icon-btn:hover{ background:rgba(255,255,255,.14); transform:scale(1.08); } }

.icon-btn svg{ transition:none; }

.icon-btn svg{ width:21px; height:21px; stroke:currentColor; fill:none; stroke-width:1.35; }

.burger{ display:none; }

/* The drawer's X had no base rule -- it was only given display:flex inside
   the phone breakpoint, so on desktop it fell back to a plain button and
   rendered a 12px sliver at the head of the nav, focusable and clickable.
   It belongs to the drawer only. */
.nav-close{ display:none; }


/* ============================================================
   5. HERO
   ============================================================ */
.hero{
  position:relative;
  /* 100svh is the viewport height with the browser's URL bar SHOWING --
     the smallest it ever gets. Once the bar retracts the viewport grows
     and the hero was left short by exactly the bar's height, which is
     the white strip that appeared under the hero on a phone.
     100lvh is the height with the bar hidden: the hero is then never
     shorter than the screen in either state. While the bar is showing
     the last ~60px of the hero sit just below the fold, which nobody
     sees -- the artwork is a cover background and the copy is centred.
     dvh was rejected: it tracks the bar continuously, so the hero would
     resize while the visitor scrolls. svh stays first as the fallback
     for anything that does not know lvh. */
  height:100svh;
  height:100lvh;
  min-height:640px;
  color:#fff;
  overflow:hidden;
  display:flex;
  align-items:center;
}

.hero-slides{ position:absolute; inset:0; }

.hero-slide{
  position:absolute; inset:0;
  opacity:0;
  transition:opacity 1.5s var(--ease-soft);
}

.hero-slide.is-active{ opacity:1; }

.hero-slide .ph{ width:100%; height:100%; border:0; }

.hero-slide picture{ display:block; width:100%; height:100%; }

.hero-slide img{
  width:100%; height:100%;
  object-fit:cover;
  /* subject sits right of centre; bias the crop so he survives
     narrow viewports and stays clear of the headline */
  object-position:70% 40%;
}

.hero-slide .ph span{ font-size:1.05rem; letter-spacing:.44em; color:rgba(255,255,255,.34); }

/* Slow drift while a slide is on screen (Ken Burns).
   .hero-art is the live one: the heroes are CSS backgrounds now, so the
   img and .ph selectors match nothing on the homepage. They are kept
   because the same rule is what a future <img> hero would need. */
.hero-slide .ph,
.hero-slide img,
.hero-slide .hero-art{ transform:scale(1.09); transition:transform 8s linear; }

.hero-slide.is-active .ph,
.hero-slide.is-active img,
.hero-slide.is-active .hero-art{ transform:scale(1); }


.hero-scrim{
  position:absolute; inset:0;
  background:linear-gradient(102deg, rgba(4,11,21,.76) 0%, rgba(4,11,21,.46) 46%, rgba(4,11,21,.26) 100%);
}

.hero-inner{ position:relative; z-index:3; width:100%; }


/* each masked phrase takes its own line, so the tagline keeps its
   two-line frame at the smaller size */
.hero-title .mask{ display:block; }

.hero-title{
  font-family:var(--font-display);
  font-weight:600;
  font-size:var(--t-hero);
  line-height:1;
  letter-spacing:-.022em;
  margin:0 0 30px;
  /* A single wide blur reads as a grey smudge over a busy photograph.
     Three tight, progressively softer shadows give a clean edge that
     stays crisp at any resolution. */
  text-shadow:0 1px 2px rgba(0,0,0,.42),
              0 3px 12px rgba(0,0,0,.36),
              0 8px 42px rgba(0,0,0,.30);
}

/* The rule carries the logo's own ramp rather than flat white: teal
   through green into gold, with a soft glow so it holds up over a
   photograph without needing to be thick. */
/* Measured against ril.com at 1440px, where the headline sits 75px from
   the edge at 100px. Ours is two lines of longer text, so it moves most
   of the way rather than all of it: 78px, and the type up from 59 to 73.
   Only the hero shifts — the site gutter is unchanged. */
.hero-inner .shell{ max-width:none; padding-inline:78px; }
@media (max-width:1100px){ .hero-inner .shell{ padding-inline:48px; } }
@media (max-width:700px){ .hero-inner .shell{ padding-inline:var(--gutter); } }

.hero-rule{
  width:340px; max-width:48%; height:3px; margin-bottom:34px;
  background:linear-gradient(90deg,#37C9B0 0%, #6FE0A4 46%, #FFCE5C 100%);
  box-shadow:0 0 14px rgba(111,224,164,.55), 0 0 26px rgba(255,206,92,.30);
  border-radius:2px;
}

/* The reveal lives on a wrapper, never on the button itself. When
   .rise and .pill sat on one element both declared `transition`, and
   .rise won — so the button inherited a 660ms delay and its colour
   change never transitioned. Separate elements, separate concerns. */
.hero-actions{ display:flex; flex-wrap:wrap; gap:18px; }

.hero-actions > .rise{ display:inline-flex; }


/* indicators double as a timer for the 5s slide interval */


.dot{
  position:relative;
  width:52px; height:3px;
  background:rgba(255,255,255,.3);
  overflow:hidden;
}

.dot .fill{
  position:absolute; inset:0;
  background:var(--gold);
  transform:scaleX(0); transform-origin:left;
}

.dot.is-active .fill{ animation:tick 5s linear forwards; }

@keyframes tick{ from{ transform:scaleX(0); } to{ transform:scaleX(1); } }


.scroll-cue{
  position:absolute; right:var(--gutter); bottom:56px;
  z-index:4;
  display:flex; align-items:center; gap:14px;
  font-size:var(--t-micro); letter-spacing:.3em; text-transform:uppercase;
  color:rgba(255,255,255,.62);
}

.scroll-cue i{ display:block; width:1px; height:52px; background:rgba(255,255,255,.3); position:relative; overflow:hidden; }

.scroll-cue i::after{
  content:""; position:absolute; inset:0;
  background:var(--gold);
  animation:cue 2.4s var(--ease-soft) infinite;
}

@keyframes cue{
  0%{ transform:translateY(-100%); }
  55%{ transform:translateY(0); }
  100%{ transform:translateY(100%); }
}


/* ============================================================
   6. STATEMENT
   ============================================================ */
/* Statement + stats measured 872px, so the numbers fell off the
   bottom of a 900px screen and overflowed a 1280x800 one by 48px.
   96px is trimmed across the two sections -- proportionally, so the
   existing rhythm is kept rather than one gap being crushed. */
.statement{ padding:96px 0 76px; text-align:center; }

.statement-mark{
  height:104px; width:auto;
  display:block;
  margin:0 auto 44px;
}

.statement-lead{
  font-family:var(--font-display);
  font-size:var(--t-lead);
  line-height:1.32;
  font-weight:600;
  letter-spacing:-.012em;
  color:var(--green-deep);
  max-width:20ch;
  margin:0 auto;
}

.statement-lead em{ font-style:italic; color:var(--gold-deep); }


/* ============================================================
   7. STATS — count-up band
   ============================================================ */
.stats{ border-block:1px solid var(--line); padding:58px 0; }

.stats-grid{ display:grid; grid-template-columns:repeat(3,1fr); gap:44px; }

.stat{ text-align:center; position:relative; }

.stat + .stat::before{
  content:""; position:absolute; left:-22px; top:8px; bottom:8px;
  width:1px; background:var(--line);
}

.stat .num{
  font-family:var(--font-display);
  font-size:clamp(2.6rem,5vw,4rem);
  line-height:1;
  color:var(--green-deep);
  letter-spacing:-.03em;
  display:block;
  font-variant-numeric:tabular-nums;
}

.stat .num .suf{ color:var(--gold-deep); }

.stat .lbl{
  display:block; margin-top:14px;
  font-size:var(--t-micro);
  letter-spacing:.24em; text-transform:uppercase;
  color:var(--ink-soft);
}


/* ============================================================
   8. BUSINESSES
   ============================================================ */
.businesses{ background:var(--paper-alt); color:var(--ink-black); padding:112px 0 118px; overflow:hidden; }


.biz-head{ margin-bottom:60px; }


/* monospace division marker — SW · 01 */

/* hard-fact strip under each division */
.spec{
  font-family:var(--font-mono);
  font-size:.7rem;
  letter-spacing:.1em;
  text-transform:uppercase;
  color:#5a636d;
  font-weight:500;
  border-top:1px solid rgba(26,29,32,.16);
  padding-top:16px;
  margin:26px 0 24px;
  line-height:1.9;
}

.biz-lede{
  font-size:1.16rem;
  color:var(--ink-black);
  margin:0 0 22px;
  font-weight:400;
}

.biz-grid{ display:grid; grid-template-columns:1fr 1fr; gap:84px; align-items:center; min-height:460px; }

.biz-copy h3{ color:var(--ink-black); margin-bottom:24px; }

.biz-copy .prose{ color:#333a42; }

.biz-visual .ph{ aspect-ratio:4/3; }

.biz-visual{ overflow:hidden; }


/* --- division block imagery ------------------------------------
   Two kinds. .biz-shot is a framed photograph: it inherits the 4:3
   box the placeholders defined, so the block rhythm is unchanged.
   .biz-figure is a cut-out with no frame -- no box, no crop, no
   aspect lock. It sets its own height from the artwork.
   Neither wrapper declares a transition, so .wipe can safely sit on
   the same element (it owns clip-path alone). */
.biz-shot{ aspect-ratio:4/3; overflow:hidden; }

.biz-shot img{ width:100%; height:100%; object-fit:cover; display:block; }


/* The cut-out runs wider than its column. A floating object carries
   transparent margins, so at equal width it reads lighter than a
   filled rectangle beside it; 112% restores the visual weight.
   .biz-visual clips by default, so this variant has to opt out.
   The extra width bleeds toward the TEXT column only, never toward
   the page edge: splitting it both ways put the right flange within
   14px of the viewport at ~1024px, where a real scrollbar covers it.
   Bleeding one way lands the outer edge exactly on the column edge,
   in line with the framed shots in the other blocks. */
.biz-visual.is-figure{ overflow:visible; }

/* Mobile-first, deliberately. The direction-specific bleed selectors
   score (0,3,1); a plain `.biz-figure img` inside @media (max-width)
   scores (0,1,1) and LOSES -- a media query adds no specificity. The
   phone layout was inheriting margin-left:-12% and clipping the left
   flange. Scoping the bleed to the wide breakpoint removes the fight
   instead of escalating it. */
.biz-figure img{ width:100%; max-width:none; height:auto; display:block; }

/* The bleed lives on the zoom wrapper only -- see below. An earlier
   copy of this rule targeted the IMAGE, and when the stylesheets were
   merged both survived: the shift was applied twice, pushing the
   cut-out 56px into the text column. */


/* five blocks stacked down the page, image side alternating */
.biz-stack{ margin-top:20px; }

.biz-block{ padding:96px 0; border-top:1px solid rgba(26,29,32,.12); }


.biz-block:first-child{ border-top:0; padding-top:12px; }

.biz-block:last-child{ padding-bottom:12px; }

/* Even-numbered blocks put the image on the left. This was flipping
   twice and so not flipping at all: order:-1 moved the visual first,
   then direction:rtl mirrored the row and put it back. One technique
   only -- order does the job on its own. */
.biz-block:nth-child(even) .biz-visual{ order:-1; }




/* ============================================================
   15. FOOTER
   ============================================================ */
/* Light footer, same pair as the stuck header: --paper ground with
   #141c26 type. The section above it is --paper-alt (#f4f8f5), which
   is only ~3% off white, so without the hairline the two grounds
   would meet with no edge at all. */
.site-footer{
  background:var(--paper);
  color:#141c26;
  border-top:1px solid var(--line);
  padding:84px 0 0;
  font-size:.93rem;
}

/* .wordmark hard-codes #fff for the dark header. Reused verbatim in
   the footer, it now sits white-on-white — both the name and the
   rule under the descriptor have to invert. */
.site-footer .wordmark b{ color:#141c26; }

.site-footer .wordmark i{ color:#141c26; border-bottom-color:#141c26; }

/* two columns: brand on the left, socials filling the space that
   opened up on the right. align-items:end drops them onto the same
   baseline as the last line of the tagline. */
.footer-top{
  display:grid;
  grid-template-columns:minmax(0,620px) 1fr;
  gap:64px;
  align-items:end;
  padding-bottom:52px;
}

.footer-connect{ justify-self:end; }

/* the tagline's default <p> margin was sitting under the column and
   pushing the icons below the text baseline — zero it so end-alignment
   lands where it looks like it should */
/* the tagline read light not because of its colour, which is already
   17:1, but because it was set at weight 300. Matched to the 400 used
   by the address and the links below it. */
.footer-brand p{ margin:0; font-weight:400; color:var(--ink-black); }

.footer-logo{
  display:inline-flex; align-items:center; gap:15px;
  margin-bottom:28px;
}

.footer-logo .mark{ height:54px; width:37px; }

.socials{ display:flex; gap:13px; }

.social{
  width:42px; height:42px;
  border-radius:50%;
  background:var(--gold);
  color:var(--navy-deep);
  display:grid; place-items:center;
  flex:none;
  transition:background var(--dur-fast) var(--ease-soft),
             transform var(--dur-fast) var(--ease-out);
}

.social svg{ width:19px; height:19px; display:block; }

/* Hover lifts to the mark's green — the exact #2f9e6b the statement
   paragraph is set in, so the interaction colour is a brand colour
   rather than a generic highlight. gold -> gold-lift was a change of
   about 3% luminance: technically a hover, visually nothing. */
@media (hover:hover){ .social:hover{ background:var(--green-deep); transform:translateY(-3px); } }

.social:active{ transform:translateY(-1px); }


.footer-bottom{
  display:flex; flex-wrap:wrap; align-items:center;
  gap:16px 36px;
  padding:26px 0 34px;
  border-top:1px solid var(--line);   /* --navy-line is white at 14% — invisible here */
  font-size:var(--t-small);
  font-weight:400;
}

/* pushed to the right edge, matching the socials above.
   Scoped to the footer: <section class="legal"> is a different thing in
   <main> on the three legal pages, and an unscoped display here beat the
   browser's own [hidden]{display:none} on it. */
.footer-bottom .legal{ display:flex; flex-wrap:wrap; gap:28px; margin-left:auto; }

.footer-bottom .legal a{ transition:color var(--dur-fast) var(--ease-soft); }

/* gold on white is 1.55:1 — a hover that makes the link harder to
   read than before it was hovered. Green is the page's other
   interaction colour (see .social:hover) and clears AA at 3.8:1. */
.footer-bottom .legal a:focus-visible{ color:var(--green-deep); }
@media (hover:hover){ .footer-bottom .legal a:hover{ color:var(--green-deep); } }


.totop{
  position:fixed; right:28px; bottom:28px;
  width:48px; height:48px;
  background:var(--gold); color:var(--navy-deep);
  border-radius:50%; display:grid; place-items:center;
  z-index:100;
  opacity:0; visibility:hidden; transform:translateY(14px) scale(.9);
  transition:opacity var(--dur-mid) var(--ease-out), transform var(--dur-mid) var(--ease-out), visibility var(--dur-mid);
}

.totop.is-visible{ opacity:1; visibility:visible; transform:none; }

@media (hover:hover){ .totop:hover{ transform:translateY(-3px); } }


/* ============================================================
   16. RESPONSIVE
   ============================================================ */
@media (max-width:1180px){
  :root{ --gutter:40px; --nav-indent:190px; --nav-inset:40px; }
  .nav-list{ gap:20px; }
  .stats-grid{ gap:44px 32px; }
}

@media (max-width:980px){
  :root{ --gutter:22px; }
  .burger{ display:grid; }
  .mainnav{
    position:fixed; inset:0 0 0 auto;
    width:min(348px,88vw);
    background:var(--navy);
    flex-direction:column; align-items:stretch; justify-content:flex-start;
    gap:0; padding:110px 26px 44px;
    transform:translateX(100%);
    transition:transform .5s var(--ease-mask);
    overflow-y:auto;
  }
  .mainnav.is-open{ transform:none; }
  .nav-list{ flex-direction:column; gap:0; }
  .nav-item{ border-bottom:1px solid var(--navy-line); }
  .nav-link{ display:block; padding:17px 0; }
  .dropdown{
    position:static; opacity:1; visibility:visible; transform:none;
    background:transparent; box-shadow:none; border-top:0;
    padding:0 0 14px 14px;
    display:none;
  }
  .nav-item.is-open .dropdown{ display:block; }
  .dropdown a{ color:rgba(255,255,255,.66); padding:9px 0; opacity:1; transform:none; }
  .dropdown{
    position:static; background:transparent; box-shadow:none;
    border-top:0; padding:0 0 14px 14px; transform:none;
  }
  .nav-item:last-child .dropdown{ left:auto; right:auto; }
  .dd-cols{ flex-direction:column; gap:0; }
  .dropdown a,
  .dd-head{ white-space:normal; }
  .dropdown a{ color:rgba(255,255,255,.7); padding:9px 0; font-weight:400; }
  @media (hover:hover){ .dropdown a:hover{ background:transparent; color:#fff; } }
  @media (hover:hover){ .dropdown a:hover > span{ transform:translateX(18px); } }
  .dd-head{ margin:14px 0 4px; color:#fff; opacity:1; transform:none; font-size:.9rem; }
  .dd-head--top{ margin-top:6px; }
  .dropdown a + .dd-head{ margin-top:18px; }
  .burger{ margin-left:auto; }
  .navrow{ padding:10px 0 14px; }
  .mainnav{ padding:0; margin-left:0; }
  .site-header.is-stuck .logo-mark{ margin-right:0; }
  .utility{ gap:22px; font-size:.85rem; }

  /* This was one broken rule: .biz-grid had been orphaned onto the
     .biz-block padding selector, so it never collapsed to one column
     AND picked up 64px of padding it was never meant to have. */
  .biz-grid{ grid-template-columns:1fr; gap:40px; min-height:0; }
  .biz-block{ padding:64px 0; }
  .biz-block:nth-child(even) .biz-grid{ direction:ltr; }
  .biz-block:nth-child(even) .biz-visual{ order:0; }
  .scroll-cue{ display:none; }
}

@media (max-width:640px){
  .logo-slot{ gap:11px; }
  .logo-slot .mark{ height:42px; width:29px; }
  .wordmark b{ font-size:1.34rem; }
  .wordmark i{ font-size:.6rem; letter-spacing:.15em; text-indent:.15em; }
  .hero-slide img{ object-position:50% 30%; }
  .utility a:not(.keep){ display:none; }

  .stats-grid{ grid-template-columns:1fr; gap:44px; }
  .stat + .stat::before{ display:none; }

  .statement-lead{ max-width:none; }
}


/* ============================================================
   17. REDUCED MOTION — everything resolves to its end state
   ============================================================ */
/* An exchanger that turns towards its words

   These renders point one way, and the same drawing is used on both
   sides of the page -- a picture on the left of the text on one page is
   on the right of it on another. Rather than ship two copies of every
   exchanger, the placement that needs the other direction mirrors it
   here: no second file, no extra bytes, and the equipment always faces
   the words it belongs to.

   Safe on the <img> because every reveal animation on this site puts
   its transform on a container, never on the picture itself. */
.mirrored{ transform:scaleX(-1); }

/* ------------------------------------------------------------
   When nothing is going to animate anything

   Every section on this site starts at opacity 0, shifted 100px to one
   side, and is brought into place by the script adding .is-in. With the
   script switched off nothing ever adds it, so the page renders blank
   and displaced -- at 390px the consent checkbox sat 53px off the left
   edge of the screen, which is how this was found. The forms submit
   perfectly well without the script; they are no use if they cannot be
   seen.

   The scripting media feature answers exactly the right question and
   answers it before the first paint, so there is no flash. Gating this
   on a class the script adds was measured and rejected: on a phone at
   8x throttling the paint lands 328ms before the script runs, which
   would show the page and then jerk it sideways.
   ------------------------------------------------------------ */
@media (scripting: none){
  .mask > i{ transform:none; }
  .rise{ opacity:1; transform:none; }
  .f-up,.f-right,.f-left{ opacity:1; transform:none; }
  .wipe{ clip-path:none; }
  .draw{ transform:none; }
  .hero-slide .ph,
  .hero-slide .hero-art{ transform:none; }
}

@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{
    animation-duration:.01ms !important;
    animation-iteration-count:1 !important;
    transition-duration:.01ms !important;
  }
  html{ scroll-behavior:auto; }
  .mask > i{ transform:none; }
  .rise{ opacity:1; transform:none; }
  .f-up,.f-right,.f-left{ opacity:1; transform:none; }
  .wipe{ clip-path:none; }
  .draw{ transform:none; }
  .hero-slide .ph,
  .hero-slide .hero-art{ transform:none; }
}




/* --- hover zoom -----------------------------------------------------
   Applies to every image on the site EXCEPT the hero, which owns its
   own 8s Ken Burns scale and must not be touched.
   The hover sits on the wrapper, not the image, so the whole tile is
   the target. Scale and timing are the reference site's measured
   values: scale(1.05) on 1s ease.
   The zoom is the image's ONLY transform -- entrance and parallax live
   on ancestor elements, because CSS keeps just the last transform on
   any one element. */
.zoomwrap{ overflow:hidden; display:block; }

.zoomwrap > img,
.zoomwrap > .ph{
  display:block; width:100%; height:100%;
  transform:scale(1);
  transition:transform 1s ease;
}

.zoomwrap:focus-visible > img{ transform:scale(1.05); }
@media (hover:hover){ .zoomwrap:hover > img, .zoomwrap:hover > .ph{ transform:scale(1.05); } }

@media (prefers-reduced-motion: reduce){
  .zoomwrap > img, .zoomwrap > .ph{ transition:none; }
  @media (hover:hover){ .zoomwrap:hover > img, .zoomwrap:hover > .ph{ transform:none; } }
}


/* ====================================================================
   ABOUT PAGE
   Only rules unique to this page. Everything above is the shared site
   stylesheet, byte-identical to the homepage.
   ==================================================================== */

/* --- 1. banner ------------------------------------------------------
   Full bleed from y=0; the fixed header sits over the artwork, exactly
   as it does over the hero on the homepage. The header carries its own
   dark scrim (.site-header::before) so the nav stays legible over the
   sky.
   The band takes the artwork's own 2.5:1 ratio rather than cropping it:
   measured, the wordmark fills 12-95% of the frame vertically and
   2-100% horizontally, so no crop keeps it whole. */
/* Banner + title block together occupy exactly one screen. The section
   is 100svh and a column flex: the artwork keeps its own 2.5:1 ratio
   and is never cropped or extended, and the title block takes whatever
   height is left, with its content centred in it. */
.about-banner{
  background:var(--navy-deep);
  min-height:100svh;
  display:flex;
  flex-direction:column;
}

.banner-art{
  display:block; width:100%; height:auto;
  aspect-ratio:2000 / 800;   /* the artwork exactly as supplied */
  flex:none;
  object-fit:cover;
}

/* The title block picks up --paper-alt, the same near-white the
   homepage uses for its light sections, so the page opens on a ground
   the reader already knows rather than a second slab of navy. */
.banner-copy{
  background:var(--paper-alt);
  /* Sized so the banner and this block together fit one screen: at
     1837x1021 the band takes 855px, leaving 166px, which is what this
     block occupies. vh units keep it in proportion on shorter screens. */
  flex:1;                     /* fills the rest of the screen */
  display:flex;
  align-items:center;
  padding:clamp(18px, 2.6vh, 40px) 0;
  border-bottom:1px solid var(--line);
}

/* a short gold rule above the title, the same device the homepage uses
   to open its sections -- it gives the block a top edge so the space
   reads as composed rather than empty */
.banner-copy .shell::before{
  content:""; display:block; width:52px; height:2px;
  background:var(--gold); margin-bottom:clamp(14px, 2.2vh, 28px);
}

.banner-title{
  font-family:var(--font-display); font-weight:600;
  font-size:clamp(2.1rem, 6.2vh, 4.4rem);
  line-height:1.02; letter-spacing:-.018em;
  color:var(--ink-black);
}

.banner-sub{
  margin-top:clamp(8px, 1.4vh, 16px);
  font-family:var(--font-display); font-weight:600;
  font-size:clamp(1.15rem, 3.2vh, 2.1rem);
  line-height:1.28; letter-spacing:-.008em;
  color:var(--green-deep);
}

.banner-sub em{ font-style:italic; color:var(--gold-deep); }



/* --- 2. our story --------------------------------------------------
   Wide measure, on purpose. The reference sets ~118 characters a line
   so the whole story lands on one screen; that is far past the usual
   65-75ch comfort range, so the type size and leading come down to
   compensate rather than the line simply being stretched. */
.story2{ background:var(--paper); padding:96px 0 4px; text-align:center; }

.story2-inner{ max-width:104ch; margin-inline:auto; }

.story2-title{
  font-family:var(--font-display);
  font-weight:700;                      /* Playfair is a variable font: 400-900, one file */
  font-size:clamp(2.2rem, 4vw, 3.3rem);
  line-height:1.08; letter-spacing:-.016em;
  color:var(--ink-black); margin:0 0 40px;
}

.story2-inner p{
  font-size:.98rem; font-weight:400; line-height:1.72;
  color:var(--ink-body); margin:0 0 17px;
}

.story2-inner p:last-child{ margin-bottom:0; }

.story2-inner strong{ font-weight:500; color:var(--ink-black); }


/* --- 3. divider line -----------------------------------------------
   No band behind it and no colour change of ground: it sits in the
   same white flow as the story, marking a beat rather than becoming
   a section of its own. */
.divider-line{ background:var(--paper); padding:54px 0 58px; text-align:center; }

.divider-rule{
  width:52px; height:2px; background:var(--gold);
  margin:0 auto 22px; transform-origin:center;
}

.divider-line h2{
  font-family:var(--font-display); font-weight:600;
  font-size:clamp(1.5rem, 2.6vw, 2.15rem);
  line-height:1.18; letter-spacing:-.012em;
  color:var(--green-deep);
}

.divider-line h2 em{ font-style:italic; color:var(--gold-deep); }


/* --- 4. what drives us --------------------------------------------- */
/* The .f-right / .f-left resting state sits 100px outside the column,
   which pushed the document 60px wider than the viewport at load and
   gave the page a horizontal scrollbar until the reveal fired.
   overflow-x:clip contains it without creating a scroll container, so
   the hover zoom can still grow vertically. */
.mv2{ background:var(--paper); padding:26px 0 104px; overflow-x:clip; }

.mv2-head{ text-align:center; margin-bottom:56px; }

.mv2-head h2{
  font-family:var(--font-display); font-weight:700;
  font-size:clamp(2rem, 3.6vw, 3rem);
  line-height:1.1; letter-spacing:-.016em; color:var(--ink-black);
}

.mv2-grid{ display:grid; grid-template-columns:1fr 1fr; gap:72px; align-items:start; }

.mv2-shot{ margin-bottom:30px; }
   /* the artwork is already 16:9 */
.mv2-shot .ph{ width:100%; height:100%; }

.mv2-title{
  font-family:var(--font-display); font-weight:700;
  font-size:clamp(1.6rem, 2.5vw, 2.1rem);
  line-height:1.14; letter-spacing:-.012em;
  color:var(--ink-black); margin:0;
}

.mv2-title::after{
  content:""; display:block; width:46px; height:2px;
  background:var(--green-deep); margin-top:20px;
}

.mv2-cell p{
  margin-top:22px;
  font-size:1.02rem; font-weight:400; line-height:1.86; color:var(--ink-body);
}


/* --- 5. the people -------------------------------------------------
   Ranged left, regular weight, large. It reads as a title through
   scale rather than through weight, which keeps it distinct from the
   two bold headings above it. */
.people{ background:var(--paper-alt); padding:100px 0 116px; overflow-x:clip; }

.people-head{ margin-bottom:58px; }

.people-head h2{
  font-family:var(--font-display); font-weight:600;
  font-size:clamp(2.1rem, 3.8vw, 3.1rem);
  line-height:1.08; letter-spacing:-.016em; color:var(--ink-black);
}

.people-head h2::after{
  content:""; display:block; width:58px; height:2px;
  background:var(--gold); margin-top:26px;
}


.lead-ptr{
  display:grid; grid-template-columns:326px minmax(0,1fr);
  gap:64px; align-items:start;
}

/* Deliberately NOT position:sticky. A sticky element repositioned on
   every frame of a smooth-scroll loop is a well-known source of jank,
   and the row already fits on screen, so it bought nothing. */
.lead-photo img{ width:100%; height:auto; display:block; }

.lead-photo::after{
  content:""; display:block; height:2px; width:56px;
  background:var(--gold); margin-top:22px;
}

.ptr-name2{
  font-family:var(--font-display); font-weight:600;
  font-size:clamp(1.55rem, 2.4vw, 2.05rem);
  line-height:1.14; letter-spacing:-.01em;
  color:var(--ink-black); margin:0;
}

.ptr-role2{
  font-family:var(--font-ui); font-size:1rem; font-weight:500;
  color:var(--ink-body); margin:12px 0 26px;
}

.lead-bio p{
  font-size:1rem; font-weight:400; line-height:1.82;
  color:var(--ink-body); margin:0 0 18px;
}

.lead-bio p:last-child{ margin-bottom:0; }


/* the other two: portraits matched to the lead's 326px so the three
   read at one scale, write-up beneath */
.duo{
  display:grid; grid-template-columns:1fr 1fr; gap:72px;
  margin-top:88px; padding-top:76px; border-top:1px solid var(--line);
}

.duo-photo{ max-width:326px; }

.duo-photo img{ width:100%; height:auto; display:block; }

.duo-photo::after{
  content:""; display:block; height:2px; width:56px;
  background:var(--gold); margin-top:22px;
}

.duo-cell .ptr-name2{ margin-top:14px; }


@media (max-width:1100px){
  .lead-ptr{ grid-template-columns:280px minmax(0,1fr); gap:48px; }
  .mv2-grid, .duo{ gap:52px; }
  .story2-inner{ max-width:none; }
}

@media (max-width:980px){
  .banner-copy{ padding:46px 0 50px; }
  .story2{ padding:74px 0 4px; }
}

@media (max-width:640px){
  .banner-copy{ padding:36px 0 40px; }
  .story2-inner p{ font-size:1rem; line-height:1.8; }
  .divider-line{ padding:44px 0 48px; }
  .mv2{ padding:20px 0 78px; }
  .mv2-head{ margin-bottom:44px; }
  .mv2-grid{ grid-template-columns:1fr; gap:56px; }
  .people{ padding:76px 0 84px; }
  .lead-ptr{ grid-template-columns:1fr; gap:32px; }
  .lead-photo{ max-width:300px; }
  .duo{ grid-template-columns:1fr; gap:56px; margin-top:64px; padding-top:54px; }
  .duo-photo{ max-width:300px; }
}



/* Anchor landings. A native cross-page jump puts the target's top at
   y=0, which is behind the sticky header. scroll-margin-top makes the
   clearance explicit rather than relying on a section's own padding.
   (This was silently lost from about.html once when a block was removed
   by a regex that ran to the end of the stylesheet; restored here.
   NB: never write the literal closing style tag inside a CSS comment --
   the HTML parser ends the stylesheet there, comment or not.) */
:target,
#story, #partners, #software, #engineering, #licensing, #academy, #marketplace,
#n-phe,
#n-bz,
#n-bloc,
#n-she1,
#n-she2,
#n-ps,
#n-st,
#n-whrb,
#n-fwh,
#n-sc,
#n-dc,
#custom-software,
#plates,
#gaskets,
#spiral-type-1,
#spiral-type-2,
#custom,
#professionals,
#institutions,
#plate-frame,
#plate-and-shell,
#parts,
#brazed,
#welded-bloc,
#spiral,
#plate-shell,
#shell-tube,
#whrb,
#feedwater,
#condenser,
#drycooler{
  scroll-margin-top:104px;
}


/* ====================================================================
   ENGINEERING PAGE
   Only rules unique to this page. Everything above is the shared site
   stylesheet, byte-identical to the homepage and About.
   ==================================================================== */

/* --- 1. banner -----------------------------------------------------
   Same treatment as About: the artwork's own 2.5:1, full bleed from
   y=0 with the header over it, and the section is exactly one screen
   so the banner and the title block land together on opening. */
.eng-banner{
  background:var(--navy-deep);
  min-height:100svh;
  display:flex;
  flex-direction:column;
}

.banner-art{
  display:block; width:100%; height:auto;
  aspect-ratio:2000 / 800;
  flex:none;
  object-fit:cover;
}

.eng-banner .ph{ aspect-ratio:2000 / 800; width:100%; flex:none; border:0; }

.banner-copy{
  background:var(--paper-alt);
  flex:1;
  display:flex;
  align-items:center;
  padding:clamp(18px, 2.6vh, 40px) 0;
  border-bottom:1px solid var(--line);
}

.banner-copy .shell::before{
  content:""; display:block; width:52px; height:2px;
  background:var(--gold); margin-bottom:clamp(14px, 2.2vh, 24px);
}

.banner-sub{
  margin-top:clamp(8px, 1.4vh, 16px);
  font-family:var(--font-display); font-weight:600;
  font-size:clamp(1.15rem, 3.2vh, 2.1rem);
  line-height:1.26; letter-spacing:-.008em;
  color:var(--green-deep);
}


/* --- 2. process design --------------------------------------------- */
.process{ background:var(--paper); padding:96px 0 84px; text-align:center; }

.process-inner{ max-width:96ch; margin-inline:auto; }

.process h2{
  font-family:var(--font-display);
  font-weight:700;                    /* Playfair is a variable font: 400-900, one file */
  font-size:clamp(2.1rem, 4vw, 3.2rem);
  line-height:1.08; letter-spacing:-.016em;
  color:var(--ink-black); margin:0 0 34px;
}

.process p{
  font-size:1rem; font-weight:400; line-height:1.78;
  color:var(--ink-body); margin:0 0 18px;
}

.process p:last-child{ margin-bottom:0; }

.process strong{ font-weight:500; color:var(--ink-black); }


/* --- 3. the ten categories -----------------------------------------
   Alternating rows. The flip is an explicit modifier using ONE
   mechanism (order), never nth-child plus direction -- those cancel,
   which is why the homepage blocks all ended up on the same side.
   overflow-x:clip contains the 100px resting offset of the sideways
   entrances, which would otherwise widen the document at load. */
.cats{ background:var(--paper); padding:0 0 40px; overflow-x:clip; }

.cat{
  display:grid; grid-template-columns:1fr 1fr;
  gap:84px; align-items:center;
  padding:74px 0; border-top:1px solid var(--line);
  scroll-margin-top:104px;
}

.cat--flip .cat-visual{ order:1; }
   /* the visual is FIRST in the DOM, so
                                        flipping means sending it last -- order:-1
                                        would have been a no-op */

/* No frame, no box, no ground: the unit alone. Each is sized so the
   ten read at one visual weight rather than one width -- a tall brazed
   plate and a long condenser otherwise look like different products.
   --w is set per unit from its own proportions. */
.cat-visual{ display:flex; justify-content:center; }

.cat-visual img{
  display:block;
  width:auto; height:auto;
  max-width:var(--w, 100%);
  max-height:clamp(320px, 62vh, 620px);
}

.cat-name{
  font-family:var(--font-display); font-weight:600;
  font-size:clamp(1.6rem, 2.6vw, 2.25rem);
  line-height:1.12; letter-spacing:-.012em;
  color:var(--ink-black); margin:0;
}

.cat-name::after{
  content:""; display:block; width:48px; height:2px;
  background:var(--green-deep); margin-top:22px;
}

.cat-body{ margin-top:26px; max-width:58ch; }

.cat-body p{
  font-size:1rem; font-weight:400; line-height:1.8;
  color:var(--ink-body); margin:0 0 16px;
}

.cat-body p:last-child{ margin-bottom:0; }



/* --- consultation call to action ------------------------------------
   A square box, not the site's pill: this is a page-level action, and
   the corner treatment keeps it distinct from the hero buttons.
   Fills gold on hover, the same gesture the hero buttons use -- the
   background colour changes, so there is no direction to it and nothing
   to play in reverse on mouse-out.
   The reveal class sits on the wrapping <p>, never on the button:
   .f-* and .cat-cta both declare a transition, and CSS keeps only the
   later one -- putting them together would silently kill the hover. */
.cat-cta{
  display:inline-flex; align-items:center; gap:13px;
  padding:15px 30px;
  border:2px solid var(--ink-black);
  font-family:var(--font-ui); font-size:.9rem; font-weight:600;
  letter-spacing:.09em; text-transform:uppercase;
  color:var(--ink-black);
  background-color:transparent;
  transition:background-color var(--dur-fast) var(--ease-soft),
             border-color     var(--dur-fast) var(--ease-soft),
             color            var(--dur-fast) var(--ease-soft);
}

.cat-cta:focus-visible{
  background-color:var(--gold);
  border-color:var(--gold);
  color:var(--navy);
}
@media (hover:hover){ .cat-cta:hover{
  background-color:var(--gold);
  border-color:var(--gold);
  color:var(--navy);
} }

.cat-cta .arw{ transition:transform var(--dur-fast) var(--ease-out); }

@media (hover:hover){ .cat-cta:hover .arw{ transform:translateX(6px); } }

.cat-cta-wrap{ margin-top:34px; }

@media (max-width:980px){ .cat-cta-wrap{ margin-top:28px; } }


@media (max-width:1100px){
  .cat{ gap:56px; }
  .process-inner{ max-width:none; }
}

@media (max-width:980px){
  .banner-copy{ padding:clamp(16px, 2.2vh, 32px) 0; }
  .process{ padding:72px 0 62px; }
  .cats{ padding-bottom:24px; }
  .cat{ grid-template-columns:1fr; gap:34px; padding:56px 0; }
  /* Stacking order for these rows lives in one place, in the
     max-width:900px block near the foot of this file. .cat-copy is
     display:contents there, so ordering it does nothing and ordering
     .cat-visual here only fought the rule that actually applies. */

  .cat-body{ max-width:none; }
}


/* --- division block imagery ------------------------------------
   Two kinds. .biz-shot is a framed photograph: it inherits the 4:3
   box the placeholders defined, so the block rhythm is unchanged.
   .biz-figure is a cut-out with no frame -- no box, no crop, no
   aspect lock. It sets its own height from the artwork.
   Neither wrapper declares a transition, so .wipe can safely sit on
   the same element (it owns clip-path alone). */
/* --- hover zoom -----------------------------------------------------
   Applies to every image on the site EXCEPT the hero, which owns its
   own 8s Ken Burns scale and must not be touched.
   The hover sits on the wrapper, not the image, so the whole tile is
   the target. Scale and timing are the reference site's measured
   values: scale(1.05) on 1s ease.
   The zoom is the image's ONLY transform -- entrance and parallax live
   on ancestor elements, because CSS keeps just the last transform on
   any one element. */
.zoomwrap{ overflow:hidden; display:block; }


.biz-shot{ aspect-ratio:4/3; overflow:hidden; }

/* The cut-out must not be clipped. The bleed now lives on the zoom
   wrapper rather than the image: with it on the image, the wrapper's
   overflow:hidden sliced 69px off the left flange at rest, and the
   hover zoom cropped it further. overflow:visible also lets the zoom
   grow outward, which is right for an object with no frame. */
.biz-figure > .zoomwrap{ overflow:visible; }

/* Bleed is opt-in per figure, not derived from nth-child parity.
   The even-block swap at the bottom of this section is inert -- it
   applies order:-1 AND direction:rtl, which cancel, so the visual is
   on the right in every block. A parity-keyed rule would therefore
   have bled the odd blocks toward the page edge. */
@media (min-width:981px){
  .biz-figure--bleed > .zoomwrap{ width:112%; margin-left:-12%; }
}


/* Anchor landings. A native cross-page jump (about.html#partners) puts
   the target's top at y=0, which is behind the 85px sticky header --
   right now only the section's own padding saves it. scroll-margin-top
   makes that explicit instead of accidental, and it also covers the
   in-page jumps in the no-Lenis fallback path. */
:target,
#story, #partners, #software, #engineering, #licensing, #academy, #marketplace,
#plate-frame , #brazed , #welded-bloc , #spiral , #plate-shell , #shell-tube , #whrb , #feedwater , #condenser , #drycooler{
  scroll-margin-top:104px;
}
/* Nthalpix Technologies — rules unique to the single-exchanger pages */

.ex-head{
  background:var(--navy-deep);
  padding:calc(157px + 10px) 0 32px;
  position:relative; overflow:hidden; isolation:isolate;
}
/* The artwork sits behind the title. Measured on the supplied image the
   title zone averages only 3.2:1 against white and carries specular
   highlights that reach 1:1, so a scrim is not decoration -- without it
   the headline disappears wherever the picture is bright. */
.ex-head-art{
  position:absolute; inset:0; width:100%; height:100%;
  object-fit:cover; object-position:center 42%;
  z-index:-2;
}
.ex-head::after{
  content:""; position:absolute; inset:0; z-index:-1;
  /* Tuned by measurement, not by eye. The first version kept only 9% of
     the artwork's luminance and held text at 10:1 -- far more scrim than
     readability needed. This keeps ~15% and still measures 6.5:1 at the
     worst point, against a 4.5:1 floor. A lighter setting reached 21%
     but left no margin, and JPEG noise alone could push it under. */
  background:
    linear-gradient(90deg, rgba(6,17,30,.88) 0%, rgba(6,17,30,.78) 34%, rgba(6,17,30,.40) 66%, rgba(6,17,30,.18) 100%),
    linear-gradient(180deg, rgba(6,17,30,.56) 0%, rgba(6,17,30,.18) 46%, rgba(6,17,30,.36) 100%);
}
.ex-head .shell{ position:relative; z-index:1; }

.ex-eyebrow{
  font-family:var(--font-mono); font-size:.74rem; font-weight:600;
  letter-spacing:.2em; text-transform:uppercase; color:var(--gold);
  margin:0 0 22px;
}

.ex-eyebrow a{ color:inherit; }

@media (hover:hover){ .ex-eyebrow a:hover{ color:#fff; } }

.ex-title{
  font-family:var(--font-display); font-weight:600;
  font-size:clamp(1.9rem, 3.9vw, 3.05rem);
  line-height:1.04; letter-spacing:-.018em; color:#fff; margin:0;
}

.ex-lede{
  margin:14px 0 0; max-width:66ch;
  font-family:var(--font-display); font-weight:600;
  font-size:clamp(1.05rem, 1.5vw, 1.32rem); line-height:1.38;
  color:var(--green-deep);
}


.ex-main{ background:var(--paper); padding:40px 0 52px; overflow-x:clip; }

.ex-grid{
  /* Not half and half: the write-up needs the width more than the unit
     does. Tall units are height-capped anyway, so a narrower image
     column costs them nothing. */
  display:grid; grid-template-columns:minmax(0,1fr) minmax(0,1.95fr);
  gap:48px; align-items:center;
}

/* the unit alone: no frame, no box, no ground — as on the overview */
.ex-visual{ display:flex; justify-content:center; }

.ex-visual img{
  display:block; width:auto; height:auto;
  max-width:var(--w, 100%);
  max-height:clamp(280px, 50vh, 560px);
}

.ex-body p{
  font-size:1.02rem; font-weight:400; line-height:1.72;
  color:var(--ink-body); margin:0 0 15px;
}

.ex-body p:last-child{ margin-bottom:0; }


.ex-cta-wrap{ margin-top:30px; }

.ex-cta{
  display:inline-flex; align-items:center; gap:13px;
  padding:16px 32px;
  border:2px solid var(--ink-black);
  font-family:var(--font-ui); font-size:.92rem; font-weight:600;
  letter-spacing:.09em; text-transform:uppercase;
  color:var(--ink-black); background-color:transparent;
  transition:background-color var(--dur-fast) var(--ease-soft),
             border-color     var(--dur-fast) var(--ease-soft),
             color            var(--dur-fast) var(--ease-soft);
}

.ex-cta:focus-visible{
  background-color:var(--gold); border-color:var(--gold); color:var(--navy);
}
@media (hover:hover){ .ex-cta:hover{
  background-color:var(--gold); border-color:var(--gold); color:var(--navy);
} }

.ex-cta .arw{ transition:transform var(--dur-fast) var(--ease-out); }

@media (hover:hover){ .ex-cta:hover .arw{ transform:translateX(6px); } }


/* the other nine, so every page links onward */
.ex-more{ background:var(--paper-alt); padding:72px 0 84px; }

.ex-more h2{
  font-family:var(--font-display); font-weight:600;
  font-size:clamp(1.5rem, 2.2vw, 1.95rem); color:var(--ink-black); margin:0 0 30px;
}

.ex-more ul{ list-style:none; margin:0; padding:0;
  display:grid; grid-template-columns:repeat(3,1fr); gap:16px; }

/* Tiles, not a bare list. Centring only works because each item is now
   a real block with its own edges -- centred text in an open list gives
   the eye no consistent left edge to scan down. */
.ex-more a{
  display:flex; align-items:center; justify-content:center; text-align:center;
  min-height:104px; padding:24px 22px;
  border:1px solid var(--line);
  background-color:var(--paper);
  color:var(--ink-black);
  font-family:var(--font-ui); font-weight:600;
  font-size:1.02rem; line-height:1.32;
  position:relative;
  transition:background-color var(--dur-fast) var(--ease-soft),
             border-color     var(--dur-fast) var(--ease-soft),
             color            var(--dur-fast) var(--ease-soft),
             transform        var(--dur-fast) var(--ease-out);
}
/* the whole tile fills, so there is no direction to it and nothing to
   play in reverse on the way out */
.ex-more a:focus-visible{
  /* --mark-cool #37c9b0, the teal already in the logo tokens and used nowhere else on
     the site. Gold belongs to the consultation buttons, and green at
     this size only reaches 3.4:1 against white. Navy text on teal
     measures 7.8:1. */
  background-color:var(--mark-cool);
  border-color:var(--mark-cool);
  color:var(--navy);
  transform:translateY(-3px);
}
@media (hover:hover){ .ex-more a:hover{
  /* --mark-cool #37c9b0, the teal already in the logo tokens and used nowhere else on
     the site. Gold belongs to the consultation buttons, and green at
     this size only reaches 3.4:1 against white. Navy text on teal
     measures 7.8:1. */
  background-color:var(--mark-cool);
  border-color:var(--mark-cool);
  color:var(--navy);
  transform:translateY(-3px);
} }
/* a gold hairline draws along the bottom as it fills */
.ex-more a::after{
  content:""; position:absolute; left:0; right:0; bottom:0; height:2px;
  background:var(--gold); transform:scaleX(0); transform-origin:left center;
  transition:transform var(--dur-mid) var(--ease-out);
}
@media (hover:hover){ .ex-more a:hover::after{ transform:scaleX(1); } }
@media (prefers-reduced-motion: reduce){
  .ex-more a{ transition:background-color .01s, color .01s; }
  @media (hover:hover){ .ex-more a:hover{ transform:none; } }
  .ex-more a::after{ transition:none; }
}


@media (max-width:980px){
  .ex-head{ padding:calc(126px + 40px) 0 44px; }
  .ex-main{ padding:56px 0 68px; }
  .ex-grid{ grid-template-columns:1fr; gap:36px; }
  /* The software inside pages carry .ex-main--balanced, whose own rule
     (0,2,1) outranks this one and caps their artwork at 54vh. The eleven
     engineering exchanger pages use plain .ex-main and so fell to this
     40vh, which rendered the same photograph at 74% of the size it has
     on the matching software page -- 148x221 against 200x299 for the
     plate-and-frame unit at 390px. Matched, so a product is the same
     size whichever page a reader meets it on. */
  .ex-visual img{ max-height:clamp(300px, 54vh, 560px); }
  .ex-more ul{ grid-template-columns:1fr 1fr; }
}

@media (max-width:640px){
  .ex-more ul{ grid-template-columns:1fr; }
}

/* --- licensing page -------------------------------------------------
   Same masthead system as About and Engineering: the artwork at its own
   ratio, full bleed from y=0, with the title block filling the rest of
   the first screen. */
.lic-banner{
  background:var(--navy-deep);
  min-height:100svh;
  display:flex; flex-direction:column;
}
.lic-banner .banner-art{ aspect-ratio:2000 / 800; }

.lic-main{ background:var(--paper); padding:96px 0 40px; overflow-x:clip; }
.lic-intro{ max-width:74ch; margin:0 auto 20px; text-align:center; }
.lic-intro h2{
  font-family:var(--font-display); font-weight:700;
  font-size:clamp(2rem, 3.6vw, 3rem);
  line-height:1.08; letter-spacing:-.016em; color:var(--ink-black); margin:0 0 28px;
}
.lic-intro p{ font-size:1.02rem; line-height:1.8; color:var(--ink-body); margin:0; }

.lic-row{
  display:grid; grid-template-columns:minmax(0,1fr) minmax(0,1.12fr);
  gap:54px; align-items:center;
  padding:70px 0; border-top:1px solid var(--line); margin-top:56px;
  scroll-margin-top:104px;
}
/* Flipping has to swap the COLUMN WIDTHS as well as the order. With
   only order:1 the visual landed in the second (wider) column and the
   write-up was squeezed into the narrow one -- so alternate rows had a
   big image and cramped text, the opposite of the intent. */
.lic-row--flip{ grid-template-columns:minmax(0,1.12fr) minmax(0,1fr); }
.lic-row--flip .lic-visual{ order:1; }
.lic-visual{ display:flex; justify-content:center; }
.lic-visual img{
  display:block; width:auto; height:auto;
  max-width:var(--w, 100%);
  /* Tall cut-outs (a brazed pack is 0.43 wide to tall) can only gain
     width by gaining height, so the cap is set close to the height the
     write-up already occupies -- the row does not grow, the unit does. */
  max-height:clamp(340px, 68vh, 660px);
}
.lic-name{
  font-family:var(--font-display); font-weight:600;
  font-size:clamp(1.6rem, 2.6vw, 2.25rem);
  line-height:1.12; letter-spacing:-.012em; color:var(--ink-black); margin:0;
}
.lic-name::after{
  content:""; display:block; width:48px; height:2px;
  background:var(--green-deep); margin-top:22px;
}
.lic-body{ margin-top:26px; }
.lic-body p{
  font-size:1rem; font-weight:400; line-height:1.76;
  color:var(--ink-body); margin:0 0 16px;
}
.lic-body p:last-child{ margin-bottom:0; }
.lic-cta-wrap{ margin-top:32px; }

@media (max-width:1100px){ .lic-row{ gap:48px; } }
@media (max-width:980px){
  .lic-main{ padding:70px 0 24px; }
  .lic-intro{ max-width:none; }
  .lic-row{ grid-template-columns:1fr; gap:32px; padding:54px 0; margin-top:44px; }
  /* Stacking order is set once, in the max-width:900px block near the
     foot of this file. See the note on .cat-visual above. */

}

/* Inside pages carry a breadcrumb eyebrow in the banner. It already
   marks the top of the block, so the gold rule would be a second marker
   doing the same job -- and the extra height pushed the banner past one
   screen on wide and short displays. */
.banner-copy .shell.has-eyebrow::before{ display:none; }
.banner-copy .has-eyebrow .ex-eyebrow{ margin-bottom:10px; }
/* and a touch less air top and bottom, to close the last few pixels */
.banner-copy--tight{ padding:clamp(14px, 1.9vh, 30px) 0; }
.banner-copy .has-eyebrow .banner-sub{ margin-top:clamp(6px, 1vh, 12px); }

/* --- marketplace ----------------------------------------------------
   Reuses the licensing row system (.lic-row and friends) rather than
   duplicating it; only the group headings and the paired-parts visual
   are new. */
.mkt-group{
  margin:78px 0 -18px;
  padding-top:56px; border-top:1px solid var(--line);
}
.mkt-group:first-of-type{ margin-top:52px; }
.mkt-group p{
  font-family:var(--font-mono); font-size:.74rem; font-weight:600;
  letter-spacing:.2em; text-transform:uppercase; color:var(--gold); margin:0 0 14px;
}
.mkt-group h2{
  font-family:var(--font-display); font-weight:700;
  font-size:clamp(1.7rem, 2.8vw, 2.4rem);
  line-height:1.1; letter-spacing:-.014em; color:var(--ink-black); margin:0;
}
.mkt-group + .lic-row{ border-top:0; margin-top:34px; }

/* plates and gaskets are one write-up in the source copy, so they share
   one row and the visual column carries both units side by side */
.mkt-pair{ display:flex; align-items:center; justify-content:center; gap:26px; }
.mkt-pair img{
  display:block; width:auto; height:auto;
  max-width:48%; max-height:clamp(260px, 46vh, 500px);
}
@media (max-width:980px){
  .mkt-group{ margin:56px 0 -12px; padding-top:44px; }
  .mkt-pair{ gap:18px; }
  .mkt-pair img{ max-height:clamp(180px, 28vh, 300px); }
}

/* --- academy --------------------------------------------------------
   These are photographs of real sessions, not cut-out equipment, so
   they get a frame rather than sitting loose on the page -- the same
   distinction the homepage makes between .biz-shot and .biz-figure. */
.acad-shot{
  aspect-ratio:4/3; overflow:hidden;
  border:1px solid var(--line);
}
.acad-shot img{ width:100%; height:100%; object-fit:cover; display:block; }

/* Course tables. Two of the academy write-ups are real <table> markup
   in the source copy, not prose -- they list courses against durations
   and have to render as tables, not as escaped tags. */
.lic-body table,
.ex-body table{
  width:100%; border-collapse:collapse; margin:6px 0 20px;
  font-family:var(--font-ui); font-size:.95rem;
}
.lic-body table th,
.ex-body table th{
  text-align:left; padding:11px 14px 11px 0;
  border-bottom:1px solid var(--ink-black);
  font-family:var(--font-mono); font-size:.7rem; font-weight:600;
  letter-spacing:.16em; text-transform:uppercase; color:var(--ink-black);
}
.lic-body table th:last-child,
.lic-body table td:last-child,
.ex-body table th:last-child,
.ex-body table td:last-child{ text-align:right; padding-right:0; white-space:nowrap; }
.lic-body table td,
.ex-body table td{
  padding:12px 14px 12px 0; border-bottom:1px solid var(--line);
  color:var(--ink-body); line-height:1.5;
}
.lic-body table tr:last-child td,
.ex-body table tr:last-child td{ border-bottom:0; }

/* The exchanger detail pages run a 1 : 1.95 grid so a long write-up,
   the unit and the button land on one screen. The academy pages are a
   different shape -- a landscape photograph rather than a tall cut-out
   -- so they get a balanced split and the picture reads properly. */
.ex-main--balanced .ex-grid{ grid-template-columns:minmax(0,1fr) minmax(0,1.25fr); gap:56px; }
.ex-main--balanced .acad-shot{ width:100%; display:block; }
.ex-main--balanced .ex-visual img{ max-height:clamp(300px, 54vh, 560px); }
@media (max-width:980px){
  .ex-main--balanced .ex-grid{ grid-template-columns:1fr; gap:34px; }
}

/* Academy inside pages put the write-up on the left and the picture on
   the right. Reversing has to swap the COLUMN WIDTHS as well as the
   order, or the image lands in the wider slot and the text is squeezed
   -- the same trap the .lic-row flip fell into. */
.ex-main--reverse .ex-grid{ grid-template-columns:minmax(0,1.25fr) minmax(0,1fr); }
.ex-main--reverse .ex-visual{ order:1; }
@media (max-width:980px){
  .ex-main--reverse .ex-grid{ grid-template-columns:1fr; }
  /* order:0 put the photograph above the heading once stacked. The copy
     leads on a narrow screen, the same as every other row. */
  .ex-main--reverse .ex-visual{ order:2; }
  .ex-main--reverse .ex-copy{ order:1; }
}

/* Mirroring. The units are photographed facing one way; when a row sits
   on the opposite side the unit ends up facing off the page. Flipping
   the image in CSS keeps it looking into the text without needing a
   second copy of the file — and leaves the same file free to face the
   other way on its own detail page, where it is always on the left.
   Safe here because none of the cut-outs carries lettering. */
.mirror-x{ transform:scaleX(-1); }

/* --- marketplace category pages -------------------------------------
   A category page lists what is in the group; it does not repeat the
   write-ups, which live on the item pages. Tiles rather than prose, so
   the two page types never compete for the same wording. */
.mkt-cat{ background:var(--paper); padding:80px 0 96px; }
.mkt-cat-intro{
  max-width:74ch; margin:0 auto 52px; text-align:center;
  font-size:1.04rem; line-height:1.78; color:var(--ink-body);
}
.cat-cards{
  display:grid; grid-template-columns:repeat(2,1fr); gap:28px;
}
.cat-card{
  display:flex; align-items:center; gap:26px;
  padding:26px 30px; border:1px solid var(--line);
  background-color:var(--paper); color:var(--ink-black);
  transition:background-color var(--dur-fast) var(--ease-soft),
             border-color     var(--dur-fast) var(--ease-soft),
             transform        var(--dur-fast) var(--ease-out);
}
.cat-card:focus-visible{
  border-color:var(--mark-cool);
  background-color:var(--paper-alt);
  transform:translateY(-3px);
}
@media (hover:hover){ .cat-card:hover{
  border-color:var(--mark-cool);
  background-color:var(--paper-alt);
  transform:translateY(-3px);
} }
.cat-card-shot{
  flex:0 0 118px; height:132px;
  display:flex; align-items:center; justify-content:center;
}
.cat-card-shot img{ max-width:100%; max-height:100%; width:auto; height:auto; display:block; }
.cat-card-body{ display:block; }
.cat-card-name{
  display:block; font-family:var(--font-display); font-weight:600;
  font-size:1.24rem; line-height:1.2; letter-spacing:-.01em; color:var(--ink-black);
}
.cat-card-line{
  display:block; margin-top:9px; font-size:.95rem; line-height:1.55; color:var(--ink-body);
}
.cat-card-go{
  display:block; margin-top:16px;
  /* .7rem is 11.2px: under the 12px floor the rest of the site's small
     labels already hold to, and this one is a call to action */
  font-family:var(--font-mono); font-size:.75rem; font-weight:600;
  letter-spacing:.18em; text-transform:uppercase; color:var(--gold-deep);
}
.cat-card .arw{ display:inline-block; transition:transform var(--dur-fast) var(--ease-out); }
@media (hover:hover){ .cat-card:hover .arw{ transform:translateX(5px); } }
@media (max-width:900px){
  .mkt-cat{ padding:60px 0 72px; }
  .cat-cards{ grid-template-columns:1fr; gap:20px; }
}
@media (max-width:520px){
  .cat-card{ flex-direction:column; align-items:flex-start; gap:18px; }
  .cat-card-shot{ flex:none; height:112px; }
}
@media (prefers-reduced-motion: reduce){
  .cat-card{ transition:background-color .01s, border-color .01s; }
  @media (hover:hover){ .cat-card:hover{ transform:none; } }
  .cat-card .arw{ transition:none; }
}
/* group headings in the dropdown are now links to their category pages */
.dd-head--link{ display:block; transition:color var(--dur-fast) var(--ease-soft); }
@media (hover:hover){ .dd-head--link:hover{ color:var(--gold); } }

/* a group label that IS a link has to accept clicks again */
.dd-head--link{ pointer-events:auto; cursor:pointer; }

/* --- software --------------------------------------------------------
   On the software pages the product IS the code, so the code carries
   the headline weight and the equipment name sits under it. Everywhere
   else on the site codes are suppressed -- there the product is the
   equipment, not the tool. */
.sw-code{
  font-family:var(--font-mono); font-weight:600;
  font-size:clamp(2.4rem, 5.2vw, 4.1rem);
  line-height:1; letter-spacing:-.02em; color:var(--ink-black); margin:0;
}
.sw-for{
  margin:16px 0 0;
  font-family:var(--font-display); font-weight:600;
  font-size:clamp(1.15rem, 1.9vw, 1.55rem); line-height:1.3;
  /* --green-deep reaches only 3.1:1 on the pale band; this is the same
     hue taken dark enough to read at 4.95:1 */
  letter-spacing:-.008em; color:#1f7a50;
}
.lic-name .sw-sub{
  display:block; margin-top:12px;
  font-family:var(--font-display); font-weight:600;
  font-size:clamp(1.15rem, 1.8vw, 1.5rem); line-height:1.28;
  letter-spacing:-.008em; color:var(--green-deep);
}
.sw-row .lic-name::after{ margin-top:20px; }

/* Software detail pages share the engineering masthead, so the code and
   its subtitle sit on the dark band rather than the pale title block --
   they need light values and a size that suits a 364px band. */
.sw-code--band{
  color:#fff;
  font-size:clamp(2.1rem, 4.4vw, 3.4rem);
}
.sw-for--band{ color:var(--mark-green); }

/* The engineering lede uses --green-deep, which is tuned for white paper.
   On the image band it measures 4.2:1 at 21px, just under the 4.5:1 needed
   for text that size. The lighter mark green on the same band reads 7.2:1. */
.ex-head .ex-lede{ color:var(--mark-green); }


/* on a light page the header is solid from the first frame, before the
   scroll handler has run, and the hero scrim is suppressed entirely */
/* A backdrop blur has to re-filter everything behind the bar on every
   scrolled frame. Measured on the contact page it pushed 95th-percentile
   frame time from 17ms to 30ms and dropped 9 frames in a short scroll,
   so the bar is simply opaque instead -- visually all but identical. */
.light-page .site-header{
  background:#fff;
  border-bottom:1px solid var(--line);
}
.light-page .site-header::before{ display:none; }
.light-page .site-header .header-inner{ color:var(--ink); }
.light-page .site-header .nav-link,
.light-page .site-header .icon-btn,
.light-page .site-header .utility a{ color:#141c26; }
.light-page .site-header .nav-link::after{ background:var(--gold-deep); }
/* --- contact --------------------------------------------------------
   Band masthead like every other inside page, then a white body: ways to
   reach us on the left, the form on its own plate at the right. The plate
   is capped so it does not dwarf the column beside it. */
.cx{ background:var(--paper); padding:78px 0 104px; }
.cx-grid{
  display:grid; grid-template-columns:minmax(0,1fr) minmax(0,0.92fr);
  gap:70px; align-items:start;
}
.cx-plate-col{ display:flex; justify-content:flex-end; }

/* ---- left column ----
   Only Email and Telephone carry a mark. Every label and every value
   starts on the same left edge, so the four blocks read as one column
   whether or not a mark is present. */
.cx-block{ margin-bottom:38px; }
.cx-block:last-child{ margin-bottom:0; }
.cx-head{
  display:flex; align-items:center; gap:10px; margin:0 0 10px;
  font-family:var(--font-ui); font-size:1rem; font-weight:600;
  letter-spacing:.004em; color:var(--ink-black);
}
.cx-mark{
  width:23px; height:23px; flex:none; display:block; color:var(--gold-deep);
}
.cx-mark svg{ width:100%; height:100%; display:block; }
.cx-value{
  font-family:var(--font-ui); font-weight:400;
  /* Playfair sets old-style figures, which makes a phone number step up
     and down; the UI face keeps every digit on one baseline */
  font-variant-numeric:lining-nums tabular-nums;
  font-size:clamp(1.16rem, 1.65vw, 1.38rem); line-height:1.4;
  color:var(--ink-black); position:relative;
  /* each address on its own line; the width fits the text so the gold
     underline on hover stops at the end of the address, not the column */
  display:block; width:fit-content;
}
.cx-value + .cx-value{ margin-top:5px; }
a.cx-value::after{
  content:""; position:absolute; left:0; right:0; bottom:-4px; height:1px;
  background:var(--gold); transform:scaleX(0); transform-origin:left center;
  transition:transform var(--dur-mid) var(--ease-out);
}
a.cx-value:focus-visible::after{ transform:scaleX(1); }
@media (hover:hover){ a.cx-value:hover::after{ transform:scaleX(1); } }
a.cx-value{ transition:color var(--dur-fast) var(--ease-soft); }
@media (hover:hover){ a.cx-value:hover{ color:var(--green-deep); } }
.cx-body{
  font-family:var(--font-ui); font-size:.97rem; font-weight:300; line-height:1.75;
  color:var(--ink-body); margin:0; max-width:44ch;
}
.cx-socials{ display:flex; gap:12px; flex-wrap:wrap; }

/* ---- the form plate ---- */
/* A gold hairline along the top edge lifts the plate off the page; the
   flat grey box it replaced was the thing that read as unfinished. */
.cx-plate{
  width:100%; max-width:540px;
  background:#fff; border:1px solid #dfe4ea;
  border-top:2px solid var(--gold);
  padding:42px 42px 38px;
  /* a tight shadow repaints far more cheaply than a 50px spread */
  box-shadow:0 8px 22px rgba(14,32,57,.07);
}
.cx-plate h2{
  font-family:var(--font-display); font-weight:600;
  font-size:clamp(1.42rem, 2.2vw, 1.8rem); color:var(--ink-black); margin:0 0 8px;
}
.cx-req{
  font-family:var(--font-ui); font-size:.9rem; font-weight:300;
  line-height:1.6; color:#5a636d; margin:0 0 30px;
}
.req{ color:#b8860b; font-weight:500; }

.field{ position:relative; margin-bottom:22px; }
.field label{
  display:block; margin-bottom:8px;
  font-family:var(--font-ui); font-size:.92rem; font-weight:500; color:var(--ink-black);
}
.field input,
.field textarea{
  width:100%; display:block;
  font-family:var(--font-ui); font-size:1rem; font-weight:400; color:#12171d;
  background:#fff; border:1px solid var(--field-edge); border-radius:2px;
  padding:13px 14px; appearance:none;
  transition:border-color var(--dur-fast) var(--ease-soft), box-shadow var(--dur-fast) var(--ease-soft);
}
.field textarea{ resize:vertical; min-height:124px; line-height:1.65; }
.field input:focus,.field textarea:focus{
  outline:none; border-color:var(--mark-cool); box-shadow:0 0 0 3px rgba(55,201,176,.16);
}
.field input::placeholder,.field textarea::placeholder{ color:#a7b0b9; font-weight:300; }
.field.is-bad input,.field.is-bad textarea{ border-color:#c0392b; }
.err{
  display:block; margin-top:6px; opacity:0;
  font-family:var(--font-ui); font-size:.83rem; color:#c0392b;
  transition:opacity var(--dur-fast) var(--ease-soft);
}
.is-bad .err{ opacity:1; }
.cx-hp{ position:absolute; left:-9999px; width:1px; height:1px; overflow:hidden; }

/* ---- consent ---- */
.consent{ display:flex; gap:12px; align-items:flex-start; margin:0 0 18px; position:relative; }
/* the native control paints with the browser's own accent (blue on most
   systems), so it is replaced with one drawn in the brand green */
.consent input{
  appearance:none; -webkit-appearance:none;
  width:19px; height:19px; margin:2px 0 0; flex:none; cursor:pointer;
  border:1.5px solid var(--field-edge); background:#fff; border-radius:3px;
  transition:background-color var(--dur-fast) var(--ease-soft),
             border-color var(--dur-fast) var(--ease-soft);
}
@media (hover:hover){ .consent input:hover{ border-color:var(--mark-cool); } }
/* The tick used to be two borders of an empty ::after box, rotated 43
   degrees and nudged into place with a margin. A rotation does not move
   the layout box it is painted in, so the mark landed high: measured off
   the painted pixels at 8x, its centre sat 1.44px above the centre of
   the square, which at this size is plainly visible. It is now drawn as
   an SVG and centred by the browser, which cannot be off.

   It is also a background rather than a pseudo-element on purpose: an
   <input> is a replaced element, and ::before/::after on one are not
   rendered outside Blink. Only Chromium is installed here, so that is
   reasoning rather than something measured -- but a background image
   does not depend on the answer either way. */
.consent input:checked{
  background-color:var(--green-deep); border-color:var(--green-deep);
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12'%3E%3Cpath d='M2.5 6.2 4.9 8.6 9.5 3.4' fill='none' stroke='%23fff' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat:no-repeat;
  background-position:center;
  background-size:12px 12px;
}
.consent input:focus-visible{ outline:2px solid var(--mark-cool); outline-offset:2px; }
.consent span.t{
  font-family:var(--font-ui); font-size:.92rem; font-weight:400;
  line-height:1.7; color:#2f3740;
}
/* now that the policy page exists this is an anchor, so it needs the
   underline suppressed that the global link style would add */
a.pp-link{ text-decoration:none; }
.pp-link{
  color:var(--green-deep); font-weight:500;
  border-bottom:1px solid rgba(47,158,107,.45); cursor:pointer;
  transition:color var(--dur-fast) var(--ease-soft), border-color var(--dur-fast) var(--ease-soft);
}
@media (hover:hover){ .pp-link:hover{ color:var(--gold-deep); border-color:var(--gold); } }
.consent .err{ position:absolute; left:30px; bottom:-16px; }
.consent.is-bad input{ border-color:#c0392b; }

/* ---- verification ---- */
.cx-verify{
  display:flex; align-items:center; gap:14px; flex-wrap:wrap; position:relative;
  border:1px solid var(--field-edge); background:#f7faf8; border-radius:2px;
  padding:15px 18px; margin:24px 0 26px;
}
.cx-verify .vq{
  font-family:var(--font-ui); font-size:.92rem; font-weight:500; color:var(--ink-black);
}
.cx-verify input{
  width:84px; padding:9px 11px; border:1px solid var(--line); background:#fff;
  font-family:var(--font-ui); font-size:.96rem; color:var(--ink-black);
  transition:border-color var(--dur-fast) var(--ease-soft);
}
.cx-verify input:focus{ outline:none; border-color:var(--mark-cool); }
.cx-verify.is-ok{ border-color:var(--mark-cool); background:rgba(55,201,176,.09); }
.cx-verify.is-bad{ border-color:#c0392b; }
.cx-verify .tick{
  display:inline-flex; align-items:center; gap:7px; opacity:0;
  font-family:var(--font-ui); font-size:.86rem; font-weight:500; color:var(--green-deep);
  transition:opacity var(--dur-fast) var(--ease-soft);
}
.cx-verify.is-ok .tick{ opacity:1; }
.cx-verify .err{ position:absolute; left:18px; bottom:-19px; }

.cx-send{
  display:inline-flex; align-items:center; gap:13px;
  padding:15px 32px; border:2px solid var(--ink-black);
  font-family:var(--font-ui); font-size:.9rem; font-weight:600;
  letter-spacing:.08em; text-transform:uppercase;
  color:var(--ink-black); background-color:transparent; cursor:pointer;
  transition:background-color var(--dur-fast) var(--ease-soft),
             border-color var(--dur-fast) var(--ease-soft), color var(--dur-fast) var(--ease-soft);
}
.cx-send:focus-visible{ background-color:var(--gold); border-color:var(--gold); color:var(--navy); }
@media (hover:hover){ .cx-send:hover{ background-color:var(--gold); border-color:var(--gold); color:var(--navy); } }
.cx-send .arw{ transition:transform var(--dur-fast) var(--ease-out); }
@media (hover:hover){ .cx-send:hover .arw{ transform:translateX(6px); } }

/* Shown only when a submission could not be delivered. It has to carry
   a way to reach us that does not depend on the thing that just failed,
   so it always names an address the visitor can write to directly.
   Same face and measure as the rest of the form copy -- an error is not
   the moment to introduce a different typeface. */
.form-fail{
  margin:16px 0 0;
  padding:14px 16px;
  background:#fdf4f4;
  border:1px solid #e6c9c9;
  border-left:3px solid #b4443f;
  font-family:var(--font-ui);
  font-size:.95rem; font-weight:300; line-height:1.6;
  color:#7d2b27;
}
.form-fail:focus{ outline:2px solid var(--gold); outline-offset:2px; }

/* the button says what it is doing while the request is in flight */
.cx-send[aria-busy="true"]{ opacity:.72; cursor:progress; }

.cx-done{ display:none; }
.cx-done.is-on{ display:block; animation:cxIn .5s var(--ease-out) both; }
@keyframes cxIn{ from{opacity:0; transform:translateY(10px)} to{opacity:1; transform:none} }
.cx-done p{ font-family:var(--font-ui); font-size:.97rem; font-weight:300; line-height:1.72; color:var(--ink-body); margin:0; }
.cx-done p + p{ margin-top:12px; }

@media (max-width:1040px){
  .cx-grid{ grid-template-columns:1fr; gap:52px; }
  .cx-plate-col{ justify-content:flex-start; }
  .cx-plate{ max-width:none; }
  .cx{ padding:60px 0 78px; }
}
@media (max-width:640px){
  .cx-plate{ padding:30px 24px 28px; }
  .cx-value,.cx-body,.cx-socials{ padding-left:0; }
  a.cx-value::after{ left:0; }
}
@media (prefers-reduced-motion: reduce){
  a.cx-value::after{ transition:none }
  .cx-done.is-on{ animation:none }
}

/* ---- telephone: country code and national number are separate inputs,
   which is what makes a reliable E.164 number possible ---- */
.tel-row{ display:grid; grid-template-columns:minmax(0,168px) minmax(0,1fr); gap:10px; }
.tel-row select,
.field > select{
  width:100%; font-family:var(--font-ui); font-size:.98rem; color:var(--ink-black);
  background:#fff; border:1px solid var(--field-edge); border-radius:2px;
  padding:13px 10px; appearance:none; cursor:pointer;
  font-variant-numeric:lining-nums tabular-nums;
  background-image:url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8'%3E%3Cpath d='M1 1.5 6 6.5l5-5' fill='none' stroke='%233d444c' stroke-width='1.6'/%3E%3C/svg%3E");
  background-repeat:no-repeat; background-position:right 11px center; background-size:11px;
  transition:border-color var(--dur-fast) var(--ease-soft), box-shadow var(--dur-fast) var(--ease-soft);
}
.tel-row select:focus,
.field > select:focus{ outline:none; border-color:var(--mark-cool); box-shadow:0 0 0 3px rgba(55,201,176,.16); }
.field.is-bad .tel-row select,
.field.is-bad > select{ border-color:#c0392b; }
.field input[inputmode="numeric"],
.tel-row input{ font-variant-numeric:lining-nums tabular-nums; letter-spacing:.02em; }

.cx-count{
  display:block; margin-top:6px; text-align:right;
  font-family:var(--font-ui); font-size:.8rem; font-weight:400; color:var(--ink-soft);
  font-variant-numeric:lining-nums tabular-nums;
}
.cx-count.is-short{ color:#8a939c; }
.cx-count.is-near{ color:#b8860b; }
.cx-count.is-over{ color:#c0392b; }

/* The DPDP Act requires a notice to sit alongside the consent request,
   in plain language, stating what is collected, why, for how long, and
   how to withdraw or complain. It is set quietly so it informs without
   turning the form into a legal document. */
.cx-notice{
  border-left:2px solid var(--line); padding:2px 0 2px 16px; margin:4px 0 22px;
}
.cx-notice h3{
  font-family:var(--font-ui); font-size:.86rem; font-weight:600;
  color:var(--ink-black); margin:0 0 8px;
}
.cx-notice p{
  font-family:var(--font-ui); font-size:.83rem; font-weight:300; line-height:1.68;
  color:var(--ink-soft); margin:0 0 7px;
}
.cx-notice p:last-child{ margin-bottom:0; }
.cx-notice a{ color:var(--green-deep); text-decoration:underline; text-underline-offset:2px; }
@media (hover:hover){ .cx-notice a:hover{ color:var(--gold-deep); } }

/* Playfair sets numerals as old-style figures, so the 1 and 2 in N-SHE1
   and N-SHE2 rendered small and dropped below the baseline. The code is
   set in the mono face on the overview rows too, matching how it appears
   on each tool's own page. */
.sw-rowcode{
  font-family:var(--font-mono); font-weight:600;
  font-size:.88em; letter-spacing:-.01em;
  font-variant-numeric:lining-nums tabular-nums;
}

/* A dropdown is held open by :hover and :focus-within. After clicking an
   item the link keeps focus and the cursor is still over the nav, so the
   menu stayed open on the new page until you clicked somewhere else.
   The suppress class closes it at once; it lifts as soon as the pointer
   leaves the header, so normal hovering is unaffected. */
/* Desktop only, and it must stay that way. This is released by mousemove
   and by the header's mouseleave -- neither of which a touchscreen ever
   fires. Unscoped, one tap on a menu link latched it for the rest of the
   session and then killed every phone dropdown with four !important
   declarations: the accordion still opened and reserved its height, and
   the panel inside it was invisible and untappable. That is the blank
   menu, and why it only ever appeared after the first navigation. */
@media (min-width:981px) and (hover:hover){
  body.nav-suppress .nav-item .dropdown{
    opacity:0 !important; visibility:hidden !important; pointer-events:none !important;
    transition:none !important;
  }
}

/* --- header contact ---------------------------------------------------
   A gold plate that sits under the utility icons, flush with the bottom
   edge of the header. Hovering drops a white panel of four ways to reach
   us; each row warms to gold under the cursor. */
.qc{
  position:fixed; z-index:70;
  top:var(--hdr-h, 157px); right:30px;
  opacity:0; visibility:hidden; pointer-events:none;
  transform:translateY(-6px);
  transition:opacity .34s var(--ease-soft), visibility .34s var(--ease-soft),
             transform .34s var(--ease-out), top .34s var(--ease-out);
}
.qc.is-on{ opacity:1; visibility:visible; pointer-events:auto; transform:translateY(0); }

/* The label and the caret are one row: the label is a plain link that
   goes straight to the contact page, the caret opens the panel. Hovering
   no longer opens anything, so a passing cursor cannot trigger it. */
.qc-bar{
  display:flex; align-items:stretch; gap:0;
  box-shadow:0 6px 20px rgba(8,21,37,.18);
  border-radius:0 0 3px 3px; overflow:hidden;
}
.qc-tab{
  display:inline-flex; align-items:center; justify-content:center;
  padding:11px 20px; cursor:pointer; border:0;
  background:var(--gold); color:var(--navy-deep);
  font-family:var(--font-ui); font-size:.83rem; font-weight:600;
  letter-spacing:.1em; text-transform:uppercase; white-space:nowrap;
  transition:background-color .22s var(--ease-soft), color .22s var(--ease-soft);
}
.qc-tab:focus-visible{ background:var(--gold-deep); color:#fff; outline:none; }
@media (hover:hover){ .qc-tab:hover{ background:var(--gold-deep); color:#fff; outline:none; } }
.qc-caret{
  display:inline-flex; align-items:center; justify-content:center;
  width:38px; padding:0; border:0; cursor:pointer;
  background:var(--gold); color:var(--navy-deep);
  border-left:1px solid rgba(8,21,37,.22);
  transition:background-color .22s var(--ease-soft), color .22s var(--ease-soft);
}
.qc-caret svg{ width:17px; height:17px; display:block; transition:transform .26s var(--ease-out); }
.qc-caret:focus-visible{ background:var(--gold-deep); color:#fff; outline:none; }
@media (hover:hover){ .qc-caret:hover{ background:var(--gold-deep); color:#fff; outline:none; } }
.qc.is-open .qc-caret svg{ transform:rotate(180deg); }

.qc-panel{
  position:absolute; top:100%; right:0; margin-top:6px; min-width:286px;
  background:#fff; border:1px solid #e4e8ed; border-top:2px solid var(--gold);
  box-shadow:0 18px 46px rgba(14,32,57,.17);
  opacity:0; visibility:hidden; pointer-events:none;
  transform:translateY(-8px) scale(.985); transform-origin:top right;
  /* Closing is quicker than opening. Opening should feel unhurried;
     closing should get out of the way, and at .26s it read as lag. */
  transition:opacity .15s var(--ease-soft), visibility .15s var(--ease-soft),
             transform .15s var(--ease-out);
}
.qc.is-open .qc-panel{
  opacity:1; visibility:visible; pointer-events:auto; transform:translateY(0) scale(1);
  transition:opacity .24s var(--ease-soft), visibility .24s var(--ease-soft),
             transform .24s var(--ease-out);
}

/* The 6px gap between the tab and the panel is not part of any element, so
   moving down through it took the cursor outside .qc, hover was lost and
   the panel shut before it could be reached. This bridges the gap. It only
   becomes active once the panel is open, so it never blocks anything. */
.qc-panel::before{
  content:""; position:absolute; left:0; right:0; top:-10px; height:10px;
}



.qc-panel a{
  display:flex; align-items:center; gap:14px;
  padding:14px 20px; background:#fff; color:var(--ink-black);
  border-bottom:1px solid #eef1f4;
  font-family:var(--font-ui); font-size:.95rem; font-weight:400;
  font-variant-numeric:lining-nums tabular-nums; white-space:nowrap;
  transition:background-color .2s var(--ease-soft), color .2s var(--ease-soft);
}
.qc-panel a:last-child{ border-bottom:0; }
.qc-panel a:focus-visible{ background:var(--gold); color:var(--navy-deep); outline:none; }
@media (hover:hover){ .qc-panel a:hover{ background:var(--gold); color:var(--navy-deep); outline:none; } }
.qc-ico{ width:21px; height:21px; flex:none; display:block; }
.qc-ico svg{ width:100%; height:100%; display:block; }
@media (hover:hover){ .qc-panel a:hover .qc-ico svg *{ fill:var(--navy-deep); } }
@media (hover:hover){ .qc-panel a:hover .qc-ico svg [data-stroke]{ stroke:var(--navy-deep); fill:none; } }

@media (max-width:900px){
  .qc{ right:16px; }
  .qc-tab{ padding:10px 16px; font-size:.78rem; }
  .qc-panel{ min-width:0; width:calc(100vw - 32px); max-width:320px; }
}
@media (prefers-reduced-motion: reduce){
  .qc,.qc-panel,.qc-tab,.qc-panel a{ transition:none; }
}


/* --- mobile touch and legibility -------------------------------------
   Measured at 390px: several controls were under the 32px a finger needs,
   and two label styles fell below 12px. The dots in particular were 3px
   tall -- the visual size is kept, the tappable area is grown around it. */
@media (max-width:900px){
  /* utility row: mail icon and Contact Us were 17px and 23px tall */
  .utility a{ display:inline-flex; align-items:center; min-height:44px; padding:0 4px; }
  .mail-btn{ min-width:44px; justify-content:center; }

  /* footer legal links were 24px */
  .site-footer .legal a,
  .site-footer nav a{ display:inline-block; padding:9px 0; }

  /* carousel dots: 3px of visual, 44px of target */
  .dot{
    position:relative; padding:20px 10px; background-clip:content-box;
    min-width:44px; min-height:44px; box-sizing:content-box;
  }

  /* label styles that fell under 12px; !important is needed because the
     originals are set with clamp(), which otherwise wins */
  .lbl{ font-size:12px !important; }
  .spec{ font-size:12px !important; line-height:1.65; }
  .ex-eyebrow, .ex-eyebrow a{ font-size:12px !important; }

  /* email and telephone on the contact page: padding only. This used to
     set display:inline-block for the tap target, which also let two
     addresses sit on one line -- info@ and sales@ ran together on a
     phone. The base rule is already display:block with a fit-content
     width, which is a block box and a tight underline both. */
  .cx-value{ padding:6px 0; }
  /* the verification answer box was 21px tall */
  .cx-verify input{ min-height:44px; }
}

/* --- legal pages -----------------------------------------------------
   Long-form prose. A narrow measure, clear headings, and a definition
   list for the "what we collect / why" pairs so the structure is
   readable rather than a wall of paragraphs. */
section.legal{ background:var(--paper); padding:72px 0 96px; }
/* the page has no images, so it uses the full measure. Two columns
   would make a legal document hard to follow, so it stays one column
   but spans the shell, with the text a step larger to suit the width. */
.legal-wrap{ max-width:none; }
.legal-updated{
  font-family:var(--font-ui); font-size:.82rem; font-weight:500;
  letter-spacing:.02em; color:var(--ink-soft); margin:0 0 34px;
  padding-bottom:14px; border-bottom:1px solid var(--line);
}
section.legal h2{
  font-family:var(--font-display); font-weight:600;
  font-size:clamp(1.4rem, 2.3vw, 1.85rem); line-height:1.22;
  color:var(--ink-black); margin:52px 0 16px;
  padding-bottom:10px; border-bottom:1px solid var(--line);
}
section.legal h2:first-of-type{ margin-top:0; }
section.legal h3{
  font-family:var(--font-ui); font-weight:600; font-size:1rem;
  color:var(--ink-black); margin:26px 0 8px;
}
section.legal p{
  font-family:var(--font-ui); font-size:1.06rem; font-weight:400;
  line-height:1.75; color:#23282E; margin:0 0 15px; max-width:96ch;
}
section.legal ul{ margin:0 0 16px; padding-left:20px; }
section.legal li{
  font-family:var(--font-ui); font-size:1.06rem; font-weight:400;
  line-height:1.7; color:#23282E; margin-bottom:9px; max-width:94ch;
}
section.legal strong{ font-weight:600; color:var(--ink-black); }
section.legal a{
  color:var(--green-deep); border-bottom:1px solid rgba(47,158,107,.4);
  transition:color var(--dur-fast) var(--ease-soft), border-color var(--dur-fast) var(--ease-soft);
}
@media (hover:hover){ section.legal a:hover{ color:var(--gold-deep); border-color:var(--gold); } }

/* a labelled pair, used for "what we collect" and the report checklist */
.legal-dl{ margin:0 0 20px; border-top:1px solid var(--line); }
.legal-dl > div{
  display:grid; grid-template-columns:minmax(0,300px) minmax(0,1fr); gap:34px;
  padding:14px 0; border-bottom:1px solid var(--line);
}
.legal-dl dt{
  font-family:var(--font-ui); font-size:1.02rem; font-weight:600; color:var(--ink-black); margin:0;
}
.legal-dl dd{
  font-family:var(--font-ui); font-size:1.02rem; font-weight:400;
  line-height:1.66; color:#23282E; margin:0;
}
@media (max-width:700px){
  .legal-dl > div{ grid-template-columns:1fr; gap:5px; }
}

/* the box that carries the address to write to */
.legal-box{
  border:1px solid var(--line); border-left:3px solid var(--gold);
  background:var(--paper-alt); padding:24px 26px; margin:26px 0 30px;
}
.legal-box p{ margin:0 0 6px; }
.legal-box p:last-child{ margin-bottom:0; }
.legal-box .lb-label{
  font-family:var(--font-ui); font-size:.72rem; font-weight:600;
  letter-spacing:.12em; text-transform:uppercase; color:var(--gold-deep); margin-bottom:9px;
}
.legal-box a{ font-weight:400; }

/* the reassurance strip on the piracy page */
.legal-note{
  display:flex; gap:14px; align-items:flex-start;
  border:1px solid var(--line); background:#fff;
  padding:20px 22px; margin:0 0 30px;
}
.legal-note .ln-ico{ width:22px; height:22px; flex:none; color:var(--green-deep); }
.legal-note .ln-ico svg{ width:100%; height:100%; display:block; }
.legal-note p{ margin:0; font-size:.95rem; }

/* --- footer detail columns -------------------------------------------
   Registered address, how to reach us, and where to go next. Sits between
   the brand block and the copyright line. */
.footer-cols{
  display:grid; grid-template-columns:1.15fr 1fr .85fr; gap:52px;
  padding:44px 0 40px; margin-top:40px;
  border-top:1px solid var(--line);
}
/* --gold-deep is #F7C144, which measures 1.66:1 on white — invisible as
   a label. A deeper bronze reads 5.3:1 and still belongs to the palette.
   The selector is scoped so the .footer-cols p rule cannot override it. */
.footer-cols .fc-head{
  display:flex; align-items:center; gap:9px; margin:0 0 14px;
  font-family:var(--font-ui); font-size:.78rem; font-weight:600;
  letter-spacing:.14em; text-transform:uppercase; color:#8A6510;
}
.fc-ico{ width:17px; height:17px; flex:none; color:#B08418; }

/* Explore had a decorative arrow where the other three headings carry a
   pictogram that means something -- a pin, an envelope, a handset. The
   arrow said nothing and its 17px plus the 9px gap pushed the label 26px
   to the right of the links underneath it, so the column read as two
   different left edges. Gone, and the heading now starts exactly where
   its links do. */
.footer-cols .fc-head--plain{ gap:0; }
.fc-ico svg{ width:100%; height:100%; display:block; }
.fc-block + .fc-block{ margin-top:30px; }
.footer-cols p{
  font-family:var(--font-ui); font-size:.95rem; font-weight:400;
  line-height:1.72; color:var(--ink-black); margin:0;
  font-variant-numeric:lining-nums tabular-nums;
}
.footer-cols a{
  display:block; width:fit-content;
  font-family:var(--font-ui); font-size:.95rem; font-weight:400;
  line-height:1.72; color:var(--ink-black);
  font-variant-numeric:lining-nums tabular-nums;
  transition:color var(--dur-fast) var(--ease-soft);
}
@media (hover:hover){ .footer-cols a:hover{ color:var(--green-deep); } }
/* the nav is inline by default, so its links ran together on one line */
.fc-links{ display:flex; flex-direction:column; align-items:flex-start; }
.fc-links a{ padding:3px 0; }
.fc-links a::before{
  content:""; display:inline-block; width:0; height:1px; margin-right:0;
  background:var(--gold); vertical-align:middle;
  transition:width var(--dur-fast) var(--ease-out), margin-right var(--dur-fast) var(--ease-out);
}
@media (hover:hover){ .fc-links a:hover::before{ width:12px; margin-right:8px; } }

@media (max-width:900px){
  .footer-cols{ grid-template-columns:1fr 1fr; gap:34px 40px; }
}
@media (max-width:620px){
  .footer-cols{ grid-template-columns:1fr; gap:30px; padding:34px 0 30px; }
}

/* --- legal pages: heading without a hero -----------------------------
   These are documents, not display pages. No banner image, no scrim —
   a plain heading on white, clear of the fixed header. */
.legal-head{
  background:var(--paper);
  padding:calc(157px + 46px) 0 0;
}
.legal-title{
  font-family:var(--font-display); font-weight:600;
  font-size:clamp(2.3rem, 5vw, 3.5rem); line-height:1.05;
  letter-spacing:-.015em; color:var(--ink-black); margin:0 0 12px;
}
.legal-lede{
  font-family:var(--font-ui); font-size:clamp(1rem, 1.4vw, 1.15rem);
  font-weight:400; line-height:1.6; color:var(--ink-body);
  margin:0; max-width:62ch;
}
@media (max-width:900px){
  .legal-head{ padding:calc(126px + 34px) 0 0; }
}

/* --- report piracy: short copy left, form right ----------------------
   The pattern Ansys uses: a brief explanation beside a complete form, so
   the person reporting can act without scrolling past an essay. */
.rp-grid{
  display:grid; grid-template-columns:minmax(0,1fr) minmax(0,1.05fr);
  gap:70px; align-items:start;
}
.rp-points{ margin:0 0 26px; padding:0; list-style:none; }
.rp-points li{
  position:relative; padding-left:30px; margin-bottom:14px;
  font-family:var(--font-ui); font-size:1.04rem; font-weight:400;
  line-height:1.65; color:#23282E;
}
.rp-points li::before{
  content:""; position:absolute; left:0; top:.55em;
  width:11px; height:2px; background:var(--gold-deep);
}
.rp-form{
  background:#fff; border:1px solid #dfe4ea; border-top:2px solid var(--gold);
  padding:36px 34px 32px; box-shadow:0 8px 22px rgba(14,32,57,.07);
}
.rp-form h2{
  margin:0 0 6px !important; border:0 !important; padding:0 !important;
  font-family:var(--font-display); font-weight:600; font-size:1.5rem; color:var(--ink-black);
}
.rp-form .cx-req{ margin-bottom:24px; }
.rp-form .field{ margin-bottom:20px; }
.rp-form textarea{ min-height:112px; }
@media (max-width:1040px){
  .rp-grid{ grid-template-columns:1fr; gap:44px; }
}

.rp-form .f-row{ display:grid; grid-template-columns:1fr 1fr; gap:18px; }
.rp-small{
  margin:16px 0 0 !important; font-size:.88rem !important; font-weight:400 !important;
  line-height:1.6 !important; color:var(--ink-soft) !important;
}
@media (max-width:520px){ .rp-form .f-row{ grid-template-columns:1fr; gap:0; } }

/* --- custom work: one large piece and two smaller -------------------
   The page exists to show that the work is not one standard shape, so it
   shows three. The plate pack takes the full height on the left and the
   other two stack beside it, filling the same block. */
.cx-gallery{ background:var(--paper); padding:0 0 12px; }
/* On the two Custom pages the three exchangers run across the page in
   one row -- plate-and-frame, copper, graphite -- so the set reads left
   to right at full width. The product rows on the overview pages keep
   the other arrangement (.cust-trio), where the block has to sit beside
   a column of text. minmax(0,1fr) on the row, because a bare 1fr keeps
   an `auto` minimum and the row would grow past the height cap. */
.cx-gal-grid--feature{
  display:grid;
  grid-template-columns:repeat(3, minmax(0,1fr));
  grid-template-rows:minmax(0,1fr);
  gap:28px;
  align-items:stretch;
  height:500px;
  max-height:500px;
}
/* These are cut-outs with their own transparency, so a white card with a
   border behind each one read as three photographs pasted onto panels
   rather than three exchangers sitting on the page. No card, no border,
   no padding: the artwork is the artwork. */
.cx-gal-grid--feature figure{
  margin:0; padding:0;
  background:none; border:0;
  display:flex; align-items:center; justify-content:center;
  min-width:0; min-height:0;
  overflow:hidden;
}
/* No hover zoom here. None of the other inside pages move their
   artwork under the cursor -- the exchanger and software detail pages
   show a still image -- so this was the odd one out. The layout is
   unchanged; only the movement is gone. */
.cx-gal-grid--feature img{
  width:100%; height:100%; max-height:100%;
  object-fit:contain; display:block;
}

@media (max-width:820px){
  /* one below the other on a phone: plate-and-frame, copper, graphite.
     Three across a 346px column would leave each one about 100px wide. */
  .cx-gal-grid--feature{
    grid-template-columns:1fr;
    grid-template-rows:auto;
    height:auto; max-height:none; gap:18px;
  }
  .cx-gal-grid--feature figure{ padding:0; height:38vh; min-height:220px; }
}

/* --- the Custom row's three cut-outs ----------------------------------
   Custom work is not one product, so one photograph under-sold it. The
   tall plate-and-frame unit runs the full height on the left, with the
   copper exchanger above the graphite one on the right, so the three
   occupy the same block a single image had. All three are cut-outs and
   sit directly on the page: no card, no border, no panel behind them. */
.cust-trio{
  display:grid;
  grid-template-columns:1.04fr 1fr;
  grid-template-rows:minmax(0,1fr) minmax(0,1fr);
  gap:16px 22px;
  /* stretch, NOT center. align-items:center stops the figures filling
     their row, so each one is sized by its content -- and then the
     img's height:100% resolves against an auto-height parent, falls
     back to the natural height, and the artwork spills out of its cell.
     That is why the copper unit overran its half and landed on top of
     the graphite one. Stretched rows give height:100% something real to
     resolve against, and object-fit:contain letterboxes inside it. */
  align-items:stretch;
  width:100%;
  /* the single-photograph rows on these pages settle at 542px tall; the
     trio is held to the same block so the column does not lurch when the
     reader reaches Custom */
  height:540px;
  max-height:540px;
}
.cust-trio figure{
  margin:0; padding:0; background:none; border:0;
  display:flex; align-items:center; justify-content:center;
  min-height:0; min-width:0;
  overflow:hidden;            /* nothing may leave its own half */
}
/* the tall one takes the whole left column */
.cust-trio figure:first-child{ grid-row:1 / span 2; }
.cust-trio img{
  width:100%; height:100%;
  max-width:100%; max-height:100%;
  object-fit:contain; display:block;
}

@media (max-width:900px){
  /* The stacked-row rules give every .cat-visual/.lic-visual image
     width:auto and a 46vh cap, which is right for a single photograph
     and would collapse the grid. The trio keeps its own geometry. */
  .cust-trio{ gap:12px 14px; height:auto; max-height:none; aspect-ratio:1.06 / 1; }
  .cust-trio img{
    width:100% !important; height:100% !important;
    max-width:100% !important; max-height:100% !important;
    margin-inline:0;
  }
}


/* --- the three Custom exchangers, named ------------------------------
   Only here. Everywhere else on the site the picture is captioned by the
   heading sitting beside it, and a second label under the artwork would
   be saying the same thing twice.

   The figure is a centring flex box in both layouts, so a caption has to
   turn it into a column and let the picture shrink to make room --
   height:100% on the img would otherwise keep its full share and push
   the words out of the bottom of a fixed-height block. Scoped to
   .named so the two figures without a caption are untouched. */
.cust-trio figure.named,
.cx-gal-grid--feature figure.named{
  flex-direction:column;
  gap:10px;
}
.cust-trio figure.named img,
.cx-gal-grid--feature figure.named img{
  height:auto;
  flex:1 1 auto;
  min-height:0;
}
.ex-name{
  flex:none;
  font-family:var(--font-ui);
  font-size:.8rem; font-weight:500; letter-spacing:.015em;
  line-height:1.35; text-align:center;
  color:#4a545e;
  text-wrap:balance;
}
@media (max-width:900px){
  .cust-trio figure.named{ gap:8px; }
  .ex-name{ font-size:.74rem; }
}

/* with the single visual gone, the copy takes the full measure */
.ex-grid--single{ grid-template-columns:1fr !important; }
.ex-grid--single .ex-copy{ max-width:none; }

/* --- mobile navigation ------------------------------------------------
   Full-screen and white, matching the reference. No hover on a phone, so
   each group is an accordion that pushes the list down. */
@media (max-width:900px){

  .mainnav{
    position:fixed; inset:0;                 /* the whole screen, not a panel */
    width:100%; max-width:none; height:100%;
    background:#fff;
    overflow-y:auto; -webkit-overflow-scrolling:touch;
    /* Without this a drag that reaches either end of the drawer carries on
       into the document underneath, which is still scrollable and still
       running the scroll-effects loop. The two fought each other and the
       drawer felt stiff and half-responsive. */
    overscroll-behavior:contain;
    transform:translateX(100%);
    transition:transform .3s var(--ease-out);
    visibility:hidden;
    padding:0 0 40px;
    z-index:95;
  }
  /* will-change on a full-screen element keeps a viewport-sized layer alive
     for the life of the page. Promote only while the drawer is actually
     moving, then let it go. */
  body.nav-open .mainnav{ will-change:transform; }

  /* The page behind is frozen while the drawer owns the screen.
     touch-action:none must NOT go on the body here: touch-action is
     resolved up the ancestor chain, so `none` on an ancestor cannot be
     re-enabled by pan-y on the drawer -- it killed touch scrolling
     inside the drawer entirely. overflow:hidden already stops the page
     behind, and overscroll-behavior:contain on the drawer stops a drag
     that reaches either end from chaining into it. */
  body.nav-open{ overflow:hidden; }
  .mainnav.is-open{ transform:translateX(0); visibility:visible; }

  .nav-close{
    position:absolute; top:12px; right:14px; z-index:2;
    width:46px; height:46px; display:flex; align-items:center; justify-content:center;
    background:transparent; border:0; cursor:pointer; color:var(--ink-black);
  }
  .nav-close svg{ width:24px; height:24px; display:block; }

  .mainnav .nav-list{ display:block; padding:74px 0 0; }
  .mainnav .nav-item{ border-bottom:1px solid rgba(20,28,38,.10); }

  .mainnav .nav-link{
    position:relative;
    display:flex; align-items:center; justify-content:space-between;
    width:100%; padding:0 0 0 22px; min-height:62px;
    font-size:1.05rem; font-weight:500; color:var(--ink-black);
  }
  .mainnav .nav-link::after{ display:none; }
  .mainnav .nav-item--plain .nav-link{ color:var(--ink-black); }
  .mainnav .nav-item--plain .nav-link{ padding:0 22px; }

  /* The expand control is now a drawn square with its own edge and tint,
     on the model of the quick-contact caret. Two things follow from that:
     the target is visible, so a thumb aims at it rather than guessing,
     and the boundary is explicit -- inside the square expands, anything
     left of it opens the page. 62x62 CSS px, well over the 44px minimum. */
  .mainnav .caret{
    display:flex; align-items:center; justify-content:center;
    flex:none; width:62px; align-self:stretch; margin:0; padding:0;
    color:var(--gold-deep);
    background:rgba(20,28,38,.04);
    border-left:1px solid rgba(20,28,38,.13);
    transition:background-color .18s var(--ease-soft);
    /* hides the ▼ text node; the glyph is redrawn by ::before so that the
       rotation applies to the glyph alone. Turning the box itself swung
       the glyph from one edge to the other and carried the border with
       it, which is the caret "moving inside" that was reported. */
    font-size:0;
  }
  .mainnav .caret::before{
    content:"\25BC";
    display:block; font-size:.68rem; line-height:1;
    transition:transform .24s var(--ease-out);
  }
  .mainnav .nav-item.is-expanded .caret{ background:rgba(247,193,68,.18); }
  .mainnav .nav-item.is-expanded .caret::before{ transform:rotate(180deg); }

  /* The panel used to go display:none -> display:block with an opacity
     transition. A transition cannot start on an element that was display
     :none in the same frame, so whether the fade ran at all came down to
     when the style flush happened: usually the panel snapped in, and
     sometimes it stayed at opacity 0 while occupying its full height --
     which is the "sub-items are not shown" fault, and why it was
     intermittent.
     It is a grid that animates between 0fr and 1fr instead. The element
     is always displayed, so the transition always has a start value, and
     one row track is the cheapest thing a browser can interpolate to a
     height. */
  /* ONE animated property, and it is not opacity or visibility.
     Those two were transitioned here as well, and the class that drives
     them flips while the drawer is still hidden and sliding in -- so
     their transitions never got a style change to run against, and the
     panel stayed at opacity:0 / visibility:hidden while its grid row
     expanded to full height. That is the blank panel: the space is
     reserved, the links are all opacity:1, and the container they sit
     in is invisible. It survived a page change because nothing ever
     re-triggered the stuck transition.
     The row track alone does the whole job -- .dd-inner clips the
     content to zero when the track is 0fr -- so there is nothing left
     that can stick. */
  .mainnav .dropdown{
    position:static; transform:none;
    background:#F4F6F8; border:0; box-shadow:none;
    /* the desktop panel's 14px padding survived the collapse and left a
       strip of grey under every closed row */
    padding:0;
    display:grid; grid-template-rows:0fr;
    opacity:1;
    /* inherit, not visible: the closed drawer is visibility:hidden, and a
       hard `visible` here would put its links back in the accessibility
       tree and the tab order while the drawer is off-screen. Inheriting
       follows the drawer, and it is not transitioned, so it cannot stick
       the way the old value did. */
    visibility:inherit;
    transition:grid-template-rows .26s var(--ease-out);
  }
  .mainnav .nav-item.is-expanded .dropdown{ grid-template-rows:1fr; }
  /* a collapsed panel is clipped to zero height; keep it out of the tab
     order too rather than relying on visibility, which is what broke */
  .mainnav .dropdown[inert]{ pointer-events:none; }
  .mainnav .dd-inner{ min-height:0; padding:0; max-width:none; overflow:hidden; }
  .mainnav .dd-cols{ display:block; padding:6px 0 12px; }
  .mainnav .dd-col{ display:block; }
  .mainnav .dd-col > a{
    display:block; padding:12px 22px 12px 36px;
    font-size:.95rem; line-height:1.4; color:var(--ink-body);
    opacity:1; transform:none;
  }
  .mainnav .dd-head, .mainnav .dd-head--link{
    display:block; padding:14px 22px 6px 36px;
    font-size:.7rem; letter-spacing:.14em; text-transform:uppercase;
    color:var(--gold-deep);
  }

  /* the burger is replaced by the X, so it must not show through */
  body.nav-open .burger, body.nav-open [aria-label="Open menu"]{ opacity:0; pointer-events:none; }

  /* a full-screen menu needs no scrim behind it */
  .nav-scrim{ display:none; }
}

/* --- mobile corrections ----------------------------------------------
   Measured at 390px before writing any of this. */
@media (max-width:900px){

  /* The full-screen banners were 844px tall holding a 156px image,
     leaving ~690px of empty navy, so the section was made to size to its
     content. The artwork was also forced to 3/2 to give it more height.
     That part was wrong: the banners are 2000x800, so a 3/2 box with
     background-size:cover throws away 40% of the width -- and on the
     marketplace banner, which is a world map with equipment placed
     across it, the units at both edges were sliced in half.
     The box now carries the artwork's own ratio, so nothing is cropped.
     It is a shorter band on a phone, which is simply what a 2.5:1 image
     is at 390px wide. */
  /* The header floats over the top of these banners. On desktop it
     covers 156px of a 576px band, which is the intended look. On a phone
     the band is 156px tall in total, so the header was hiding 125px of
     it -- four fifths of the artwork -- and only a 31px sliver showed.
     The section is pushed down by the header's height (a constant 126px
     from 320px to 900px) so the whole banner sits below it. The padding
     is navy, the same ground the header sits on, so it reads as one
     dark field rather than a gap. */
  .lic-banner, .about-banner{ min-height:0; padding-top:126px; }
  .lic-banner .banner-art, .about-banner .banner-art,
  .banner-art{ aspect-ratio:2000 / 800; background-position:center center; }

  /* the floating panel is measured from the viewport, not the tab */
  .qc-panel{
    min-width:0;
    width:calc(100vw - 32px);
    max-width:340px;
    right:0;
  }
}

/* (5) at 320px the utility row and the wordmark collided and pushed the
   page 28px wide; the phone number drops out below 360px */
/* At 320px the logo and the utility row together needed 348px inside a
   320px viewport, pushing the whole page 28px wide. The gutter tightens
   and the "Contact Us" text drops — the menu now carries both emails,
   the phone number and a Contact button, so nothing is lost. */
@media (max-width:360px){
  :root{ --gutter:16px; }
  /* the icon is already gone below 900px; keep the words, they are the
     only contact affordance in the header */
  .site-header .wordmark{ font-size:.88rem; }
  .header-inner, .shell.topbar, .shell.navrow{ min-width:0; }
  .utility{ min-width:0; }
}

/* A fixed off-canvas drawer still extends the page's scrollable width,
   whatever its visibility, and the header then stretches to match. Clip
   the horizontal axis at the root: unlike overflow:hidden this leaves
   position:sticky working. */
html{ overflow-x:clip; }
body{ overflow-x:clip; }

/* --- figures in the display face -------------------------------------
   Playfair sets old-style figures by default: 1 and 2 are drawn at
   x-height, so "Type 1" reads with a small 1 beside full-height caps.
   Every place the display face carries a number gets lining figures. */
.ex-title, .ex-lede, .sw-for, .banner-title, .lic-intro h2,
.biz-title, .cat-title, .ex-more h2, .legal-title, .hero-title,
h1, h2, h3, .mask > i{
  font-variant-numeric:lining-nums;
  font-feature-settings:"lnum" 1, "onum" 0;
}

/* --- reading order when the columns stack ----------------------------
   On a phone the reading order is: heading, then the image, then the
   write-up. On the overview pages the heading lives inside the copy
   block, so display:contents promotes its children into the same flex
   container and lets all three be ordered independently.

   Inside pages keep the visual first, because their heading is already
   in the band above it. */
@media (max-width:900px){

  /* align-items:center is set on all three of these for the desktop
     two-column layout, where it centres the columns against each other
     vertically. Turning the container into a column flex here re-points
     that same property at the horizontal axis, so every child narrower
     than the screen -- the SW-01 label, the discipline heading, the
     "Explore Software" line -- was being centred. Only the artwork
     should be centred, and it centres itself with margin-inline:auto. */
  .cat, .lic-row, .biz-grid{ display:flex; flex-direction:column; align-items:stretch; }
  .cat-copy, .lic-copy, .biz-copy{ display:contents; }

  /* ONE ordering scale for every stacked product row, and every child
     is named. display:contents leaves an unnamed child at 0, and two
     children sharing a number fall back to document order -- which is
     how the CTA came to sit above the write-up on all 34 rows, and the
     photograph above the heading on 18 of them.

         1  eyebrow / code label
         2  name
         3  tagline
         4  image
         5  write-up
         6  call to action

     The catch-all is 5, not 0: anything added later and left unnamed
     joins the write-up rather than jumping to the head of the row. */
  .cat-copy > *, .lic-copy > *, .biz-copy > *{ order:5; }

  .cat-eyebrow, .lic-eyebrow, .cat-code, .lic-code{ order:1; }

  .cat-name, .lic-name, .biz-title, .biz-copy > h3{ order:2; }

  .biz-copy > .biz-lede, .cat-lede, .lic-lede, .sw-lede{ order:3; }
  /* Each row carries a --w set for the desktop column, which on a phone
     shrank some images to 59px inside a 390px screen. Full width here,
     with the height free to follow the artwork. */
  .cat-visual, .lic-visual, .biz-visual,
  .cat--flip .cat-visual, .lic-row--flip .lic-visual{
    order:4; margin:22px 0 24px;
    width:100% !important; max-width:none !important;
  }
  /* The per-row --w is applied to the image as a max-width, which on a
     phone left some of them 227px wide inside a 346px column. Cleared,
     with a height cap so a tall cut-out cannot run to 800px. */
  .cat-visual img, .lic-visual img, .biz-visual img{
    width:auto; height:auto;
    max-width:100% !important;
    max-height:46vh;
    object-fit:contain;
    margin-inline:auto; display:block;
  }
  .cat-body, .lic-body, .biz-body, .biz-copy > .prose{ order:5; }

  /* The call to action always comes last. These are the <p> wrappers --
     .cat-cta and .lic-cta are the anchors inside them and are not flex
     items, so ordering those had no effect at all. */
  .cat-cta-wrap, .lic-cta-wrap,
  .cat-copy .pill, .lic-copy .pill,
  .biz-copy > p:has(> .readmore){
    order:6; margin-top:22px;
  }
  /* the desktop flip must not survive into the stacked layout */
  .biz-block:nth-child(even) .biz-visual{ order:4; }

  /* inside pages: band heading, then image, then text */
  .ex-grid{ display:flex; flex-direction:column; }
  .ex-visual{ order:1; margin-bottom:24px; }
  .ex-copy{ order:2; }
  .ex-main--reverse .ex-visual{ order:1; }
  .ex-main--reverse .ex-copy{ order:2; }
}

/* --- footer on a phone ------------------------------------------------
   minmax(0,620px) 1fr let the brand column collapse to 20px, so the
   tagline wrapped one character per line. Stacked, with the five social
   icons in a single row beneath the paragraph. */
@media (max-width:900px){
  .footer-top{
    grid-template-columns:1fr;
    gap:26px;
    align-items:start;
    padding-bottom:38px;
  }
  .footer-brand{ width:100%; }
  .footer-brand p{ max-width:46ch; }
  .footer-connect{ width:100%; }
  .footer-connect .socials, .footer-connect > div{
    display:flex; flex-wrap:nowrap; gap:12px; justify-content:flex-start;
  }
  .social{ width:42px; height:42px; flex:none; }
  .footer-bottom{
    flex-direction:column; align-items:flex-start; gap:14px;
    padding-top:22px; padding-bottom:26px;
  }
  .footer-bottom .legal{ display:flex; flex-wrap:wrap; gap:16px; }
}

/* The pinned logo sat at x=0, touching the screen edge, which read as
   the mark being cut off. It now keeps the page gutter. */
@media (max-width:900px){
  .site-header.is-stuck .logo-mark{ margin-left:var(--gutter); }
  .site-header .logo-slot{ padding-left:0; }
}

/* --- utility row on a phone -------------------------------------------
   The mail icon told the visitor nothing; the address itself is the
   useful thing. On a phone the icon goes and the floating panel, which
   already carries the email, the phone number, WhatsApp and a link to
   the form, is the single way to reach us from the header. */
@media (max-width:900px){
  .utility .mail-btn{ display:none; }
  /* Contact Us read small next to the burger. Both are now sized to sit
     comfortably together on the top line. */
  .utility > a.keep:not(.mail-btn){
    display:inline-flex; align-items:center; min-height:44px; padding:0 4px;
    font-size:.95rem; font-weight:500; letter-spacing:.04em;
  }
}

/* --- header rows on a phone -------------------------------------------
   The burger sat on the second row, below Contact Us. On a phone both
   belong on the top line: logo left, then Contact Us and the burger
   together on the right. The second row keeps only the pinned mark. */
@media (max-width:900px){
  .shell.topbar{
    display:flex; align-items:center; justify-content:space-between; gap:10px;
    position:relative; z-index:2;
  }
  .utility{ display:flex; align-items:center; gap:6px; }

  /* The burger sits in the second row of the markup but must appear on
     the first. It positions against .header-inner, so top:50% centred it
     on the whole header. The top row is a known height, so it is centred
     on that instead. */
  /* the burger centres on 29px, so the row is given the same centre */
  .shell.topbar{
    min-height:58px; height:58px; padding-block:0;
    padding-right:calc(var(--gutter) + 54px);
  }
  .shell.topbar > *{ align-self:center; }
  .burger{
    position:absolute; top:29px; right:var(--gutter); transform:translateY(-50%);
    z-index:3; width:46px; height:46px;
  }
  .burger svg, .burger span{ transform:scale(1.15); transform-origin:center; }
  /* once the header collapses there is only one row, so it re-centres */
  .site-header.is-stuck .burger{ top:50%; }
  .shell.navrow{ padding-right:calc(var(--gutter) + 4px); }
  .navrow .icon-btn[aria-label="Search"]{ display:none; }
}

/* --- the compact white header ----------------------------------------
   Scrolled, the header kept both rows and ran to 126px with the logo
   pushed to the bottom and the burger floating at the top. Collapsed it
   is a single 62px bar: mark left, burger right, both on one centre line. */
@media (max-width:900px){
  .site-header.is-stuck .shell.topbar{ display:none; }
  .site-header.is-stuck .shell.navrow{
    min-height:62px; height:62px;
    display:flex; align-items:center; justify-content:space-between;
    padding-block:0;
    padding-inline:var(--gutter);      /* the mark was flush to the edge */
  }
  .site-header.is-stuck .header-inner{ min-height:62px; }
  .site-header.is-stuck .logo-mark{
    position:static; margin:0; display:flex; align-items:center;
  }
  .site-header.is-stuck .logo-mark img{ height:34px; width:auto; }
  .site-header.is-stuck .burger{
    position:static; transform:none; width:44px; height:44px; margin:0;
  }
}

/* --- touch feedback ---------------------------------------------------
   Mobile browsers paint a translucent blue block over whatever is tapped.
   It is the default, it is not part of any design, and on a dark ground
   it looks like a fault. Removed everywhere; the site provides its own
   feedback through :active states. */
html{ -webkit-tap-highlight-color:rgba(0,0,0,0); }
*, *::before, *::after{
  -webkit-tap-highlight-color:rgba(0,0,0,0);
  -webkit-touch-callout:none;
}
a, button, summary, [role="button"], input, select, textarea, label{
  -webkit-tap-highlight-color:transparent;
}
/* text stays selectable; only interface chrome is not */
.site-header, .mainnav, .site-footer, .qc, .burger, .nav-close,
.hero, .totop, .dots, .caret{
  -webkit-user-select:none; user-select:none;
}

/* The Contact Us entry in the nav list exists for the phone menu, where
   it is the only route to the contact page. On desktop the utility row
   already carries one, so showing both put two on the same screen. */
@media (min-width:901px){
  .nav-item--plain{ display:none; }
}

/* --- hero and banner artwork -----------------------------------------
   These are drawn as CSS backgrounds rather than <img> elements, and
   deliberately so. Google parses only HTML images; a background is
   treated as decoration and never enters Google Images, so the heroes
   cannot be found by a reverse image search or pulled by an automated
   image crawler. They also cannot be right-clicked, dragged or saved
   through the usual route.

   Product photography is untouched — those stay as <img> with alt text,
   because they should be indexed. */
.ex-head-art, .banner-art, .hero-art{
  background-image:var(--bg);
  background-size:cover;
  background-repeat:no-repeat;
  -webkit-user-select:none; user-select:none;
  -webkit-user-drag:none;
  pointer-events:none;
}
.ex-head-art{
  position:absolute; inset:0; width:100%; height:100%;
  background-position:center 42%;
  z-index:-2;
}
.banner-art{
  display:block; width:100%;
  aspect-ratio:2000 / 800;
  background-position:center center;
}
.hero-art{
  position:absolute; inset:0; width:100%; height:100%;
  background-position:70% 40%;
}
@media (max-aspect-ratio: 3/4){
  .hero-art{ background-image:var(--bg-portrait, var(--bg)); background-position:center 42%; }
}

/* --- the four exchangers on the marketplace block ---------------------
   One image could not represent a marketplace that trades four kinds of
   equipment. Four cells in the same space, each cut-out centred in its
   own square so the group reads as a set rather than a collage. */
.mkt-quad{
  display:grid; grid-template-columns:1fr 1fr; gap:14px;
  width:100%;
}
.mkt-cell{
  margin:0; padding:14px;
  background:#fff; border:1px solid var(--line);
  display:flex; align-items:center; justify-content:center;
  aspect-ratio:1 / 1;
  transition:border-color var(--dur-fast) var(--ease-soft),
             box-shadow var(--dur-fast) var(--ease-soft);
}
@media (hover:hover){ .mkt-cell:hover{ border-color:var(--gold); box-shadow:0 8px 22px rgba(14,32,57,.09); } }
.mkt-cell img{
  width:100%; height:100%; object-fit:contain; display:block;
  transition:transform var(--dur-mid) var(--ease-out);
}
@media (hover:hover){ .mkt-cell:hover img{ transform:scale(1.05); } }
@media (max-width:900px){
  .mkt-quad{ gap:10px; }
  .mkt-cell{ padding:10px; }
}

/* --- trademark notice -------------------------------------------------
   Convention for a logo or design mark places the symbol at the lower
   right of the mark, not as a superscript — superscript is for wordmarks.
   It appears once, on the most prominent use, which is the mark in the
   homepage header. Sized at roughly a fifth of the mark so it reads as a
   notice rather than part of the artwork. */
.logo-slot .mark{ position:relative; }
.logo-tm{
  /* Top right, which is where a trademark notice conventionally sits on
     a mark. It was at the foot, where the mark's own diagonal crowds it.
     At .5rem/8px and 95% opacity it was too faint to read at all on a
     phone; 10.5px at full opacity and a heavier weight is legible on
     both without becoming part of the artwork. */
  position:absolute; right:-11px; top:-1px;
  font-family:var(--font-ui);
  font-size:.66rem; font-weight:700; letter-spacing:.02em;
  line-height:1; color:var(--gold);
  /* the glyph is a hair under a pixel grid at this size; nudging the
     rendering keeps the R and the circle from smearing together */
  -webkit-font-smoothing:antialiased;
  text-rendering:geometricPrecision;
  -webkit-user-select:none; user-select:none;
}
.site-header.is-stuck .logo-tm{ color:var(--gold-deep); }

/* The mark drops from 56px to 42px on a phone; the notice comes down
   with it, but proportionally less, so it stays readable. */
@media (max-width:640px){
  .logo-tm{ font-size:.6rem; right:-10px; top:-1px; }
}


/* --- 404 -------------------------------------------------------------
   A dead end should hand the reader the map, not an apology. The six
   destinations are listed with what each one is for, so someone who
   mistyped a URL or followed a stale link can get where they meant to go
   without hunting through the menu.
   Self-contained classes on purpose: .ex-title and .ex-eyebrow are
   styled for the dark band at the top of an inside page, and reusing
   them here put white text on white. */
.nf{
  background:var(--paper);
  padding:calc(126px + 64px) 0 96px;
  min-height:62vh;
}
.nf-code{
  font-family:var(--font-mono);
  font-size:.9rem; font-weight:500; letter-spacing:.22em;
  color:var(--gold-deep);
  margin-bottom:14px;
}
.nf-title{
  font-family:var(--font-display); font-weight:600;
  font-size:clamp(2.3rem, 5.4vw, 4rem);
  line-height:1.04; letter-spacing:-.018em;
  color:var(--ink-black);
  margin:0 0 16px;
}
.nf-lede{
  font-family:var(--font-display);
  font-size:clamp(1.15rem, 2.4vw, 1.62rem);
  line-height:1.34; color:var(--green-deep);
  margin:0 0 26px;
}
.nf-body{ max-width:70ch; }
.nf-body p{
  font-size:1.02rem; line-height:1.72; color:#333a42;
  margin:0 0 14px;
}
.nf-body a{ color:var(--green-deep); text-decoration:underline; text-underline-offset:3px; }
@media (hover:hover){ .nf-body a:hover{ color:var(--ink-black); } }

/* Each cell carries its own border rather than letting a grid background
   show through the gaps -- with six cells in a four-column track the two
   empty slots on the last row were rendering as a grey slab. */
.nf-map{
  display:grid;
  grid-template-columns:repeat(auto-fit, minmax(252px, 1fr));
  gap:14px;
  margin:38px 0 34px;
}
.nf-map a{
  display:block;
  padding:20px 22px;
  background:#fff;
  border:1px solid var(--line);
  border-left:3px solid var(--gold);
  transition:border-color var(--dur-fast) var(--ease-soft),
             background var(--dur-fast) var(--ease-soft),
             transform var(--dur-fast) var(--ease-out);
}
.nf-map a:focus-visible{
  background:var(--paper-alt);
  border-left-color:var(--green-deep);
  transform:translateY(-2px);
  outline:none;
}
@media (hover:hover){ .nf-map a:hover{
  background:var(--paper-alt);
  border-left-color:var(--green-deep);
  transform:translateY(-2px);
  outline:none;
} }
.nf-map a:focus-visible{ box-shadow:0 0 0 2px var(--gold); }
.nf-map b{
  display:block;
  font-family:var(--font-ui); font-size:1.04rem; font-weight:600;
  color:var(--ink-black); margin-bottom:5px;
}
.nf-map span{
  display:block;
  font-size:.9rem; line-height:1.45; color:var(--ink-body);
}

@media (prefers-reduced-motion: reduce){
  .nf-map a{ transition:none; }
  .nf-map a:focus-visible{ transform:none; }
  @media (hover:hover){ .nf-map a:hover{ transform:none; } }
}

@media (max-width:900px){
  .nf{ padding:calc(126px + 40px) 0 64px; min-height:0; }
}
@media (max-width:640px){
  .nf-map{ grid-template-columns:1fr; gap:12px; margin:30px 0 28px; }
  .nf-map a{ padding:16px 18px; }
}


/* --- thank you -------------------------------------------------------
   Shown once a form has been accepted. The page becomes header, this
   band, footer -- so the mark and the social icons stay in view, which
   is the point: the visitor should land somewhere that still looks like
   the company, not on a bare confirmation line.
   The ground is --paper-alt, the same pale green the five disciplines
   sit on at home, and the type is the page's own black Playfair. */
.ty{
  background:var(--paper-alt);
  /* The header is fixed and floats over whatever is beneath it. With the
     form's dark hero band gone this is the first thing on the page, so
     it has to start below the header or the heading sits under it. The
     body also gets .light-page when this is shown, without which the
     header keeps the white type it uses over a dark hero and becomes
     unreadable on this pale ground. */
  padding:calc(157px + clamp(52px, 8vh, 104px)) 0 clamp(84px, 13vh, 148px);
  text-align:center;
}
.ty .shell{ max-width:76ch; }

/* the short gold rule the site opens its sections with */
.ty-rule{
  display:block; width:52px; height:2px;
  background:var(--gold);
  margin:0 auto clamp(20px, 3vh, 34px);
}
.ty-title{
  font-family:var(--font-display); font-weight:600;
  font-size:clamp(2.7rem, 7vw, 5.2rem);
  line-height:1.02; letter-spacing:-.02em;
  color:var(--ink-black);
  margin:0 0 clamp(16px, 2.4vh, 26px);
}
.ty-sub{
  font-family:var(--font-ui); font-weight:300;
  font-size:clamp(1rem, 1.5vw, 1.12rem);
  line-height:1.72; color:var(--ink-black);
  margin:0 auto; max-width:62ch;
}
.ty-back{ margin:clamp(26px, 4vh, 42px) 0 0; }

@media (max-width:900px){
  .ty{ padding:calc(126px + 48px) 0 72px; }
}
@media (max-width:640px){
  .ty .shell{ max-width:none; }
}

/* The hero's first line holds "Innovating Engineering," together with a
   non-breaking space so it never splits on a wide screen. At 320px that
   phrase is 313px wide inside a 288px column, so it was being cut off
   at the right edge. The clamp's floor is 1.9rem, which 5.1vw never
   reaches down there; below 360px it steps down enough to fit. */
@media (max-width:360px){
  .hero-title{ font-size:1.72rem; }
}

/* ============================================================
   18. REQUEST A DEMO / REQUEST A CONSULTATION
   Left: what is being asked for, and how else to reach us.
   Right: the form. One dark band behind both, held still while the
   page scrolls over it, ending exactly where the footer starts.
   ============================================================ */

/* background-attachment:fixed is the obvious way to hold a background
   still and the wrong one: iOS Safari silently downgrades it to
   scroll, and where it is honoured the browser repaints the whole
   viewport on every frame. A sticky layer pulled back out of the flow
   by its own height does the same thing on the compositor, works on
   iOS, and stops at the section's own bottom edge -- which is where
   the footer begins. */
.rq{
  position:relative;
  isolation:isolate;
  overflow:clip;                 /* not hidden: that would make a scroll
                                    container and sticky would stop working */
  background:var(--navy-deep);   /* what shows if the image never loads */
  color:#fff;
}
.rq-bg{
  position:sticky; top:0;
  height:100vh;  margin-bottom:-100vh;
  height:100svh; margin-bottom:-100svh;   /* no jump as the URL bar hides */
  z-index:-1;
  pointer-events:none;
  /* the artwork is busy in exactly the brand colours, so it is darkened
     hardest under the copy and allowed to come through on the right */
  background-image:
    linear-gradient(101deg, rgba(6,17,30,.95) 0%, rgba(6,17,30,.90) 34%,
                            rgba(6,17,30,.74) 68%, rgba(6,17,30,.60) 100%),
    var(--bg);
  background-size:cover, cover;
  background-position:center, center;
  background-repeat:no-repeat, no-repeat;
}

.rq-grid{
  display:grid;
  grid-template-columns:minmax(0,1fr) minmax(0,540px);
  gap:clamp(38px, 5.5vw, 92px);
  align-items:start;
  /* top and bottom only: the shorthand would blow away .shell's own
     horizontal padding and put the copy against the screen edge */
  padding-top:calc(157px + clamp(46px, 6vh, 88px));
  padding-bottom:clamp(78px, 10vh, 128px);
}

/* ---- left column ---- */
.rq-eyebrow{
  margin:0 0 18px;
  font-family:var(--font-ui); font-size:.78rem; font-weight:500;
  letter-spacing:.19em; text-transform:uppercase; color:rgba(255,255,255,.62);
}
.rq-eyebrow a{ color:inherit; transition:color var(--dur-fast) var(--ease-soft); }
.rq-eyebrow a:focus-visible{ color:var(--gold); }
@media (hover:hover){ .rq-eyebrow a:hover{ color:var(--gold); } }

/* the product's own name, playing the part the red wordmark plays on
   the reference page -- gold is this company's equivalent, and reads
   9.9:1 on the darkened band */
.rq-code{
  margin:0;
  font-family:var(--font-display); font-weight:600;
  font-size:clamp(2.55rem, 5.6vw, 4.5rem); line-height:1.02;
  letter-spacing:-.01em; color:var(--gold);
}
.rq-for{
  margin:16px 0 0;
  font-family:var(--font-ui); font-weight:400;
  font-size:clamp(1.08rem, 1.75vw, 1.42rem); line-height:1.45;
  color:#fff;
}
.rq-rule{
  display:block; width:74px; height:2px; margin:26px 0 0;
  background:var(--gold);
}
.rq-lede{
  margin:26px 0 0; max-width:46ch;
  font-family:var(--font-ui); font-size:1rem; font-weight:300; line-height:1.78;
  color:rgba(255,255,255,.84);
}

/* ---- how else to reach us ----
   White at 58% on a dark ground reads as disabled text, and weight 300
   at .94rem is a whisper. These are the two things a visitor who does
   not want to fill a form is looking for, so they are set to be read:
   full white, a heavier weight, and a size that holds its own next to
   the form beside it. */
.rq-reach-head{
  margin:36px 0 0;
  font-family:var(--font-ui); font-size:.92rem; font-weight:600;
  letter-spacing:.15em; text-transform:uppercase; color:var(--gold);
}
.rq-reach{ margin:20px 0 0; display:flex; flex-direction:column; gap:18px; align-items:flex-start; }
.rq-line{
  display:inline-flex; align-items:center; gap:15px;
  font-family:var(--font-ui); font-size:1.14rem; font-weight:500;
  color:#fff; transition:color var(--dur-fast) var(--ease-soft);
}
.rq-line:focus-visible{ color:var(--gold); }
@media (hover:hover){ .rq-line:hover{ color:var(--gold); } }
/* The icon itself, with nothing behind it. A ring around a glyph on a
   busy background reads as a button that does not do anything. */
.rq-ico{
  flex:none; display:grid; place-items:center;
  color:var(--gold);
  transition:color var(--dur-fast) var(--ease-soft),
             transform var(--dur-fast) var(--ease-soft);
}
/* drawn as vectors at 26px rather than scaled from a bitmap, so they
   stay sharp at every pixel density */
.rq-ico svg{ width:26px; height:26px; display:block; }
.rq-line:focus-visible .rq-ico{ color:var(--gold-lift); transform:translateX(1px); }
@media (hover:hover){ .rq-line:hover .rq-ico{ color:var(--gold-lift); transform:translateX(1px); } }

.rq-note{
  margin:32px 0 0; max-width:46ch;
  font-family:var(--font-ui); font-size:1.02rem; font-weight:400; line-height:1.72;
  color:rgba(255,255,255,.92);
}

/* ---- right column ---- */
.rq-plate{ max-width:none; }         /* the grid column already caps it */

/* two fields on one line, the way the reference form pairs them */
.f2{ display:grid; grid-template-columns:1fr 1fr; gap:0 18px; }

/* ---- phone ---- */
@media (max-width:900px){
  .rq-bg{ background-image:
    linear-gradient(180deg, rgba(6,17,30,.93) 0%, rgba(6,17,30,.86) 55%, rgba(6,17,30,.80) 100%),
    var(--bg-portrait, var(--bg)); }
  .rq-grid{
    grid-template-columns:minmax(0,1fr);
    gap:44px;
    padding-top:calc(126px + 40px);
    padding-bottom:74px;
  }
  /* the plate is the full column here, so it is the viewport that
     decides whether two fields still fit on one line */
  .rq-lede,
  .rq-note{ max-width:none; }
}
/* The country list and the number cannot sit side by side in half a
   plate: at 1440 that cell is 219px and "India (+91)" alone wants 150.
   Stacked, both are legible at every width, and Email still pairs with
   Phone the way the rest of the form pairs its fields. */
.f2 .tel-row{ grid-template-columns:minmax(0,1fr); gap:9px; }

@media (max-width:640px){
  .f2{ grid-template-columns:1fr; }
}


/* On a phone the 2000x800 banner is 156px tall at 390px wide -- shorter
   than the 126px header that floats over it. That is why the section
   needed padding-top:126px, and why the navy showed as a bare band above
   a thin strip of artwork.
   Below 600px a portrait crop of the same artwork is used instead, at
   1122x1402. At 390px wide it stands 487px tall, so the header overlays
   its top quarter and the rest reads as a proper banner -- the way the
   home page hero already works. The padding goes with it.
   --bg-m is only set on the three pages that have a portrait version; a
   banner without one falls back to --bg and is untouched. A background
   inside a media query that does not match is never downloaded, so a
   desktop visitor does not fetch these at all. */
@media (max-width:600px){
  .lic-banner, .about-banner{ padding-top:0; }
  .lic-banner .banner-art, .about-banner .banner-art, .banner-art{
    background-image:var(--bg-m, var(--bg));
    aspect-ratio:1122 / 1402;
  }
}
