@charset "UTF-8";
/* Poppins, served from this site. Four weights, Latin subset, swap so text is
   readable immediately in the fallback and reflows once when the face lands.
   Licence: assets/fonts/POPPINS-LICENCE.txt (SIL Open Font Licence 1.1). */
@font-face{font-family:Poppins;font-style:normal;font-weight:400;font-display:swap;src:url(../fonts/poppins-400.woff2) format("woff2")}
@font-face{font-family:Poppins;font-style:normal;font-weight:500;font-display:swap;src:url(../fonts/poppins-500.woff2) format("woff2")}
@font-face{font-family:Poppins;font-style:normal;font-weight:600;font-display:swap;src:url(../fonts/poppins-600.woff2) format("woff2")}
@font-face{font-family:Poppins;font-style:normal;font-weight:700;font-display:swap;src:url(../fonts/poppins-700.woff2) format("woff2")}
/* Dennison G.E.S — prototype site styles */
:root{
  --bg:#f6f7f9; --surface:#fff; --surface-2:#fafbfc; --surface-3:#eef1f5;
  --ink:#0f1419; --ink-2:#4d5866; --ink-3:#616b79; --ink-4:#93a0ad;
  /* Kicker metrics, shared with the hero alignment rule. */
  --kicker-size:11.5px; --kicker-lh:1.55; --kicker-gap:16px;
  --kicker-block:calc(var(--kicker-size) * var(--kicker-lh) + var(--kicker-gap));
  --line:#dfe4ea; --line-2:#eef1f5;
  --accent:#1b589e; --accent-dark:#204588; --accent-ink:#fff;
  --ok:#0f6b52; --ok-bg:#e3f3ec;
  --warn:#8a5200; --warn-bg:#fdf0dc;
  --info:#1b4a8f; --info-bg:#e7edf7;
  --amber:#ffb057; --dark:#0f1419;
  --shadow:0 1px 2px rgba(15,20,25,.05), 0 12px 28px -18px rgba(15,20,25,.28);
  --f-sans:'Poppins',system-ui,-apple-system,sans-serif;
  --f-cond:'Poppins',system-ui,-apple-system,sans-serif;
  /* Was IBM Plex Mono. Its default zero is dotted, which Dean disliked on
     the phone numbers, and mono was only ever earning its place for figure
     alignment that this site does not actually need: there are no columns
     of numbers, just phone numbers, stat figures and small caps labels.
     One face is simpler, one less web font to fetch, and no dots. */
  --f-mono:'Poppins',system-ui,-apple-system,sans-serif;
  --wrap:1240px;
}
*{box-sizing:border-box}
html{-webkit-text-size-adjust:100%}
body{margin:0;background:var(--bg);color:var(--ink);font-family:var(--f-sans);font-size:16px;line-height:1.55;-webkit-font-smoothing:antialiased}
img{max-width:100%}
a{color:var(--accent);text-decoration:none}
a:hover{color:var(--accent-dark)}
a:focus-visible,button:focus-visible,input:focus-visible,select:focus-visible,textarea:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
.wrap{max-width:var(--wrap);margin:0 auto;padding-inline:20px}
h1,h2,h3,h4{text-wrap:balance;margin:0}
p{margin:0}
.mono{font-family:var(--f-mono);font-variant-numeric:tabular-nums}

/* ---------- masthead ---------- */
.top{background:var(--surface);border-bottom:1px solid var(--line);position:sticky;top:0;z-index:20}
.top-in{max-width:var(--wrap);margin:0 auto;padding:14px 20px;display:flex;align-items:center;gap:22px;flex-wrap:wrap}
.brand{font-family:var(--f-cond);font-weight:700;font-size:20px;letter-spacing:.03em;text-transform:uppercase;color:var(--ink)}
.brand span{color:var(--accent)}
.nav{display:flex;gap:20px;font-size:14px;font-weight:500;flex-wrap:wrap}
.nav a{color:var(--ink-2)}
.nav a:hover,.nav a.on{color:var(--ink)}
.nav a.on{box-shadow:inset 0 -2px 0 var(--accent)}
.top-cta{display:flex;gap:10px;align-items:center;margin-left:auto;flex-wrap:wrap}
.tel{font-family:var(--f-mono);font-size:14px;color:var(--ink-2);white-space:nowrap}

/* ---------- alert bar ---------- */
.alert{background:var(--dark);color:#fff}
.alert-in{max-width:var(--wrap);margin:0 auto;padding:10px 20px;display:flex;align-items:center;gap:14px;flex-wrap:wrap}
.alert svg{flex:none}
.alert b{font-size:15px;font-weight:600}
.alert p{font-size:14px;color:#b9c5d1;margin:0}
.alert .grp{display:flex;gap:14px;align-items:center;margin-left:auto;flex-wrap:wrap}
.alert .num{font-family:var(--f-mono);font-size:19px;font-weight:600;letter-spacing:-.01em;color:#fff}

/* ---------- buttons ---------- */
.btn{display:inline-block;font-family:var(--f-sans);font-size:15px;font-weight:600;padding:12px 22px;border-radius:5px;border:1px solid var(--accent);background:var(--accent);color:var(--accent-ink);cursor:pointer;white-space:nowrap}
.btn:hover{background:var(--accent-dark);border-color:var(--accent-dark);color:#fff}
.btn.ghost{background:var(--surface);color:var(--ink);border-color:var(--line)}
.btn.ghost:hover{background:var(--surface-3);color:var(--ink)}
.btn.amber{background:var(--amber);border-color:var(--amber);color:#21170a}
.btn.amber:hover{background:#ffa03a;border-color:#ffa03a;color:#21170a}
.btn.light{background:#fff;border-color:#fff;color:var(--dark)}
.btn.on-dark{background:transparent;border-color:#33414f;color:#aebbc8}
.btn.sm{font-size:13px;padding:8px 14px}
.btn.lg{font-size:16px;padding:14px 26px}

/* ---------- shared bits ---------- */
.eyebrow{font-family:var(--f-mono);font-size:11px;font-weight:600;letter-spacing:.12em;text-transform:uppercase;color:var(--ink-3)}
.eyebrow.acc{color:var(--accent)}
.lede{font-size:18px;line-height:1.6;color:var(--ink-2);max-width:58ch}
.muted{color:var(--ink-2)}
.small{font-size:13px;color:var(--ink-3);line-height:1.55}
.sec{padding-block:52px}
.sec.tight{padding-block:36px}
.sec.white{background:var(--surface);border-block:1px solid var(--line)}
.sec.dark{background:var(--dark);color:#eef2f6}
.sec.dark h2,.sec.dark h1{color:#fff}
.sec.dark p{color:#aebbc8}
.sec-head{display:flex;align-items:flex-end;justify-content:space-between;gap:20px;flex-wrap:wrap;margin-bottom:22px}
h1.page{font-family:var(--f-cond);font-size:clamp(27px,3.5vw,40px);line-height:1.12;font-weight:600;letter-spacing:-.014em}
h2{font-family:var(--f-cond);font-size:clamp(22px,2.85vw,29px);font-weight:600;letter-spacing:-.012em;line-height:1.18}
h3{font-family:var(--f-cond);font-size:19px;font-weight:600;letter-spacing:-.008em;line-height:1.3}
.grid{display:grid;gap:18px}
.g2{grid-template-columns:repeat(auto-fit,minmax(300px,1fr))}
.g3{grid-template-columns:repeat(auto-fit,minmax(290px,1fr))}
.g4{grid-template-columns:repeat(auto-fit,minmax(230px,1fr))}
.g5{grid-template-columns:repeat(auto-fit,minmax(180px,1fr))}
.card{background:var(--surface);border:1px solid var(--line);border-radius:8px;padding:22px 24px;display:flex;flex-direction:column;gap:10px}
.card.flat{box-shadow:none}
.card h3{margin:0}
.pill{display:inline-flex;align-self:flex-start;align-items:center;gap:6px;font-family:var(--f-mono);font-size:10px;font-weight:600;letter-spacing:.1em;text-transform:uppercase;padding:3px 8px;border-radius:3px}
.pill.ok{color:var(--ok);background:var(--ok-bg)}
.pill.warn{color:var(--warn);background:var(--warn-bg)}
.pill.info{color:var(--info);background:var(--info-bg)}
.stat{display:flex;flex-direction:column;gap:2px}
.stat b{font-family:var(--f-mono);font-size:27px;font-weight:600;letter-spacing:-.02em;line-height:1}
.stat span{font-size:13px;color:var(--ink-3);line-height:1.45}
.arrow{font-weight:600;font-size:15px;color:var(--accent)}
.disclaimer{font-size:13px;color:var(--ink-3);line-height:1.55;max-width:96ch;margin-top:18px}

/* hero */
.hero{display:grid;grid-template-columns:minmax(0,1.05fr) minmax(0,.95fr);gap:48px;align-items:center;padding-block:56px}
.hero-copy{display:flex;flex-direction:column;gap:18px}
@media (max-width:900px){.hero{grid-template-columns:1fr;gap:32px;padding-block:36px}}

/* panel */
.panel{background:var(--surface);border:1px solid var(--line);border-radius:8px;box-shadow:var(--shadow);overflow:hidden}
.panel-head{padding:14px 20px;border-bottom:1px solid var(--line-2);display:flex;align-items:center;gap:10px}
.panel-head .t{font-weight:600;font-size:15px}
.panel-grid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:1px;background:var(--line-2)}
.panel-grid>div{padding:17px 18px;background:var(--surface)}
@media (max-width:900px){.panel-grid{grid-template-columns:repeat(2,minmax(0,1fr))}}
.panel-foot{padding:15px 20px;background:var(--surface-2);border-top:1px solid var(--line-2);display:flex;gap:10px;align-items:flex-start}
.panel-foot span{font-size:13.5px;color:var(--ink-2);line-height:1.55}

/* spec list */
dl.specs{margin:0;display:grid;border-top:1px solid var(--line-2)}
dl.specs>div{display:grid;grid-template-columns:13ch 1fr;gap:12px;padding:7px 0;border-bottom:1px solid var(--line-2)}
dl.specs dt{font-family:var(--f-mono);font-size:10px;letter-spacing:.1em;text-transform:uppercase;color:var(--ink-3);padding-top:3px}
dl.specs dd{margin:0;font-family:var(--f-mono);font-size:13px;font-variant-numeric:tabular-nums}

/* stock
   ---------------------------------------------------------------------------
   A shop front, which means every card is the same shape whatever arrived in
   the media library. Machines get photographed on a phone in the workshop:
   one portrait, one landscape, one not at all. Left alone in a 16/9 box with
   place-items:center that produced three different card heights in one row,
   with grey down the sides of the portrait one.

   The frame is a fixed 4:3 and the picture is cropped to fill it. Cropping a
   machine is fine here in a way it is not on a product panel: the card is a
   thumbnail leading somewhere, and the machine page shows it uncropped. */
.stock{display:flex;flex-direction:column;gap:0;padding:0;overflow:hidden}
.thumb{position:relative;background:var(--surface-3);border-bottom:1px solid var(--line-2);
  aspect-ratio:4/3;display:grid;place-items:center;padding:0;overflow:hidden}
.thumb svg{width:88%;height:auto}
.thumb img,.thumb .stock-img{position:absolute;inset:0;width:100%;height:100%;
  object-fit:cover;object-position:50% 50%;display:block}

/* No photograph yet. An empty grey rectangle reads as a broken image, so this
   says which it is, and tells whoever maintains the listings what is missing. */
.stock-none{position:absolute;inset:0;display:grid;place-content:center;justify-items:center;
  align-content:center;gap:14px;padding:20px;text-align:center;
  background:var(--surface-2);color:var(--ink-4)}
.stock-none svg{width:min(66%,190px);height:auto;opacity:.62}
.stock-none span{font-family:var(--f-mono);font-size:10.5px;font-weight:500;
  letter-spacing:.13em;text-transform:uppercase;color:var(--ink-3)}
.stock-none-lg{position:relative;aspect-ratio:4/3;border:1px solid var(--line);
  border-radius:8px;overflow:hidden;background:var(--surface-2)}

.stock-body{padding:16px 20px 20px;display:flex;flex-direction:column;gap:9px;flex:1}
.stock-meta{font-size:13px;color:var(--ink-2);line-height:1.65;margin:0}
.stock-meta-none{color:var(--ink-4)}
.stock-top{display:flex;align-items:baseline;justify-content:space-between;gap:10px}
.price{display:flex;align-items:baseline;justify-content:space-between;gap:10px;border-top:1px solid var(--line-2);padding-top:12px;margin-top:auto}
.price b{font-family:var(--f-mono);font-size:18px;font-weight:600}

/* table */
.tbl{width:100%;border-collapse:collapse;font-size:14px}
.tbl th{font-family:var(--f-mono);font-size:10px;letter-spacing:.1em;text-transform:uppercase;color:var(--ink-3);text-align:left;font-weight:600;padding:12px 16px;background:var(--surface-2);border-bottom:1px solid var(--line-2)}
.tbl td{padding:13px 16px;border-bottom:1px solid var(--line-2)}
.tbl tr:last-child td{border-bottom:0}
.tbl .mono{font-size:13px;color:var(--ink-2)}
.scroll-x{overflow-x:auto;background:var(--surface);border:1px solid var(--line);border-radius:8px}

/* footer */
footer.site{background:var(--dark);color:#aebbc8;padding-block:44px 30px}
footer.site a{color:#d4dde5}
footer.site a:hover{color:#fff}
footer.site h4,footer.site .foot-h{font-family:var(--f-mono);font-size:11px;font-weight:600;letter-spacing:.12em;text-transform:uppercase;color:#7e93a8;margin:0 0 12px}
.foot-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(190px,1fr));gap:32px}
.foot-links{display:flex;flex-direction:column;gap:8px;font-size:14px}
.foot-bottom{border-top:1px solid #24303a;margin-top:32px;padding-top:20px;display:flex;gap:18px;flex-wrap:wrap;font-size:13px;color:#7e93a8}
.proto{background:var(--accent);color:#fff;font-size:13px;text-align:center;padding:8px 20px}
.proto b{font-weight:600}
@media (max-width:560px){
  .panel-grid{grid-template-columns:1fr}
  .top-in{gap:12px}
  .nav{gap:14px;font-size:13px;order:3;width:100%}
  .top-cta{margin-left:0}
}

/* --- imagery --- */
.shot{display:block;width:100%;height:auto;border-radius:6px;background:#eef1f5}
.shot-sq{aspect-ratio:1/1;object-fit:cover}
.banner{position:relative;border-radius:8px;overflow:hidden;background:#0f1419}
.banner img{display:block;width:100%;height:auto}
.banner-cap{position:absolute;left:0;right:0;bottom:0;padding:22px 26px;color:#fff;
  background:linear-gradient(to top,rgba(10,14,18,.82),rgba(10,14,18,0))}
.oem-logo{height:30px;width:auto;display:block}

/* --- brand marks --- */
.brand img{height:34px;width:auto;display:block}
.brand-word{font-family:var(--f-cond);font-weight:700;font-size:21px;letter-spacing:.02em;text-transform:uppercase}
.foot-logo{height:34px;width:auto;display:block;margin-bottom:14px}

/* =========================================================
   EDITORIAL LAYER — bigger type, rules not boxes,
   asymmetric splits, full-bleed bands
   ========================================================= */
:root{
  --navy:#132c52;        /* band navy, from the logo family */
  --navy-2:#0c1f3c;
  --paper:#f4f2ed;       /* warm off-white */
  --rule:#cbd1d6;
}

/* type scale */
h1.big{font-family:var(--f-cond);font-weight:600;
  font-size:clamp(1.95rem,3.8vw,3.5rem);line-height:1.06;letter-spacing:-.022em;
  margin:0 0 26px;max-width:18ch;text-wrap:balance}
h2.big{font-family:var(--f-cond);font-weight:600;color:var(--ink);
  font-size:clamp(1.6rem,2.8vw,2.45rem);line-height:1.12;letter-spacing:-.02em;
  margin:0 0 20px;text-wrap:balance}
h3.mid{font-family:var(--f-cond);font-weight:600;font-size:clamp(1.1rem,1.62vw,1.4rem);
  letter-spacing:-.01em;margin:0;color:var(--ink)}

/* The size, leading and gap are variables so that the hero's right column can
   be offset by exactly the height this label occupies. See "Hero intro aligned
   to the headline" near the end of this file. The values are the ones that
   were already computing here, so nothing moves. */
.kicker{font-family:var(--f-mono);font-size:var(--kicker-size);font-weight:600;
  line-height:var(--kicker-lh);letter-spacing:.14em;
  text-transform:uppercase;color:var(--accent);margin:0 0 var(--kicker-gap)}
.kicker.dim{color:var(--ink-3)}
.kicker.light{color:#8fb0da}

/* sections */
.ed{padding-block:clamp(64px,8.5vw,118px)}
.ed.paper{background:var(--paper)}
.ed.white{background:#fff}
.ed.navy{background:var(--navy);color:#fff}
.ed.navy h2.big,.ed.navy h3.mid{color:#fff}
.ed.tightish{padding-block:clamp(48px,6vw,80px)}

/* A page that opens with a back link rather than a headline does not need the
   full editorial top. The link is navigation, not a statement, and 118px of
   white above it pushed the machine itself below the fold on a laptop while
   the sibling archive, which uses .sec, opened at 52px. Two pages one click
   apart should not start at two different scales. */
/* THE TOP OF A PAGE
   ---------------------------------------------------------------------------
   A page either opens with a colour or photo band, which starts hard against
   the fault bar and needs nothing, or it opens with text on white.

   The second kind had accumulated four different tops: `.ed` at 118px, `.sec`
   at 92px, a one-off `.sec.tight`, and two more I added fixing the machine
   pages one at a time. Nobody chose that. It is one value now, and the
   modifiers below are kept only as aliases so no template silently loses its
   spacing.

   56px, not the 34px the machine page briefly had: About and Contact open
   with a headline making a statement, and a statement wants a little air
   above it. A back link does not, which is what `.backlink` still trims. */
.ed.pagetop,.sec.pagetop,
.ed.backlink,.sec.tight-top,.sec.tight{padding-top:clamp(30px,3.6vw,56px)}

/* A back link is navigation, not a statement, so it sits tighter still. */
.ed.backlink{padding-top:clamp(22px,2.4vw,34px)}
.backlink-row{margin:0 0 clamp(14px,1.6vw,20px)}

/* asymmetric intro split */
.split{display:grid;grid-template-columns:.86fr 1.14fr;gap:clamp(34px,6vw,92px);align-items:start}
.split.flip{grid-template-columns:1.18fr .82fr;align-items:stretch}
.split.even-ish{grid-template-columns:1.08fr .92fr}
.split p.lead{font-size:clamp(1.02rem,1.35vw,1.14rem);color:var(--ink-2);max-width:66ch;margin:0}
.ed.navy .split p.lead{color:#bccadd}

/* numbered rule list */
.rows{margin-top:clamp(38px,5vw,60px);border-top:1px solid var(--rule)}
.row-item{display:grid;grid-template-columns:62px .8fr 1.35fr auto;gap:24px;
  padding:28px 0;border-bottom:1px solid var(--rule);align-items:baseline}
.row-item .n{font-family:var(--f-mono);font-size:13px;font-weight:600;color:var(--accent)}
.row-item p{margin:0;color:var(--ink-2);max-width:62ch}
.row-item .go{font-weight:600;font-size:14px;color:var(--accent);white-space:nowrap}
.ed.navy .rows,.ed.navy .row-item{border-color:#32496b}
.ed.navy .row-item p{color:#bccadd}

/* Every row in one list shares the same columns.

   Each .row-item was its own grid, so the `auto` link column sized to that
   row's own link text. "Get an engineer" is narrower than "View the machines
   we support", which pushed every other column along by a different amount on
   every row: four headings starting at four different places.

   The columns are now declared once on the list and inherited, so the auto
   column resolves to the widest link across the whole list and all four rows
   line up. The mobile templates move to the list for the same reason.

   Guarded, because without subgrid the list would become a grid whose rows
   lay out their own columns anyway. Browsers that lack it keep exactly the
   behaviour they have today. */
@supports (grid-template-columns:subgrid){
  .rows{display:grid;grid-template-columns:62px .8fr 1.35fr auto}
  .rows > .row-item{grid-column:1 / -1;grid-template-columns:subgrid}
  @media (max-width:960px){
    .rows{grid-template-columns:44px 1fr}
  }
  @media (max-width:680px){
    .rows{grid-template-columns:34px 1fr}
  }
}

/* plain group grid, rules not cards */
.groups{display:grid;grid-template-columns:1fr 1fr;border-top:3px solid var(--ink)}
.group{padding:24px 28px 26px 0;border-bottom:1px solid var(--line)}
.group:nth-child(even){padding-left:28px;border-left:1px solid var(--line)}
.group p{margin:6px 0 0;color:var(--ink-2)}

/* big figures */
.figs{display:grid;grid-template-columns:1fr 1fr;margin-top:44px;border-top:1px solid #32496b}
.fig{padding:22px 18px 22px 0;border-bottom:1px solid #32496b}
.fig:nth-child(even){padding-left:22px;border-left:1px solid #32496b}
.fig b{display:block;font-family:var(--f-cond);font-size:clamp(1.8rem,3.15vw,2.85rem);
  line-height:1.06;letter-spacing:-.025em;color:#fff}
.fig span{color:#a9bdd6;font-size:14px}

/* full-bleed two-up band */
.bleed{display:grid;grid-template-columns:1fr 1fr}
.bleed > *{min-height:340px;padding:clamp(40px,5.5vw,76px);color:#fff}
.bleed .a{background:var(--accent)}
.bleed .b{background:#24313e}
.bleed .c{background:var(--navy)}
.bleed .d{background:var(--accent-dark)}
.bleed h3{font-family:var(--f-cond);font-weight:600;font-size:clamp(1.6rem,2.7vw,2.4rem);
  letter-spacing:-.025em;margin:0 0 14px;color:#fff}
.bleed p{color:#e2eaf4;max-width:48ch;margin:0}

/* image placeholder that does not look like a bug */
.imgslot{position:relative;min-height:420px;overflow:hidden;
  background:linear-gradient(140deg,#5f6e7a 0%,#2f3e4d 48%,var(--navy-2) 100%)}
.imgslot::after{content:attr(data-note);position:absolute;inset:auto 24px 24px 24px;
  color:rgba(255,255,255,.72);font-family:var(--f-mono);font-size:11px;letter-spacing:.12em;
  text-transform:uppercase;line-height:1.7}
.imgslot::before{content:"";position:absolute;inset:0;
  background:linear-gradient(0deg,rgba(6,16,30,.55),transparent 55%)}

.tline{margin-top:40px;display:flex;gap:14px 26px;flex-wrap:wrap;color:#9fb3cc;font-size:14px}
.tline span{display:inline-flex;align-items:center;gap:9px}
.tline span::before{content:"";width:5px;height:5px;border-radius:50%;background:#e8933c}

.tlink{font-weight:600;color:var(--accent);border-bottom:1px solid #aac5e5;padding-bottom:3px}
.ed.navy .tlink,.bleed .tlink{color:#fff;border-color:rgba(255,255,255,.45)}

@media (max-width:960px){
  .split,.split.flip,.split.even-ish,.groups,.bleed,.figs{grid-template-columns:1fr}
  .group:nth-child(even){padding-left:0;border-left:0}
  .fig:nth-child(even){padding-left:0;border-left:0}
  .row-item{grid-template-columns:44px 1fr}
  .row-item p,.row-item .go{grid-column:2}
}
@media (max-width:680px){
  .row-item{grid-template-columns:34px 1fr;gap:12px}
  .imgslot{min-height:300px}
}


/* --- Archivo standing in for Sculpin: it is wider, so rein the display sizes in --- */
h1.big{font-size:clamp(2.6rem,4.7vw,4.4rem);letter-spacing:-.035em;max-width:17ch}
h2.big{font-size:clamp(1.85rem,3.4vw,3.1rem);letter-spacing:-.03em}
h3.mid{letter-spacing:-.012em}
.brand-word{letter-spacing:.01em}

/* --- CMYK as section markers only. The mark carries the colour; the page does not ---
   Cycles every four, because CMYK is four. Lists run to seven, eight and nine
   items on the manufacturer, service and Summa pages, and before this the
   fifth onwards all fell back to plain accent blue, so a long list started in
   brand colours and finished in something else.

   Two sets. The light one is darkened from the logo values so the numerals
   clear 3:1 against white and paper: #00b4f8 measured 2.2 and #c9a400 2.4.
   The magenta already passed and is untouched. On a dark band the problem
   inverts, so the bright logo values are used there and the black becomes
   white. */
.row-item .n,
.row-item:nth-child(4n+1) .n{color:#0e8ec6}
.row-item:nth-child(4n+2) .n{color:#e6008c}
.row-item:nth-child(4n+3) .n{color:#9c8000}
.row-item:nth-child(4n+4) .n{color:var(--ink)}

.sec.dark .row-item:nth-child(4n+1) .n,.ed.navy .row-item:nth-child(4n+1) .n,
.close .row-item:nth-child(4n+1) .n,.bleed .row-item:nth-child(4n+1) .n{color:#00b4f8}
.sec.dark .row-item:nth-child(4n+2) .n,.ed.navy .row-item:nth-child(4n+2) .n,
.close .row-item:nth-child(4n+2) .n,.bleed .row-item:nth-child(4n+2) .n{color:#ff4fb0}
.sec.dark .row-item:nth-child(4n+3) .n,.ed.navy .row-item:nth-child(4n+3) .n,
.close .row-item:nth-child(4n+3) .n,.bleed .row-item:nth-child(4n+3) .n{color:#f0c63a}
.sec.dark .row-item:nth-child(4n+4) .n,.ed.navy .row-item:nth-child(4n+4) .n,
.close .row-item:nth-child(4n+4) .n,.bleed .row-item:nth-child(4n+4) .n{color:#fff}

/* --- WordPress bits the prototype never needed --- */
.skip{position:absolute;left:-9999px;top:0;z-index:100;background:var(--accent);color:#fff;
  padding:12px 18px;border-radius:0 0 4px 0;font-weight:600}
.skip:focus{left:0}
.prose{font-size:1.05rem;line-height:1.7;color:var(--ink-2);max-width:74ch}
.prose h2{font-family:var(--f-cond);font-size:clamp(1.5rem,2.6vw,2.1rem);letter-spacing:-.025em;
  color:var(--ink);margin:2em 0 .5em;line-height:1.15}
.prose h3{font-family:var(--f-cond);font-size:1.25rem;letter-spacing:-.015em;color:var(--ink);
  margin:1.8em 0 .4em}
.prose p{margin:0 0 1.1em}
.prose ul,.prose ol{margin:0 0 1.2em;padding-left:1.3em;line-height:1.9}
.prose img{max-width:100%;height:auto;border-radius:6px}
.prose blockquote{margin:1.6em 0;padding-left:20px;border-left:4px solid #e8933c;
  font-weight:600;color:var(--ink)}
.prose a{border-bottom:1px solid #aac5e5}

.pagination,.navigation.pagination{margin-top:38px;display:flex;gap:8px;flex-wrap:wrap;
  font-family:var(--f-mono);font-size:14px}
.pagination .page-numbers{padding:9px 14px;border:1px solid var(--line);border-radius:4px;
  color:var(--ink-2);background:#fff}
.pagination .page-numbers.current{background:var(--accent);border-color:var(--accent);color:#fff}
.screen-reader-text{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);
  clip-path:inset(50%);white-space:nowrap}

.searchform input[type=search]{padding:12px 14px;border:1px solid var(--line);border-radius:4px;
  font:inherit;font-size:15px;background:#fff;color:var(--ink)}

/* WooCommerce, parts only. Enough to stop Woo's defaults fighting the design. */
.woocommerce ul.products{display:grid;grid-template-columns:repeat(auto-fill,minmax(230px,1fr));
  gap:18px;margin:0;padding:0;list-style:none}
.woocommerce ul.products li.product{background:#fff;border:1px solid var(--line);border-radius:8px;
  padding:18px;margin:0;width:auto;float:none;text-align:left}
.woocommerce ul.products li.product .woocommerce-loop-product__title{font-family:var(--f-cond);
  font-size:1.05rem;font-weight:600;letter-spacing:-.01em;color:var(--ink);padding:0;margin:10px 0 4px}
.woocommerce ul.products li.product .price{color:var(--ink);font-family:var(--f-mono);font-size:15px;
  font-weight:600}
.woocommerce ul.products li.product img{border-radius:5px;margin-bottom:6px}
.woocommerce .button,.woocommerce a.button,.woocommerce button.button{background:var(--accent);
  color:#fff;border-radius:4px;font-weight:600;font-size:14px;padding:11px 16px;font-family:inherit}
.woocommerce .button:hover,.woocommerce a.button:hover{background:var(--accent-dark);color:#fff}
.woocommerce .woocommerce-message,.woocommerce .woocommerce-info{border-top-color:var(--accent);
  background:var(--surface-2);border-radius:6px}
.woocommerce .woocommerce-breadcrumb{font-family:var(--f-mono);font-size:12px;color:var(--ink-3)}

/* staging banner reuses the prototype strip */
/* the review banner scrolls away. Only the header sticks. */
body.is-staging .proto{position:static}


/* ---------------------------------------------------------------------------
   Sticky header vs the WordPress admin bar
   ---------------------------------------------------------------------------
   The admin bar is position:fixed at top:0 and 32px tall, 46px under 782px
   wide. A sticky header at top:0 slides underneath it and gets clipped. Only
   logged in users ever see this, which is exactly the people reviewing the
   site, so it looks like a fault when it is not.
   --------------------------------------------------------------------------- */
body.admin-bar .top{top:32px}
@media screen and (max-width:782px){
  body.admin-bar .top{top:46px}
}

/* Give the sticky header a shadow once it lifts off the page, so it reads as
   a layer rather than as content that failed to scroll. */
.top{transition:box-shadow .18s ease}
.top.is-stuck{box-shadow:0 1px 0 var(--line),0 8px 24px -14px rgba(15,20,25,.4)}

/* Header contents must never wrap, or the sticky bar grows and eats the page. */
.top-in{flex-wrap:nowrap}
.top .nav{min-width:0;overflow:hidden}
@media (max-width:900px){
  .top-in{flex-wrap:wrap;row-gap:10px}
  .top .nav{order:3;width:100%;overflow:visible}
  .top-cta{margin-left:auto}
}


/* ---------------------------------------------------------------------------
   Layout stability
   ---------------------------------------------------------------------------
   Pages were jumping while they loaded. Three causes, all addressed here.

   1. Web font swap. Archivo arrives from Google and the browser paints in a
      fallback first. With display type at 4rem and -.035em tracking, the
      reflow when it swaps is violent. The @font-face below gives the fallback
      matched metrics so the swap barely moves anything.
   2. Nothing reserved space. Hero and image panels could collapse and then
      expand once content arrived.
   3. The footer logo had no size, so it painted at its natural width first.
   --------------------------------------------------------------------------- */

/* Metric matched fallback. size-adjust is tuned so Arial occupies close to the
   same space as Poppins. Measured in headless Chromium: at the same font-size
   Poppins sets 6.7% wider than Arial, and Poppins' own ascent and descent are
   105% and 35% of the em. Nudge it if a headline still shifts: bigger number
   means the fallback renders larger. */
@font-face{
  font-family:'Poppins fallback';
  src:local('Arial'),local('Helvetica Neue'),local('Liberation Sans');
  size-adjust:107%;
  ascent-override:98%;
  descent-override:33%;
  line-gap-override:0%;
}

:root{
  --f-sans:'Poppins','Poppins fallback',system-ui,-apple-system,sans-serif;
  --f-cond:'Poppins','Poppins fallback',system-ui,-apple-system,sans-serif;
}

/* Reserve the space a section will end up occupying, so nothing collapses
   and then pushes the page down. */
.hero,.split.even-ish{min-height:clamp(340px,42vh,500px)}
.imgslot{min-height:420px}
@media (max-width:680px){
  .hero,.split.even-ish{min-height:0}
  .imgslot{min-height:300px}
}

/* Both logos get a fixed height and a reserved box. */
.brand img,.foot-logo,footer.site .wrap img{height:34px;width:auto;display:block}
.brand{min-height:34px;display:flex;align-items:center}
footer.site .wrap > .foot-grid > div:first-child img{height:40px;margin-bottom:14px}

/* Images never render at natural size first. */
img{max-width:100%;height:auto}


/* ---------------------------------------------------------------------------
   Menus rendered by wp_nav_menu
   ---------------------------------------------------------------------------
   WordPress always outputs menu items as <li>. Left alone they come out as a
   bulleted list, which is where the dots between the nav items came from.
   --------------------------------------------------------------------------- */
.nav-list,.foot-list{list-style:none;margin:0;padding:0}
.nav-list li,.foot-list li{margin:0;padding:0;list-style:none}
.nav-list li::marker,.foot-list li::marker{content:none}

.nav-list{display:flex;align-items:center;gap:22px;flex-wrap:wrap}
.nav-list a{font-size:14px;font-weight:500;color:var(--ink-2);white-space:nowrap}
.nav-list a:hover{color:var(--accent)}
.nav-list .current-menu-item > a,
.nav-list .current_page_item > a,
.nav-list .current-menu-ancestor > a{color:var(--ink);font-weight:600}

.foot-list{display:flex;flex-direction:column;gap:9px}
.foot-list a{font-size:14px;color:inherit}

/* Belt and braces: nothing inside the header or the site footer should ever
   grow a bullet, whatever a plugin decides to inject. */
header.top ul,footer.site ul{list-style:none;margin:0;padding:0}
header.top li,footer.site li{list-style:none}

/* --- team --- */
.people{display:grid;grid-template-columns:repeat(auto-fill,minmax(160px,1fr));gap:26px 20px;margin:0;padding:0;list-style:none}
.person{text-align:left}
.person-photo{display:block;width:100%;aspect-ratio:1/1;object-fit:cover;border-radius:6px;background:var(--surface-2)}
.person-initials{display:flex;align-items:center;justify-content:center;font-family:var(--f-cond);
  font-size:2rem;font-weight:600;color:var(--ink-4);letter-spacing:.02em}
.person-name{font-weight:600;color:var(--ink);margin:12px 0 0;font-size:15px}
.person-role{font-family:var(--f-mono);font-size:11.5px;letter-spacing:.06em;text-transform:uppercase;
  color:var(--ink-3);margin:3px 0 0;line-height:1.5}


/* ---------------------------------------------------------------------------
   Manufacturer logos
   ---------------------------------------------------------------------------
   A logo supplied for a dark background is invisible on a light one, and vice
   versa. The Summa kit ships both and names them confusingly: the file called
   "Whitebackground" is the one FOR a white background, not the one WITH one.

   Rule for this site: light sections use the primary mark, dark sections use
   the reversed one. Never scale a logo below 24px high, and never put one on
   a background it was not drawn for.
   --------------------------------------------------------------------------- */
.oem-logo{height:34px;width:auto;display:block;margin-bottom:18px}
@media (max-width:680px){ .oem-logo{height:28px} }

/* On a dark band a light-background mark needs its own plate rather than
   being recoloured, which would breach most brand guidelines. */
.ed.navy .oem-logo,.bleed .oem-logo{background:#fff;padding:8px 12px;border-radius:4px;
  height:50px;box-sizing:content-box}


/* ---------------------------------------------------------------------------
   Full bleed hero with a photograph
   ---------------------------------------------------------------------------
   Copy on a dark panel, image filling the other half edge to edge. Used on
   the Summa page and available to any page that has a photograph worth the
   space. A logo alone on a pale background is a weak opening and, if the
   logo happens to be the reversed version, an invisible one.
   --------------------------------------------------------------------------- */
.hero-bleed{display:grid;grid-template-columns:1.02fr .98fr;background:#151b22;color:#fff;
  align-items:stretch;overflow:hidden}
.hero-bleed-copy{padding:clamp(56px,7vw,104px) 5vw clamp(52px,6vw,88px) max(28px,calc((100vw - 1200px)/2));
  display:flex;flex-direction:column;justify-content:center}
.hero-bleed-media{position:relative;min-height:380px;background:#0e1319}
.hero-bleed-media .hero-img,.hero-bleed-media img{position:absolute;inset:0;
  width:100%;height:100%;object-fit:cover;display:block}
.hero-bleed-media::after{content:"";position:absolute;inset:0;
  background:linear-gradient(90deg,rgba(21,27,34,.9),rgba(21,27,34,0) 38%)}
@media (max-width:900px){
  .hero-bleed{grid-template-columns:1fr}
  .hero-bleed-copy{padding-inline:24px}
  .hero-bleed-media{min-height:300px}
  .hero-bleed-media::after{background:linear-gradient(0deg,rgba(21,27,34,.75),rgba(21,27,34,0) 45%)}
}

/* A manufacturer logo is never stretched, whatever else is on the page. */
.oem-logo{height:38px!important;width:auto!important;max-width:220px;object-fit:contain;
  display:block;margin:0 0 22px;position:static}
@media (max-width:680px){ .oem-logo{height:30px!important} }


/* ---------------------------------------------------------------------------
   Missing media placeholder
   ---------------------------------------------------------------------------
   Takes the size of whatever it is standing in for. The previous version was
   a fixed 420px panel, so a missing 38px logo pushed the hero to twice its
   height and the photograph beside it zoomed to fill the gap.
   --------------------------------------------------------------------------- */
.media-missing{display:flex;align-items:center;justify-content:center;
  background:rgba(127,140,160,.14);border:1px dashed rgba(127,140,160,.5);border-radius:4px;
  font-family:var(--f-mono);font-size:10px;letter-spacing:.06em;text-transform:uppercase;
  color:rgba(150,165,185,.9);text-align:center;padding:6px 10px;overflow:hidden;box-sizing:border-box}
.media-missing.oem-logo{height:38px!important;width:160px!important;max-width:160px;margin:0 0 22px}
.media-missing.hero-img{position:absolute;inset:0;width:100%;height:100%;border-radius:0}
.media-missing.shot{width:100%;aspect-ratio:1/1;height:auto}

/* ---------------------------------------------------------------------------
   Hero height has to be bounded
   ---------------------------------------------------------------------------
   The banner images are 1600 x 576, nearly 3:1. Drop one into a container
   that has grown tall and object-fit:cover crops it to a detail of one
   letter, which is what happened here.
   --------------------------------------------------------------------------- */
.hero-bleed{min-height:clamp(420px,52vh,560px);max-height:680px}
.hero-bleed-copy{min-width:0}
.hero-bleed-media{min-height:0;height:100%}
.hero-bleed-media img,.hero-bleed-media .hero-img{object-position:center}
@media (max-width:900px){
  .hero-bleed{min-height:0;max-height:none}
  .hero-bleed-media{min-height:280px;max-height:340px}
}


/* ---------------------------------------------------------------------------
   Full bleed photographic hero
   ---------------------------------------------------------------------------
   One photograph edge to edge with the copy over it. Needs a dark image with
   somewhere quiet for the text to sit, which the Vantage head shot has on the
   left. The scrim underneath guarantees contrast even if the image is later
   swapped for a brighter one.
   --------------------------------------------------------------------------- */
.hero-photo{position:relative;isolation:isolate;background:#0b0e12;overflow:hidden;
  min-height:clamp(440px,58vh,620px);display:flex;align-items:center}
.hero-photo .hero-photo-bg,.hero-photo img:first-child{
  position:absolute;inset:0;width:100%;height:100%;object-fit:cover;
  object-position:65% center;z-index:-2;display:block}
.hero-photo::before{content:"";position:absolute;inset:0;z-index:-1;
  background:linear-gradient(90deg,rgba(8,11,15,.94) 0%,rgba(8,11,15,.82) 32%,rgba(8,11,15,.28) 62%,rgba(8,11,15,.1) 100%)}
.hero-photo-copy{position:relative;width:min(100% - 48px,var(--wrap));margin-inline:auto;
  padding-block:clamp(56px,7vw,88px);max-width:none}
.hero-photo-copy > *{max-width:640px}
.hero-photo-copy .oem-logo{filter:drop-shadow(0 2px 8px rgba(0,0,0,.5))}

@media (max-width:820px){
  .hero-photo{min-height:0;align-items:stretch}
  .hero-photo .hero-photo-bg{object-position:70% center}
  .hero-photo::before{background:linear-gradient(180deg,rgba(8,11,15,.78) 0%,rgba(8,11,15,.92) 55%,rgba(8,11,15,.96) 100%)}
  .hero-photo-copy{padding-block:clamp(44px,9vw,64px)}
}


/* ---------------------------------------------------------------------------
   Masthead corrections
   ---------------------------------------------------------------------------
   Three faults, all visible at rest on the Summa page:

   1. The phone number was printed twice, once in the masthead and again in the
      breakdown bar directly beneath it. Removed from the masthead in the
      template; the breakdown bar is where the number belongs because it sits
      next to the action.
   2. The breakdown bar is #0f1419 and a dark hero is #0b0e12, so the two ran
      together into one black mass and the header had no visible bottom edge.
      A hairline and a lift in the bar's own ground separate them.
   3. The masthead carried more height than its contents needed, so the page
      opened with roughly 160px of furniture before any content.
   --------------------------------------------------------------------------- */
.top-in{padding:11px 20px;gap:26px}
.brand img{height:38px}
.brand{min-height:38px}

.alert{background:#171e27;border-bottom:1px solid rgba(255,255,255,.1);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.06)}
.alert-in{padding:9px 20px;gap:12px}
.alert b{font-size:14px}
.alert p{font-size:13.5px}
.alert .num{font-size:18px}
.alert .btn.sm{padding:8px 16px;font-size:13.5px}

@media (max-width:900px){
  .alert p{display:none}
}


/* ---------------------------------------------------------------------------
   Full bleed bands: align the type to the rest of the page
   ---------------------------------------------------------------------------
   A .bleed band runs edge to edge, but its COPY should still start on the same
   vertical line as the logo and the nav above it. It was using a viewport
   percentage for its padding instead, so the heading sat about 80px left of
   everything else on the page and the whole band read as slightly off.

   The gutter below is the same expression .wrap resolves to, so the first
   column's text edge and the container's text edge are the same line at every
   width.
   --------------------------------------------------------------------------- */
.bleed{--gutter:max(24px,calc((100vw - var(--wrap))/2 + 20px))}
.bleed > *{padding:clamp(52px,6.5vw,92px) clamp(32px,4vw,60px);display:flex;
  flex-direction:column;justify-content:center}
.bleed > *:nth-child(odd){padding-left:var(--gutter)}
.bleed > *:nth-child(even){padding-right:var(--gutter)}
.bleed > .hero-bleed-media{padding:0;display:block}

/* A product shot cut out on white does not belong on a navy ground cropped to
   fill. Give it its own light panel and show the whole machine. */
.hero-bleed-media.light{background:#f2f4f7}
.hero-bleed-media.light .hero-img,.hero-bleed-media.light img{
  object-fit:contain;padding:clamp(28px,3.5vw,52px)}
.hero-bleed-media.light::after{display:none}

@media (max-width:820px){
  .bleed{grid-template-columns:1fr}
  .bleed > *{padding-inline:24px}
  .bleed > *:first-child{padding-left:24px}
  .bleed > *:last-child{padding-right:24px}
}


/* ---- photographic hero: corrections after rendering it ---- */
/* Text edge on the same line as the logo, not 20px left of it. */
.hero-photo-copy{width:min(100%,var(--wrap));padding-inline:20px}
.hero-photo-copy > *{max-width:none}
.hero-photo-copy .kicker,.hero-photo-copy p,.hero-photo-copy .tline{max-width:56ch}
/* At full display size the headline ran to five lines and pushed the hero to
   860px, which is most of a laptop screen. Three lines, wider measure. */
.hero-photo h1.big{color:#fff;font-size:clamp(2.3rem,3.6vw,3.5rem);max-width:21ch;margin:0 0 22px}
.hero-photo .kicker{margin-bottom:14px}

/* A white button on a black photograph is a hole in the picture. */
.btn.ghost.on-dark{background:transparent;color:#fff;border-color:rgba(255,255,255,.42)}
.btn.ghost.on-dark:hover{background:rgba(255,255,255,.1);color:#fff;border-color:#fff}

/* The shot is cut out on white, so the panel behind it should be white too or
   the cut-out shows as a rectangle. */
.hero-bleed-media.light{background:#fff}
.hero-photo-copy .tline{max-width:none;flex-wrap:nowrap}
.hero-photo-copy{padding-block:clamp(48px,5.4vw,72px)}
@media (max-width:1100px){.hero-photo-copy .tline{flex-wrap:wrap}}

/* Move the cutting head clear of the headline.
   The photograph is only slightly wider than the hero box, so panning it with
   object-position alone can shift the subject by about 40px, which is not
   enough to get it out from behind the text. Rendering the image wider than
   the box and anchoring it to the LEFT pushes the machine across to the right
   hand side, where the scrim is at its lightest and the copy is finished. */
.hero-photo .hero-photo-bg{width:148%;max-width:none;object-position:0% 46%}
@media (max-width:1100px){.hero-photo .hero-photo-bg{width:125%;object-position:0% 48%}}
@media (max-width:820px){.hero-photo .hero-photo-bg{width:100%;object-position:62% center}}


/* ---------------------------------------------------------------------------
   Summa hero: black copy panel, photograph in its own panel
   ---------------------------------------------------------------------------
   The photograph ran the full width with the copy over it, which put the
   cutting head behind the headline. Splitting it gives the type a clean black
   ground and gives the machine a panel of its own, with the head centred in
   it. object-position is doing the work: the picture is 1920x857 and the panel
   is roughly square, so the frame is cropped hard left and right and the head
   is pulled into the middle of what is left. No upscaling, so it stays sharp.
   --------------------------------------------------------------------------- */
.hero-split{display:grid;grid-template-columns:1.06fr .94fr;background:#0b0e12;color:#fff;
  min-height:clamp(440px,56vh,600px);align-items:stretch}
.hero-split-copy{display:flex;flex-direction:column;justify-content:center;
  padding:clamp(48px,5.4vw,76px) clamp(36px,4vw,64px) clamp(48px,5.4vw,76px)
          max(24px,calc((100vw - var(--wrap))/2 + 20px))}
.hero-split-copy .oem-logo{margin:0 0 20px}
.hero-split-copy .kicker{margin:0 0 14px}
.hero-split h1.big{color:#fff;font-size:clamp(1.85rem,2.6vw,2.55rem);max-width:21ch;margin:0 0 18px}
.hero-split-lead{font-size:clamp(1rem,1.35vw,1.12rem);line-height:1.6;color:#c3ccd8;max-width:48ch;margin:0}
.hero-split-cta{display:flex;gap:12px;flex-wrap:wrap;margin-top:30px}
.hero-split .tline{margin-top:32px}

.hero-split-media{position:relative;overflow:hidden;background:#05070a}
.hero-split-media .hero-split-img,.hero-split-media img{
  position:absolute;inset:0;width:100%;height:100%;object-fit:cover;
  object-position:54% center;display:block}
/* a soft feather where the panel meets the black, so the join is not a seam */
.hero-split-media::before{content:"";position:absolute;inset:0;z-index:1;pointer-events:none;
  background:linear-gradient(90deg,rgba(11,14,18,.92) 0,rgba(11,14,18,0) 16%)}
.hero-split-media .media-missing{position:absolute;inset:0;width:100%;height:100%;border-radius:0}
/* One banner height across the site on desktop. The height used to follow
   the screen height and the length of each page's opening paragraph, so it
   ran from 504px to 706px and the banner jumped as you moved between pages.
   710px clears the longest opening on the site at every desktop width; a
   longer one would still grow rather than clip. */
@media (min-width:901px){ .hero-split{min-height:710px} }

@media (max-width:900px){
  .hero-split{grid-template-columns:1fr;min-height:0}
  .hero-split-copy{padding:clamp(40px,7vw,56px) 24px;order:2}
  .hero-split-media{order:1;min-height:clamp(240px,42vw,320px)}
  .hero-split-media .hero-split-img{object-position:54% 40%}
  .hero-split-media::before{background:linear-gradient(0deg,rgba(11,14,18,.9) 0,rgba(11,14,18,0) 40%)}
}

/* ---------------------------------------------------------------------------
   Paired figure beside a column of text
   ---------------------------------------------------------------------------
   The applications block used to stack two square crops in a narrow left hand
   column, which ran them past the edge of the panel and left the right third of
   the row empty. The text now leads and the pictures sit beside it: one large,
   one smaller under it, both bounded by the column rather than by a fixed
   square.
   --------------------------------------------------------------------------- */
.figpair{margin:0;display:grid;gap:14px}
.figpair-main,.figpair-sub{position:relative;overflow:hidden;border-radius:6px;background:var(--surface-3)}
.figpair-main{aspect-ratio:4/3}
.figpair-sub{aspect-ratio:16/9}
.figpair img,.figpair .shot{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;display:block}
.figpair .media-missing{position:absolute;inset:0;width:100%;height:100%;border-radius:0}
.figpair figcaption{font-size:13px;color:var(--ink-3);line-height:1.5;margin-top:2px}

@media (max-width:820px){
  .figpair{grid-template-columns:1fr 1fr;align-items:start}
  .figpair figcaption{grid-column:1/-1}
}

/* Nothing inside a page section may be wider than its column. Hand written
   page files use inline widths here and there, and one overflowing image drags
   a horizontal scrollbar onto the whole document. */
.sec img,.sec .shot,.split img{max-width:100%;height:auto}


/* ---------------------------------------------------------------------------
   Text column and figure column ending on the same line
   ---------------------------------------------------------------------------
   With the pictures on fixed aspect ratios they ran about 260px past the
   bottom of the text, leaving a hole under the copy. The figure column now
   stretches to whatever height the text sets and the two panels divide it
   between them, so both columns finish level and the row reads as one block.
   The minimum height stops the pictures being squashed into letterbox strips
   if the copy beside them is ever short.
   --------------------------------------------------------------------------- */
.figrow{align-items:stretch}
.figrow .figpair{height:100%;grid-template-rows:1.25fr 1fr auto;min-height:440px}
.figrow .figpair-main,.figrow .figpair-sub{aspect-ratio:auto;min-height:0}
.figrow .figpair figcaption{align-self:end}

@media (max-width:820px){
  .figrow .figpair{height:auto;min-height:0;grid-template-rows:auto}
  .figrow .figpair-main{aspect-ratio:4/3}
  .figrow .figpair-sub{aspect-ratio:16/9}
}


/* ---------------------------------------------------------------------------
   Figure column that finishes level with the text
   ---------------------------------------------------------------------------
   Two stacked pictures at their own aspect ratios ran about 280px past the
   bottom of the copy, so the row ended with a tall column of photograph next to
   a block of white. Stretching the figure to the row height and splitting it in
   two equal cells makes both columns finish on the same line, and the pictures
   crop rather than dictate the height.
   --------------------------------------------------------------------------- */
.split.figrow{align-items:stretch}
.split.figrow .figpair{height:100%;grid-template-rows:1fr 1fr auto;gap:12px;min-height:400px}
.split.figrow .figpair-main,
.split.figrow .figpair-sub{aspect-ratio:auto;height:100%;min-height:0}
.split.figrow .figpair figcaption{margin-top:4px}

@media (max-width:820px){
  .split.figrow{align-items:start}
  .split.figrow .figpair{height:auto;min-height:0;grid-template-rows:auto auto auto}
  .split.figrow .figpair-main{aspect-ratio:4/3}
  .split.figrow .figpair-sub{aspect-ratio:16/9}
}

/* ---------------------------------------------------------------------------
   Level the figure column WITHOUT depending on the page markup
   ---------------------------------------------------------------------------
   The previous fix hung off a class on the row, which meant it only took effect
   once the page was re-imported. Worse, the row it has to beat carries an
   inline `align-items:start`, and a stylesheet cannot override an inline style
   on the container.

   `align-self` on the child can, because it is set on a different element.
   So the figure levels itself regardless of what the row says, and regardless
   of which version of the page content is sitting in the database.
   --------------------------------------------------------------------------- */
.split > .figpair{align-self:stretch;height:100%;min-height:0;
  grid-template-rows:minmax(0,1fr) minmax(0,1fr) auto;gap:12px}
.split > .figpair .figpair-main,
.split > .figpair .figpair-sub{aspect-ratio:auto;height:100%;min-height:0}

@media (max-width:820px){
  .split > .figpair{align-self:start;height:auto;min-height:0;
    grid-template-rows:auto auto auto}
  .split > .figpair .figpair-main{aspect-ratio:4/3}
  .split > .figpair .figpair-sub{aspect-ratio:16/9}
}

/* The overflow guard above sets `height:auto` on images inside a section, which
   at equal specificity beats .figpair's `height:100%` and lets the picture set
   its own height again. Restate it with enough specificity to win. */
.split > .figpair .figpair-main img,
.split > .figpair .figpair-main .shot,
.split > .figpair .figpair-sub img,
.split > .figpair .figpair-sub .shot{
  position:absolute;inset:0;width:100%;height:100%;object-fit:cover;display:block}

/* ---------------------------------------------------------------------------
   Click to load video
   ---------------------------------------------------------------------------
   A still frame with a play button until somebody asks for the video. Keeps
   several hundred kilobytes and YouTube's cookies off the page for the large
   majority of visitors who never press play.
   --------------------------------------------------------------------------- */
.videoblock{margin:clamp(26px,3.4vw,40px) 0 0}
.ytfacade{position:relative;display:block;width:100%;aspect-ratio:16/9;padding:0;
  border:0;border-radius:8px;overflow:hidden;cursor:pointer;background:#0f1419;
  box-shadow:0 1px 0 var(--line),0 18px 40px -28px rgba(15,20,25,.55)}
.ytfacade img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;display:block}
.ytfacade::after{content:"";position:absolute;inset:0;
  background:linear-gradient(0deg,rgba(9,12,16,.6) 0,rgba(9,12,16,.05) 46%)}
.ytplay{position:absolute;left:50%;top:50%;translate:-50% -50%;z-index:2;
  width:74px;height:52px;border-radius:12px;background:rgba(15,20,25,.74);
  border:1px solid rgba(255,255,255,.28);display:grid;place-items:center;
  transition:background .16s ease,scale .16s ease}
.ytplay::before{content:"";width:0;height:0;margin-left:3px;
  border-left:17px solid #fff;border-top:11px solid transparent;border-bottom:11px solid transparent}
.ytfacade:hover .ytplay,.ytfacade:focus-visible .ytplay{background:var(--accent);scale:1.06}
.ytlabel{position:absolute;left:0;right:0;bottom:0;z-index:2;text-align:left;
  padding:16px 18px;color:#fff;font-family:var(--f-sans);font-size:15px;font-weight:600}
.ytframe{width:100%;aspect-ratio:16/9;border:0;border-radius:8px;display:block}
.ytnote{font-size:13px;color:var(--ink-3);line-height:1.55;margin-top:10px}
.ytnote a{color:var(--ink-2);text-decoration:underline;text-underline-offset:2px}

@media (max-width:600px){
  .ytplay{width:60px;height:42px}
  .ytplay::before{border-left-width:14px;border-top-width:9px;border-bottom-width:9px}
  .ytlabel{font-size:14px;padding:12px 14px}
}

/* ---------------------------------------------------------------------------
   Media finder
   ---------------------------------------------------------------------------
   A customer does not arrive asking which tool they want. They arrive with a
   material and a question: can you cut this. So this runs material first, with
   the tooling and the thickness as the answer rather than the heading.

   Built as a theme component rather than as part of the Summa page, because the
   same question gets asked about every manufacturer we sell. A page supplies
   the items and the filters; the behaviour comes from here.

   Progressive enhancement: with no JavaScript it is a readable list of
   materials with their tooling. The script adds the filtering.
   --------------------------------------------------------------------------- */
.mediafinder{margin-top:clamp(26px,3.2vw,38px)}
.mf-controls{display:flex;gap:16px 24px;align-items:center;flex-wrap:wrap;
  padding-bottom:18px;border-bottom:1px solid var(--rule)}
.mf-filters{display:flex;gap:8px;flex-wrap:wrap}
.mf-chip{font-family:var(--f-sans);font-size:13.5px;font-weight:600;color:var(--ink-2);
  background:var(--surface);border:1px solid var(--line);border-radius:999px;
  padding:8px 15px;cursor:pointer;white-space:nowrap;
  transition:border-color .14s ease,color .14s ease,background .14s ease}
.mf-chip:hover{border-color:var(--ink-4);color:var(--ink)}
.mf-chip.is-on{background:var(--ink);border-color:var(--ink);color:#fff}
.mf-search{margin-left:auto;position:relative;flex:0 1 260px;min-width:200px}
.mf-search input{width:100%;font-family:var(--f-sans);font-size:14px;color:var(--ink);
  background:var(--surface);border:1px solid var(--line);border-radius:6px;
  padding:9px 12px 9px 34px}
.mf-search input::placeholder{color:var(--ink-4)}
.mf-search::before{content:"";position:absolute;left:12px;top:50%;translate:0 -50%;
  width:13px;height:13px;border:1.6px solid var(--ink-4);border-radius:50%;
  box-shadow:6px 6px 0 -5.2px var(--ink-4);pointer-events:none}
.mf-count{font-family:var(--f-mono);font-size:12px;letter-spacing:.04em;
  text-transform:uppercase;color:var(--ink-3);margin:14px 0 0}

.mf-grid{list-style:none;margin:6px 0 0;padding:0;display:grid;gap:1px;
  grid-template-columns:repeat(auto-fill,minmax(270px,1fr));background:var(--rule)}
.mf-item{list-style:none;background:var(--surface);padding:20px 20px 18px;
  display:flex;flex-direction:column;gap:9px;transition:background .14s ease}
.mf-item:hover{background:var(--surface-2)}
.mf-item h3{font-family:var(--f-sans);font-size:16px;font-weight:600;color:var(--ink);
  margin:0;line-height:1.35}
.mf-spec{display:flex;gap:10px;align-items:baseline;margin:0;font-size:13.5px;line-height:1.5}
.mf-k{flex:0 0 68px;font-family:var(--f-mono);font-size:11px;letter-spacing:.05em;
  text-transform:uppercase;color:var(--ink-4)}
.mf-spec > span:last-child{color:var(--ink-2)}
.mf-tags{display:flex;gap:6px;flex-wrap:wrap;margin:4px 0 0}
.mf-tags span{font-size:11.5px;font-weight:600;letter-spacing:.02em;color:var(--accent);
  background:rgba(37,99,235,.08);border-radius:3px;padding:3px 7px}
.mf-item[hidden]{display:none}
.mf-empty{margin:22px 0 0;font-size:15px;color:var(--ink-2)}

/* The grid uses a 1px gap over a ruled background to draw the dividing lines,
   which leaves a ragged edge on the last row when it is not full. A generous
   outer rule closes it off. */
.mf-grid{border:1px solid var(--rule)}

@media (max-width:640px){
  .mf-search{margin-left:0;flex:1 1 100%}
  .mf-grid{grid-template-columns:1fr}
}

/* Visually hidden, still read out. Used for labels that the placeholder already
   communicates to sighted users. */
.vh{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;
  clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap;border:0}

/* The ruled-background trick left a grey block where the last row was short of
   a full set of columns. Draw the dividing lines on the cells instead, so an
   unfilled cell draws nothing. */
.mf-grid{gap:0;background:var(--surface)}
.mf-item{box-shadow:inset -1px 0 0 var(--rule),inset 0 -1px 0 var(--rule)}

/* What each industry actually makes, in the manufacturer's own words. Appears
   when a filter is on, so choosing one tells you something rather than only
   taking rows away. */
.mf-notes{margin-top:14px}
.mf-note{display:flex;gap:10px;align-items:baseline;margin:0;
  font-size:13.5px;line-height:1.6;color:var(--ink-2);max-width:92ch}
.mf-note .mf-k{flex:0 0 68px}
.mf-note[hidden]{display:none}
@media (max-width:560px){
  .mf-note{flex-direction:column;gap:4px}
  .mf-note .mf-k{flex:none}
}

/* ---------------------------------------------------------------------------
   Media finder, second pass: consistent tiles and the CMYK splash
   ---------------------------------------------------------------------------
   The first pass let every tile find its own shape, so a two word material sat
   next to a three line one and the rows never lined up. Now each tile has the
   same four parts in the same order, the thickness is a lozenge rather than a
   label and a value, and the tags sit on the floor of the tile whatever height
   the content is.

   The colour is the mark's own CMYK, one quadrant per application, used as an
   identifier rather than decoration: cyan for sign and display, magenta for
   industrial, yellow for packaging, black for textile. Tints for the grounds
   and darkened versions for the text, because the brand colours at 11px on
   white are unreadable.
   --------------------------------------------------------------------------- */
:root{
  --c-sign:#00b4f8;      --c-sign-ink:#0a6f96;   --c-sign-bg:rgba(0,180,248,.12);
  --c-industrial:#e6008c;--c-industrial-ink:#a4046a;--c-industrial-bg:rgba(230,0,140,.10);
  --c-packaging:#c9a400; --c-packaging-ink:#7a6300;--c-packaging-bg:rgba(201,164,0,.17);
  --c-textile:#0f1419;   --c-textile-ink:#0f1419; --c-textile-bg:rgba(15,20,25,.08);
}

.mf-item{padding:0;gap:0;position:relative;box-shadow:inset -1px 0 0 var(--rule),inset 0 -1px 0 var(--rule)}
.mf-item::before{content:"";position:absolute;inset:0 0 auto 0;height:3px;background:var(--ink-4)}
.mf-item[data-app^="sign"]::before{background:var(--c-sign)}
.mf-item[data-app^="industrial"]::before{background:var(--c-industrial)}
.mf-item[data-app^="packaging"]::before{background:var(--c-packaging)}
.mf-item[data-app^="textile"]::before{background:var(--c-textile)}

.mf-body{display:flex;flex-direction:column;gap:12px;height:100%;padding:22px 20px 18px}
.mf-item h3{font-size:16.5px;line-height:1.3;letter-spacing:-.005em;margin:0}

/* The thickness is the number people came for, so it gets to be an object
   rather than a line of prose. */
.mf-thick{display:inline-flex;align-self:flex-start;align-items:center;gap:7px;
  font-family:var(--f-mono);font-size:12.5px;font-weight:500;letter-spacing:-.01em;
  color:var(--ink);background:var(--surface-3);border:1px solid var(--line);
  border-radius:999px;padding:5px 12px 5px 10px;margin:0}
.mf-thick::before{content:"";width:6px;height:6px;border-radius:50%;background:var(--ink-4);flex:none}
.mf-item[data-app^="sign"] .mf-thick::before{background:var(--c-sign)}
.mf-item[data-app^="industrial"] .mf-thick::before{background:var(--c-industrial)}
.mf-item[data-app^="packaging"] .mf-thick::before{background:var(--c-packaging)}
.mf-item[data-app^="textile"] .mf-thick::before{background:var(--c-textile)}

.mf-tool{margin:0;font-size:13.5px;line-height:1.5;color:var(--ink-2)}
.mf-tool b{display:block;font-family:var(--f-mono);font-size:10.5px;font-weight:600;
  letter-spacing:.08em;text-transform:uppercase;color:var(--ink-4);margin-bottom:3px}

/* Pinned to the floor so every tile has its tags on the same line. */
.mf-tags{margin-top:auto;padding-top:4px;gap:5px}
.mf-tags span{font-size:11px;font-weight:600;letter-spacing:.015em;
  border-radius:999px;padding:4px 9px;background:var(--surface-3);color:var(--ink-2)}
.mf-tags span[data-tag="sign"]{background:var(--c-sign-bg);color:var(--c-sign-ink)}
.mf-tags span[data-tag="industrial"]{background:var(--c-industrial-bg);color:var(--c-industrial-ink)}
.mf-tags span[data-tag="packaging"]{background:var(--c-packaging-bg);color:var(--c-packaging-ink)}
.mf-tags span[data-tag="textile"]{background:var(--c-textile-bg);color:var(--c-textile-ink)}

/* An active filter wears its own colour, so the chip and the tiles agree. */
.mf-chip.is-on{background:var(--ink);border-color:var(--ink);color:#fff}
.mf-chip[data-filter="sign"].is-on{background:var(--c-sign-ink);border-color:var(--c-sign-ink)}
.mf-chip[data-filter="industrial"].is-on{background:var(--c-industrial-ink);border-color:var(--c-industrial-ink)}
.mf-chip[data-filter="packaging"].is-on{background:var(--c-packaging-ink);border-color:var(--c-packaging-ink)}
.mf-chip[data-filter="textile"].is-on{background:var(--c-textile-ink);border-color:var(--c-textile-ink)}

.mf-note .mf-k{color:var(--ink-4)}
.mf-note[data-mf-note="sign"] .mf-k{color:var(--c-sign-ink)}
.mf-note[data-mf-note="industrial"] .mf-k{color:var(--c-industrial-ink)}
.mf-note[data-mf-note="packaging"] .mf-k{color:var(--c-packaging-ink)}

/* One thickness string is long enough to wrap the lozenge onto two lines, which
   made its tile 20px taller than its neighbours and floated the dot in the
   middle of nowhere. A lozenge is an object: it stays on one line and gets
   wider, and shrinks its type a touch rather than breaking. */
.mf-thick{white-space:nowrap;max-width:100%;overflow:hidden;text-overflow:ellipsis}
@media (min-width:641px) and (max-width:1100px){
  .mf-thick{font-size:11.5px;padding-inline:9px 10px}
}

/* Ellipsis on a spec is worse than small type on a spec: the whole point of the
   lozenge is the number. Drop a size so the longest string fits whole. */
.mf-thick{font-size:11.5px;letter-spacing:-.005em;padding:5px 11px 5px 9px}
@media (min-width:641px) and (max-width:1100px){.mf-thick{font-size:11.5px}}

/* With the qualifiers moved into the tooling line the lozenge fits at full size
   again, so put the size back. */
.mf-thick{font-size:12.5px;padding:5px 12px 5px 10px;letter-spacing:-.01em}

/* ---------------------------------------------------------------------------
   Media finder, third pass: take things out
   ---------------------------------------------------------------------------
   Six things were competing in a 280px box: a name, a THICKNESS label, a value,
   a TOOLING label, a value, and two tags repeating what the colour bar already
   said. A tile only has to answer two questions, what is it and how thick can
   it go, with the tooling as a quiet third.

   So: labels gone, tags gone from view, colour bar carries the application. The
   tags stay in the markup because the search reads them, they are just not
   drawn. Nothing about the filtering changes.
   --------------------------------------------------------------------------- */
.mf-body{gap:10px;padding:20px 20px 20px}
.mf-item h3{font-size:16px;font-weight:600;line-height:1.35}
.mf-tool{font-size:13px;line-height:1.5;color:var(--ink-3);margin-top:auto}
.mf-tool b{display:none}
.mf-tags{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;
  clip-path:inset(50%);white-space:nowrap}

/* Two applications, two colours, one bar. Cheaper than two more objects in the
   box and it still says which is the primary. */
.mf-item[data-app="sign industrial"]::before{background:linear-gradient(90deg,var(--c-sign) 50%,var(--c-industrial) 50%)}
.mf-item[data-app="sign packaging"]::before{background:linear-gradient(90deg,var(--c-sign) 50%,var(--c-packaging) 50%)}
.mf-item[data-app="packaging sign"]::before{background:linear-gradient(90deg,var(--c-packaging) 50%,var(--c-sign) 50%)}
.mf-item[data-app="industrial packaging"]::before{background:linear-gradient(90deg,var(--c-industrial) 50%,var(--c-packaging) 50%)}

/* ---------------------------------------------------------------------------
   Media finder: Summa's own material taxonomy
   ---------------------------------------------------------------------------
   Rebuilt against Summa's three material pages, which pair each material with a
   module and a tool. Three categories, so three colours rather than four, and
   the lozenge now holds the module rather than a thickness: the module is the
   datum that decides the machine, and Summa quotes it for every material where
   they quote thickness for only a few.
   --------------------------------------------------------------------------- */
:root{
  --c-board:#00b4f8;      --c-board-ink:#0a6f96;      --c-board-bg:rgba(0,180,248,.12);
  --c-flexible:#e6008c;   --c-flexible-ink:#a4046a;   --c-flexible-bg:rgba(230,0,140,.10);
  --c-specialty:#c9a400;  --c-specialty-ink:#7a6300;  --c-specialty-bg:rgba(201,164,0,.17);
}
.mf-item[data-app="board"]::before{background:var(--c-board)}
.mf-item[data-app="flexible"]::before{background:var(--c-flexible)}
.mf-item[data-app="specialty"]::before{background:var(--c-specialty)}
.mf-item[data-app="board"] .mf-thick::before{background:var(--c-board)}
.mf-item[data-app="flexible"] .mf-thick::before{background:var(--c-flexible)}
.mf-item[data-app="specialty"] .mf-thick::before{background:var(--c-specialty)}
.mf-chip[data-filter="board"].is-on{background:var(--c-board-ink);border-color:var(--c-board-ink)}
.mf-chip[data-filter="flexible"].is-on{background:var(--c-flexible-ink);border-color:var(--c-flexible-ink)}
.mf-chip[data-filter="specialty"].is-on{background:var(--c-specialty-ink);border-color:var(--c-specialty-ink)}
.mf-note[data-mf-note="board"] .mf-k{color:var(--c-board-ink)}
.mf-note[data-mf-note="flexible"] .mf-k{color:var(--c-flexible-ink)}
.mf-note[data-mf-note="specialty"] .mf-k{color:var(--c-specialty-ink)}

/* The module is a name, not a measurement, so it sits in sans and carries a
   little more weight than the thickness figures did. */
.mf-thick{font-family:var(--f-sans);font-size:12.5px;font-weight:600;letter-spacing:0;
  color:var(--ink);white-space:normal}
.mf-source{margin:18px 0 0;font-size:12.5px;line-height:1.6;color:var(--ink-3);max-width:80ch}

/* ---------------------------------------------------------------------------
   Restructured Summa page
   ---------------------------------------------------------------------------
   The page is now a route into the range rather than the catalogue, so the
   rhythm has to change between sections instead of repeating one card grid.
   These are the pieces that were only ever styled inline before.
   --------------------------------------------------------------------------- */

/* Range list: a letter, a name, a sentence and a link on one rule. Reads as a
   contents page, which is what it is. */
.rows .row-item .n{font-size:1.7rem;font-weight:700;font-family:var(--f-sans);line-height:1}
#ranges .row-item{grid-template-columns:64px minmax(140px,.7fr) 1.6fr auto;align-items:baseline}
#ranges .row-item .n{color:var(--accent)}
#ranges .row-item:nth-child(4n+1) .n{color:#0e8ec6}
#ranges .row-item:nth-child(4n+2) .n{color:#e6008c}
#ranges .row-item:nth-child(4n+3) .n{color:#9c8000}
#ranges .row-item:nth-child(4n+4) .n{color:var(--ink)}

/* Numbered process steps, three across a top rule. */
.steps{display:grid;grid-template-columns:repeat(3,1fr);margin-top:clamp(30px,3.6vw,46px);
  border-top:2px solid var(--ink)}
.step{padding:26px 28px 8px 0}
.step + .step{padding-left:28px;border-left:1px solid var(--rule)}
.step b{display:block;font-family:var(--f-mono);font-size:12px;font-weight:600;
  letter-spacing:.08em;color:var(--accent);margin-bottom:10px}
.step h3{font-size:1.15rem;font-weight:600;margin:0 0 8px;color:var(--ink)}
.step p{margin:0;font-size:14.5px;line-height:1.6;color:var(--ink-2)}

@media (max-width:900px){
  #ranges .row-item{grid-template-columns:52px 1fr;gap:10px 16px}
  #ranges .row-item p,#ranges .row-item .go{grid-column:2}
  .steps{grid-template-columns:1fr;border-top-width:2px}
  .step{padding:22px 0 6px}
  .step + .step{padding-left:0;border-left:0;border-top:1px solid var(--rule)}
}

/* ---------------------------------------------------------------------------
   Mobile navigation
   ---------------------------------------------------------------------------
   From the GPT build of v0.11.0. The theme had no mobile menu: below 900px the
   nav wrapped onto its own row inside a sticky header, which then ate a third
   of a phone screen. A toggle is the right answer and this is theirs, kept
   close to as written because it was already in the theme's idiom.
   --------------------------------------------------------------------------- */
.nav-toggle{display:none;margin-left:auto;align-items:center;gap:9px;padding:9px 11px;
  border:1px solid var(--line);border-radius:5px;background:#fff;color:var(--ink);
  font-family:var(--f-sans);font-size:13px;font-weight:600;cursor:pointer}
.nav-toggle-icon{display:grid;gap:3px;width:17px}
.nav-toggle-icon i{display:block;height:2px;border-radius:2px;background:currentColor;
  transition:transform .18s ease,opacity .18s ease}

@media (max-width:900px){
  .top-in{position:relative;flex-wrap:nowrap;padding-block:10px}
  .nav-toggle{display:inline-flex;order:2}
  .top-cta{margin-left:0;order:3}
  /* The drawer scrolls, not the page behind it. It was fixed height with
     overflow visible, so the lower half of the menu was unreachable and a
     swipe scrolled the page underneath instead. 30/09/2026 */
  .top .nav{display:none;position:absolute;left:16px;right:16px;top:calc(100% + 1px);
    width:auto;padding:8px;background:#fff;border:1px solid var(--line);border-top:0;
    border-radius:0 0 7px 7px;box-shadow:0 18px 32px -18px rgba(15,20,25,.42);order:4;
    max-height:calc(100dvh - 100%);overflow-y:auto;overscroll-behavior:contain;
    -webkit-overflow-scrolling:touch}
  .top.nav-open .nav{display:block}
  .top .nav-list{display:grid;gap:0}
  /* Top level items only. This used to match every link in the drawer, which
     from 25/09/2026 includes the panel rows, and gave a sub-link the same
     weight and the same divider as the section above it. 25/09/2026 */
  .top .nav-list > li > .nav-link,.top .nav > a{display:block;padding:12px 10px;
    font-size:15px;white-space:normal}
  .top.nav-open .nav-toggle-icon i:nth-child(1){transform:translateY(5px) rotate(45deg)}
  .top.nav-open .nav-toggle-icon i:nth-child(2){opacity:0}
  .top.nav-open .nav-toggle-icon i:nth-child(3){transform:translateY(-5px) rotate(-45deg)}
}

@media (max-width:600px){
  .top-cta{display:none}
  .brand img{height:31px}
  .alert-in{gap:8px 10px;padding-block:9px}
  .alert p{display:none}
  .alert .grp{margin-left:auto;gap:9px}
  .alert .num{font-size:15px}
  .alert .btn{font-size:12px;padding:7px 9px}
}

/* Also from the GPT build, and overdue: honour the operating system setting. */
@media (prefers-reduced-motion:reduce){
  html{scroll-behavior:auto}
  *,*::before,*::after{scroll-behavior:auto!important;
    transition-duration:.01ms!important;animation-duration:.01ms!important}
}

/* On a phone the paired figure was still trying to sit two across, which pushed
   the second picture 36px past the right edge and gave the whole document a
   horizontal scrollbar. One column below 820px. */
@media (max-width:820px){
  .figpair,.split > .figpair{grid-template-columns:1fr;grid-template-rows:auto auto auto}
  .figpair figcaption{grid-column:auto}
}

/* ---------------------------------------------------------------------------
   The 468px hole under every section heading
   ---------------------------------------------------------------------------
   `.split.even-ish` was given a `min-height:clamp(420px,52vh,640px)` back when
   it was only ever the hero's two-column layout. The restructured Summa page
   uses the same class nine times as a section head, heading on the left and a
   short paragraph on the right, so every one of them was being held open to
   468px on a 900px screen. A head whose content is 63px tall was reserving
   seven times that, which is the "unneeded space between sections".

   The min-height belongs to the hero and nothing else.
   --------------------------------------------------------------------------- */
.split.even-ish{min-height:0}
.hero{min-height:clamp(420px,52vh,640px)}

/* A section head is a heading, a sentence and a measured gap to whatever it
   introduces. One rule, so the rhythm is the same down the page. */
/* The standfirst column was .92fr against a 1.08fr heading column: the bigger
   column holding the smaller content, which is why a two word heading left
   half the row empty while the paragraph was pushed past the midpoint. Even
   columns, and a gap that stops growing with the viewport. */
.split.sechead,.split.even-ish.sechead,.split.flip.sechead{
  grid-template-columns:1fr 1fr;gap:clamp(28px,3.4vw,56px)}
/* And it has to give those columns back on a phone.
   The stacking rule for `.split` lives in the 960px block far above this
   one and is a single class; this rule is two classes and comes later, so
   it out-specified the media query and won. Every section head on the site
   was two 161px columns at 390px wide, which is where "Summa is a Belgian
   manufacturer" became one word per line. Same failure as the `.even-ish`
   column re-weight earlier in the month: a later, more specific rule
   silently reaching a context it was never written for. Matched specificity
   and matched position is the fix. */
@media (max-width:960px){
  .split.sechead,.split.even-ish.sechead,.split.flip.sechead{
    grid-template-columns:1fr}
}
.sechead{align-items:start;margin-bottom:clamp(26px,3vw,40px);
  gap:clamp(24px,4vw,64px) clamp(32px,5vw,80px)}
.sechead > div:first-child{padding-top:2px}
.sechead h2{margin-top:6px}
.sechead p{margin:0}

/* Sections were also carrying 52px of their own padding on top of the hole.
   With the hole closed they can breathe properly instead. */
.sec{padding-block:clamp(56px,6.4vw,92px)}
.sec.tight{padding-block:clamp(44px,5vw,68px)}

/* The block a section head introduces sets its own top margin; with the head
   now carrying the gap, those double up. */
.sechead + .mediafinder,
.sechead + .rows,
.sechead + .steps,
.sechead + .videoblock{margin-top:0}

/* ---------------------------------------------------------------------------
   Figures on a light ground
   ---------------------------------------------------------------------------
   The `.figs` block belongs to the navy band: its rules are #32496b, which is a
   navy hairline. Dropping it onto the light support section and overriding the
   colour inline gave it a heavy frame and pushed the first number off the text
   edge, so the numbers no longer lined up with the paragraph above them.

   This is the light version, written as its own thing rather than as an
   override. Four figures on one line, a hairline top and bottom, thin dividers
   between, and the first number flush with the column's text edge.
   --------------------------------------------------------------------------- */
.statrow{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));
  margin-top:clamp(28px,3.4vw,42px);
  border-top:1px solid var(--rule);border-bottom:1px solid var(--rule)}
.stat{padding:18px 18px 18px 0}
.stat + .stat{padding-left:20px;box-shadow:inset 1px 0 0 var(--rule)}
.stat b{display:block;font-family:var(--f-cond);font-weight:600;
  font-size:clamp(1.55rem,2.2vw,2.05rem);line-height:1.05;letter-spacing:-.035em;
  color:var(--ink);font-variant-numeric:tabular-nums}
.stat span{display:block;margin-top:5px;font-size:12.5px;line-height:1.45;color:var(--ink-3)}

@media (max-width:1100px){
  .statrow{grid-template-columns:repeat(2,minmax(0,1fr))}
  .stat{padding:16px 16px 16px 0;box-shadow:none}
  .stat:nth-child(even){padding-left:20px;box-shadow:inset 1px 0 0 var(--rule)}
  .stat:nth-child(-n+2){border-bottom:1px solid var(--rule)}
}
@media (max-width:420px){
  .statrow{grid-template-columns:1fr}
  .stat,.stat:nth-child(even){padding:14px 0;box-shadow:none}
  .stat + .stat{border-top:1px solid var(--rule)}
  .stat:nth-child(-n+2){border-bottom:0}
}

/* ---------------------------------------------------------------------------
   Application guide
   ---------------------------------------------------------------------------
   The quick version: four applications, one suggested starting point. The full
   material and tooling reference is its own page, linked from here, because it
   answers a different question and a landing page should not try to answer
   both at once.
   --------------------------------------------------------------------------- */
.chooser{display:grid;grid-template-columns:minmax(0,.8fr) minmax(0,1.2fr);
  border:1px solid var(--line);background:var(--surface)}
.chooser-ask{padding:clamp(24px,3vw,34px);background:var(--surface-2);
  border-right:1px solid var(--line)}
.chooser-ask h3{font-size:1.2rem;font-weight:600;color:var(--ink);margin:0 0 6px}
.chooser-ask > p{margin:0;font-size:14.5px;color:var(--ink-2)}
.chooser-list{display:grid;gap:9px;margin-top:22px}
.choice{text-align:left;padding:14px 16px;font-family:var(--f-sans);font-size:15px;
  font-weight:600;color:var(--ink);background:var(--surface);
  border:1px solid var(--line);border-radius:4px;cursor:pointer;
  transition:background .14s ease,border-color .14s ease,color .14s ease}
.choice:hover{border-color:var(--ink-4)}
.choice.is-on{background:var(--navy,#0b213d);border-color:var(--navy,#0b213d);color:#fff}

.chooser-result{padding:clamp(26px,3.6vw,42px);display:flex;flex-direction:column;
  justify-content:center}
.chooser-result h3{font-family:var(--f-cond);font-weight:600;
  font-size:clamp(1.5rem,2.6vw,2.15rem);letter-spacing:-.03em;color:var(--ink);
  margin:10px 0 12px;line-height:1.1}
.chooser-result > p{margin:0;color:var(--ink-2);line-height:1.65;max-width:62ch}
.chooser-detail{margin-top:18px!important;padding-top:16px;
  border-top:1px solid var(--line);font-size:14.5px}
.chooser-detail b{color:var(--ink)}
.chooser-links{display:flex;gap:22px;flex-wrap:wrap;margin-top:22px!important}

@media (max-width:900px){
  .chooser{grid-template-columns:1fr}
  .chooser-ask{border-right:0;border-bottom:1px solid var(--line)}
}

/* ---------------------------------------------------------------------------
   Support section on navy
   ---------------------------------------------------------------------------
   Numbered, ruled, and image-led. The numbers are amber because on navy they
   are the only warm thing on the page and they mark the sequence without
   shouting.
   --------------------------------------------------------------------------- */
.support-grid{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);
  gap:clamp(40px,6vw,96px);align-items:center}
.support .support-lead{color:#c7d2de;font-size:1.06rem;line-height:1.7;margin:16px 0 0;max-width:52ch}
.support-list{list-style:none;margin:clamp(28px,3.4vw,40px) 0 0;padding:0;
  border-top:1px solid #33496a}
.support-list li{display:grid;grid-template-columns:44px 1fr;gap:10px;
  padding:16px 0;border-bottom:1px solid #33496a}
.support-list b{font-family:var(--f-mono);font-size:13px;font-weight:600;color:var(--amber)}
.support-list strong{display:block;color:#fff;font-size:15.5px;font-weight:600}
.support-list span{display:block;margin-top:3px;color:#b9c7d8;font-size:14.5px;line-height:1.55}

.support-images{display:grid;grid-template-columns:1fr 1fr;gap:12px}
.support-shot{position:relative;overflow:hidden;border-radius:4px;background:#0d1b2e;
  aspect-ratio:4/3}
.support-shot.wide{grid-column:1/-1;aspect-ratio:16/9}
.support-shot img,.support-shot .shot{position:absolute;inset:0;width:100%;height:100%;
  object-fit:cover;display:block}
.support-shot .media-missing{position:absolute;inset:0;width:100%;height:100%;border-radius:0}
.support-note{margin:clamp(24px,3vw,34px) 0 0;font-size:12.5px;line-height:1.55;color:#8fa3bb;max-width:80ch}

@media (max-width:900px){
  .support-grid{grid-template-columns:1fr}
  .support-list li{grid-template-columns:36px 1fr}
}

/* Four facts under a featured system. Same hairline language as the stat row,
   but these carry a sentence rather than a number, so they get more room. */
.specpairs{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));
  margin-top:clamp(28px,3.4vw,40px);border-top:1px solid var(--rule)}
.spec{padding:18px 26px 18px 0;border-bottom:1px solid var(--rule)}
.spec:nth-child(even){padding-left:26px;box-shadow:inset 1px 0 0 var(--rule)}
.spec b{display:block;font-family:var(--f-mono);font-size:10.5px;font-weight:600;
  letter-spacing:.08em;text-transform:uppercase;color:var(--ink-3);margin-bottom:6px}
.spec span{display:block;font-size:14.5px;line-height:1.6;color:var(--ink-2)}
@media (max-width:760px){
  .specpairs{grid-template-columns:1fr}
  .spec,.spec:nth-child(even){padding:16px 0;box-shadow:none}
}

/* ---------------------------------------------------------------------------
   Featured system: picture and facts side by side
   ---------------------------------------------------------------------------
   A heading, one paragraph and a video read as an unfinished section. The
   machine goes on the left at a size worth looking at, the facts sit beside it,
   and the film follows underneath.

   The product shots are cut outs on white, so the panel is white rather than
   grey and the image is contained rather than cropped. Cropping a machine to
   fill a box is how you end up showing somebody half a gantry.
   --------------------------------------------------------------------------- */
.feature{display:grid;grid-template-columns:minmax(0,.95fr) minmax(0,1.05fr);
  gap:clamp(32px,5vw,72px);align-items:center}
.feature-shot{position:relative;background:#fff;border:1px solid var(--rule);
  border-radius:4px;aspect-ratio:1/1;overflow:hidden}
.feature-shot img,.feature-shot .shot{position:absolute;inset:0;width:100%;height:100%;
  object-fit:contain;padding:clamp(18px,2.6vw,34px);display:block}
.feature-shot .media-missing{position:absolute;inset:0;width:100%;height:100%;border-radius:0}
.feature-copy .specpairs{margin-top:clamp(22px,2.6vw,30px)}

@media (max-width:900px){
  .feature{grid-template-columns:1fr}
  .feature-shot{aspect-ratio:4/3;order:2}
  .feature-copy{order:1}
}

/* Referential-use small print, inside the band it qualifies rather than
   floating between the last section and the footer.

   `max-width:90ch` was wrong here: at 12px that resolves to about 490px, so the
   line read as a narrow column pinned under the left hand copy with a large
   void beside it. Small print at the foot of a band should run the width of the
   band and be two lines, not five. */
.smallprint{margin:clamp(24px,3vw,34px) 0 0;padding-top:16px;
  border-top:1px solid var(--line);
  font-size:12.5px;line-height:1.65;color:var(--ink-3);max-width:none}
/* The dark band variant. This used to be the base, which is why smallprint
   on a light section rendered at 2.6:1. */
.alert .smallprint,.sec.dark .smallprint,.ed.navy .smallprint,.bleed .smallprint,
.close .smallprint,.hero-split .smallprint,.hero-photo .smallprint{
  border-top-color:rgba(255,255,255,.14);color:#8ea2ba}

/* ---------------------------------------------------------------------------
   Action at the end of a section
   ---------------------------------------------------------------------------
   A primary action that follows a full width block belongs at the end of it,
   not tucked under the first column where it reads as part of that column.
   This matches the closing navy band, which already puts its buttons on the
   right, and leaves the hero alone: a button directly under body copy stays
   with the copy.

   On a phone there is only one column, so it goes full width and the argument
   disappears.
   --------------------------------------------------------------------------- */
.section-actions{display:flex;align-items:center;justify-content:flex-end;
  gap:clamp(20px,3vw,40px);flex-wrap:wrap;margin-top:clamp(26px,3vw,38px)}
.section-actions-note{margin:0;margin-right:auto;font-size:14.5px;line-height:1.6;
  color:var(--ink-3);max-width:46ch}
@media (max-width:700px){
  .section-actions{justify-content:stretch;flex-direction:column;align-items:stretch}
  .section-actions-note{margin-right:0}
  .section-actions .btn{text-align:center}
}

/* `.bleed p` sets `max-width:48ch`, which at 12px is 310px, so the small print
   was being held to a narrow column by a rule written for body copy in the same
   band. Same class of mistake as the figures panel: a rule meant for one thing
   reaching something else. Beat it on specificity rather than with !important. */
.bleed .smallprint,.ed.navy .smallprint{max-width:none;color:#8ea2ba}

/* ---------------------------------------------------------------------------
   Support images: fill the band rather than stopping short
   ---------------------------------------------------------------------------
   The image stack was sized by three fixed aspect ratios, so its height came
   from the column width and had nothing to do with the copy beside it. On a
   long list that left a slab of navy under the pictures.

   Same fault as the paired figure earlier in the week. The column now stretches
   to the row and the two rows share the height; the pictures crop rather than
   dictate. Their intrinsic height is nil, because the images inside are
   absolutely positioned, so the row is driven by the copy, which is what should
   be setting it.
   --------------------------------------------------------------------------- */
.support-grid{align-items:stretch}
.support-images{height:100%;grid-template-rows:minmax(0,1.32fr) minmax(0,1fr);
  align-content:stretch}
.support-shot{aspect-ratio:auto;min-height:0;height:100%}
.support-shot.wide{aspect-ratio:auto}

@media (max-width:900px){
  .support-grid{align-items:start}
  .support-images{height:auto;grid-template-rows:auto auto}
  .support-shot{aspect-ratio:4/3;height:auto}
  .support-shot.wide{aspect-ratio:16/9}
}

/* ---------------------------------------------------------------------------
   Closing band
   ---------------------------------------------------------------------------
   Rebuilt to the proportions in the GPT concept, which Dean preferred and which
   are better: a near black ground rather than the mid navy, a heading given
   room to be a heading, the sentence running its natural width underneath, and
   two solid buttons instead of one solid and one outlined.

   The mid navy was the problem. It is the same navy as the support band further
   up, so the page ended on a colour it had already used, and the heading was
   held to 16ch fighting for space with the buttons. Near black reads as the end
   of the page and hands over to the footer.
   --------------------------------------------------------------------------- */
.close{background:#0a1724;color:#fff;padding-block:clamp(48px,5.6vw,76px)}
.close-row{display:grid;grid-template-columns:minmax(0,1.35fr) minmax(0,auto);
  gap:clamp(28px,4vw,60px);align-items:center}
.close h2{font-family:var(--f-cond);font-weight:600;color:#fff;
  font-size:clamp(1.9rem,3.4vw,2.9rem);line-height:1.08;letter-spacing:-.032em;
  margin:0;max-width:22ch;text-wrap:balance}
.close-row > div > p{margin:14px 0 0;color:#b9c7d8;font-size:1rem;line-height:1.6;max-width:none}
.close-actions{display:flex;gap:12px;flex-wrap:wrap}

/* A solid light button reads as a second real action. The outlined version
   disappeared against a dark ground at this size. */
.btn.light{background:#fff;border-color:#fff;color:#0a1724}
.btn.light:hover{background:#e8edf3;border-color:#e8edf3;color:#0a1724}

.close .smallprint{margin-top:clamp(30px,3.6vw,44px);padding-top:16px;
  border-top:1px solid rgba(255,255,255,.12);color:#7f93ab;max-width:none}

@media (max-width:820px){
  .close-row{grid-template-columns:1fr}
  .close-actions{margin-top:4px}
  .close-actions .btn{flex:1 1 auto;text-align:center}
}

/* ---------------------------------------------------------------------------
   Full bleed bands with more than one row
   ---------------------------------------------------------------------------
   The gutter was applied with :first-child and :last-child, which is right for
   a band of two cells and wrong for anything taller. The homepage equipment
   panel is two by two, so only the top left and bottom right corners lined up
   with the page; the other two sat 63px inside it.

   In a two column grid, odd children are the left column and even ones the
   right, whatever the row count. Same result for a single row, correct for
   four cells.
   --------------------------------------------------------------------------- */

/* The homepage hero was padded against a 1200px wrap while the site wrap is
   1240, so its copy started 20px left of every heading below it. */
/* .home-hero-copy is gone: the homepage hero now uses the same .hero-split
   component as every other section page, so it uses .hero-split-copy with it.
   Removed 18/09/2026 rather than left behind for somebody to wonder about. */

/* ---------------------------------------------------------------------------
   Chooser: stop the panel resizing between answers
   ---------------------------------------------------------------------------
   The result panel sized itself to whichever recommendation was showing, so
   clicking through the four applications made the box grow and shrink and
   walked the heading down the screen. A minimum height taken from the tallest
   of the four states holds it still, and the heading gets a fixed slot so every
   answer starts on the same line.

   The number below is measured, not guessed: the four states render at 268,
   252, 268 and 268 at 1440, and taller as the column narrows.
   --------------------------------------------------------------------------- */
.chooser-result{min-height:clamp(300px,26vw,340px)}
.chooser-result h3{min-height:2.35em;display:flex;align-items:flex-start}
.chooser-result > p[data-result-copy]{min-height:4.9em}
@media (max-width:900px){
  .chooser-result{min-height:0}
  .chooser-result h3,.chooser-result > p[data-result-copy]{min-height:0}
}

/* An internal review note. Deliberately ugly: it must never be mistaken for
   page content by the person reading the page or by the person writing it. */
.dn-note{display:block;margin:14px 0;padding:10px 14px;
  background:rgba(255,176,87,.14);border:1px dashed rgba(180,120,40,.6);
  border-radius:4px;font-size:13px;line-height:1.55;color:#5c3d00}
.dn-note b{display:block;font-family:var(--f-mono);font-size:10.5px;font-weight:600;
  letter-spacing:.08em;text-transform:uppercase;color:#6b4700;margin-bottom:3px}

/* Five-step engagement row. Same language as the three-step process, one more
   column, and it collapses earlier because five columns of prose is unreadable
   below about a thousand pixels. */
@media (max-width:1100px){
  .steps[style*="repeat(5"]{grid-template-columns:repeat(2,1fr)!important}
  .steps[style*="repeat(5"] .step + .step{padding-left:28px;border-left:1px solid var(--rule)}
  .steps[style*="repeat(5"] .step:nth-child(odd){padding-left:0;border-left:0}
}
@media (max-width:700px){
  .steps[style*="repeat(5"]{grid-template-columns:1fr!important}
  .steps[style*="repeat(5"] .step,.steps[style*="repeat(5"] .step:nth-child(odd){
    padding-left:0;border-left:0;border-top:1px solid var(--rule)}
}

/* ---- Section butting onto a colour band -------------------------------
   A light section carries its own bottom padding, then the band that
   follows carries its top padding, and the two stack into a hole. Most
   visible where the colour changes, because you see the full height of the
   trailing padding as an empty white strip. Trim the trailing one only when
   a full width band comes next; the band supplies the breathing room. */
.ed:has(+ .ed.navy),.ed:has(+ .close),.sec:has(+ .ed.navy),.sec:has(+ .close){padding-bottom:clamp(40px,4.4vw,64px)}

/* ---- Long button labels on narrow screens -----------------------------
   .btn is white-space:nowrap, which is right at desktop sizes and wrong on
   a phone: one long label ("Discuss your coverage requirement") sets the
   min-content width of its row and pushes the whole page sideways. Poppins
   sets about 23% wider than Archivo, so labels that just fitted no longer
   do. Let the text wrap below the phone breakpoint instead. */
@media (max-width:560px){
  .btn{white-space:normal;text-wrap:balance;text-align:center}
}

/* ---- Front end forms --------------------------------------------------
   The fault report. Two rules govern it.

   One: a form that spans a 1240px wrap is unreadable. A 700px wide box for
   a model number gives the eye nowhere to land and the two columns end up
   so far apart they stop reading as a pair. The form sits in its own
   column with a panel beside it, and every field is sized to what goes in
   it rather than to the grid.

   Two: the groups are numbered 01 to 04 and match the four numbered points
   on the page above it, in the same order and with the same words. The page
   is the instructions, the form is the thing. */
.formwrap{display:grid;grid-template-columns:minmax(0,1fr) 300px;gap:clamp(24px,3vw,44px);
  align-items:start;margin-top:clamp(28px,3.4vw,42px)}
.dnform{background:#fff;border:1px solid var(--line-2);border-radius:8px;
  padding:clamp(22px,2.4vw,32px);box-shadow:var(--shadow)}
.dnform-hp{position:absolute;left:-9999px;width:1px;height:1px;overflow:hidden}

/* Context carried in from the link that brought them here. */
.dnform-re{margin:0 0 20px;padding:10px 14px;background:var(--info-bg);border-radius:5px;
  font-size:13.5px;color:var(--ink-2)}
.dnform-re b{color:var(--ink)}
.dnform-set{border:0;margin:0;padding:0 0 26px}
.dnform-set + .dnform-set{border-top:1px solid var(--line);padding-top:26px}
.dnform-set:last-of-type{padding-bottom:6px}
.dnform-set legend{float:left;width:100%;padding:0;margin:0 0 18px;display:flex;
  align-items:baseline;gap:12px}
.dnform-set legend b{font-family:var(--f-mono);font-size:13px;font-weight:600;
  color:var(--accent);letter-spacing:.04em}
.dnform-set legend span{font-family:var(--f-cond);font-size:1.12rem;font-weight:600;
  letter-spacing:-.01em;color:var(--ink)}

.dnform-grid{clear:both;display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:20px}
.dnform-field{display:flex;flex-direction:column;gap:6px;min-width:0}
.dnform-field.is-full{grid-column:1/-1}
.dnform-field label,.dnform-label{font-size:13.5px;font-weight:600;color:var(--ink);line-height:1.3}
.dnform-field label em,.dnform-label em{font-style:normal;font-weight:400;font-size:11.5px;
  color:var(--ink-3);letter-spacing:.02em}
.dnform-field input,.dnform-field textarea{font-family:var(--f-sans);font-size:15px;color:var(--ink);
  background:var(--surface-2);border:1px solid var(--line-2);border-radius:5px;padding:11px 13px;
  width:100%;box-sizing:border-box;line-height:1.5;transition:border-color .12s,background .12s}
.dnform-field textarea{resize:vertical;min-height:88px}
.dnform-field input:focus,.dnform-field textarea:focus{outline:2px solid var(--accent);
  outline-offset:1px;border-color:var(--accent);background:#fff}
.dnform-field.has-err input,.dnform-field.has-err textarea{border-color:#c0392b;background:#fdf7f6}
/* Where the group heading already says it, the label stays for screen
   readers and comes off the page. */
.dnform-field label.is-sr,.dnform-label.is-sr{position:absolute;width:1px;height:1px;
  overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}
.dnform-hint{font-size:12.5px;color:var(--ink-3);line-height:1.45}
.dnform-err{font-size:12.5px;font-weight:600;color:#b32d2e}

/* Segmented choice. Big enough to hit with a thumb in a factory, and the
   stopped option colours itself so the answer is visible at a glance. */
.dnform-seg{display:grid;gap:8px}
.dnform-seg.cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}
.dnform-seg.cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}
/* Four options, as on the machine enquiry form. Two by two rather than four
   across, because four labels in one row wrap to two lines each on a laptop. */
.dnform-seg.cols-4{grid-template-columns:repeat(2,minmax(0,1fr))}
.dnform-opt{position:relative;display:flex;align-items:center;justify-content:center;
  text-align:center;min-height:52px;padding:8px 12px;border:1px solid var(--line-2);
  border-radius:6px;background:var(--surface-2);cursor:pointer;
  font-size:14px;font-weight:600;color:var(--ink-2);line-height:1.3;
  transition:border-color .12s,background .12s,color .12s}
.dnform-opt input{position:absolute;opacity:0;width:1px;height:1px}
.dnform-opt:hover{border-color:var(--ink-3);background:#fff}
.dnform-opt:has(input:checked){border-color:var(--accent);background:var(--info-bg);color:var(--ink)}
.dnform-opt:has(input:focus-visible){outline:2px solid var(--accent);outline-offset:2px}
.dnform-opt.opt-stopped:has(input:checked){border-color:#b32d2e;background:#fdecec;color:#8a2020}

.dnform-actions{display:flex;align-items:center;gap:18px;flex-wrap:wrap;
  border-top:1px solid var(--line);margin-top:4px;padding-top:22px}
.dnform-note{font-size:13px;color:var(--ink-3);line-height:1.5}

/* The panel beside it. Carries the phone number, because a stopped machine
   should not be filling in a form at all. */
.formside{display:flex;flex-direction:column;gap:14px;position:sticky;top:96px}
.formside-card{background:var(--surface-3);border-radius:8px;padding:20px 22px}
.formside-card p{margin:0;font-size:13.5px;line-height:1.6;color:var(--ink-2)}
.formside-num{font-family:var(--f-mono);font-size:1.28rem;font-weight:600;letter-spacing:-.01em;
  color:var(--ink)!important;margin:10px 0 10px!important}
.formside-steps{margin:12px 0 0;padding-left:18px;font-size:13.5px;line-height:1.6;color:var(--ink-2)}
.formside-steps li + li{margin-top:9px}

.formerr-top{background:#fdecec;border:1px solid #e8b4b4;color:#8a2020;border-radius:5px;
  padding:12px 15px;font-size:14.5px;margin:0 0 22px}
.formdone{background:#fff;border:1px solid var(--line-2);border-left:3px solid var(--accent);
  border-radius:8px;padding:28px 30px;margin-top:clamp(28px,3.4vw,42px);max-width:66ch;
  box-shadow:var(--shadow)}
.formdone-head{font-family:var(--f-cond);font-size:1.32rem;font-weight:600;color:var(--ink);margin:0 0 10px}
.formdone p{margin:0;font-size:15px;line-height:1.7;color:var(--ink-2)}

@media (max-width:1000px){
  .formwrap{grid-template-columns:1fr}
  /* Handover 17/09/2026: on mobile the form comes first and the supporting
     boxes follow it. The phone number is already in the sticky alert bar at
     the top of every page, so a stopped machine still has the number in
     reach without pushing the form down. */
  .formside{position:static;flex-direction:row;flex-wrap:wrap}
  .formside-card{flex:1 1 260px}
}
@media (max-width:620px){
  .dnform-grid{grid-template-columns:1fr}
  .dnform-seg.cols-2,
  .dnform-seg.cols-3,
  .dnform-seg.cols-4{grid-template-columns:1fr}
  .dnform-opt{min-height:46px;justify-content:flex-start;text-align:left}
  .formside{flex-direction:column}
}

/* ---- Plain links inside dark bands ------------------------------------
   a{color:var(--accent)} is set on the anchor itself, so it beats any
   colour inherited from the band around it. A phone number dropped into a
   navy band with [dn_phone link="1"] therefore rendered accent blue on
   navy: barely readable, and it looked like a formatting fault because it
   was one. Styled components (.btn, .tlink, .arrow) already handle their
   own colour on dark, so they are excluded. */
.alert a:not(.btn):not(.tlink):not(.arrow),
.sec.dark a:not(.btn):not(.tlink):not(.arrow),
.ed.navy a:not(.btn):not(.tlink):not(.arrow),
.bleed .c a:not(.btn):not(.tlink):not(.arrow),
.close a:not(.btn):not(.tlink):not(.arrow),
.hero-photo a:not(.btn):not(.tlink):not(.arrow),
.hero-split a:not(.btn):not(.tlink):not(.arrow){color:inherit}
.alert a:not(.btn):not(.tlink):not(.arrow):hover,
.sec.dark a:not(.btn):not(.tlink):not(.arrow):hover,
.ed.navy a:not(.btn):not(.tlink):not(.arrow):hover,
.bleed .c a:not(.btn):not(.tlink):not(.arrow):hover,
.close a:not(.btn):not(.tlink):not(.arrow):hover,
.hero-photo a:not(.btn):not(.tlink):not(.arrow):hover,
.hero-split a:not(.btn):not(.tlink):not(.arrow):hover{color:#fff;text-decoration:underline;text-underline-offset:3px}

/* Internal notes on a dark band. The amber-on-cream note was built for light
   sections; dropped into a navy one it fell to 1.4:1. Same fault as the
   smallprint above, so it gets the same treatment rather than a one-off. */
.sec.dark .dn-note,.ed.navy .dn-note,.bleed .dn-note,.close .dn-note,.hero-split .dn-note{
  background:rgba(255,176,87,.15);border-color:rgba(255,196,120,.5);color:#ffdcab}
.sec.dark .dn-note b,.ed.navy .dn-note b,.bleed .dn-note b,.close .dn-note b,.hero-split .dn-note b{
  color:#ffb057}

/* ---- End of page call to action band ----------------------------------
   Four pages hand-rolled this as an inline grid, which meant no media
   query could reach it: inline styles beat every selector. At 390px the
   phone number is nowrap at 22px and pushed the page 8px sideways. One
   class, one place to change it, and it stacks when it has to. */
.ctaband{display:grid;grid-template-columns:1fr auto;gap:30px;align-items:center}
.ctaband .num{font-family:var(--f-mono);font-size:clamp(1.3rem,3vw,2.2rem);font-weight:600;
  color:#fff;white-space:nowrap;line-height:1.1}
@media (max-width:760px){
  .ctaband{grid-template-columns:1fr;gap:20px}
  .ctaband .num{font-size:clamp(1.4rem,7vw,2rem)}
}

/* ---- Section head above a rows list -----------------------------------
   The intro paragraph sat in the right half of a two column split, while
   the row descriptions below it sat in the third column of a four column
   grid. Two different left edges in what reads as one column of text.

   Rather than nudge one to match the other, a section head immediately
   followed by a .rows list borrows that list's grid, so the intro lands in
   the description column by construction. Change the row grid later and
   this follows it. */
@media (min-width:961px){
  .sechead:has(+ .rows){grid-template-columns:62px .8fr 1.35fr auto;gap:24px}
  .sechead:has(+ .rows) > *:first-child{grid-column:1 / 3}
  .sechead:has(+ .rows) > *:last-child{grid-column:3 / 5}
  .sechead:has(+ .rows) > *:last-child > *{max-width:62ch}
}

/* ---- Official partners row --------------------------------------------
   The names were eleven copies of the same inline style, and the note
   under them carried max-width:92ch while the names ran the full panel.
   Two different right edges in one block, which is what made it read as a
   box sitting inside a wider panel. The note now runs to the same width as
   the names it is explaining. */
.oemrow{display:flex;flex-wrap:wrap;gap:12px 26px;align-items:baseline;margin-top:16px}
/* --ink-4 is a de-emphasis grey for dark grounds. On the paper band these
   measured 2.38:1, and at 21px semibold they need 4.5. They are links and
   they are the content of the panel, so they get a readable colour. */
.oemrow a{font-family:var(--f-cond);font-size:21px;font-weight:600;color:var(--ink-3);
  letter-spacing:.01em;white-space:nowrap;transition:color .12s}
.oemrow a:hover{color:var(--ink-2)}
.oemnote{font-size:13.5px;color:var(--ink-3);line-height:1.65;max-width:none;margin-top:18px}
@media (max-width:680px){
  .oemrow{gap:10px 22px}
  .oemrow a{font-size:19px}
}

/* The partners band leads with a statement now rather than a label. A kicker
   is 11.5px uppercase tracked at .14em, which is built for two or three words
   and falls apart across a sentence, so this is a proper heading. */
.oemhead{font-family:var(--f-cond);font-weight:600;color:var(--ink);margin:0;
  font-size:clamp(1.15rem,1.85vw,1.5rem);letter-spacing:-.012em;line-height:1.3;max-width:34ch}

/* ---- Footer balance and legal row -------------------------------------
   Handover 17/09/2026: first column left, middle columns centred within
   their own tracks, last column right. Stacks and left aligns on mobile,
   because centred text in a narrow column is harder to scan. */
@media (min-width:861px){
  footer.site .foot-grid > div:nth-child(2),
  footer.site .foot-grid > div:nth-child(3){text-align:center}
  footer.site .foot-grid > div:nth-child(2) .foot-h,
  footer.site .foot-grid > div:nth-child(3) .foot-h{text-align:center}
  footer.site .foot-grid > div:last-child{text-align:right}
  footer.site .foot-grid > div:last-child .foot-h{text-align:right}
}
.foot-legal{display:flex;flex-wrap:wrap;gap:10px 26px;align-items:center;
  border-top:1px solid #2a3440;margin-top:34px;padding-top:22px}
.foot-legal a,.foot-legal button{font-size:13.5px;color:#aebbc8;background:none;
  border:0;padding:7px 0;cursor:pointer;font-family:inherit;display:inline-flex;align-items:center;min-height:32px}
.foot-legal a:hover,.foot-legal button:hover{color:#fff}
@media (max-width:860px){
  footer.site .foot-grid > div{text-align:left}
}


/* ---- Pre-footer action strip -----------------------------------------
   Handover 17/09/2026: the blue CTA above the footer read as detached.
   Compact strip, less vertical padding, headline plus one sentence plus
   the number and the action. Suppressed entirely on Report a fault,
   where it duplicates the whole point of the page. */
.ed.tightish.navy{padding-block:clamp(30px,3.2vw,44px)}
.ctaband h2.big{font-size:clamp(1.35rem,2.1vw,1.85rem);margin-bottom:6px}
.ctaband p{font-size:15px;line-height:1.55}
.ctaband .num{font-size:clamp(1.2rem,2.4vw,1.7rem)}
body.page-report-an-issue .ed.tightish.navy,
body.page-report-an-issue .close{display:none}

/* ---- Parts shop -------------------------------------------------------
   Native WooCommerce output, styled to the site. Nothing here depends on
   the old page builder. */
.shop-search{display:flex;gap:10px;flex-wrap:wrap;margin-top:clamp(26px,3vw,36px)}
.shop-search input[type=search]{flex:1 1 320px;min-width:0;font-family:var(--f-sans);
  font-size:15px;padding:12px 14px;border:1px solid var(--line-2);border-radius:5px;
  background:var(--surface-2);color:var(--ink)}
.shop-search input[type=search]:focus{outline:2px solid var(--accent);outline-offset:1px;background:#fff}
.shop-cats{display:grid;grid-template-columns:repeat(auto-fill,minmax(210px,1fr));gap:12px;
  margin-top:clamp(22px,2.6vw,30px)}
.shop-cat{display:flex;flex-direction:column;gap:3px;padding:16px 18px;background:var(--surface-2);
  border:1px solid var(--line-2);border-radius:7px;transition:border-color .12s,background .12s}
.shop-cat:hover{border-color:var(--accent);background:#fff}
.shop-cat b{font-size:15px;color:var(--ink)}
.shop-cat span{font-size:13px;color:var(--ink-3)}
.shop-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(230px,1fr));gap:18px;
  margin-top:clamp(26px,3vw,36px)}
.shop-card{background:#fff;border:1px solid var(--line-2);border-radius:8px;overflow:hidden;
  transition:border-color .12s,box-shadow .12s}
.shop-card:hover{border-color:var(--accent);box-shadow:var(--shadow)}
.shop-card-link{display:flex;flex-direction:column;height:100%;color:inherit}
.shop-card-img{display:block;width:100%;aspect-ratio:4/3;object-fit:cover;background:var(--surface-3)}
.shop-card-img.is-empty{background:var(--surface-3)}
.shop-card-body{padding:16px 18px 18px;display:flex;flex-direction:column;gap:8px;flex:1}
.shop-card-body h3{font-size:15.5px;font-weight:600;line-height:1.35;margin:0;color:var(--ink)}
.shop-card-meta{margin:0}
.shop-card-meta .pill.ok{background:#e3f2e8;color:#155c2e}
.shop-card-meta .pill.warn{background:var(--warn-bg);color:var(--warn)}
.shop-card-price{margin:auto 0 0;font-size:15px;font-weight:600;color:var(--ink)}
.shop-card-price del{font-weight:400;color:var(--ink-3);margin-right:6px}
.shop-empty{background:var(--surface-2);border:1px solid var(--line-2);border-radius:8px;
  padding:26px 28px;margin-top:clamp(26px,3vw,36px);max-width:62ch}
.shop-empty-head{font-family:var(--f-cond);font-size:1.18rem;font-weight:600;color:var(--ink);margin:0 0 8px}
.shop-empty p{margin:0;font-size:15px;line-height:1.7;color:var(--ink-2)}

/* ---- Careers ----------------------------------------------------------
   Listing, single vacancy and the no vacancy state. Styled here rather
   than in the plugin so vacancies look like the rest of the site. */
.dnc-list{margin-top:clamp(28px,3.4vw,42px);border-top:1px solid var(--rule)}
.dnc-item{display:grid;grid-template-columns:1.5fr 1fr;gap:24px;padding:26px 0;
  border-bottom:1px solid var(--rule);align-items:start}
.dnc-item h3{font-size:1.28rem;font-weight:600;margin:0 0 6px;letter-spacing:-.012em}
.dnc-item h3 a{color:var(--ink)}
.dnc-item h3 a:hover{color:var(--accent)}
.dnc-dept{font-family:var(--f-mono);font-size:11px;font-weight:600;letter-spacing:.12em;
  text-transform:uppercase;color:var(--ink-3);margin:0 0 8px}
.dnc-sum{margin:0;font-size:15px;line-height:1.65;color:var(--ink-2);max-width:56ch}
.dnc-facts{list-style:none;margin:0 0 12px;padding:0;display:flex;flex-direction:column;gap:5px}
.dnc-facts li{font-size:14px;color:var(--ink-2)}
.dnc-facts-grid{margin-top:clamp(24px,3vw,34px)}
.dnc-ul{margin:12px 0 26px;padding-left:20px;font-size:1.02rem;line-height:1.75;color:var(--ink-2)}
.dnc-ul li+li{margin-top:7px}
.dnc-closes{font-size:15px;color:var(--ink-2)}
.dnc-closed{background:var(--warn-bg);border:1px solid #e6c489;border-radius:6px;
  padding:14px 18px;margin-bottom:24px;font-size:15px;color:#6b4700}
.dnc-closed p{margin:0}
.dnc-none{background:var(--surface-2);border:1px solid var(--line-2);border-radius:8px;
  padding:clamp(24px,3vw,34px);margin-top:clamp(28px,3.4vw,42px);max-width:64ch}
.dnc-none-head{font-family:var(--f-cond);font-size:1.25rem;font-weight:600;color:var(--ink);margin:0 0 10px}
.dnc-none p{margin:0;font-size:15px;line-height:1.7;color:var(--ink-2)}
.dnc-emailonly{background:var(--surface-2);border:1px solid var(--line-2);border-radius:8px;
  padding:22px 24px;font-size:15px;line-height:1.7;color:var(--ink-2);max-width:62ch}
.dnc-emailonly p{margin:0}
.dnc-form{margin-top:22px}
.dnc-form input[type=file]{font-family:var(--f-sans);font-size:14px;padding:10px 12px;
  border:1px dashed var(--line-2);border-radius:5px;background:var(--surface-2);width:100%;box-sizing:border-box}
.dnc-done{background:#fff;border:1px solid var(--line-2);border-left:3px solid var(--accent);
  border-radius:8px;padding:26px 28px;max-width:62ch;box-shadow:var(--shadow)}
.dnc-done-head{font-family:var(--f-cond);font-size:1.28rem;font-weight:600;color:var(--ink);margin:0 0 10px}
.dnc-done p{margin:0;font-size:15px;line-height:1.7;color:var(--ink-2)}
@media (max-width:760px){
  .dnc-item{grid-template-columns:1fr;gap:14px}
}

/* One image rather than a stack, per the 17/09/2026 handover. */
.figone{margin:0}
.figone img,.figone .dn-slot,.figone .slot{width:100%;aspect-ratio:4/3;object-fit:cover;
  border-radius:8px;display:block}

/* ---------------------------------------------------------------- 22. stock preview
   Used-equipment preview on Digital cutting and Equipment. The empty state is
   the one that matters: single refurbished machines sell, and an empty grid
   with nothing in it reads as a dead site rather than a busy workshop. */
.stockprev-wrap{margin-top:clamp(28px,3.4vw,42px)}
.stockprev-head{font-size:1.1rem;margin:0 0 16px;color:var(--ink)}
.stockprev-more{margin-top:20px}
.stockprev-empty{border:1px solid var(--line);border-radius:14px;
  padding:clamp(22px,3vw,34px);background:#fff}
.stockprev-empty p{margin:0 0 10px;font-size:1.02rem;line-height:1.7;color:var(--ink-2)}
.stockprev-empty p:last-child{margin-bottom:0}
.stockprev-empty strong{color:var(--ink)}
.stockprev-actions{display:flex;align-items:center;gap:18px;flex-wrap:wrap;margin-top:18px!important}
.sec .stockprev-empty,.sec.white .stockprev-empty{background:var(--paper,#fff)}
.zund-note{margin-top:8px}

/* Equipment archive: the four routes under the hero copy. */
.hero-routes{display:flex;flex-direction:column;gap:10px;margin-top:22px;align-items:flex-start}
@media(min-width:760px){.hero-routes{display:grid;grid-template-columns:1fr 1fr;gap:12px 28px}}

/* ---------------------------------------------------------------- 23. legal pages
   Privacy, Cookies and Terms. The footer links to all three, so the routes
   must exist; the copy is a draft and says so at the top of every one of
   them, loudly enough that nobody mistakes it for approved wording. */
.wrap.narrow{max-width:860px}
.prose.legal{max-width:78ch}
.prose.legal h2{margin-top:2em}
.prose.legal h3{margin-top:1.5em;font-size:1.1rem}
.legalnote{border:1px solid #d9a441;border-left:5px solid #d9a441;
  background:#fdf7ec;border-radius:10px;padding:clamp(18px,2.4vw,26px);
  margin-bottom:clamp(30px,4vw,44px)}
.legalnote p{margin:0 0 10px;font-size:15px;line-height:1.7;color:#5a4416}
.legalnote p:last-child{margin-bottom:0}
.legalnote strong{color:#4a3208}
.tbc{background:#fdf1d6;border-bottom:1px dotted #b07d1c;color:#6b4d0d;
  padding:1px 4px;border-radius:3px;font-style:italic}

/* ---------------------------------------------------------------- 24. Summa ranges
   Four ranges, one block each, one image each. The F Series is featured
   rather than exclusive: it gets the accent eyebrow and the video, the other
   three get the same block so the page does not read as an F Series page
   with three footnotes. */
.rangejump{display:grid;gap:12px;margin-top:clamp(28px,3.4vw,42px);
  grid-template-columns:repeat(auto-fit,minmax(190px,1fr))}
.rangejump a{display:flex;flex-direction:column;gap:4px;padding:16px 18px;
  border:1px solid var(--rule);border-radius:12px;background:#fff;
  text-decoration:none;transition:border-color .15s ease,transform .15s ease}
.rangejump a:hover{border-color:var(--accent);transform:translateY(-2px)}
.rangejump a b{font-family:var(--f-cond);font-size:1.12rem;letter-spacing:-.015em;color:var(--ink)}
.rangejump a span{font-size:13px;color:var(--ink-3)}
.range{scroll-margin-top:90px}
.feature.flip{direction:rtl}
.feature.flip > *{direction:ltr}
@media(max-width:860px){.feature.flip{direction:ltr}}
.range-cta{display:flex;align-items:center;gap:20px;flex-wrap:wrap;
  margin-top:clamp(22px,2.6vw,30px)}
.range.featured .videoblock{margin-top:clamp(34px,4vw,50px)}

/* .rows.plain: no CMYK numeral cycling. Used where the numbers are a list,
   not a design feature. The manufacturer page is B2B and discreet, and four
   colours of numeral there is decoration for its own sake. */
.rows.plain .row-item .n{color:var(--ink-3)!important;font-weight:600}

/* ---------------------------------------------------------------- 25. team roster
   No portraits until approved photography exists. Without an image the grid
   collapses into a thin column of names, so the no-photo variant gets its own
   layout: a ruled list that reads as a roster rather than a grid of gaps. */
.people:has(.person.no-photo){grid-template-columns:repeat(auto-fill,minmax(230px,1fr));gap:0 34px}
.person.no-photo{padding:15px 0;border-top:1px solid var(--rule)}
.person.no-photo .person-name{margin:0;font-size:16px}
.person.no-photo .person-role{margin-top:4px}

/* ---------------------------------------------------------------- 26. report a fault
   The numbered treatment above the form has gone: the form already carries
   the same four groups as headings, so it was the same instruction twice, in
   colour. What is left is the one thing this page has to get across, which is
   when to ring instead. */
/* .urgentbox is gone: the "ring us instead" box duplicated the form's own
   "Faster on the phone" panel, which sits beside the first section of the
   form on the same screen. Removed 18/09/2026. The rules went with it rather
   than being left behind for somebody to wonder about. */
.formnote{margin-top:clamp(22px,2.6vw,30px);font-size:14px;line-height:1.7;
  color:var(--ink-3);max-width:68ch}

/* ---------------------------------------------------------------- 27. managed images
   A photography slot with a picture assigned in Appearance > Images. The
   placeholder rules above still apply to a slot with nothing set, so a site
   that has never opened that screen looks exactly as it did before.

   Fill and focal position are not here: they are generated per slot into the
   head, because they differ per image and per breakpoint. */
.imgslot.has-image{background:none;padding:0}
.imgslot.has-image::before,.imgslot.has-image::after{display:none}
.imgslot.has-image > img{position:absolute;inset:0;width:100%;height:100%;
  display:block;object-fit:cover;object-position:50% 50%}

/* Natural: the box takes the shape of the picture rather than the other way
   round, so nothing is cropped and there is no empty band. */
.imgslot.has-image.fit-natural{position:relative;min-height:0;height:auto;
  overflow:visible}
.imgslot.has-image.fit-natural > img{position:static;width:100%;height:auto}

.imgslot.has-image.fit-contain > img{object-fit:contain}

/* ---------------------------------------------------------------------------
   A managed slot inside a framed container
   ---------------------------------------------------------------------------
   `.imgslot` is a box in its own right: it carries a 420px minimum height so
   that an empty slot is visible on the page. Drop one inside a container that
   already has its own shape and the slot keeps that 420px instead of taking
   the container's height, which is how the V Series photograph ended up
   sitting at the top of its panel with a white band underneath it. The hero
   and the support panel were fixed one at a time; these are the rest of the
   framed containers, fixed together.

   `.feature-shot` is the product frame: white, square, and deliberately
   contained with a margin rather than cropped, because a machine cropped to
   the edges of a box is half a machine. A picture assigned through
   Appearance > Images now gets that same treatment, so it matches the F, L
   and S Series shots that are packaged with the theme. The focal sliders
   still move the picture inside the frame.
   --------------------------------------------------------------------------- */
.feature-shot .imgslot,
.figpair .imgslot,
.hero-bleed-media .imgslot{position:absolute;inset:0;width:100%;height:100%;
  min-height:0;aspect-ratio:auto;border-radius:0;overflow:hidden}

.feature-shot .imgslot.has-image > img{position:absolute;inset:0;width:100%;height:100%;
  object-fit:contain;padding:clamp(18px,2.6vw,34px);display:block}
.figpair .imgslot.has-image > img,
.hero-bleed-media .imgslot.has-image > img{position:absolute;inset:0;width:100%;
  height:100%;object-fit:cover;padding:0;display:block}

/* `.shot` carries a #eef1f5 wash so a photograph that has not loaded yet is a
   grey rectangle rather than nothing. In a container that crops, the picture
   covers it and it is never seen. In a frame that CONTAINS and pads, it is
   seen: it printed a grey border around the F, L and S Series photographs
   while the V Series slot, which is not a `.shot`, showed the frame's white.
   The frame decides the colour, so the wash steps aside inside one. */
.feature-shot .shot,
.hero-bleed-media.light .shot{background:transparent;border-radius:0}

/* ---------------------------------------------------------------------------
   A figure with one picture, not two
   ---------------------------------------------------------------------------
   Every rule above assumes `.figpair` contains a main picture AND a sub
   picture, so it lays three rows out: `1fr 1fr auto`. Give it a single
   photograph and a caption and the picture takes the first 1fr, the CAPTION
   takes the second, and the third row collapses to nothing.

   Measured on the service page at 1440px: a 400px figure column resolved to
   `188px 188px 0px`. The photograph filled the top 188px, the caption floated
   in a 188px band of white below it, and the column finished level with the
   text only by accident.

   One picture means two rows. The photograph takes everything the caption does
   not, so it fills the panel and the two columns genuinely start and finish
   together.

   Keyed on whether a second picture is present rather than on a class, so it
   works on page content already sitting in the database and cannot be undone
   by a re-import. --------------------------------------------------------- */
.figpair:not(:has(.figpair-sub)),
.figrow .figpair:not(:has(.figpair-sub)),
.split > .figpair:not(:has(.figpair-sub)),
.split.figrow .figpair:not(:has(.figpair-sub)){
  grid-template-rows:minmax(0,1fr) auto;
}

/* Below the stacking breakpoint the column is no longer matched to a block of
   text beside it, so the photograph goes back to its own shape rather than
   filling an arbitrary height. */
@media (max-width:820px){
  .figpair:not(:has(.figpair-sub)),
  .figrow .figpair:not(:has(.figpair-sub)),
  .split > .figpair:not(:has(.figpair-sub)),
  .split.figrow .figpair:not(:has(.figpair-sub)){
    grid-template-rows:auto auto;
  }
  .figpair:not(:has(.figpair-sub)) .figpair-main{aspect-ratio:4/3}
}

/* Browsers without :has() keep the old three-row layout, which would strand the
   caption in the middle. Pinning it to the end of its row puts it directly
   under the photograph instead, which is wrong by a few pixels rather than by
   two hundred. */
@supports not (selector(:has(*))){
  .figpair figcaption{align-self:start;margin-top:0}
}

/* ---------------------------------------------------------------------------
   A support panel with one photograph, not two
   ---------------------------------------------------------------------------
   Same fault as the figure column, in a different component. `.support-images`
   lays out two rows, `1.32fr 1fr`, because the navy panel originally carried a
   wide shot above two small ones. The Summa, manufacturer and service panels
   were all cut to a single photograph, so the picture now takes 1.32fr of the
   column height and the remaining 1fr is an empty band of navy running down to
   the bottom of the list.

   One photograph means one row, filling the column, so it finishes level with
   the last numbered item beside it.

   Keyed on whether a second shot is present, so it follows the content rather
   than needing a class on every panel. ------------------------------------- */
.support-images:not(:has(.support-shot + .support-shot)){
  grid-template-rows:minmax(0,1fr);
}

/* The placeholder inside a shot carries a 420px minimum of its own, which would
   push the panel past the text it is supposed to line up with. Inside a shot
   the shot decides the height. */
.support-shot .imgslot{min-height:0;height:100%}

@media (max-width:820px){
  .support-images:not(:has(.support-shot + .support-shot)){
    grid-template-rows:auto;
  }
  .support-shot .imgslot{height:auto;min-height:300px}
}

/* ---------------------------------------------------------------------------
   Stat row: every cell clears its rule
   ---------------------------------------------------------------------------
   `.stat` was written with `padding-left:0` on the first cell and 20px on the
   rest, on the assumption that only the second, third and fourth cells carry a
   dividing rule. Several pages set `box-shadow:inset 1px 0 0` inline on ALL
   four cells, so the first one ends up with a rule drawn 1px to the left of its
   figure and no space between them. On the service page "28" sits hard against
   the line while "1995" has 20px of air, which reads as a mistake because it is
   one.

   Equal padding on all four. The row's outer edge still lines up with the rest
   of the page, and the figures clear the rules wherever a page chooses to draw
   them. Done in the stylesheet rather than by editing the four inline styles,
   because those live in page content that is already in the database.
   ------------------------------------------------------------------------ */
.statrow > .stat{padding-left:20px}

@media (max-width:1100px){
  .statrow > .stat{padding-left:20px}
}

/* One column, no rules, so the figures go back to the page's left edge. */
@media (max-width:420px){
  .statrow > .stat{padding-left:0}
}

/* ---------------------------------------------------------------------------
   Hero intro aligned to the headline
   ---------------------------------------------------------------------------
   In the two-column hero the left side is a small kicker above a large
   headline, and the right side is a paragraph of introduction. Both columns
   are top-aligned, so the introduction started level with the kicker: an
   eleven-point label on one side and body copy on the other, with the headline
   beginning 34px lower. It read as two unrelated things that happened to share
   a row.

   The introduction now starts level with the headline. Text lines up with
   text, the kicker sits above both as a label for the whole row, and the two
   columns read as one block.

   The offset is the kicker's own line box plus its bottom margin, taken from
   the same variables the kicker is drawn with, so the two cannot drift apart
   if the label's size or spacing is ever changed.

   Scoped by content, not by a class: a hero is a `.split` whose left column
   opens with a kicker and whose right column carries a lead paragraph. Section
   headings use `.eyebrow` and a different layout, so they are untouched.

   Note this is the opposite of the rule for the navy support panel, where the
   photograph aligns to the top of the column rather than to the heading. A
   block with an edge should line up with the column; a line of text should
   line up with the line of text beside it.
   ------------------------------------------------------------------------ */
.split:has(> :first-child > .kicker):has(> :nth-child(2) .lead) > :nth-child(2){
  padding-top:var(--kicker-block);
}

/* Stacked: the headline is above the introduction rather than beside it, so
   there is nothing to line up with and the offset would just be a gap. */
@media (max-width:960px){
  .split:has(> :first-child > .kicker):has(> :nth-child(2) .lead) > :nth-child(2){
    padding-top:0;
  }
}

/* ---------------------------------------------------------------------------
   A hero photograph that has not been supplied yet is still hero sized
   ---------------------------------------------------------------------------
   `.hero-split-media` stretches an `<img>` and the "not uploaded" placeholder
   to fill the whole panel, but a `[dn_slot]` placeholder was left at its own
   420px minimum. So the service page, which has a real photograph, filled its
   hero to the bottom, while CTP and Digital cutting stopped two thirds of the
   way down with a band of black underneath. Three heroes, three different
   image heights, for no reason the visitor can see.

   A slot in a hero fills the hero, exactly like the picture that will replace
   it, so the layout does not change shape on the day the photograph arrives.
   ------------------------------------------------------------------------ */
.hero-split-media .imgslot{position:absolute;inset:0;width:100%;height:100%;
  min-height:0;border-radius:0}

@media (max-width:900px){
  .hero-split-media .imgslot{position:absolute;inset:0;min-height:0}
}

/* ---------------------------------------------------------------------------
   Manufacturer and technology partnerships
   ---------------------------------------------------------------------------
   Nine relationships. The numbered row list this replaced is a good component
   for six capabilities read in order, and a poor one for nine names read by
   scanning: it runs the length of the page and most entries carry no
   description, so each row is mostly empty.

   Same visual language as the rest of the page, laid out as a grid rather than
   a list. Rules, not cards, matching `.groups` above. Three columns on
   desktop, two on tablet, one on phone, and the cell dividers follow the
   column count so no row ever shows a rule against the page edge.
   ------------------------------------------------------------------------ */
.partners{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));
  margin-top:clamp(38px,5vw,60px);border-top:1px solid var(--rule)}
.partner{display:flex;flex-direction:column;
  padding:26px 28px 28px;border-bottom:1px solid var(--rule)}
.partner h3{font-family:var(--f-cond);font-size:1.28rem;letter-spacing:-.02em;
  font-weight:600;color:var(--ink);margin:0;text-wrap:balance}
.partner-role{font-family:var(--f-mono);font-size:12px;font-weight:600;
  letter-spacing:.06em;text-transform:uppercase;color:var(--accent);
  margin:7px 0 0;line-height:1.5}
.partner-note{margin:14px 0 0;font-size:14.5px;line-height:1.65;color:var(--ink-2)}
.partner-link{margin:16px 0 0;padding-top:2px}
.partner .arrow{font-weight:600;font-size:14px;color:var(--accent)}
/* The link sits directly under whatever precedes it rather than being pushed
   to the bottom of the cell. Pushing it down lines the links up across a row,
   which looks tidy until one entry in the row carries a paragraph and the
   others do not: then a two line entry has its link stranded 150px below its
   own text. Content together at the top, slack at the bottom, reads calmer. */
.partner-link{margin-top:16px}

/* Vertical dividers, dropped on the first column so nothing draws a rule
   against the left edge of the page. */
.partners > .partner:not(:nth-child(3n+1)){box-shadow:inset 1px 0 0 var(--rule)}
.partners > .partner:nth-child(3n+1){padding-left:0}

@media (max-width:1100px){
  .partners{grid-template-columns:repeat(2,minmax(0,1fr))}
  .partners > .partner:not(:nth-child(3n+1)){box-shadow:none}
  .partners > .partner:nth-child(3n+1){padding-left:28px}
  .partners > .partner:not(:nth-child(2n+1)){box-shadow:inset 1px 0 0 var(--rule)}
  .partners > .partner:nth-child(2n+1){padding-left:0}
}

@media (max-width:640px){
  .partners{grid-template-columns:1fr}
  /* Reset both nth-child families by name. The two-column rules above are a
     tenth of a point more specific than a bare `.partners > .partner`, so a
     shorthand reset here loses to them and every fourth entry keeps a 28px
     indent it should not have. Measured: SCREEN sat 28px right of AVT. */
  .partners > .partner,
  .partners > .partner:nth-child(2n+1),
  .partners > .partner:nth-child(3n+1){
    box-shadow:none;padding:22px 0 24px;
  }
}

/* A single partnership stated on its own page. Same component as the grid on
   the manufacturer page, one column, so the two pages read as the same system
   rather than two descriptions of the same relationship. */
.partners.is-single{grid-template-columns:1fr}
.partners.is-single > .partner{padding-left:0;box-shadow:none;max-width:82ch}
.partners.is-single .partner-note + .partner-note{margin-top:12px}

/* ---------------------------------------------------------------- 28. no vacancies
   What the careers page shows when there is nothing to advertise, and what it
   shows if the careers plugin is ever deactivated. Those two look identical
   from outside, which is the point: a visitor should never be able to tell
   that a plugin is missing. */
.vacancies-empty{margin-top:clamp(32px,4vw,46px);border:1px solid var(--rule);
  border-radius:14px;padding:clamp(24px,3.2vw,38px);background:#fff;max-width:74ch}
.vacancies-empty p{margin:0 0 12px;font-size:1.02rem;line-height:1.7;color:var(--ink-2)}
.vacancies-empty p:last-child{margin-bottom:0}
.vacancies-empty-head{font-family:var(--f-cond);font-size:1.35rem;font-weight:600;
  letter-spacing:-.02em;color:var(--ink)}
.vacancies-empty-actions{display:flex;align-items:center;gap:20px;flex-wrap:wrap;
  margin-top:20px!important}
.sec .vacancies-empty{background:var(--surface,#fff)}

/* ---------------------------------------------------------------- 29. consent
   Banner and preferences dialog. Accept and Reject are the same size and the
   same visual weight as each other: a Reject button that is quieter than the
   Accept button is a dark pattern, and a regulator reads it as one. */
.dnc-bar{position:fixed;left:0;right:0;bottom:0;z-index:1200;background:var(--navy,#17304d);
  color:#fff;box-shadow:0 -10px 34px rgba(8,18,32,.28)}
.dnc-bar[hidden]{display:none}
.dnc-bar-inner{max-width:1200px;margin:0 auto;padding:18px clamp(16px,4vw,40px);
  display:grid;grid-template-columns:minmax(0,1fr) auto;gap:20px 32px;align-items:center}
.dnc-bar-copy p{margin:0 0 6px;font-size:14.5px;line-height:1.6;color:#c7d6e8}
.dnc-bar-copy p:last-child{margin-bottom:0}
.dnc-bar-copy strong{color:#fff;font-size:15.5px}
.dnc-bar-copy a{color:#fff;border-bottom:1px solid rgba(255,255,255,.5)}
.dnc-bar-actions{display:flex;gap:10px;align-items:center;flex-wrap:wrap}
.dnc-bar-actions .btn{min-width:130px;justify-content:center;text-align:center}
.dnc-bar .btn.ghost{background:transparent;color:#fff;border:1px solid rgba(255,255,255,.55)}
.dnc-more{color:#fff;text-decoration:underline;background:none;border:0;cursor:pointer;
  font:inherit;font-size:14px;padding:6px 4px}
@media(max-width:820px){
  .dnc-bar-inner{grid-template-columns:1fr}
  .dnc-bar-actions .btn{flex:1 1 auto}
}

.dnc-modal{position:fixed;inset:0;z-index:1300;background:rgba(8,18,32,.6);
  display:flex;align-items:center;justify-content:center;padding:20px}
.dnc-modal[hidden]{display:none}
.dnc-modal-box{background:#fff;border-radius:14px;max-width:620px;width:100%;
  max-height:88vh;overflow:auto;padding:clamp(24px,3.4vw,36px)}
.dnc-modal-box h2{font-family:var(--f-cond);font-size:1.5rem;letter-spacing:-.02em;
  margin:0 0 6px;color:var(--ink)}
.dnc-cat{display:flex;align-items:flex-start;justify-content:space-between;gap:24px;
  padding:18px 0;border-bottom:1px solid var(--rule)}
.dnc-cat div{display:flex;flex-direction:column;gap:3px}
.dnc-cat strong{font-size:15px;color:var(--ink)}
.dnc-cat span{font-size:13.5px;line-height:1.6;color:var(--ink-2);max-width:52ch}
.dnc-cat input[type=checkbox]{width:20px;height:20px;margin-top:2px;flex:0 0 auto}
.dnc-always{font-family:var(--f-mono);font-size:11.5px;letter-spacing:.06em;
  text-transform:uppercase;color:var(--ink-3);white-space:nowrap;margin-top:3px}
.dnc-modal-actions{display:flex;gap:12px;align-items:center;flex-wrap:wrap;margin-top:24px}
.dnc-modal-note{font-size:12.5px;line-height:1.6;color:var(--ink-3);margin-top:16px}
html.dnc-open{overflow:hidden}
.foot-legal-link{background:none;border:0;padding:0;font:inherit;cursor:pointer;
  color:inherit;text-decoration:underline}
@media(max-width:560px){
  .dnc-cat{flex-direction:row}
  .dnc-modal-actions .btn{flex:1 1 auto;justify-content:center;text-align:center}
}

/* ---------------------------------------------------------------------------
   29. Sustainability
   ---------------------------------------------------------------------------
   The one page on the site that is not selling engineering. It keeps the
   header, footer, grid and typeface so it plainly belongs here, and changes
   the ground under them: a soft natural wash instead of the corporate navy,
   green and earth against Dennison blue, rounded tiles.

   Everything is scoped to the eco- prefix so none of it can leak into a
   service page. The palette below is measured: every text pair on this page
   passes WCAG AA against the ground it actually sits on.
   --------------------------------------------------------------------------- */
:root{
  --eco-ground:#f2f7f3;
  --eco-tint:#e7f0ea;
  --eco-deep:#12362a;
  --eco-green:#1f5c44;
  --eco-green-dk:#17452f;
  --eco-ink:#2b3a34;
  --eco-earth:#6b4f34;
  --eco-sky:#cfe3ef;
  --eco-line:#cfe0d5;
  /* Both sampled from the original artwork: the sky the hills were drawn
     against, and the colour of their base. */
  --eco-sky-band:#9ab3ea;
  --eco-hill:#076048;
}

.ecohero{background:var(--eco-ground);padding:clamp(46px,7vw,86px) 0 clamp(40px,6vw,70px)}
.ecohero-grid{display:grid;grid-template-columns:minmax(0,1.02fr) minmax(0,.98fr);
  gap:clamp(28px,5vw,64px);align-items:center}
.eco-kicker{color:var(--eco-green)}
.ecohero-h{font-size:clamp(30px,4.4vw,46px);line-height:1.12;letter-spacing:-.02em;
  color:var(--eco-deep);margin:10px 0 0;max-width:15ch}
.ecohero-lead{color:var(--eco-ink);margin-top:18px;max-width:52ch}
.ecohero-cta{margin:26px 0 0}
.ecohero-since{margin:14px 0 0;font-size:13.5px;color:var(--eco-earth);letter-spacing:.01em}
.ecohero-art{min-width:0;max-width:540px;margin-left:auto;width:100%}
.ecohero-art svg{width:100%;height:auto;display:block}

.btn-eco{background:var(--eco-green);border-color:var(--eco-green);color:#fff}
.btn-eco:hover{background:var(--eco-green-dk);border-color:var(--eco-green-dk);color:#fff}

/* The tree.
   Dennison's own animated tree, converted from Lottie to SVG so the site can
   drive it. Lottie drew it on a few hundred kilobytes of runtime; this is 35
   groups and eleven lines of CSS, and it grows in the same order because the
   drawing order is the order Lottie built it in.

   It plays once. A decorative illustration that loops forever is a thing the
   eye keeps returning to while somebody is trying to read the paragraph next
   to it. Under prefers-reduced-motion nothing moves at all: the finished tree
   is simply there. */
.dntree{width:100%}
.dntree-svg{width:100%;height:auto;display:block;overflow:visible}
.dntree-part{transform-box:fill-box;transform-origin:50% 100%;
  animation:dntree-grow .5s cubic-bezier(.2,.9,.3,1.15) both;
  animation-delay:calc(var(--i, 0) * 38ms)}
@keyframes dntree-grow{from{transform:scale(.1);opacity:0}to{transform:none;opacity:1}}

/* After the last leaf lands, the whole canopy breathes twice and stops. */
.dntree-hero .dntree-svg{animation:dntree-sway 6s ease-in-out 1.6s 2 both}
@keyframes dntree-sway{
  0%,100%{transform:rotate(0)}
  33%{transform:rotate(.7deg)}
  66%{transform:rotate(-.6deg)}
}
.dntree-hero{transform-origin:50% 100%}

@media (prefers-reduced-motion:reduce){
  .dntree-part{animation:none}
  .dntree-hero .dntree-svg{animation:none}
}

.ecosec{background:var(--eco-ground);padding:clamp(40px,6vw,74px) 0}
.ecosec-tint{background:var(--eco-tint)}
/* The hero and the section under it share --eco-ground, so without this
   hairline they read as one very tall band. Adjacency-scoped deliberately:
   it cannot reach an .ecosec anywhere else on the page. */
.ecohero + .ecosec{border-top:1px solid var(--eco-line)}
.ecohead{max-width:64ch}
.ecosec-h{font-size:clamp(24px,3vw,32px);line-height:1.18;letter-spacing:-.015em;
  color:var(--eco-deep);margin:8px 0 0}
.ecosec-lead{color:var(--eco-ink);margin-top:14px;font-size:1.02rem;line-height:1.7}

/* The widget is somebody else's component. Give it the width and stay out of
   its way: no fixed height, no overflow clipping, no aspect ratio of ours. */
.ecoband{margin-top:clamp(26px,4vw,40px);width:100%}
ecologi-impact-banner{display:block;width:100%}
.eco-fallback{background:#fff;border:1px solid var(--eco-line);border-radius:10px;
  padding:clamp(22px,3vw,32px)}
.eco-fallback h3{margin:0;font-size:19px;color:var(--eco-deep)}
.eco-fallback p{margin:12px 0 0;color:var(--eco-ink);line-height:1.7;max-width:62ch}
.eco-fallback .btn{margin-top:18px;background:var(--eco-green);border-color:var(--eco-green);color:#fff}
ecologi-impact-banner:defined .eco-fallback{display:none}

.ecogrid-h{margin:clamp(28px,4vw,40px) 0 0;font-size:15px;letter-spacing:.06em;
  text-transform:uppercase;color:var(--eco-earth)}
.ecogrid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));
  gap:clamp(16px,2.4vw,26px);margin-top:18px}
/* The tiles carried a 100px icon beside the text, which read as a bullet list
   with decoration rather than as four things worth looking at. The picture is
   a band across the top now, at the width of the card, which is what gives a
   card its weight. */
.ecotile{position:relative;display:flex;flex-direction:column;background:#fff;
  border:1px solid var(--eco-line);border-radius:12px;overflow:hidden;
  transition:border-color .16s,box-shadow .16s,transform .16s}
.ecotile:hover{border-color:#a9c9b6;box-shadow:0 18px 36px -24px rgba(18,54,42,.55);transform:translateY(-2px)}
.ecotile-media{aspect-ratio:16/9;width:100%;overflow:hidden;background:var(--eco-tint)}
.ecotile-art{width:100%;height:100%;display:block;object-fit:cover}
.ecotile-body{display:flex;flex-direction:column;flex:1;
  padding:clamp(18px,2.4vw,24px)}
.ecotile-cat{margin:0;font-size:11.5px;font-weight:600;letter-spacing:.07em;
  text-transform:uppercase;color:var(--eco-green)}
.ecotile-title{margin:7px 0 0;font-size:17.5px;line-height:1.3;color:var(--eco-deep)}
.ecotile-meta{margin:6px 0 0;font-size:12.5px;color:var(--eco-earth)}
.ecotile-blurb{margin:10px 0 0;font-size:14.5px;line-height:1.65;color:var(--eco-ink)}

/* The visible label IS the link, and it is stretched over the whole tile, so
   the thing that looks clickable is the thing that is. One tab stop per card,
   no nested anchors, and the focus ring is drawn on the card rather than on
   four words at the bottom of it. */
.ecotile-link{margin-top:auto;padding-top:14px;font-size:13.5px;font-weight:600;
  color:var(--eco-green);text-decoration:none;align-self:flex-start}
.ecotile-link::after{content:"";position:absolute;inset:0}
.ecotile-link:hover{text-decoration:underline;text-underline-offset:3px}
.ecotile-link:focus-visible{outline:none}
.ecotile:has(.ecotile-link:focus-visible){outline:3px solid var(--accent);outline-offset:3px}
.ecomore{margin:clamp(22px,3vw,30px) 0 0}

.ecosplit{display:grid;grid-template-columns:minmax(0,1.05fr) minmax(0,.95fr);
  gap:clamp(26px,4vw,56px);align-items:start}
.ecopoints{list-style:none;margin:0;padding:0;display:grid;gap:14px}
.ecopoints li{background:#fff;border:1px solid var(--eco-line);border-radius:10px;
  padding:16px 18px}
.ecopoints b{display:block;color:var(--eco-deep);font-size:15px}
.ecopoints span{display:block;margin-top:4px;color:var(--eco-ink);font-size:14.5px;line-height:1.6}

/* The closing panel.
   It was one narrow column of text in a very wide green band, with the right
   half empty and the badge stranded at the bottom. Two columns now: the
   invitation on the left, the live badge and the attribution on the right.

   The hills are the artwork from the old site, laid across the foot of the
   panel. The panel's own green is #076048 because that is the exact colour of
   the base of that image, so the drawing rises out of the panel instead of
   sitting on a rectangle of a slightly different green. */
.ecoclose{position:relative;background:var(--eco-sky-band);padding:clamp(48px,6vw,80px) 0 0;
  overflow:hidden}
/* One column. It was two, with the right-hand side holding a badge that
   rendered blank; removing the badge without removing its column would have
   left a reserved empty half. */
.ecoclose-in{max-width:58ch}
/* Type goes dark on the sky rather than white.
   Ecologi's own banner sets white text on this blue, which measures about
   2:1 and is not readable. The blue is the point, so the blue stays and the
   text changes: navy on sky measures 9.5:1, and the button is Dennison blue,
   which is the one place on this page the brand colour belongs. */
.ecoclose-h{font-size:clamp(24px,3.2vw,34px);line-height:1.16;letter-spacing:-.015em;
  color:#13254a;margin:0}
.ecoclose-p{color:#22345c;margin:14px 0 0;font-size:1.02rem;line-height:1.7}
.ecoclose-cta{margin:24px 0 0}
.ecoclose .btn-eco{background:var(--accent);border-color:var(--accent);color:#fff}
.ecoclose .btn-eco:hover{background:var(--accent-dark);border-color:var(--accent-dark);color:#fff}
.ecoclose .btn-eco:focus-visible{outline:3px solid #13254a;outline-offset:3px}

.ecofoot{margin:26px 0 0;font-size:12.5px;line-height:1.6;color:#2a3d63;max-width:52ch}

/* Decorative, and decorative only: it carries no meaning a reader would miss,
   so it is a background rather than an <img> and it is hidden from assistive
   technology. The band keeps a sensible height on a phone by holding its own
   width rather than shrinking with the viewport. */
/* The band is the picture's own shape, stated as a ratio rather than a
   height. It was height:clamp(106px,12.96vw,187px) with background-size
   100% auto: at any viewport wider than about 1440 the drawing kept growing
   with the width while the box stopped at 187px, so the tops of the peaks
   were cut off in a straight line. A ratio cannot drift out of step with the
   file the way two independent measurements can. */
.ecohills{margin-top:clamp(40px,6vw,72px);aspect-ratio:2400/311;
  background:url(../img/ecologi-hills.png) bottom center / 100% 100% no-repeat}
@media (max-width:820px){
  /* Below this width the band gets too thin to read as hills, so it stops
     shrinking with the viewport and overflows at the sides instead. 820 x
     311 / 2400 is 106, so the ratio still holds. */
  .ecohills{aspect-ratio:auto;height:106px;background-size:820px 106px}
}


@media (max-width:900px){
  .ecohero-grid,.ecosplit{grid-template-columns:1fr}
  .ecohero-art{order:-1;max-width:420px}
  .ecogrid{grid-template-columns:1fr}
}
@media (max-width:560px){
  .ecotile{grid-template-columns:1fr}
  .ecotile-media{width:min(140px,50%)}
}

/* ---------------------------------------------------------------------------
   30. Machine photographs
   ---------------------------------------------------------------------------
   A main frame and a strip of thumbnails, for a machine with more than one
   picture. The main frame is 4:3 and contains rather than crops: the card in
   the listing is a thumbnail and can crop, but this is the picture somebody
   is actually looking at before deciding whether to get in the car.
   --------------------------------------------------------------------------- */
.mgal{margin:0}
.mgal-main{position:relative;aspect-ratio:4/3;background:var(--surface-3);
  border:1px solid var(--line);border-radius:8px;overflow:hidden}
.mgal-main img{position:absolute;inset:0;width:100%;height:100%;
  object-fit:contain;padding:clamp(10px,1.4vw,18px);display:block}
.mgal-thumbs{list-style:none;margin:12px 0 0;padding:0;display:grid;
  grid-template-columns:repeat(auto-fill,minmax(88px,1fr));gap:10px}
.mgal-thumb{position:relative;display:block;aspect-ratio:1/1;overflow:hidden;
  border:1px solid var(--line);border-radius:6px;background:var(--surface-3);
  transition:border-color .14s,box-shadow .14s}
.mgal-thumb img{position:absolute;inset:0;width:100%;height:100%;
  object-fit:cover;display:block}
.mgal-thumb:hover{border-color:var(--ink-4)}
.mgal-thumb:focus-visible{outline:3px solid var(--accent);outline-offset:2px}
.mgal-thumb.is-current{border-color:var(--accent);
  box-shadow:0 0 0 1px var(--accent) inset}
@media (max-width:560px){
  .mgal-thumbs{grid-template-columns:repeat(auto-fill,minmax(70px,1fr))}
}

/* ---------------------------------------------------------------------------
   31. A machine, laid out as a shop listing
   ---------------------------------------------------------------------------
   The decision at the top — what it is, whether you can have it, what it
   costs, how to ask — and the evidence below it. The price used to sit under
   eleven rows of specification, which is eleven rows further down than anybody
   reads before they know what something costs.
   --------------------------------------------------------------------------- */
.stock-none-name{font-size:14px;font-weight:600;color:var(--ink-2);letter-spacing:0;
  text-transform:none;line-height:1.35;max-width:22ch}

.stock-pill{display:inline-flex;align-items:center;gap:7px;margin:16px 0 0;
  font-family:var(--f-mono);font-size:11px;font-weight:600;letter-spacing:.11em;
  text-transform:uppercase;padding:5px 11px;border-radius:4px}
.stock-pill::before{content:"";width:7px;height:7px;border-radius:50%;background:currentColor}
.stock-pill.is-available{color:var(--ok);background:var(--ok-bg)}
.stock-pill.is-reserved{color:var(--warn);background:var(--warn-bg)}

/* Sold. Anybody who has to read carefully to notice is a customer we have
   annoyed, so this is a block and not a word in a table. */
.sold-banner{margin-top:18px;border:2px solid var(--ink);border-radius:8px;
  background:var(--ink);color:#fff;padding:clamp(16px,2vw,22px)}
.sold-banner-h{margin:0;font-size:clamp(17px,2vw,21px);font-weight:700;letter-spacing:-.01em}
.sold-banner-p{margin:8px 0 0;font-size:14.5px;line-height:1.65;color:#c9d2db;max-width:52ch}

.machine-blurb{margin:18px 0 0;font-size:1.02rem;line-height:1.7;color:var(--ink-2);max-width:56ch}

.machine-price{margin-top:clamp(20px,2.4vw,28px);padding-top:clamp(18px,2vw,22px);
  border-top:1px solid var(--line)}
.machine-price b{display:block;font-family:var(--f-mono);font-size:clamp(26px,3.4vw,34px);
  font-weight:600;letter-spacing:-.015em;color:var(--ink);line-height:1.1}
.machine-price span{display:block;margin-top:7px;font-size:13.5px;line-height:1.6;
  color:var(--ink-3);max-width:46ch}

.machine-cta{display:flex;gap:12px;flex-wrap:wrap;margin-top:clamp(18px,2.2vw,24px)}
.machine-where{font-size:14px;color:var(--ink-3);line-height:1.6;margin-top:16px;max-width:54ch}

.machine-history{margin-top:clamp(22px,2.6vw,30px);border:1px solid var(--line);
  border-radius:8px;padding:clamp(16px,2vw,22px);background:var(--surface-2)}
.machine-history .eyebrow{color:var(--ink-3)}
.machine-history p:last-child{margin:8px 0 0;font-size:15px;line-height:1.7;color:var(--ink)}

/* The buy box is static. Everything it holds, the price included, stays at
   the top of the column where the decision is made, and nothing follows the
   reader down to sit beside the tool list. It was sticky twice and neither
   version was right on the page. */
/* The buy box follows the page again.
   Plain CSS sticky and nothing else: no sentinel, no JavaScript, nothing
   hides on the way down. The two previous versions both shed the price while
   stuck, which is the behaviour Dean called heavy and then asked to keep.
   `align-self:start` shrinks the grid item to its own height, and a sticky
   element cannot travel past the bottom of its own box, so the column has to
   stretch for any of this to work. */
.machine-col{align-self:stretch;min-width:0}
@media (min-width:901px){
  .machine-buy{position:sticky;top:clamp(84px,9vh,112px)}
}
.machine-basis{margin:22px 0 0;font-size:12.5px;line-height:1.6;color:var(--ink-3);
  max-width:56ch}
.machine-warranty{margin:16px 0 0;font-size:14.5px;line-height:1.65;color:var(--ink-2);
  max-width:50ch}
.machine-advert{margin-top:clamp(26px,3vw,34px);padding-top:clamp(20px,2.4vw,26px);
  border-top:1px solid var(--line)}
.machine-advert .eyebrow{color:var(--ink-3)}
.machine-advert .prose{margin-top:12px}
.machine-advert .prose ul{margin:0 0 18px;padding-left:20px;display:grid;gap:6px}
.machine-advert .prose li{font-size:15px;line-height:1.6;color:var(--ink-2)}
.machine-advert .prose p{font-size:15px;line-height:1.7;color:var(--ink-2)}
.machine-advert .prose strong{color:var(--ink)}

/* The legal footnote reads as a footnote.
   Small print is capped at a reading measure on purpose: at 13px, running it
   the full width of a 1200px column is around 180 characters a line, which is
   most of the way to unreadable. What was missing was anything saying the
   block was deliberate, so it looked like a paragraph that had failed to fill
   its space. A rule above it says otherwise. */
.legal-foot{margin-top:clamp(26px,3vw,38px);padding-top:clamp(16px,2vw,22px);
  border-top:1px solid var(--line-2)}
.legal-foot .disclaimer{margin-top:0}
.legal-foot .disclaimer + .disclaimer{margin-top:12px}

/* A section head with nothing after it.
   `.sechead` reserves space beneath itself to separate the heading block from
   the content that follows. On a section where the heading block IS the
   content, that margin is space held for something that does not exist, and
   it sat inside the section's own padding: 92px of padding, 40px of orphaned
   margin, 92px of padding, around four lines of text. */
.sechead:last-child{margin-bottom:0}
.wrap > .sechead:only-child{margin-bottom:0}

/* ---------------------------------------------------------------------------
   32. The OptiScout banner
   ---------------------------------------------------------------------------
   An advert inside the page rather than another section of body copy: a full
   width navy band, the real OptiScout mark, the appointment stated next to
   it, four things you get, and a button rather than an underlined link.

   The logo sits on a white plate. It is supplied as near-black artwork on
   transparency, so on navy it would be invisible, and inverting somebody
   else's mark with a CSS filter produces a muddy grey rather than white and
   modifies their artwork. The plate is the same treatment the Summa logo
   already gets on a navy band, so the two read as one system.

   Cyan is the accent, measured at 9:1 on this navy. It is used on the rule,
   the list marks and the appointment label, never on body text.
   --------------------------------------------------------------------------- */
:root{ --oban-cyan:#4fd6e8; }

.oban{background:var(--navy);color:#fff;padding:clamp(52px,7vw,96px) 0;
  position:relative;overflow:hidden}
.oban::before{content:"";position:absolute;inset:0 0 auto 0;height:3px;
  background:linear-gradient(90deg,var(--oban-cyan),rgba(79,214,232,0))}
.oban-grid{display:grid;grid-template-columns:minmax(0,55fr) minmax(0,45fr);
  gap:clamp(30px,4.6vw,64px);align-items:center}

.oban-brand{display:flex;align-items:center;gap:16px;flex-wrap:wrap;margin-bottom:26px}
/* The reversed white logo straight on the navy, no white box, sized as the
   Summa banner's logo is, so the two partner banners read as a pair. */
.oban-logo{display:block;height:38px!important;width:auto!important;max-width:210px;
  object-fit:contain}
@media (max-width:680px){ .oban-logo{height:30px!important} }
.oban-role{font-family:var(--f-mono);font-size:11px;font-weight:600;letter-spacing:.12em;
  text-transform:uppercase;color:var(--oban-cyan);
  border:1px solid rgba(79,214,232,.45);border-radius:4px;padding:6px 10px}

.oban-h{font-size:clamp(28px,3.6vw,42px);line-height:1.1;letter-spacing:-.02em;
  color:#fff;margin:0;max-width:17ch}
.oban-p{margin:16px 0 0;font-size:1.04rem;line-height:1.7;color:#c6d5e6;max-width:56ch}

.oban-list{list-style:none;margin:26px 0 0;padding:0;display:grid;gap:11px}
.oban-list li{position:relative;padding-left:28px;font-size:15px;line-height:1.55;color:#e4ecf5}
.oban-list li::before{content:"";position:absolute;left:0;top:.58em;width:12px;height:2px;
  background:var(--oban-cyan);border-radius:1px}

.oban-cta{margin:30px 0 0}
.btn-oban{background:var(--oban-cyan);border-color:var(--oban-cyan);color:#07263a;
  font-size:16px;padding:14px 26px}
.btn-oban:hover{background:#7fe3ee;border-color:#7fe3ee;color:#07263a}
.btn-oban:focus-visible{outline:3px solid #fff;outline-offset:3px}

.oban-media{position:relative;aspect-ratio:4/3;border-radius:10px;overflow:hidden;
  background:#0c1f3c}
.oban-media img,.oban-media .imgslot{position:absolute;inset:0;width:100%;height:100%;
  min-height:0;border-radius:0}
.oban-media .imgslot.has-image > img{object-fit:cover}

@media (max-width:900px){
  .oban-grid{grid-template-columns:1fr}
  /* The picture goes below the copy, so the button is reachable without
     scrolling past a photograph to find it. */
  .oban-media{order:2;aspect-ratio:16/9}
  .oban-copy{order:1}
}

/* ---------------------------------------------------------------------------
   33. The Summa banner
   ---------------------------------------------------------------------------
   The same family as the OptiScout banner above it, and deliberately not the
   same template. Two supplied assets force the differences.

   The logo. Summa supply a reversed mark, white artwork on transparency, so
   it sits straight on the navy at full size. OptiScout's is near-black and
   needs a white plate under it. This banner therefore leads with the mark
   itself rather than with a plate, which is the more confident of the two and
   belongs to the brand we actually sell.

   The picture. Every F Series shot in Summa's kit is a cut-out on pure white.
   Cropped to fill a dark panel the way `.oban-media` crops a photograph, it
   would render as a white rectangle with a machine inside it. So it gets its
   own light card and the whole machine is shown, which is the rule
   `.hero-bleed-media.light` already follows elsewhere on the site: a product
   shot cut out on white does not belong on a navy ground cropped to fill.

   Cyan is the accent at 8:1 on this navy, used on the rule, the relationship
   line and the list marks, never on body text. The top rule runs the opposite
   way to the OptiScout one so the two read as a pair rather than a repeat.

   The relationship line says UK Sales and Service Partner and nothing wider.
   Dennison's worldwide reach is its own engineering capability and is not a
   Summa appointment; this banner must never imply one.
   --------------------------------------------------------------------------- */
.sban{background:var(--navy);color:#fff;padding:clamp(52px,7vw,92px) 0;
  position:relative;overflow:hidden}
.sban::before{content:"";position:absolute;inset:0 0 auto 0;height:3px;
  background:linear-gradient(90deg,rgba(79,214,232,0),var(--oban-cyan))}
.sban-grid{display:grid;grid-template-columns:minmax(0,48fr) minmax(0,52fr);
  gap:clamp(30px,4.4vw,60px);align-items:center}

.sban-brand{display:flex;align-items:center;gap:20px;flex-wrap:wrap;margin-bottom:24px}
.sban-logo{display:block;height:38px!important;width:auto!important;max-width:210px;
  object-fit:contain}
@media (max-width:680px){ .sban-logo{height:30px!important} }
.sban-role{position:relative;padding-left:20px;font-family:var(--f-mono);font-size:11px;
  font-weight:600;letter-spacing:.14em;text-transform:uppercase;color:var(--oban-cyan)}
.sban-role::before{content:"";position:absolute;left:0;top:50%;width:12px;height:1px;
  background:rgba(79,214,232,.65)}

.sban-h{font-size:clamp(28px,3.5vw,40px);line-height:1.08;letter-spacing:-.02em;
  color:#fff;margin:0;max-width:18ch}
.sban-p{margin:16px 0 0;font-size:1.02rem;line-height:1.7;color:#c6d5e6;max-width:52ch}

.sban-list{list-style:none;margin:24px 0 0;padding:0;display:grid;gap:10px}
.sban-list li{position:relative;padding-left:26px;font-size:15px;line-height:1.55;color:#e4ecf5}
.sban-list li::before{content:"";position:absolute;left:1px;top:.42em;width:8px;height:8px;
  border:1.5px solid var(--oban-cyan);border-radius:1px;transform:rotate(45deg)}

.sban-cta{margin:30px 0 0;display:flex;align-items:center;gap:24px;flex-wrap:wrap}
.btn-sban{background:var(--oban-cyan);border-color:var(--oban-cyan);color:#07263a;
  font-size:16px;padding:14px 26px}
.btn-sban:hover{background:#7fe3ee;border-color:#7fe3ee;color:#07263a}
.btn-sban:focus-visible{outline:3px solid #fff;outline-offset:3px}
.sban-alt{color:#cfe0f5;font-size:15px;border-bottom:1px solid rgba(207,224,245,.4);
  padding-bottom:2px}
.sban-alt:hover{color:#fff;border-bottom-color:#fff}

/* The picture panel.
   It was a white card, because the F Series product shots Summa supply are
   cut-outs on white and dropping one on navy would have shown a white
   rectangle with a machine in it. The banner now advertises the F Series
   Vantage, whose photography is shot on black, so the panel is dark and the
   picture fills it. Same reasoning, opposite answer: the panel follows the
   asset rather than the asset being forced into the panel. */
.sban-media{background:#05070a;border-radius:12px;overflow:hidden;
  aspect-ratio:3/2;display:flex;align-items:center;justify-content:center;
  border:1px solid rgba(255,255,255,.1)}
.sban-media img{display:block;width:100%;height:100%;object-fit:cover}
.sban-media .media-missing{width:100%;height:100%;border-radius:0;color:#8ea2ba;
  background:#0c1526;display:flex;align-items:center;justify-content:center;
  text-align:center;padding:20px;font-size:13px}
.sban-flag{margin:0 0 18px;font-family:var(--f-mono);font-size:10.5px;font-weight:600;
  letter-spacing:.14em;text-transform:uppercase;color:var(--amber)}
.sban-note{margin:14px 0 0;font-family:var(--f-mono);font-size:11px;letter-spacing:.08em;
  text-transform:uppercase;color:#8ea2ba}

@media (max-width:900px){
  /* Relationship line, headline, copy and the button all sit above the
     picture, so nobody scrolls past a machine to find out what to do next. */
  .sban-grid{grid-template-columns:1fr;gap:clamp(26px,5vw,36px)}
  .sban-copy{order:1}
  .sban-figure{order:2}
  .sban-h{max-width:20ch}
}

/* ---------------------------------------------------------------------------
   34. The Summa page, rebuilt as a sales page
   ---------------------------------------------------------------------------
   The old page gave four ranges equal weight and equal length, which made it
   long and made the featured product invisible. This is the opposite shape:
   one product with room, the rest of the range as four cards, and every route
   out of the page landing on a Dennison form rather than on summa.com.

   Two image problems this has to solve at once. The Vantage photography
   Summa supply is shot on black, and the V, L and S product shots are cut
   outs on white. So the featured card carries its picture on a dark panel and
   the other three carry theirs on a light one, in the same card frame. That
   also does the highlighting the brief asked for, without a coloured border
   doing the shouting.

   `.media-missing` inside a card is a labelled panel rather than a blank
   white rectangle, because the V Series has no photography from Summa yet and
   an empty panel reads as a broken page.
   --------------------------------------------------------------------------- */
.hero-note{margin:22px 0 0;font-size:14px;line-height:1.5;color:#9fb0c4;
  padding-left:15px;border-left:2px solid var(--amber);max-width:44ch}

/* The featured product ---------------------------------------------------- */
.vshot{margin:clamp(30px,3.8vw,48px) 0 0;border-radius:12px;overflow:hidden;
  background:#05070a;line-height:0}
.vshot img,.vshot .shot{width:100%;height:auto;display:block;border-radius:0;
  background:#05070a}
.vshot .media-missing{min-height:260px;border-radius:0}

.vpoints{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));
  gap:clamp(22px,2.6vw,34px) clamp(26px,3vw,44px);
  margin:clamp(30px,3.6vw,46px) 0 0}
.vpoints h3{font-size:1.06rem;font-weight:600;color:var(--ink);margin:0 0 7px;
  padding-top:14px;border-top:2px solid var(--accent)}
.vpoints p{margin:0;font-size:14.5px;line-height:1.62;color:var(--ink-2)}

/* The range cards --------------------------------------------------------- */
.rangecards{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));
  gap:clamp(16px,1.8vw,24px);margin-top:clamp(30px,3.6vw,46px)}
.rangecard{display:flex;flex-direction:column;background:#fff;
  border:1px solid var(--line);border-radius:12px;overflow:hidden;
  scroll-margin-top:90px}
.rangecard-media{background:#fff;border-bottom:1px solid var(--line-2);
  display:flex;align-items:center;justify-content:center;padding:18px;
  aspect-ratio:16/10;overflow:hidden}
.rangecard-media.dark{background:#05070a;padding:0}
.rangecard-media img,.rangecard-media .shot{width:100%;height:100%;
  object-fit:contain;border-radius:0;background:transparent}
.rangecard-media.dark img{object-fit:cover}
.rangecard-media .media-missing{width:100%;height:100%;border-radius:0;
  display:flex;align-items:center;justify-content:center;text-align:center;
  padding:18px;font-size:13px;line-height:1.5;color:var(--ink-3);
  background:repeating-linear-gradient(135deg,#eef1f5 0 10px,#e8ecf2 10px 20px)}
.rangecard-body{display:flex;flex-direction:column;flex:1;
  padding:clamp(20px,2.2vw,28px)}
.rangecard-body h3{font-family:var(--f-cond);font-weight:600;
  font-size:clamp(1.2rem,1.7vw,1.45rem);letter-spacing:-.015em;
  color:var(--ink);margin:0 0 8px}
.rangecard-body > p{margin:0;font-size:15px;line-height:1.62;color:var(--ink-2)}
.rangecard-flag{font-family:var(--f-mono);font-size:10.5px;font-weight:600;
  letter-spacing:.12em;text-transform:uppercase;color:var(--amber);margin:0 0 10px}
.rangecard-cta{display:flex;flex-wrap:wrap;align-items:center;gap:14px 20px;
  margin-top:auto;padding-top:20px}

/* The featured card spans the row and puts its picture beside the copy. */
.rangecard.is-featured{grid-column:1 / -1;background:var(--navy);
  border-color:var(--navy);display:grid;
  grid-template-columns:minmax(0,52fr) minmax(0,48fr);align-items:stretch}
.rangecard.is-featured .rangecard-media{aspect-ratio:auto;min-height:300px;
  border-bottom:0}
.rangecard.is-featured .rangecard-body{justify-content:center}
.rangecard.is-featured h3{color:#fff}
.rangecard.is-featured > .rangecard-body > p{color:#c6d5e6}
.rangecard.is-featured .tlink{color:#cfe0f5;border-color:rgba(207,224,245,.45)}
.rangecard.is-featured .tlink:hover{color:#fff;border-color:#fff}

@media (max-width:900px){
  .vpoints{grid-template-columns:repeat(2,minmax(0,1fr))}
  .rangecards{grid-template-columns:repeat(2,minmax(0,1fr))}
  .rangecard.is-featured{grid-template-columns:1fr}
  .rangecard.is-featured .rangecard-media{aspect-ratio:16/9;min-height:0}
}
@media (max-width:640px){
  .vpoints{grid-template-columns:1fr}
  .rangecards{grid-template-columns:1fr}
}

/* Brochure downloads ------------------------------------------------------ */
.brochlist{list-style:none;margin:clamp(26px,3vw,38px) 0 0;padding:0;
  display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:12px}
.brochlist a{display:flex;align-items:baseline;gap:14px;flex-wrap:wrap;
  padding:18px 20px;border:1px solid var(--line);border-radius:10px;
  background:var(--surface-2);text-decoration:none;
  transition:border-color .15s ease,background .15s ease}
.brochlist a:hover{border-color:var(--accent);background:#fff}
.brochlist b{font-size:15.5px;font-weight:600;color:var(--ink)}
.brochlist span{font-family:var(--f-mono);font-size:11.5px;letter-spacing:.06em;
  text-transform:uppercase;color:var(--ink-3)}
/* A brochure we do not hold yet is a request, not a disabled button. It is
   deliberately quieter than a real download but still a live link. */
.brochlist li.is-ask a{background:transparent;border-style:dashed}
.brochlist li.is-ask b{color:var(--ink-2)}
.dn-broch-size{font-family:var(--f-mono);font-size:11px;letter-spacing:.06em;
  text-transform:uppercase;opacity:.8;margin-left:9px;font-weight:600}
.btn .dn-broch-size{opacity:.75}
.brochnote-admin{margin-top:18px;padding:12px 16px;border-radius:8px;
  background:var(--warn-bg);color:var(--warn);font-size:13px;line-height:1.6}
.brochnote-admin code{font-family:var(--f-mono);font-size:12px}

@media (max-width:720px){ .brochlist{grid-template-columns:1fr} }

/* ---------------------------------------------------------------------------
   35. The homepage, reordered
   ---------------------------------------------------------------------------
   Dennison's own capability first, the partner advert last. These are the
   parts of that order that needed CSS rather than moving markup about.
   --------------------------------------------------------------------------- */

/* The route strip.
   Navigation between the hero and the proof strip, not a content section:
   one band, three columns, one line each. It sat inside the hero for one
   build as three stacked boxes, which made the homepage the only page whose
   hero did not look like the rest of the site.

   Height is the constraint that keeps it honest. A third line of copy in any
   column turns a signpost into a section and pushes the page's first real
   content below the fold, so the copy stays at one line and the band stays
   around 170px on a desktop. */
.routestrip{background:var(--surface-3);border-bottom:1px solid var(--line)}
.routestrip-in{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));
  gap:clamp(24px,3vw,48px);padding-block:clamp(26px,2.6vw,34px)}
.route{display:flex;flex-direction:column;gap:5px}
.route + .route{padding-left:clamp(24px,3vw,48px);box-shadow:inset 1px 0 0 var(--line)}
.route h2{font-family:var(--f-cond);font-weight:600;font-size:1.12rem;
  letter-spacing:-.015em;color:var(--ink);margin:0}
.route p{margin:0;font-size:14px;line-height:1.5;color:var(--ink-2)}
.route .arrow{margin-top:5px;font-size:14px}

/* Three across for as long as three columns are readable. A tablet has the
   width for it, and stacking at 860px turned a 170px signpost into a 400px
   section on the one viewport that did not need it. */
@media (max-width:1000px){
  .routestrip-in{gap:clamp(18px,2.4vw,30px)}
  .route + .route{padding-left:clamp(18px,2.4vw,30px)}
  .route h2{font-size:1.02rem}
  .route p{font-size:13.5px}
  .route .arrow{font-size:13.5px}
}
@media (max-width:700px){
  .routestrip-in{grid-template-columns:1fr;gap:0;padding-block:8px}
  .route{padding:16px 0}
  .route + .route{padding-left:0;box-shadow:none;border-top:1px solid var(--line)}
}

/* The proof strip. It sits on its own band directly under the hero and the
   figures appear nowhere else on the page. */
.proofband{padding-block:clamp(30px,3.4vw,48px)}
.proofband .statrow{margin-top:0}
.proofline{margin:clamp(18px,2vw,26px) 0 0;font-size:15px;line-height:1.6;
  color:var(--ink-2);max-width:78ch}
/* Two of the four figures are phrases rather than numbers, so the numeral
   size would set the whole row to the width of "UK and mainland Europe". */
.statrow.wordy .stat b{font-size:clamp(1.15rem,1.5vw,1.45rem);line-height:1.15;
  letter-spacing:-.02em}

/* A confirmed relationship title inside a card, under the heading. */
.card-role{margin:0 0 10px;font-family:var(--f-mono);font-size:10.5px;
  font-weight:600;letter-spacing:.1em;text-transform:uppercase;color:var(--accent)}

/* The closing band serves three audiences, so it carries three actions
   rather than one button and a number. */
.closegrp{display:flex;align-items:center;gap:14px 20px;flex-wrap:wrap}
.closegrp .num{font-family:var(--f-mono);font-size:clamp(1.1rem,2vw,1.4rem);
  font-weight:600;color:#fff;white-space:nowrap}

/* Four cards in one row on a desktop, two on a tablet, one on a phone.
   `.g2` is auto-fit at 300px, which puts three on a row at this width and
   leaves the fourth on its own looking like an afterthought. */
.g4{grid-template-columns:repeat(4,minmax(0,1fr))}
@media (max-width:1100px){ .g4{grid-template-columns:repeat(2,minmax(0,1fr))} }
@media (max-width:620px){ .g4{grid-template-columns:1fr} }

/* A placeholder nobody has to read.
   `.is-quiet` is what the public gets where an image has not been supplied:
   the same designed panel, with the production note left off. See
   dennison_render_image_slot() and dennison_sc_media() for why. */
.imgslot.is-quiet::after{content:none}
.media-missing.is-quiet{border-style:solid;border-color:rgba(127,140,160,.22);
  background:linear-gradient(140deg,rgba(127,140,160,.10),rgba(127,140,160,.20))}

/* ---------------------------------------------------------------------------
   36. Manufacturer relationship badges
   ---------------------------------------------------------------------------
   These were eleven copies of the same inline style carrying three different
   words, and the words were the problem: "Official partner" as a catch-all on
   brands whose agreements cover completely different things, and "Service
   experience" on brands where a real title exists.

   The badge now carries the exact confirmed title. Three states, because
   there are three kinds of relationship and a customer should be able to tell
   them apart without reading the paragraph: appointed, independent, and
   independent-but-constrained, where the manufacturer can restrict access.
   --------------------------------------------------------------------------- */
.bbadge{display:inline-block;font-size:11px;font-weight:600;letter-spacing:.06em;
  text-transform:uppercase;padding:3px 8px;border-radius:3px;line-height:1.5;
  white-space:normal}
.bbadge.appointed{color:#0f6b52;background:#e8f3ef}
.bbadge.independent{color:#5b6774;background:#eef1f5}
.bbadge.limited{color:#8a5200;background:#fdf0dc}

/* The role line under a partner heading in a rows list. The heading carries
   the confirmed title, which is long; this carries what the equipment does,
   which is what the reader was actually scanning for. */
.partner-role-inline{display:block;margin-top:5px;font-family:var(--f-mono);font-size:11px;
  font-weight:600;letter-spacing:.1em;text-transform:uppercase;color:var(--ink-3)}

/* ---------------------------------------------------------------------------
   37. The support block on a light ground
   ---------------------------------------------------------------------------
   `.support` was written for the navy band and hard-codes white text, navy
   hairlines and a navy photograph backdrop. On the Summa page it now follows
   the application selector, and two full-width navy sections in a row read as
   one very tall section with a seam in it.

   This is the light version written as its own thing rather than as a set of
   inline overrides, which is the same mistake `.figs` made on the support
   section and which took a rebuild to undo.
   --------------------------------------------------------------------------- */
.support-light .support-lead{color:var(--ink-2)}
.support-light .support-list{border-top-color:var(--line)}
.support-light .support-list li{border-bottom-color:var(--line)}
.support-light .support-list b{color:var(--accent)}
.support-light .support-list strong{color:var(--ink)}
.support-light .support-list span{color:var(--ink-2)}
.support-light .support-shot{background:var(--surface-3)}

/* ---------------------------------------------------------------------------
   38. Homepage rhythm
   ---------------------------------------------------------------------------
   The reorder in 0.35.0 got the content order right and left the page reading
   as one long column of text and small cards. These are the parts that give
   it its shape back, without inventing photography the business does not
   have: a real photograph beside the service list, four categories with no
   boxes drawn round them, one navy proof band doing the work of three
   sections, and the coloured equipment panels restored.
   --------------------------------------------------------------------------- */

/* Machines: four categories, no cards. The rule above each one carries the
   grouping; a box round each added weight and no information. */
.groups.four{grid-template-columns:repeat(4,minmax(0,1fr));border-top-width:3px}
.groups.four .group{padding:22px 24px 24px 0;border-bottom:0}
.groups.four .group:nth-child(even){padding-left:0;border-left:0}
.groups.four .group + .group{padding-left:24px;box-shadow:inset 1px 0 0 var(--line)}
.group-link{margin-top:14px!important}
@media (max-width:1000px){
  .groups.four{grid-template-columns:repeat(2,minmax(0,1fr))}
  .groups.four .group{border-bottom:1px solid var(--line)}
  .groups.four .group:nth-child(odd){padding-left:0;box-shadow:none}
}
@media (max-width:620px){
  .groups.four{grid-template-columns:1fr}
  .groups.four .group + .group{padding-left:0;box-shadow:none}
}

/* Proof: the picture half and the navy half, carrying the About message and
   the three figures. One band doing what three sections used to. */
.proof .c h2.big{color:#fff;margin:12px 0 0;max-width:17ch}
.proof-lead{color:#c3d1e2;font-size:1.02rem;line-height:1.68;max-width:52ch}
/* `.bleed p` sets margin:0 and is an element plus a class, so it out-specifies
   a bare `.proof-lead` however late that sits in the file. The two paragraphs
   in this band ran together as one block because of it. Scoped to the band, so
   it cannot reach a paragraph in any other .bleed panel.
   Fourth time this month a selector has reached, or failed to reach, a context
   it was not written for. The stylesheet pass is overdue. */
.proof .c .proof-lead{margin:20px 0 0}
.proof .figs{margin-top:clamp(28px,3.4vw,40px)}
/* Two figures on the first row and the third across the bottom. "Worldwide,
   service, installation and project deployment" does not fit a half column
   without wrapping into a paragraph. */
.proof .figs .fig:last-child{grid-column:1 / -1;padding-left:0;border-left:0;
  display:flex;align-items:baseline;gap:14px;flex-wrap:wrap}
.proof .figs .fig:last-child span{margin-top:0}
.proof-note{margin:18px 0 0;font-size:13.5px;line-height:1.6;color:#94a9c4;max-width:56ch}

/* Three equipment panels rather than four, and software underneath them
   rather than beside them: a few thousand pounds a year was taking a quarter
   of the page's commercial grid. */
.bleed.three{grid-template-columns:repeat(3,minmax(0,1fr))}
.bleed.three > *{padding-inline:clamp(32px,4vw,60px)}
.bleed.three > *:first-child{padding-left:var(--gutter)}
.bleed.three > *:last-child{padding-right:var(--gutter)}
/* Equal columns gave unequal panels. The outer two carry the page gutter on
   their outside edge, which on a wide screen is 360px, so their text got a
   third of the room the middle panel had: "Refurbished" was clipped and
   "Parts and spares" broke onto three lines. The outer columns are now wider
   by exactly the gutter they carry, so all three panels get the same width
   for their words. Desktop only; the stacked layout below 1000px is untouched. */
@media (min-width:1001px){
  .bleed.three{
    --p:clamp(32px,4vw,60px);
    --d:calc(var(--gutter) - var(--p));
    grid-template-columns:
      calc((100% - 2 * var(--d)) / 3 + var(--d))
      calc((100% - 2 * var(--d)) / 3)
      calc((100% - 2 * var(--d)) / 3 + var(--d));
  }
}
@media (max-width:1000px){
  .bleed.three{grid-template-columns:1fr}
  .bleed.three > *{padding-left:var(--gutter);padding-right:var(--gutter)}
}

.softstrip{background:var(--surface-3);border-top:1px solid var(--line)}
.softstrip-in{display:flex;align-items:baseline;gap:16px 32px;flex-wrap:wrap;
  padding-block:clamp(18px,2vw,26px)}
.softstrip-in p{margin:0;font-size:14.5px;line-height:1.6;color:var(--ink-2);max-width:82ch}
.softstrip-in b{color:var(--ink)}
.softstrip-in .arrow{font-size:14.5px;white-space:nowrap}

/* A four step process row. `.steps` is a three column grid, written for the
   three step test-cut block; the Summa journey has four. */
.steps.four{grid-template-columns:repeat(4,minmax(0,1fr))}
@media (max-width:1000px){ .steps.four{grid-template-columns:repeat(2,minmax(0,1fr))} }
@media (max-width:620px){ .steps.four{grid-template-columns:1fr} }

/* Summa page: the announcement, with the photograph from the day beside it.
   The picture came as a social post with a white frame and a bevelled
   bottom-right corner, which cut into the frame and the toe of one shoe. The
   frame is cropped off the file; the bevel is kept here as a clipped corner,
   so the section colour shows through it instead of a white triangle. Nothing
   in the photograph is repainted. A clean original uploaded to the Media
   Library under the same filename replaces it with no code change. */
.announce-grid{display:grid;grid-template-columns:minmax(0,4fr) minmax(0,7fr);
  gap:clamp(32px,5vw,72px);align-items:center}
.announce-photo{margin:0}
.announce-photo img{aspect-ratio:1018/1288;object-fit:cover;border-radius:0;background:transparent;
  clip-path:polygon(0 0,100% 0,100% 91.4%,90.8% 100%,0 100%)}
@media (max-width:720px){
  .announce-grid{grid-template-columns:1fr}
  .announce-photo{max-width:460px}
}

/* ==========================================================================
   Summa product centre: local navigation, breadcrumbs, range and model cards.
   Everything here is scoped to its own class so it cannot reach another page.
   ========================================================================== */

/* Local navigation under the hero. One row that scrolls sideways on a phone,
   so it never stacks into a second menu competing with the main one. */
.summanav{background:#fff;border-bottom:1px solid var(--line);position:relative;z-index:2}
.summanav-in{display:flex;align-items:center;gap:20px}
.summanav ul{list-style:none;margin:0;padding:0;display:flex;gap:4px;flex:1;min-width:0;
  overflow-x:auto;scrollbar-width:none;-webkit-overflow-scrolling:touch}
.summanav ul::-webkit-scrollbar{display:none}
.summanav li{flex:0 0 auto}
.summanav a{display:block;padding:16px 12px;font-size:14px;font-weight:500;color:var(--ink-2);
  white-space:nowrap;border-bottom:2px solid transparent;text-decoration:none}
.summanav a:hover{color:var(--ink)}
.summanav a.is-here{color:var(--ink);font-weight:600;border-bottom-color:var(--accent)}
.summanav a:focus-visible{outline:2px solid var(--accent);outline-offset:-2px}
.summanav .summanav-cta{flex:0 0 auto;padding:9px 14px;border:1px solid var(--line);border-radius:6px;
  font-weight:600;color:var(--accent);border-bottom-width:1px}
.summanav .summanav-cta:hover{background:var(--surface-3)}
@media (max-width:700px){
  .summanav .summanav-cta{display:none}
  .summanav ul{margin-inline:-8px}
}

/* Breadcrumbs, sized to sit above a hero kicker on the dark panel. */
.crumbs ol{list-style:none;margin:0 0 18px;padding:0;display:flex;flex-wrap:wrap;gap:6px;
  font-size:12.5px;color:#8fb0da}
.crumbs li + li::before{content:"\203A";margin-right:6px;opacity:.7}
.crumbs a{color:#c6d5e6;text-decoration:none;border-bottom:1px solid rgba(198,213,230,.35)}
.crumbs a:hover{color:#fff}
.crumbs [aria-current]{color:#8fb0da}

/* Overview: four equal range cards, since the Vantage has its own section
   directly above and does not need to be featured twice. */
.rangecards.four{grid-template-columns:repeat(4,minmax(0,1fr))}
.rangecard-models{font-family:var(--f-mono);font-size:11px;font-weight:600;letter-spacing:.06em;
  text-transform:uppercase;color:var(--ink-3);margin:0 0 10px;line-height:1.6}
@media (max-width:1100px){ .rangecards.four{grid-template-columns:repeat(2,minmax(0,1fr))} }
@media (max-width:640px){ .rangecards.four{grid-template-columns:1fr} }

/* Range pages: the models, light by design. Name, a fact or two, one line.
   Specifications live in Summa's brochure, one link below the cards. */
.modelcards{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));
  gap:clamp(16px,1.8vw,24px);margin-top:clamp(28px,3.4vw,42px)}
.modelcards.two{grid-template-columns:repeat(2,minmax(0,1fr))}
.modelcards.four{grid-template-columns:repeat(4,minmax(0,1fr))}
.modelcard{background:#fff;border:1px solid var(--line);border-radius:10px;
  padding:clamp(18px,2vw,24px);display:flex;flex-direction:column}
.modelcard h3{font-family:var(--f-cond);font-weight:600;font-size:1.25rem;letter-spacing:-.015em;
  color:var(--ink);margin:0}
.modelcard .modelcard-fact{font-family:var(--f-mono);font-size:11.5px;font-weight:600;letter-spacing:.04em;
  color:var(--accent);margin:8px 0 0}
.modelcard p{margin:10px 0 0;font-size:14.5px;line-height:1.6;color:var(--ink-2)}
/* The model codes, because a buyer searches for V1625 rather than for a size
   range. Pinned to the foot of the card so the four line up. 30/09/2026 */
.modelcard .modelcard-models{margin:14px 0 0;padding-top:12px;border-top:1px solid var(--line-2);
  font-family:var(--f-mono,var(--f-sans));font-size:12px;letter-spacing:.02em;color:var(--ink);
  margin-top:auto}
@media (max-width:1000px){ .modelcards,.modelcards.four{grid-template-columns:repeat(2,minmax(0,1fr))} }
@media (max-width:640px){ .modelcards,.modelcards.two,.modelcards.four{grid-template-columns:1fr} }

/* Applications: a plain two-column list, worded as guidance. */
.applist{list-style:none;margin:clamp(24px,3vw,36px) 0 0;padding:0;
  display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:0 clamp(24px,3vw,48px)}
.applist li{padding:14px 0;border-top:1px solid var(--line);font-size:15px;line-height:1.55;color:var(--ink-2)}
.applist li b{display:block;color:var(--ink);font-weight:600;margin-bottom:2px}
@media (max-width:640px){ .applist{grid-template-columns:1fr} }

/* The one brochure link on a range page. */
.brochstrip{margin-top:clamp(24px,3vw,34px);padding:18px 20px;border:1px solid var(--line);
  border-radius:10px;background:var(--surface-2);display:flex;flex-wrap:wrap;align-items:center;
  justify-content:space-between;gap:12px 24px}
.brochstrip p{margin:0;font-size:14.5px;line-height:1.6;color:var(--ink-2);max-width:70ch}
.brochstrip b{color:var(--ink)}
/* A soft fade on the right edge says "there is more" when the row scrolls. */
@media (max-width:700px){
  .summanav-in{position:relative}
  .summanav-in::after{content:"";position:absolute;top:0;right:0;bottom:0;width:36px;
    background:linear-gradient(90deg,rgba(255,255,255,0),#fff);pointer-events:none}
}

/* "View all materials" under the shortened material finder. */
.mf-more{margin-top:18px}
.mf-more[hidden]{display:none}

/* Summa range banners. Summa's approved hero images are wide banners with the
   machine on the right and a dark gradient on the left. Filling the height and
   anchoring to the right edge keeps the machine in view at every width; the
   dark left of the image runs into the copy panel. Range pages are the only
   heroes carrying breadcrumbs, which is what scopes this. */
.hero-split:has(.is-summa-range) .hero-split-media img{object-fit:cover;object-position:right center}
/* On desktop the picture panel is taller than it is wide, so only part of a
   2.2:1 banner can show at full height. Summa's machines sit between roughly
   55% and 96% across the banner; these positions keep that span in the window
   rather than pinning the window hard right and losing the machine's left end. */
@media (min-width:1280px){ .hero-split:has(.is-summa-range) .hero-split-media img{object-position:95% center} }
@media (min-width:901px) and (max-width:1279px){ .hero-split:has(.is-summa-range) .hero-split-media img{object-position:88% center} }
/* Summa's banners are bright where our crop begins, so the join with the
   copy panel needs a longer feather than a dark photograph does. */
@media (min-width:901px){
  .hero-split:has(.is-summa-range) .hero-split-media::before{
    background:linear-gradient(90deg,rgba(11,14,18,.96) 0,rgba(11,14,18,.55) 14%,rgba(11,14,18,0) 36%)}
}

/* Summa menu as the second row of the sticky site header, on Summa pages. */
.top .summanav.is-sub{border-top:1px solid var(--line);border-bottom:0;background:var(--surface-2)}
.top .summanav.is-sub .summanav-in{max-width:var(--wrap);margin:0 auto;padding-inline:20px}
.top .summanav.is-sub a{padding:10px 12px;font-size:13.5px}
.top .summanav.is-sub .summanav-cta{padding:6px 12px;font-size:13px}
@media (max-width:700px){ .top .summanav.is-sub .summanav-in::after{background:linear-gradient(90deg,rgba(250,251,252,0),var(--surface-2))} }
/* Anchor jumps land below the taller header. */
html:has(.top .summanav){scroll-padding-top:140px}

/* ==========================================================================
   News & Insights: cards, archive, article, homepage strip.
   ========================================================================== */
.newsgrid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:clamp(18px,2vw,28px)}
@media (max-width:1000px){ .newsgrid{grid-template-columns:repeat(2,minmax(0,1fr))} }
@media (max-width:640px){ .newsgrid{grid-template-columns:1fr} }
.newscard{display:flex;flex-direction:column;background:#fff;border:1px solid var(--line);border-radius:10px;overflow:hidden}
.newscard-media{display:block;aspect-ratio:16/10;background:var(--surface-3);overflow:hidden}
.newscard-media img{display:block;width:100%;height:100%;object-fit:cover;transition:transform .4s ease}
.newscard:hover .newscard-media img{transform:scale(1.03)}
.newscard-noimg{display:flex;align-items:flex-end;height:100%;padding:18px;background:var(--navy);color:#8fb0da;
  font-family:var(--f-mono);font-size:11px;font-weight:600;letter-spacing:.12em;text-transform:uppercase}
.newscard-body{display:flex;flex-direction:column;flex:1;padding:clamp(18px,2vw,24px)}
.newscard-cat{margin:0 0 8px;font-family:var(--f-mono);font-size:11px;font-weight:600;letter-spacing:.12em;text-transform:uppercase}
.newscard-cat a{color:var(--accent)}
.newscard h3{font-family:var(--f-cond);font-weight:600;font-size:1.2rem;line-height:1.3;letter-spacing:-.015em;margin:0}
.newscard h3 a{color:var(--ink)}
.newscard h3 a:hover{color:var(--accent)}
.newscard-date{margin:8px 0 0;font-size:13px;color:var(--ink-3)}
.newscard-excerpt{margin:10px 0 0;font-size:14.5px;line-height:1.6;color:var(--ink-2)}
.newscard-more{margin:auto 0 0;padding-top:16px}
/* The featured article: picture beside the words on desktop. */
.newsfeature{margin-bottom:clamp(24px,3vw,36px)}
.newscard.is-feature{display:grid;grid-template-columns:minmax(0,1.2fr) minmax(0,1fr)}
.newscard.is-feature .newscard-media{aspect-ratio:auto;min-height:340px}
.newscard.is-feature .newscard-body{justify-content:center;padding:clamp(24px,3.4vw,44px)}
.newscard.is-feature h3{font-size:clamp(1.4rem,2.2vw,1.9rem)}
.newscard.is-feature .newscard-more{margin-top:18px}
@media (max-width:800px){
  .newscard.is-feature{grid-template-columns:1fr}
  .newscard.is-feature .newscard-media{aspect-ratio:16/10;min-height:0}
}
/* Category filter: plain links, so it works without JavaScript. */
.newsfilter{display:flex;flex-wrap:wrap;gap:8px;margin-top:clamp(24px,3vw,34px)}
.newsfilter a{padding:7px 14px;border:1px solid var(--line);border-radius:999px;font-size:14px;color:var(--ink-2);background:#fff}
.newsfilter a:hover{border-color:var(--ink-3);color:var(--ink)}
.newsfilter a.is-on{background:var(--ink);border-color:var(--ink);color:#fff}
.newsempty{font-size:1.02rem;color:var(--ink-2)}
.newspager{margin-top:clamp(28px,3.4vw,42px)}
.newspager ul{list-style:none;display:flex;flex-wrap:wrap;gap:6px;margin:0;padding:0}
.newspager a,.newspager span{display:block;padding:8px 13px;border:1px solid var(--line);border-radius:6px;font-size:14px;color:var(--ink-2);background:#fff}
.newspager .current{background:var(--ink);border-color:var(--ink);color:#fff}
/* Homepage strip and related articles share the head row. */
.newsstrip-head{display:flex;flex-wrap:wrap;align-items:flex-end;justify-content:space-between;gap:12px 24px;
  margin-bottom:clamp(22px,2.6vw,32px)}
.newsstrip-head h2{margin:0}
/* The article. */
.newsnarrow{max-width:780px}
/* One background for the whole article, so the header, picture and text read as one piece. */
.newsarticle{background:#fff}
.newsarticle .newshead{background:transparent;border:0;padding-bottom:clamp(26px,3vw,40px)}
.newsmetaline{display:flex;flex-wrap:wrap;align-items:center;gap:10px;margin:0;font-family:var(--f-mono);font-size:11.5px;font-weight:600;letter-spacing:.12em;text-transform:uppercase;color:var(--ink-3)}
.newsmetacat{color:var(--accent)}
.newsmetacat:hover{text-decoration:underline}
@media (max-width:640px){ .newsmetaline{flex-direction:column;align-items:flex-start;gap:4px} .newsmetaline > span{display:none} }
.newscrumbs ol{list-style:none;margin:0 0 26px;padding:0;display:flex;flex-wrap:wrap;gap:6px;font-size:13px;color:var(--ink-3)}
.newscrumbs li + li::before{content:"\203A";margin-right:6px}
.newscrumbs a{color:var(--ink-2)}
.newstitle{margin:10px 0 0}
.newslead{margin:16px 0 0;font-size:1.15rem;line-height:1.6;color:var(--ink-2)}
.newsimage{margin:0 auto;padding-top:0}
.newsimage img{display:block;border-radius:10px}
/* Whole picture: never cropped, shown at its own shape, no taller than 720px. */
.newsimage.is-whole{text-align:center}
.newsimage.is-whole img{width:auto;max-width:100%;height:auto;max-height:720px;margin:0 auto}
/* Banner: full width, cropped to a wide strip around the chosen focus. */
.newsimage.is-banner img{width:100%;height:auto;aspect-ratio:16/7;object-fit:cover}
@media (max-width:640px){ .newsimage.is-banner img{aspect-ratio:4/3} }
.newsbody .newssource{margin-top:28px;padding-top:14px;border-top:1px solid var(--line);font-size:13.5px;color:var(--ink-3)}
.newsimage figcaption{margin-top:8px;font-size:13px;color:var(--ink-3)}
.newsbody{padding-block:clamp(28px,3.4vw,44px);max-width:none}
.newsbody img{max-width:100%;height:auto;border-radius:8px}
.newsmeta{border-top:1px solid var(--line);padding:18px 0 clamp(36px,4vw,56px);font-size:14px;color:var(--ink-3)}
.newsmeta p{margin:0 0 8px}

/* Parts: the eBay panel, shown only when an address is set. */
.ebaystrip{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:clamp(20px,3vw,40px);align-items:center;
  padding:clamp(24px,3vw,40px);background:#fff;border:1px solid var(--line);border-radius:12px}
.ebaystrip-act{display:flex;flex-direction:column;align-items:flex-start;gap:12px}
@media (max-width:800px){ .ebaystrip{grid-template-columns:1fr} }

/* Parts: the opening header's two columns read as a pair, so centre them
   against each other rather than hanging the title off the top. Scoped to
   this page: .sechead is used with very different content elsewhere. */
.page-parts-spares .pagetop .sechead{align-items:center}

/* Service agreement levels. Four columns of increasing cover, each one
   inheriting the level before it, so only the addition is listed. */
.tiers{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:clamp(16px,1.6vw,22px);margin-top:clamp(28px,3.4vw,44px)}
.tier{display:flex;flex-direction:column;background:#fff;border:1px solid var(--line);border-radius:12px;overflow:hidden;
  box-shadow:0 1px 2px rgba(11,14,18,.06)}
/* The coloured head sets the card's edge, so the white body below it does not
   float free of its own header on a pale section background. */
.tier{border-color:color-mix(in srgb, var(--metal) 34%, #fff)}
/* One row for the head and one for the list, shared by all four cards, so a
   two line price and a one line price still line up. */
@supports (grid-template-columns: subgrid){
  .tiers{grid-template-rows:auto 1fr}
  .tier{display:grid;grid-row:span 2;grid-template-rows:subgrid}
}
/* A coloured band per level, so the four read as a ladder at a glance. Each
   colour is dark enough to carry white text at AA. */
.tier-head{padding:clamp(18px,1.8vw,22px);background:var(--metal);color:#fff}
.tier.is-bronze{--metal:#8a5a2b}
.tier.is-silver{--metal:#6f7780}
.tier.is-gold{--metal:#9a7410}
.tier.is-platinum{--metal:#2b3441}
.tier h3{font-family:var(--f-cond);font-weight:600;font-size:1.3rem;letter-spacing:-.01em;margin:0;color:#fff}
.tier-price{margin:8px 0 0;color:rgba(255,255,255,.82);font-size:13.5px}
.tier-price b{display:block;font-size:1.35rem;color:#fff;font-family:var(--f-cond);letter-spacing:-.01em}
.tier-plus{margin:16px 0 0;font-family:var(--f-mono);font-size:11px;font-weight:600;letter-spacing:.11em;text-transform:uppercase;color:var(--ink-3)}
.tier .ticks{margin:0;align-content:start;padding:clamp(18px,1.8vw,22px);list-style:none;display:flex;flex-direction:column;gap:10px;font-size:14.5px;line-height:1.55;color:var(--ink-2)}
.tier .ticks li{position:relative;padding-left:24px}
.tier .ticks li::before{content:"";position:absolute;left:0;top:6px;width:13px;height:7px;border-left:2px solid var(--metal);border-bottom:2px solid var(--metal);transform:rotate(-45deg)}
.tier .ticks li.is-new{color:var(--ink);font-weight:500}
.tiers-note{margin:clamp(20px,2.4vw,28px) 0 0;max-width:86ch;font-size:13.5px;line-height:1.7;color:var(--ink-3)}
@media (max-width:1080px){ .tiers{grid-template-columns:repeat(2,minmax(0,1fr))} }
@media (max-width:640px){ .tiers{grid-template-columns:1fr} }

/* Service agreements: the two routes in for a customer with no contract.
   The urgent one carries the weight, the other sits beside it in white, and
   legacy equipment follows as a strip rather than a third equal choice. */
.optpair{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:clamp(18px,2vw,26px);margin-top:clamp(28px,3.4vw,44px)}
.optpanel{display:flex;flex-direction:column;padding:clamp(24px,2.6vw,36px);background:#fff;border:1px solid var(--line);border-radius:12px}
.optpanel .eyebrow{margin:0}
.optpanel h3{font-family:var(--f-cond);font-weight:600;font-size:clamp(1.25rem,1.8vw,1.55rem);letter-spacing:-.015em;margin:10px 0 0}
.optpanel p{margin:12px 0 0;color:var(--ink-2);line-height:1.7}
.optpanel-act{margin:auto 0 0;padding-top:22px}
.optpanel.is-primary{background:var(--navy);border-color:var(--navy);color:#fff}
.optpanel.is-primary h3{color:#fff}
.optpanel.is-primary .eyebrow{color:#8fb0da}
.optpanel.is-primary p{color:#c7d6e8}
.legacystrip{display:flex;flex-wrap:wrap;gap:16px 32px;align-items:center;justify-content:space-between;
  margin-top:clamp(18px,2vw,26px);padding:clamp(18px,2vw,24px) clamp(20px,2.4vw,28px);
  background:#fff;border:1px solid var(--line);border-radius:12px}
.legacystrip h3{font-family:var(--f-cond);font-weight:600;font-size:1.1rem;margin:0;color:var(--ink)}
.legacystrip p{margin:6px 0 0;font-size:14.5px;line-height:1.6;color:var(--ink-2);max-width:78ch}
@media (max-width:860px){ .optpair{grid-template-columns:1fr} }

/* Footer social row. Only the profiles that are filled in appear. */
.social{display:flex;gap:10px;list-style:none;margin:0 0 0 auto;padding:0}
.social a{display:flex;align-items:center;justify-content:center;width:34px;height:34px;border-radius:8px;
  border:1px solid rgba(255,255,255,.22);color:#cbd8e9}
.social a:hover{background:rgba(255,255,255,.1);color:#fff;border-color:rgba(255,255,255,.4)}

/* Beaten by the footer's own list reset, so say it with the parent. */
.foot-legal .social{margin-left:auto}
@media (max-width:640px){
  /* On a phone the legal links wrap, so the icons take a row of their own on
     the left rather than hanging off the end of one. */
  .foot-legal .social{margin-left:0;width:100%}
}

/* Parts: what the stores hold, by equipment family. */
.partsgrid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:clamp(18px,2vw,26px);margin-top:clamp(28px,3.4vw,44px)}
.partsgroup{padding:clamp(20px,2vw,26px);background:#fff;border:1px solid var(--line);border-radius:12px}
.partsgroup h3{font-family:var(--f-cond);font-weight:600;font-size:1.12rem;letter-spacing:-.01em;margin:0 0 12px;color:var(--ink)}
.partsgroup ul{margin:0;padding:0;list-style:none;display:flex;flex-direction:column;gap:7px;font-size:14.5px;line-height:1.5;color:var(--ink-2)}
.partsgroup li{padding-left:14px;position:relative}
.partsgroup li::before{content:"";position:absolute;left:0;top:9px;width:5px;height:1px;background:var(--accent)}
.partsnote{margin:clamp(20px,2.4vw,28px) 0 0;max-width:92ch;font-size:13.5px;line-height:1.7;color:var(--ink-3)}
/* Four cards read better as a square than as a row of three with a gap. */
.partsgrid.two{grid-template-columns:repeat(2,minmax(0,1fr))}
@media (max-width:1000px){ .partsgrid{grid-template-columns:repeat(2,minmax(0,1fr))} }
@media (max-width:640px){ .partsgrid{grid-template-columns:1fr} }

/* Footer contact links: a phone number and an email address are the two most
   likely things to be tapped on a phone, and both were text-sized targets on
   text-sized lines. 44px of height each, with real space between them. */
.foot-contact{margin:12px 0 0}
.foot-contact a{display:inline-flex;align-items:center;min-height:44px;padding:2px 0}
.foot-contact + .foot-contact{margin-top:0}
@media (max-width:860px){ .foot-contact a{min-height:48px} }

/* ------------------------------------------------------------------ Summa
   F Series tooling. Summa's product images are cut-outs on white, so every
   image panel on this page is white and the picture is contained rather than
   cropped: a tool photographed against white cannot be cropped to fill a box
   without losing the tip, which is the part that matters. */
.hero-split.media-light .hero-split-media{background:#fff}
.hero-split.media-light .hero-split-media img{object-fit:contain;padding:clamp(24px,3vw,48px)}
@media (max-width:900px){ .hero-split.media-light .hero-split-media{min-height:280px} }

/* Table, module, tool: the three things that decide the cut. */
.chain{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:clamp(16px,2vw,26px);margin-top:clamp(28px,3.4vw,44px)}
.chain-step{margin:0;background:#fff;border:1px solid var(--line);border-radius:12px;overflow:hidden;position:relative}
.chain-step img{display:block;width:100%;height:210px;object-fit:cover;background:#fff}
.chain-step img.is-product,.chain-step .chain-img.is-product{object-fit:contain;padding:18px;background:#fff}
.chain-step figcaption{padding:16px clamp(16px,1.8vw,22px) 20px;border-top:1px solid var(--line)}
.chain-step b{display:block;font-family:var(--f-cond);font-weight:600;font-size:1.08rem;color:var(--ink)}
.chain-step span{display:block;margin-top:4px;font-size:14px;line-height:1.5;color:var(--ink-2)}
@media (max-width:760px){ .chain{grid-template-columns:1fr} .chain-step img{height:170px} }

/* Module cards. */
.prodgrid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:clamp(18px,2vw,26px);margin-top:clamp(28px,3.4vw,44px)}
.prodcard{display:flex;flex-direction:column;background:#fff;border:1px solid var(--line);border-radius:12px;overflow:hidden}
.prodcard-img{background:#fff;padding:22px;border-bottom:1px solid var(--line);height:244px;display:flex;align-items:center;justify-content:center}
.prodcard-img img{display:block;width:100%;height:100%;object-fit:contain}
.prodcard h3{font-family:var(--f-cond);font-weight:600;font-size:1.15rem;letter-spacing:-.01em;margin:20px clamp(18px,2vw,24px) 0}
.prodcard p{margin:10px clamp(18px,2vw,24px) 0;font-size:14.5px;line-height:1.6;color:var(--ink-2)}
.prodcard-link{margin-top:auto;padding:18px 0 22px}
@media (max-width:1000px){ .prodgrid{grid-template-columns:repeat(2,minmax(0,1fr))} }
@media (max-width:640px){ .prodgrid{grid-template-columns:1fr} .prodcard-img{height:210px} }

/* Tooling by job: picture beside the words, so the page never runs two
   text blocks together. */
.jobgrid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:clamp(18px,2vw,26px);margin-top:clamp(28px,3.4vw,44px)}
.jobcard{display:grid;grid-template-columns:132px minmax(0,1fr);background:#fff;border:1px solid var(--line);border-radius:12px;overflow:hidden}
.jobcard-img{background:#fff;border-right:1px solid var(--line);display:flex;align-items:center;justify-content:center;padding:16px}
.jobcard-img img{display:block;width:100%;height:190px;object-fit:contain}
.jobcard-body{padding:clamp(18px,2vw,24px)}
.jobcard h3{font-family:var(--f-cond);font-weight:600;font-size:1.15rem;letter-spacing:-.01em;margin:0}
.jobcard p{margin:10px 0 0;font-size:14.5px;line-height:1.6;color:var(--ink-2)}
.jobcard-tools b{display:block;font-family:var(--f-mono);font-size:10.5px;font-weight:600;letter-spacing:.12em;text-transform:uppercase;color:var(--ink-3);margin-bottom:4px}
.jobcard-mod{font-family:var(--f-mono);font-size:11px;letter-spacing:.08em;text-transform:uppercase;color:var(--accent)}
@media (max-width:900px){ .jobgrid{grid-template-columns:1fr} }
@media (max-width:520px){ .jobcard{grid-template-columns:1fr} .jobcard-img{border-right:0;border-bottom:1px solid var(--line)} .jobcard-img img{height:150px} }

/* ---------------------------------------------------------------------------
   PRIMARY NAV PANELS                                          added 25/09/2026

   Four subjects in the bar, with a panel under two of them and a three column
   panel under Equipment sales.

   The panel is a child of the <li> and positioned against the header, not
   against the item, so the wide one can run the full width of the page while
   the narrow ones sit under their own word.

   Opening is hover on a pointer, click on touch, and the button for anyone on
   a keyboard. `:focus-within` is what makes tabbing through it work without a
   line of script.
   --------------------------------------------------------------------------- */
.top-in{position:relative}
.nav-list{gap:4px}
.nav-item{position:static;display:flex;align-items:center}
.nav-link{display:block;padding:9px 11px;border-radius:7px;font-size:14.5px;line-height:1.2;
  color:var(--ink-2);white-space:nowrap}
.nav-item:hover > .nav-link,.nav-item:focus-within > .nav-link{background:var(--surface-2);color:var(--ink)}
.nav-item.is-current > .nav-link{color:var(--ink);font-weight:600}
.nav-more{display:inline-flex;align-items:center;justify-content:center;width:22px;height:30px;
  margin-left:-6px;padding:0;border:0;background:none;color:var(--ink-4);cursor:pointer}
.nav-item:hover .nav-more,.nav-item:focus-within .nav-more{color:var(--ink-2)}

.nav-panel{position:absolute;top:100%;left:0;right:0;z-index:30;margin-top:0;
  background:#fff;border:1px solid var(--line);border-top:2px solid var(--accent);
  border-radius:0 0 10px 10px;box-shadow:0 26px 46px -22px rgba(15,20,25,.45);
  opacity:0;visibility:hidden;transform:translateY(-4px);transition:opacity .13s ease,transform .13s ease}
/* The bridge. Between the bottom of the menu item and the top of the panel
   there is the header's own padding, and crossing it lost the hover, so the
   panel closed on the way to it. This is part of the panel, so hovering it
   keeps the item hovered, and it only exists while the panel is open. */
.nav-panel::before{content:"";position:absolute;left:0;right:0;top:-22px;height:22px}
.nav-item:hover > .nav-panel,
.nav-item.is-open > .nav-panel,
.nav-item:focus-within > .nav-panel,
.nav-item .nav-more[aria-expanded="true"] + .nav-panel{opacity:1;visibility:visible;transform:none}
.nav-item.is-open > .nav-link{background:var(--surface-2);color:var(--ink)}

/* Rows inside the panel. */
.nav-row{display:block;padding:9px 11px;border-radius:7px}
.nav-row:hover{background:var(--surface-2)}
.nav-row b{display:block;font-size:14.5px;font-weight:600;color:var(--ink);line-height:1.35}
.nav-row span{display:block;font-size:12.5px;color:var(--ink-3);margin-top:1px}

.nav-mega{display:grid;grid-template-columns:repeat(3,1fr);max-width:var(--wrap);margin:0 auto}
.nav-col{padding:22px 22px 24px;border-right:1px solid var(--line-2);display:flex;flex-direction:column}
.nav-col-actions{margin-top:auto}
.nav-col:last-child{border-right:0}
.nav-col.is-summa{background:var(--surface-2)}
.nav-col-h{margin:0;font-family:var(--f-mono,var(--f-sans));font-size:11px;font-weight:700;
  letter-spacing:.14em;text-transform:uppercase;color:var(--ink-4)}
.nav-col-p{margin:9px 0 14px;font-size:13.5px;line-height:1.55;color:var(--ink-2);max-width:38ch}
.nav-col .nav-row{margin-inline:-11px}
.nav-col.is-summa .nav-row:hover{background:#fff}
.nav-col-actions{display:flex;align-items:center;gap:16px;flex-wrap:wrap;
  margin:16px 0 0;padding-top:16px;border-top:1px solid var(--line-2)}
.nav-col-actions .btn{padding:9px 15px;font-size:14px}

@media (max-width:1080px){
  .nav-link{padding:9px 8px;font-size:14px}
  .nav-col{padding:18px}
}

@media (max-width:900px){
  /* In the drawer the panels are stacked, always open, and indented. Nothing
     hovers on a phone and a two-tap menu inside a menu is how people end up
     on the wrong page. */
  .top .nav{padding:6px 8px 10px}
  .nav-list{display:grid;gap:0}
  .nav-item{display:block;border-bottom:1px solid var(--line-2)}
  .nav-item:last-child{border-bottom:0}
  .nav-link{padding:13px 10px;font-size:15.5px;font-weight:600;color:var(--ink)}
  .nav-more{display:none}
  .nav-panel{position:static;opacity:1;visibility:visible;transform:none;border:0;
    box-shadow:none;background:none;border-radius:0;padding:0 0 10px}
  .nav-mega{display:grid;grid-template-columns:1fr;padding:0}
  .nav-col{padding:8px 0 14px;border-right:0}
  .nav-col.is-summa{background:none}
  .nav-col-p{display:none}
  .nav-col .nav-row,.nav-row{margin-inline:0;padding:7px 10px 7px 22px;border-bottom:0}
  .nav-row b{font-size:14px;font-weight:500;color:var(--ink-2)}
  .nav-row:hover b{color:var(--accent)}
  .nav-row span{display:none}
  .nav-col-h{padding:10px 10px 2px 22px;font-size:10.5px}
  .nav-col-actions{padding-left:22px}
}

/* ---------------------------------------------------------------------------
   ROUTE CARDS                                                 added 25/09/2026

   The three doors on the equipment sales page. A picture, a name, one
   sentence, and the real links underneath rather than a button that makes
   somebody click twice to find out what is inside.

   Equal heights come from subgrid, so the three sets of links line up however
   long the sentences are.
   --------------------------------------------------------------------------- */
.routecards{display:grid;grid-template-columns:repeat(3,1fr);gap:clamp(16px,2vw,24px)}
.routecard{display:grid;grid-template-rows:auto 1fr;background:#fff;border:1px solid var(--line);
  border-radius:10px;overflow:hidden;box-shadow:0 18px 40px -26px rgba(15,20,25,.4)}
.routecard-img{aspect-ratio:16/10;overflow:hidden;background:var(--surface-2)}
.routecard-img img{width:100%;height:100%;object-fit:cover;display:block}
.routecard-img .imgslot{height:100%;min-height:0;border:0;border-radius:0}
.routecard-img .imgslot img{width:100%;height:100%;object-fit:cover}
.routecard-body{padding:24px 24px 26px;display:flex;flex-direction:column}
.routecard-flag{margin:0 0 6px;font-size:12px;font-weight:600;letter-spacing:.02em;color:var(--accent)}
.routecard h2{margin:0;font-family:var(--f-cond);font-size:clamp(1.3rem,2vw,1.6rem);
  font-weight:600;letter-spacing:-.01em;color:var(--ink)}
.routecard > .routecard-body > p{margin:10px 0 0;font-size:14.8px;line-height:1.65;color:var(--ink-2)}
.routecard-links{list-style:none;margin:16px 0 0;padding:14px 0 0;border-top:1px solid var(--line-2)}
.routecard-links li{margin:0;padding:0;list-style:none}
.routecard-links li + li{border-top:1px solid var(--line-2)}
.routecard-links a{display:block;padding:9px 0;font-size:14.5px;font-weight:500;color:var(--ink)}
.routecard-links a:hover{color:var(--accent)}
.routecard-links a::after{content:" \2192";color:var(--ink-4)}
.routecard.is-summa{border-color:color-mix(in srgb,var(--accent) 35%,var(--line))}

@media (max-width:1000px){.routecards{grid-template-columns:1fr;max-width:620px;margin-inline:auto}}

/* Manufacturer filter on the stock archive.                    added 25/09/2026
   Built from the makes actually in stock, so it never offers a route to an
   empty page. */
.makerow{display:flex;flex-wrap:wrap;gap:8px;margin-top:clamp(26px,3vw,34px)}
.makechip{display:inline-flex;align-items:center;gap:7px;padding:8px 14px;border:1px solid var(--line);
  border-radius:999px;background:#fff;font-size:14px;font-weight:500;color:var(--ink)}
.makechip span{font-family:var(--f-mono,var(--f-sans));font-size:11.5px;color:var(--ink-4)}
.makechip:hover{border-color:var(--accent);color:var(--accent)}
.makechip.is-on{background:var(--navy);border-color:var(--navy);color:#fff}
.makechip.is-on span{color:#b9cde4}
.stock-note{margin:14px 0 0;font-size:12.5px;line-height:1.6;color:var(--ink-3)}

/* Breadcrumbs on a light section. The rule above is written for the dark
   hero; on a white page top it rendered pale blue on white. 25/09/2026 */
.sec.white .crumbs ol,.sec .crumbs ol{color:var(--ink-4)}
.sec.white .crumbs a,.sec .crumbs a{color:var(--ink-3);border-bottom-color:var(--line)}
.sec.white .crumbs a:hover,.sec .crumbs a:hover{color:var(--accent)}
.sec.white .crumbs [aria-current],.sec .crumbs [aria-current]{color:var(--ink-4)}
.pagetop .crumbs ol{margin-bottom:12px}

/* Four routes, from 25/09/2026: parts is now a subject in its own right and
   the homepage says so. At tablet width four columns become two, which is
   better than four 140px columns of broken lines. */
.routestrip.four .routestrip-in{grid-template-columns:repeat(4,minmax(0,1fr))}
@media (max-width:1040px){
  .routestrip.four .routestrip-in{grid-template-columns:repeat(2,minmax(0,1fr));row-gap:22px}
  .routestrip.four .route:nth-child(3){padding-left:0;box-shadow:none}
}
@media (max-width:700px){
  .routestrip.four .routestrip-in{grid-template-columns:1fr;row-gap:0}
  .routestrip.four .route:nth-child(3){border-top:1px solid var(--line)}
}

/* A button inside the nav is a button. `.nav a` sets the link colour for the
   bar and was winning over `.btn`, which painted the Summa panel's call to
   action dark blue on dark blue. 25/09/2026 */
.nav .btn{color:#fff}
.nav .btn.ghost,.nav .btn.light{color:var(--ink)}

/* A cross-link between the two commercial journeys. Parts and machines are
   different purchases and stay on different pages, but somebody on the wrong
   one should get across in a single click. 25/09/2026 */
.crosslink{display:flex;align-items:center;justify-content:space-between;gap:clamp(20px,3vw,44px);
  flex-wrap:wrap;padding:clamp(22px,2.6vw,30px) clamp(24px,3vw,34px);background:var(--surface-2);
  border:1px solid var(--line);border-radius:10px}
.crosslink h2{margin:0;font-family:var(--f-cond);font-size:clamp(1.15rem,1.9vw,1.45rem);
  font-weight:600;letter-spacing:-.01em;color:var(--ink)}
.crosslink p{margin:6px 0 0;font-size:14.8px;line-height:1.6;color:var(--ink-2);max-width:62ch}
.crosslink-act{display:flex;align-items:center;gap:16px;flex-wrap:wrap;margin:0}

/* ---------------------------------------------------------------------------
   SOFTWARE MATRIX                                             added 30/09/2026

   Which edition runs on which machine. A table because it is a table: three
   columns, a head row, and rows that collapse into stacked blocks with their
   labels on a phone rather than into a sideways scroll.
   --------------------------------------------------------------------------- */
.swtable{margin-top:clamp(28px,3.4vw,42px);border:1px solid var(--line);border-radius:10px;
  overflow:hidden;background:#fff}
.swrow{display:grid;grid-template-columns:200px 230px 1fr;gap:0}
.swrow > div{padding:16px 20px;border-bottom:1px solid var(--line-2);font-size:15px;
  line-height:1.6;color:var(--ink-2)}
.swrow:last-child > div{border-bottom:0}
.swrow.is-head > div{background:var(--surface-2);font-family:var(--f-mono,var(--f-sans));
  font-size:11px;font-weight:700;letter-spacing:.14em;text-transform:uppercase;
  color:var(--ink-4);padding-block:11px}
.swrow > div:first-child{font-weight:600;color:var(--ink)}
.swrow > div + div{box-shadow:inset 1px 0 0 var(--line-2)}
.swrow b{color:var(--ink)}
.swrow a{color:var(--ink);border-bottom:1px solid var(--line)}
.swrow a:hover{color:var(--accent);border-bottom-color:var(--accent)}

@media (max-width:860px){
  .swrow{grid-template-columns:1fr}
  .swrow.is-head{display:none}
  .swrow{border-bottom:1px solid var(--line);padding:6px 0}
  .swrow:last-child{border-bottom:0}
  .swrow > div{border-bottom:0;padding:5px 18px}
  .swrow > div + div{box-shadow:none}
  .swrow > div:first-child{padding-top:16px;font-size:16px}
  .swrow > div:last-child{padding-bottom:18px}
}

/* ---------------------------------------------------------------------------
   PRODUCT IMAGES: THE OVERFLOW FIX                            added 30/09/2026

   The module and tool photographs were breaking out of their cards and running
   over the heading underneath. It was never the stale stylesheet it looked
   like: `.sec img, .sec .shot, .split img { height:auto }` at line 843 is two
   classes, and every rule that gave these images a fixed height was one class
   and an element, so the site-wide rule won and the height went back to auto.
   A 1200px tall product shot in a 244px box then did exactly what it was told.

   Fixed by matching that specificity rather than by reaching for !important,
   and by clipping the frames as well, so a future image that escapes is
   trimmed rather than printed over the text.
   --------------------------------------------------------------------------- */
.prodcard .prodcard-img{overflow:hidden}
.prodcard .prodcard-img img,
.prodcard .prodcard-img .shot{width:100%;height:100%;object-fit:contain;max-width:100%;
  background:#fff}
.jobcard .jobcard-img{overflow:hidden}
.jobcard .jobcard-img img,
.jobcard .jobcard-img .shot{width:100%;height:190px;object-fit:contain;max-width:100%;
  background:#fff}
.chain .chain-step img,
.chain .chain-step .shot{height:210px;object-fit:cover}
.chain .chain-step img.is-product,
.chain .chain-step .shot.is-product{object-fit:contain}

@media (max-width:640px){ .prodcard .prodcard-img img,.prodcard .prodcard-img .shot{height:100%} }
@media (max-width:520px){ .jobcard .jobcard-img img,.jobcard .jobcard-img .shot{height:150px} }

/* ---------------------------------------------------------------------------
   THE TOOL LINE-UP                                            added 30/09/2026

   Fifteen tools, each with Summa's own photograph and Summa's own figure,
   grouped by what the tool does. It replaces six job cards that named the
   tools in a comma separated list, which is why the page read as though tools
   were missing when in fact only the pictures were.

   The photographs are tall and narrow, so the frame is portrait and the image
   is contained inside it rather than cropped.
   --------------------------------------------------------------------------- */
.toolhead{margin:clamp(30px,3.4vw,44px) 0 0;font-family:var(--f-cond);font-weight:600;
  font-size:1.18rem;letter-spacing:-.01em;color:var(--ink);padding-bottom:12px;
  border-bottom:1px solid var(--line)}
.toolgrid{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:clamp(14px,1.6vw,20px);
  margin-top:clamp(18px,2vw,26px)}
.toolcard{display:flex;flex-direction:column;background:#fff;border:1px solid var(--line);
  border-radius:10px;overflow:hidden}
.toolcard-img{height:190px;padding:16px;background:#fff;border-bottom:1px solid var(--line-2);
  display:flex;align-items:center;justify-content:center;overflow:hidden}
.toolcard .toolcard-img img,
.toolcard .toolcard-img .shot{width:100%;height:100%;object-fit:contain;max-width:100%;background:#fff}
.toolcard-img.is-empty{background:var(--surface-2)}
.toolcard-img.is-empty span{font-family:var(--f-mono,var(--f-sans));font-size:10.5px;
  letter-spacing:.12em;text-transform:uppercase;color:var(--ink-4);text-align:center}
.toolcard h4{margin:16px 18px 0;font-size:1rem;font-weight:600;letter-spacing:-.01em;color:var(--ink)}
.toolcard p{margin:7px 18px 0;font-size:14px;line-height:1.55;color:var(--ink-2)}
.toolcard p b{color:var(--ink);font-weight:600}
.toolcard-mod{display:block;margin:14px 18px 16px;padding-top:12px;border-top:1px solid var(--line-2);
  font-family:var(--f-mono,var(--f-sans));font-size:10.5px;letter-spacing:.1em;
  text-transform:uppercase;color:var(--ink-4);margin-top:auto}

/* Blades and bits: smaller, because they are a reference row rather than a
   product grid. */
.bladegrid{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:clamp(12px,1.4vw,18px);
  margin-top:clamp(24px,3vw,36px)}
.bladecard{margin:0;background:#fff;border:1px solid var(--line);border-radius:10px;overflow:hidden}
.bladecard img,.bladecard .shot{display:block;width:100%;height:150px;object-fit:contain;
  background:#fff;padding:12px}
.bladecard figcaption{padding:11px 14px 13px;border-top:1px solid var(--line-2);font-size:13.5px;
  font-weight:500;color:var(--ink)}

@media (max-width:1000px){
  .toolgrid,.bladegrid{grid-template-columns:repeat(3,minmax(0,1fr))}
}
@media (max-width:720px){
  .toolgrid,.bladegrid{grid-template-columns:repeat(2,minmax(0,1fr))}
  .toolcard-img{height:150px}
  .bladecard img,.bladecard .shot{height:120px}
}


/* Body scroll lock while the mobile drawer is open. Without it the page runs
   under the menu on a phone, which is what the menu is covering. 30/09/2026 */
body.nav-locked{overflow:hidden;touch-action:none}

/* Summa's logo at the head of its column, in place of the panel label.
   The supplied SVG carries its own clear space, so it needs none added.
   30/09/2026 */
.nav-col-brand{display:block;margin:-4px 0 10px}
.nav-col-brand img{display:block;width:98px;height:auto}
.nav-col.is-summa .nav-col-p{margin:0 0 10px}
/* Seven rows in this column against four in the next, so it sets the height of
   the whole panel. Tighter rows here keep it in one screen on a laptop. */
.nav-col.is-summa .nav-row{padding-block:6px}
.nav-col.is-summa .nav-col-actions{margin-top:14px;padding-top:14px}
/* And a floor under it: on a short screen the panel scrolls rather than
   running off the bottom. */
.nav-panel{max-height:calc(100dvh - 150px);overflow-y:auto;overscroll-behavior:contain}

/* The module cards link down to the tool group their tools sit in, so the
   heading has to clear the sticky header and the Summa row under it.
   30/09/2026 */
.toolhead{scroll-margin-top:150px}

/* ---------------------------------------------------------------------------
   SUMMA SOFTWARE PORTFOLIO                                    added 01/10/2026

   Six product cards directly under the hero, so the software family is
   visible before any explanation of it. Summa supply no software logos, so
   the product name is set large and does the work a logo would; nothing here
   invents a mark.

   Three variants rather than six identical boxes: the three editions that
   come with a machine, the two platform products in navy because they are
   bought on their own merits, and the design software as a quieter card.
   --------------------------------------------------------------------------- */
.swcards{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:clamp(14px,1.6vw,20px)}
.swcard{display:flex;flex-direction:column;background:#fff;border:1px solid var(--line);
  border-top:3px solid var(--accent);border-radius:10px;padding:clamp(20px,2.2vw,26px);
  box-shadow:0 16px 36px -28px rgba(15,20,25,.5)}
.swcard-for{margin:0;font-family:var(--f-mono,var(--f-sans));font-size:10.5px;font-weight:700;
  letter-spacing:.12em;text-transform:uppercase;color:var(--ink-4)}
.swcard h2{margin:10px 0 0;font-family:var(--f-cond);font-weight:600;
  font-size:clamp(1.5rem,2.3vw,1.85rem);letter-spacing:-.02em;color:var(--ink);line-height:1.05}
.swcard > p:not(.swcard-for):not(.swcard-link){margin:12px 0 0;font-size:14.8px;line-height:1.6;
  color:var(--ink-2)}
.swcard-link{display:flex;flex-wrap:wrap;gap:16px;margin:18px 0 0;padding-top:14px;
  border-top:1px solid var(--line-2);margin-top:auto;font-size:14px}

.swcard.is-platform{background:var(--navy);border-color:var(--navy);border-top-color:#3aa7e0}
.swcard.is-platform .swcard-for{color:#8fb0da}
.swcard.is-platform h2{color:#fff}
.swcard.is-platform > p:not(.swcard-for):not(.swcard-link){color:#d6e3f2}
.swcard.is-platform .swcard-link{border-top-color:rgba(255,255,255,.18)}
.swcard.is-platform .tlink{color:#9fd0f3}
.swcard.is-platform .tlink:hover{color:#fff}

.swcard.is-note{background:var(--surface-2);border-top-color:var(--ink-4)}

/* GoData and GoConnect in full, side by side. */
.swpair{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:clamp(16px,2vw,24px);
  margin-top:clamp(28px,3.4vw,42px)}
.swpanel{background:#fff;border:1px solid var(--line);border-radius:10px;
  padding:clamp(22px,2.4vw,30px)}
.swpanel h3{margin:0;font-family:var(--f-cond);font-weight:600;font-size:1.45rem;
  letter-spacing:-.015em;color:var(--ink)}
.swpanel > p{margin:10px 0 0;font-size:15px;line-height:1.65;color:var(--ink-2)}
.swpanel .ticks{list-style:none;margin:18px 0 0;padding:16px 0 0;border-top:1px solid var(--line-2);
  display:flex;flex-direction:column;gap:10px;font-size:14.5px;line-height:1.5;color:var(--ink-2)}
.swpanel .ticks li{position:relative;padding-left:22px}
.swpanel .ticks li::before{content:"";position:absolute;left:0;top:7px;width:9px;height:5px;
  border-left:2px solid var(--accent);border-bottom:2px solid var(--accent);transform:rotate(-45deg)}

@media (max-width:1000px){
  .swcards{grid-template-columns:repeat(2,minmax(0,1fr))}
  .swpair{grid-template-columns:1fr}
}
@media (max-width:640px){ .swcards{grid-template-columns:1fr} }

/* A band of articles about one topic, dropped onto a section page.
   Shares the news card, so it cannot drift from the archive. 01/10/2026 */
.topicnews-head{display:flex;align-items:baseline;justify-content:space-between;gap:20px;
  flex-wrap:wrap;margin-bottom:clamp(20px,2.4vw,30px)}
.topicnews-head h2{margin:0;font-family:var(--f-cond);font-weight:600;
  font-size:clamp(1.3rem,2vw,1.6rem);letter-spacing:-.015em;color:var(--ink)}

/* ---------------------------------------------------------------------------
   NEWS ARCHIVE: THE GAP UNDER THE FILTER                      added 01/10/2026

   The header block and the archive band each carried a full 92px of section
   padding, so 185px of nothing sat between the category chips and the first
   article. That rhythm is right when a band opens with a section heading and
   wrong here, where the header ends in small chips and the next band opens
   with a card.

   Halved rather than removed: the chips still need air under them, and the
   colour change still needs to read as a new band.
   --------------------------------------------------------------------------- */
.sec.pagetop:has(.newsfilter){padding-bottom:clamp(26px,2.6vw,36px)}
.sec.newsarchive{padding-top:clamp(30px,3.4vw,48px)}

/* No `:has()` (older Safari and Firefox before 121): the archive side of the
   fix still applies, so the gap closes most of the way rather than not at
   all. */
@supports not selector(:has(*)){
  .sec.newsarchive{padding-top:clamp(26px,3vw,40px)}
}

/* Machines we have sold. A plain list on purpose: photographs here would
   compete with the machines that are actually for sale. */
.soldsec{padding-top:clamp(40px,5vw,64px)}
.soldgrid{display:grid;grid-template-columns:repeat(auto-fill,minmax(260px,1fr));gap:2px;margin-top:clamp(22px,3vw,30px);
  border-top:1px solid var(--line)}
.soldrow{display:flex;align-items:baseline;justify-content:space-between;gap:12px;
  padding:13px 14px 13px 0;border-bottom:1px solid var(--line);color:var(--ink-1);text-decoration:none;
  font-size:.97rem;line-height:1.4}
.soldrow span{display:block}
.soldrow b{flex:0 0 auto;font-weight:600;color:var(--ink-2);font-variant-numeric:tabular-nums}
.soldrow:hover{color:var(--brand);background:color-mix(in srgb,var(--brand) 5%,transparent)}
.soldrow:hover b{color:var(--brand)}
@media (max-width:700px){
  .soldgrid{grid-template-columns:1fr}
  .soldrow{padding-right:4px}
}
