/* Swiftheat Thermal Technologies — one stylesheet for the whole site.
   Art direction: photography led hero and industry layer (dark ground, condensed
   display type), datasheet treatment for the product and specification layer
   (near white ground, hairline rules, tabular figures), with one recurring
   temperature scale device carried across both. */

@font-face{font-family:"Archivo Narrow";src:url("../fonts/archivo-narrow-latin-600-normal.woff2") format("woff2");font-weight:600;font-style:normal;font-display:swap}
@font-face{font-family:"Archivo Narrow";src:url("../fonts/archivo-narrow-latin-700-normal.woff2") format("woff2");font-weight:700;font-style:normal;font-display:swap}
@font-face{font-family:"Inter";src:url("../fonts/inter-latin-400-normal.woff2") format("woff2");font-weight:400;font-style:normal;font-display:swap}
@font-face{font-family:"Inter";src:url("../fonts/inter-latin-500-normal.woff2") format("woff2");font-weight:500;font-style:normal;font-display:swap}
@font-face{font-family:"Inter";src:url("../fonts/inter-latin-600-normal.woff2") format("woff2");font-weight:600;font-style:normal;font-display:swap}

:root{
  --ink-900:hsl(214 32% 11%);--ink-800:hsl(214 26% 18%);--ink-700:hsl(214 20% 28%);
  --ink-600:hsl(214 14% 40%);--ink-500:hsl(214 12% 46%);--ink-300:hsl(214 16% 80%);
  --ink-200:hsl(214 20% 88%);--ink-100:hsl(214 24% 94%);
  --paper:hsl(40 24% 97%);--surface:#fff;--surface-sunk:hsl(40 20% 95%);
  /* Accent ramp taken from Swiftheat's own logo, which is raw #ff0000 red beside
     raw #0000ff blue. The ramp is that red deepened into something usable on
     screen; the ink ramp above is already the navy that answers the logo blue.
     Red at a given lightness is darker than orange at the same lightness, so
     700, 600 and 400 all read at a higher contrast than the orange they
     replaced. 500 is the exception. Every text use of it sits on a dark
     surface, and the palest of those is the photograph placeholder at
     hsl(214 30% 16%) rather than ink-900, so 500 is lightened instead of
     deepened and saturation is pushed to keep it a red rather than a salmon.
     It clears 4.6:1 on the placeholder and 5.4:1 on ink-900. */
  --heat-700:hsl(4 84% 33%);--heat-600:hsl(6 86% 39%);--heat-500:hsl(12 100% 58%);
  --heat-400:hsl(6 74% 48%);--heat-200:hsl(8 90% 90%);--heat-100:hsl(10 88% 96%);
  --focus:hsl(215 90% 42%);
  --shadow-image:0 1px 2px hsl(214 32% 11% / .08),0 12px 32px hsl(214 32% 11% / .12);
  --s1:4px;--s2:8px;--s3:12px;--s4:16px;--s5:24px;--s6:32px;--s7:48px;--s8:64px;--s9:96px;
  --radius:3px;--wrap:1180px;
  --header-h:72px;   /* masthead height; the sticky jump nav offsets by it */
  --header-offset:var(--header-h);
}
/* Scroll-down hides the masthead and releases this offset so the jump nav
   (and anything else parked under the header) can take the top of the screen.
   On a phone, a focused field or an open keyboard does the same, so the
   sticky bar and the keyboard do not split the screen. */
html.header-hidden,html.is-typing{--header-offset:0px}
*,*::before,*::after{box-sizing:border-box}
html{-webkit-text-size-adjust:100%;scroll-behavior:smooth}
@media (prefers-reduced-motion:reduce){html{scroll-behavior:auto}*{transition:none!important;animation:none!important}}
body{margin:0;background:var(--paper);color:var(--ink-800);
  font-family:Inter,system-ui,sans-serif;font-size:1rem;line-height:1.65;
  font-feature-settings:"tnum" 1;-webkit-font-smoothing:antialiased}
h1,h2,h3,h4,.display{font-family:"Archivo Narrow",Archivo,"Arial Narrow",sans-serif;font-weight:700;color:var(--ink-900);letter-spacing:-.01em}
h1{font-size:clamp(2.25rem,1.5rem + 3vw,3.5rem);line-height:1.02;margin:0 0 var(--s4)}
h2{font-size:clamp(1.5rem,1.25rem + 1.1vw,2.1rem);line-height:1.12;margin:0 0 var(--s4)}
h3{font-size:1.15rem;line-height:1.3;margin:0 0 var(--s3);font-weight:600}
h4{font-size:.95rem;margin:0 0 var(--s2);font-weight:600}
p{margin:0 0 var(--s4);max-width:68ch}
ul,ol{margin:0 0 var(--s4);padding-left:1.15em;max-width:68ch}
li{margin-bottom:var(--s2)}
li::marker{color:var(--heat-600)}
a{color:var(--heat-700)}
strong{font-weight:600;color:var(--ink-900)}
img{max-width:100%;height:auto}
:focus-visible{outline:3px solid var(--focus);outline-offset:2px}
.skip{position:absolute;left:-9999px}
.skip:focus{left:var(--s4);top:var(--s4);z-index:99;background:var(--ink-900);color:#fff;padding:var(--s3) var(--s4)}
.wrap{max-width:var(--wrap);margin:0 auto;padding:0 var(--s5)}
.vh{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}

/* ---------- site chrome ---------- */
.topbar{background:var(--ink-900);color:hsl(214 16% 72%);font-size:.82rem;padding:var(--s2) 0}
.topbar .wrap{display:flex;gap:var(--s5);flex-wrap:wrap;justify-content:flex-end;align-items:center}
.topbar .where{margin-right:auto;max-width:none}
.topbar a{color:hsl(214 16% 82%);text-decoration:none}
.topbar a:hover{color:#fff;text-decoration:underline}
.masthead{background:var(--surface);border-bottom:1px solid var(--ink-200);position:sticky;top:0;z-index:20;
  transition:transform .22s ease,box-shadow .22s ease}
html.is-scrolled .masthead{box-shadow:0 8px 24px hsl(214 32% 11% / .08)}
html.header-hidden .masthead,html.is-typing .masthead{transform:translateY(-100%);box-shadow:none;pointer-events:none}
.masthead .wrap{display:flex;align-items:center;gap:var(--s5);min-height:var(--header-h)}
/* The masthead lockup is Swiftheat's own logo, traced to vector by
   build/logo-svg.py, over the descriptor the logo itself does not carry. */
.logo{display:block;text-decoration:none;flex:0 0 auto;line-height:1}
.logo img{display:block;width:172px;height:auto}
.logo small{display:block;font-family:Inter,sans-serif;font-size:.75rem;font-weight:500;letter-spacing:.14em;text-transform:uppercase;color:var(--ink-500);margin-top:5px}
.navtoggle{display:none;margin-left:auto;align-items:center;gap:var(--s2);min-height:44px;padding:var(--s2) var(--s3);
  background:var(--surface);border:1px solid var(--ink-300);border-radius:var(--radius);color:var(--ink-900);
  font:inherit;font-size:.9rem;font-weight:600;cursor:pointer}
.navtoggle svg{display:block}
.mainnav{margin-left:auto}
.mainnav > ul{display:flex;gap:var(--s1);list-style:none;margin:0;padding:0;max-width:none}
.mainnav li{margin:0}
.mainnav a{display:block;padding:var(--s3) var(--s3);color:var(--ink-700);text-decoration:none;font-size:.92rem;font-weight:500;border-radius:var(--radius);white-space:nowrap}
.mainnav a:hover{background:var(--ink-100);color:var(--ink-900)}
.mainnav > ul > li > a[aria-current]{color:var(--heat-700);box-shadow:inset 0 -3px 0 var(--heat-500)}
.mainnav .cta a{background:var(--heat-600);color:#fff;font-weight:600}
.mainnav .cta a:hover{background:var(--heat-700);color:#fff}
/* Products disclosure: hover and focus-within on desktop, a 44px chevron on
   touch. Child combinators keep the nested list from inheriting the row. */
.mainnav .has-sub{position:relative}
.mainnav .has-sub > a{display:flex;align-items:center;gap:var(--s2)}
.mainnav .has-sub > a::after{content:"";width:0;height:0;border-left:4px solid transparent;
  border-right:4px solid transparent;border-top:5px solid currentColor;margin-top:2px}
.mainnav .subtoggle{display:none;align-items:center;justify-content:center;min-width:44px;min-height:44px;
  padding:0;border:0;background:transparent;color:var(--ink-700);cursor:pointer}
.mainnav .subtoggle svg{display:block}
.mainnav .submenu{display:none;position:absolute;top:calc(100% - 1px);left:0;z-index:21;
  min-width:18rem;margin:0;padding:var(--s2) 0;list-style:none;max-width:none;
  background:var(--surface);border:1px solid var(--ink-200);border-top:3px solid var(--heat-500);
  border-radius:var(--radius);box-shadow:var(--shadow-image)}
.mainnav .has-sub:hover > .submenu,
.mainnav .has-sub:focus-within > .submenu{display:block}
.mainnav .has-sub.is-closed > .submenu{display:none}
html.header-hidden .mainnav .has-sub > .submenu,
html.is-typing .mainnav .has-sub > .submenu{display:none}
.mainnav .submenu a{white-space:normal;font-size:.88rem;line-height:1.35;padding:var(--s3) var(--s4);border-radius:0}
.mainnav .submenu a[aria-current]{color:var(--heat-700);box-shadow:inset 3px 0 0 var(--heat-500)}

.btn{display:inline-block;background:var(--heat-600);color:#fff;text-decoration:none;font-weight:600;
  padding:var(--s3) var(--s5);border-radius:var(--radius);min-height:44px;line-height:1.85;border:0;cursor:pointer;font-size:1rem;font-family:inherit}
.btn:hover{background:var(--heat-700);color:#fff}
.btn-ghost{background:transparent;color:var(--ink-900);border:1px solid var(--ink-300)}
.btn-ghost:hover{background:var(--surface);border-color:var(--heat-500);color:var(--ink-900)}
.btn-light{background:#fff;color:var(--ink-900)}
.btn-light:hover{background:var(--heat-100);color:var(--ink-900)}
.btn-onink{background:transparent;color:#fff;border:1px solid hsl(214 24% 36%)}
.btn-onink:hover{background:hsl(214 30% 17%);color:#fff;border-color:var(--heat-500)}

/* Same surface as the masthead, so this is a trail not a tinted band between
   two white sections. Items stay on one line; they wrap as a unit, not as a
   full-width first step that parks the rest on a second row. */
.crumb{font-size:.85rem;color:var(--ink-600);background:var(--surface);padding:var(--s2) 0}
.crumb ol{display:flex;flex-wrap:wrap;align-items:center;column-gap:var(--s2);row-gap:0;list-style:none;margin:0;padding:0;max-width:none}
.crumb li{margin:0;display:flex;align-items:center;flex:0 0 auto;white-space:nowrap}
.crumb li::after{content:"\203A";margin-left:var(--s2);color:var(--ink-300)}
.crumb li:last-child::after{content:""}
.crumb a{color:var(--ink-600)}

/* ---------- hero, datasheet register ---------- */
.hero{background:var(--surface);border-top:1px solid var(--ink-200);border-bottom:1px solid var(--ink-200);padding:var(--s7) 0 var(--s8)}
.hero .grid{display:grid;grid-template-columns:minmax(0,1.05fr) minmax(0,.95fr);gap:var(--s8);align-items:start}
.eyebrow{font-size:.78rem;text-transform:uppercase;letter-spacing:.14em;color:var(--heat-700);font-weight:600;margin:0 0 var(--s3)}
.hero p.lede,p.lede{font-size:1.14rem;color:var(--ink-700);max-width:52ch}
.chips{display:flex;flex-wrap:wrap;gap:var(--s3);list-style:none;padding:0;margin:var(--s5) 0;max-width:none}
.chips li{background:var(--surface-sunk);border:1px solid var(--ink-200);border-radius:var(--radius);
  padding:var(--s3) var(--s4);min-width:140px;margin:0}
.chips b{display:block;font-family:"Archivo Narrow",sans-serif;font-size:1.5rem;line-height:1;color:var(--ink-900)}
/* .tbd is less specific than .chips b, so the marker has to be restated here
   or an unconfirmed figure reads as a confirmed one. */
.chips b.tbd{color:var(--heat-700)}
.hero-dark .chips b.tbd{color:var(--heat-200)}
.chips span{display:block;font-size:.78rem;color:var(--ink-600);text-transform:uppercase;letter-spacing:.07em;margin-top:var(--s2)}
.actions{display:flex;gap:var(--s3);flex-wrap:wrap;margin-top:var(--s5)}
/* Four headline figures read as a block of four, not as three and a stray one.
   Below this width they go back to flowing, because a forced two up squeezes
   the labels onto three lines. */
@media (min-width:700px){.hero .chips{display:grid;grid-template-columns:repeat(2,minmax(0,1fr))}}

/* ---------- hero, photography register (home and industry pages) ---------- */
.hero-dark{background:var(--ink-900);color:hsl(214 18% 84%);border:0;padding:var(--s8) 0}
.hero-dark h1,.hero-dark h2,.hero-dark h3{color:#fff}
.hero-dark h1{font-size:clamp(2.5rem,1.4rem + 4.4vw,4.5rem)}
.hero-dark p{color:hsl(214 16% 80%)}
.hero-dark p.lede{color:hsl(214 16% 84%);font-size:1.2rem}
.hero-dark .eyebrow{color:var(--heat-500)}
.hero-dark .chips li{background:hsl(214 30% 15%);border-color:hsl(214 24% 26%)}
.hero-dark .chips b{color:#fff}
.hero-dark .chips span{color:hsl(214 14% 66%)}
.hero-dark .shot{background:repeating-linear-gradient(45deg,hsl(214 30% 15%),hsl(214 30% 15%) 10px,hsl(214 28% 17%) 10px,hsl(214 28% 17%) 20px);border-color:hsl(214 24% 30%)}
.hero-dark .shot .label{color:var(--heat-500)}
.hero-dark .shot p{color:hsl(214 14% 70%)}

/* photograph placeholder. Doubles as the shot list for the photography brief. */
.shot{background:repeating-linear-gradient(45deg,hsl(40 20% 95%),hsl(40 20% 95%) 10px,hsl(40 18% 92%) 10px,hsl(40 18% 92%) 20px);
  border:1px dashed var(--ink-300);border-radius:var(--radius);padding:var(--s5);
  display:flex;flex-direction:column;justify-content:center;min-height:280px;text-align:center}
.shot .label{font-size:.75rem;text-transform:uppercase;letter-spacing:.13em;color:var(--heat-700);font-weight:600}
.shot p{font-size:.9rem;color:var(--ink-600);margin:var(--s3) auto 0;max-width:34ch}
.shot-sm{min-height:150px}
.shot.filled{display:block;padding:0;background:none;border-style:solid;overflow:hidden;box-shadow:var(--shadow-image)}
.shot.filled img{display:block;width:100%;height:100%;object-fit:cover;border-radius:calc(var(--radius) - 1px)}
/* A part on a knocked out ground rather than a photograph of a room. Cover
   would crop the ends off the element, so it is contained and given a surface
   to sit on, and the panel takes its height from the picture. */
/* --art-bg is the colour the photograph's own background was measured at, set
   on the element by the build. The client asked for the borders off their
   pictures and the backgrounds left on, so the panel matches the picture rather
   than the picture being cut out to match the panel. The fallback is what the
   panel was before any photograph landed in it. */
.shot.filled.shot-part{background:var(--art-bg,var(--surface));border-color:var(--ink-200);
  padding:var(--art-pad,var(--s5));min-height:0;display:flex;align-items:center;justify-content:center;box-shadow:none}
.shot[data-gallery] a{display:flex;align-items:center;justify-content:center;width:100%;
  min-height:44px;text-decoration:none;color:inherit;cursor:zoom-in}
.shot[data-gallery]:hover,.three[data-gallery] .shot:hover{border-color:var(--heat-500)}
.shot.filled:not(.shot-part)[data-gallery] > a{display:block;height:100%}
.shot.filled.shot-part img{width:auto;max-width:100%;height:auto;max-height:340px;object-fit:contain}
section.band.alt .shot.filled.shot-part{background:var(--art-bg,var(--paper))}
.hero .shot.filled.shot-part{background:var(--art-bg,var(--surface))}

/* ---------- jump nav ---------- */
.jump{background:var(--surface-sunk);border-bottom:1px solid var(--ink-200);position:sticky;top:var(--header-offset);z-index:15;
  transition:top .22s ease}
/* The link row scrolls sideways when it does not fit. Without an edge fade a
   phone user sees four of eight links and no hint the rest are there. Right
   padding on the list matches the fade so the last link can scroll clear of it. */
.jump .wrap{position:relative}
.jump .wrap::after{content:"";position:absolute;top:0;right:0;bottom:0;width:40px;
  pointer-events:none;background:linear-gradient(to right,hsl(40 20% 95% / 0),var(--surface-sunk))}
@media (min-width:1100px){.jump .wrap::after{display:none}}
.jump ul{display:flex;gap:var(--s1);list-style:none;margin:0;padding:0 40px 0 0;overflow-x:auto;max-width:none}
@media (min-width:1100px){.jump ul{padding-right:0}}
.jump li{margin:0}
.jump a{display:block;white-space:nowrap;padding:var(--s3) var(--s4);font-size:.85rem;font-weight:500;
  color:var(--ink-700);text-decoration:none;border-bottom:2px solid transparent}
.jump a:hover{color:var(--ink-900);border-bottom-color:var(--heat-500)}
/* Current section: same underline as hover, plus the heat-700 used on the
   main nav's aria-current, so the marker is not colour alone. */
.jump a[aria-current]{color:var(--heat-700);border-bottom-color:var(--heat-500)}
/* Hash targets sit under the sticky masthead and jump row. Offset them so a
   click lands with the heading in view, which also keeps the spy in step. */
.jump ~ main section[id]{scroll-margin-top:calc(var(--header-h) + var(--s7))}

/* ---------- sections ---------- */
section.band{padding:var(--s8) 0;border-bottom:1px solid var(--ink-200)}
section.band.alt{background:var(--surface)}
section.band.ink{background:var(--ink-900);color:hsl(214 18% 84%);border-bottom-color:var(--ink-900)}
section.band.ink h2,section.band.ink h3{color:#fff}
section.band.ink p{color:hsl(214 16% 78%)}
section.band.ink a{color:hsl(30 90% 78%)}
.two{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(320px,100%),1fr));gap:var(--s7);align-items:start}
.three{display:grid;grid-template-columns:repeat(auto-fit,minmax(260px,1fr));gap:var(--s6);align-items:start}
.sechead{max-width:64ch;margin-bottom:var(--s6)}
.sechead p{margin-bottom:0}

figure{margin:0}
figure svg{width:100%;height:auto;display:block}
figcaption,.cap{font-size:.82rem;color:var(--ink-600);margin-top:var(--s3)}
.drawing{background:var(--art-bg,var(--surface));border:1px solid var(--ink-200);border-radius:var(--radius);padding:var(--s5)}
/* Same frame as the drawing it replaces, so a family with a photograph in the
   hero and one without still look like the same page. */
/* The build caps each photograph at its own pixel width, so centre what is
   narrower than the figure rather than leaving it hard against the left. */
.figure-photo{box-shadow:var(--shadow-image)}
.figure-photo img{display:block;width:100%;height:auto;max-height:400px;object-fit:contain;margin-inline:auto}
.figure-photo[data-gallery] a{display:block;min-height:44px;text-decoration:none;color:inherit;cursor:zoom-in}
.figure-photo[data-gallery]:hover{border-color:var(--heat-500)}
section.band.alt .drawing{background:var(--art-bg,var(--paper))}
section.band.ink .drawing{background:hsl(214 30% 15%);border-color:hsl(214 24% 26%)}
section.band.ink figcaption{color:hsl(214 14% 66%)}

/* The works gallery uses one deliberate portrait crop so mixed phone-camera
   framing reads as a cohesive set while retaining each original image file. */
.three > .shot.filled{aspect-ratio:3 / 4;min-height:0;position:relative}
.three[data-gallery] .shot.filled > a{position:absolute;inset:0;display:block;
  min-height:44px;text-decoration:none;color:inherit;cursor:zoom-in}
.three[data-gallery] .shot.filled img{width:100%;height:100%;object-fit:cover}

/* Product-form collage: one lead photograph plus a tight 2-up of the rest.
   Related pictures sit closer to each other than to the copy beside them.
   The lead is the primary; the small tiles are secondary by size, not by
   colour. A wide tile is for a form sheet that has to stay readable. */
.collage{display:grid;grid-template-columns:1fr 1fr;gap:var(--s2);margin:0}
.collage-item{display:flex;align-items:center;justify-content:center;
  min-height:44px;padding:var(--s3);text-decoration:none;color:inherit;cursor:zoom-in;
  background:var(--art-bg,var(--surface));border:1px solid var(--ink-200);border-radius:var(--radius)}
.collage-lead,.collage-wide{grid-column:1 / -1;padding:var(--s4)}
.collage-item:hover{border-color:var(--heat-500)}
.collage-item img{display:block;width:auto;max-width:100%;height:auto;max-height:140px;object-fit:contain}
.collage-lead img{max-height:240px}
.collage-wide img{max-height:none}
.collage figcaption{grid-column:1 / -1}

/* Click-to-enlarge gallery. Native dialog so the rest of the page is inert.
   Dark ground, light type, 44 px controls. The track slides; reduced-motion
   users get an instant swap instead. */
.gallery{width:min(960px, calc(100vw - 32px));max-height:calc(100dvh - 32px);
  margin:auto;padding:var(--s5);border:0;border-radius:var(--radius);overflow:auto;
  background:var(--ink-900);color:hsl(214 16% 84%);
  box-shadow:0 24px 64px hsl(214 32% 6% / .45)}
.gallery::backdrop{background:hsl(214 32% 11% / .88)}
.gallery-bar{display:flex;align-items:center;justify-content:space-between;
  gap:var(--s4);margin:0 0 var(--s4)}
.gallery-count{margin:0;font-size:.82rem;color:hsl(214 14% 70%);font-variant-numeric:tabular-nums}
.gallery-stage{overflow:hidden;position:relative;margin:0 48px}
.gallery:not(.gallery-multi) .gallery-prev,
.gallery:not(.gallery-multi) .gallery-next{display:none}
.gallery:not(.gallery-multi) .gallery-stage{margin:0}
.gallery:not(.gallery-multi) .gallery-count{visibility:hidden}
.gallery-track{display:flex;transition:transform .28s ease}
.gallery-slide{flex:0 0 100%;display:flex;align-items:center;justify-content:center;min-height:0}
.gallery-slide img{display:block;width:auto;max-width:100%;height:auto;
  max-height:min(68dvh, 720px);object-fit:contain}
.gallery-cap{margin:var(--s4) 0 0;font-size:.9rem;color:hsl(214 16% 84%);max-width:none;text-align:center}
.gallery-close,.gallery-prev,.gallery-next{
  display:inline-flex;align-items:center;justify-content:center;
  min-width:44px;min-height:44px;padding:0;cursor:pointer;
  background:hsl(214 30% 15%);border:1px solid hsl(214 24% 36%);border-radius:var(--radius);
  color:#fff;font:inherit}
.gallery-close:hover,.gallery-prev:hover,.gallery-next:hover{
  background:hsl(214 30% 17%);border-color:var(--heat-500);color:#fff}
.gallery-stage-wrap{position:relative}
.gallery-prev,.gallery-next{position:absolute;top:50%;transform:translateY(-50%);z-index:1}
.gallery-prev{left:var(--s2)}
.gallery-next{right:var(--s2)}
@media (prefers-reduced-motion:reduce){
  .gallery-track{transition:none}
}

/* ---------- tables ---------- */
.tablewrap{overflow-x:auto;border:1px solid var(--ink-200);border-radius:var(--radius);background:var(--surface);margin:0 0 var(--s5)}
section.band.alt .tablewrap{background:var(--paper)}
table{border-collapse:collapse;width:100%;font-size:.9rem;min-width:520px}
caption{text-align:left;font-size:.8rem;color:var(--ink-600);padding:var(--s3) var(--s4);border-bottom:1px solid var(--ink-200)}
th,td{text-align:left;padding:var(--s3) var(--s4);border-bottom:1px solid var(--ink-100);vertical-align:top}
thead th{background:var(--surface-sunk);color:var(--ink-900);font-weight:600;font-size:.76rem;
  text-transform:uppercase;letter-spacing:.07em;white-space:nowrap}
tbody tr:last-child td{border-bottom:0}
td.n,th.n{text-align:right;white-space:nowrap;font-variant-numeric:tabular-nums}
.tbd{color:var(--heat-700);font-weight:500}

/* ---------- temperature scale, the recurring device ---------- */
.tscale{margin:0 0 var(--s5);max-width:640px}
.tscale .track{position:relative;height:14px;border-radius:7px;
  background:linear-gradient(to right,hsl(215 60% 62%),hsl(40 24% 97%) 28%,hsl(38 92% 62%) 62%,hsl(8 78% 48%))}
.tscale .span{position:absolute;top:-5px;height:24px;border-radius:3px;
  background:hsl(214 32% 11% / .16);border:2px solid var(--ink-900)}
.tscale .ticks{display:flex;justify-content:space-between;list-style:none;margin:var(--s2) 0 0;padding:0;max-width:none;
  font-size:.75rem;color:var(--ink-600);font-variant-numeric:tabular-nums}
.tscale .ticks li{margin:0}
.tscale .cap{font-size:.82rem;color:var(--ink-600);margin:var(--s3) 0 0}
section.band.ink .tscale .span{border-color:#fff;background:hsl(0 0% 100% / .18)}
section.band.ink .tscale .ticks,section.band.ink .tscale .cap{color:hsl(214 14% 70%)}

/* ---------- option catalogue ---------- */
.optgroup{margin-bottom:var(--s7)}
.optgroup > h3{display:flex;align-items:baseline;gap:var(--s3)}
.optgroup > h3 .idx{font-family:"Archivo Narrow",sans-serif;font-size:1.5rem;color:var(--heat-400);line-height:1}
.opts{display:grid;grid-template-columns:repeat(auto-fill,minmax(210px,1fr));gap:var(--s4);list-style:none;padding:0;margin:0;max-width:none}
.opts li{background:var(--surface);border:1px solid var(--ink-200);border-radius:var(--radius);padding:var(--s4);margin:0}
section.band.alt .opts li{background:var(--paper)}
.opts .code{display:inline-block;font-family:ui-monospace,Menlo,monospace;font-size:.75rem;font-weight:600;
  background:var(--ink-900);color:#fff;padding:2px var(--s2);border-radius:2px;letter-spacing:.04em}
.opts h4{margin:var(--s3) 0 var(--s1)}
.opts p{font-size:.85rem;color:var(--ink-600);margin:0;max-width:none}
.opts .rating{display:block;font-size:.78rem;color:var(--heat-700);font-weight:600;margin-top:var(--s2);font-variant-numeric:tabular-nums}
.opts svg{margin-bottom:var(--s2)}
/* Accessory photographs off the old site. They are small and they vary wildly
   in aspect, from a 34px wide sleeve to a square fitting, so the slot is fixed
   and the picture is contained inside it rather than sized by its own width.
   An empty .optshot holds the same space on the options in the group that have
   no photograph, which keeps the row aligned. The class is NOT .shot: that name
   already belongs to the dashed "photograph required" placeholder. */
/* Taller and centred at the client's request against the option catalogue:
   "the images should be little bigger and to be in center".

   The slot keeps its height so the code badges and option names stay on one
   line across the row, but the picture inside is never stretched past its own
   pixels: max-width and max-height with auto sizing scale a large part down and
   leave a small one alone. Some of these arrive from the client as 132 px line
   diagrams, and a single column phone layout was blowing one of them up to 308
   px wide, which is 2.2x and looks it. Small and sharp beats big and soft. */
/* The client photographs keep the ground they were shot on, so each tile is
   painted that ground. The fallback is white rather than transparent so the
   accessories carried over from the old site, which were knocked out of a white
   studio ground years ago, sit on the same tile as the ones that still have
   theirs: a row of four where two are framed and two float reads as a mistake. */
.opts .optshot{display:flex;align-items:center;justify-content:center;
  height:132px;margin:var(--s3) 0;
  background:var(--art-bg,var(--surface));border-radius:calc(var(--radius) - 2px)}
.opts a.optshot{cursor:zoom-in;text-decoration:none;color:inherit}
.opts a.optshot:hover{box-shadow:inset 0 0 0 1px var(--heat-500)}
.opts .optshot img{display:block;max-width:100%;max-height:100%;width:auto;height:auto;
  border-radius:calc(var(--radius) - 2px)}

.note{background:var(--heat-100);border-left:4px solid var(--heat-500);padding:var(--s4) var(--s5);border-radius:0 var(--radius) var(--radius) 0;margin:0 0 var(--s5)}
.note p:last-child{margin-bottom:0}
section.band.ink .note{background:hsl(214 30% 15%);border-left-color:var(--heat-500)}

/* ---------- cards ---------- */
.cards{display:grid;grid-template-columns:repeat(auto-fit,minmax(215px,1fr));gap:var(--s4);list-style:none;padding:0;margin:0;max-width:none}
.cards li{margin:0}
.cards a{display:block;background:var(--surface);border:1px solid var(--ink-200);border-radius:var(--radius);
  padding:var(--s4);text-decoration:none;color:var(--ink-800);height:100%}
.cards a:hover{border-color:var(--heat-500)}
.cards strong{display:block;font-family:"Archivo Narrow",sans-serif;font-size:1.1rem;color:var(--ink-900);margin-bottom:var(--s2)}
.cards span{font-size:.85rem;color:var(--ink-600)}
section.band.alt .cards a{background:var(--paper)}
section.band.ink .cards a{background:hsl(214 30% 15%);border-color:hsl(214 24% 26%);color:hsl(214 16% 78%)}
section.band.ink .cards strong{color:#fff}
section.band.ink .cards span{color:hsl(214 14% 70%)}
/* The dark band recolours every link, which would repaint a button's label and
   blank out a white card. Both have to be restated for the dark ground. */
section.band.ink .btn{color:#fff}
section.band.ink ol.steps > li{background:hsl(214 30% 15%);border-color:hsl(214 24% 26%)}
section.band.ink ol.steps p{color:hsl(214 16% 78%)}
section.band.ink ol.steps > li::before{color:var(--heat-500)}

/* product cards carry a drawing above the label */
.pcards{display:grid;grid-template-columns:repeat(auto-fit,minmax(250px,1fr));gap:var(--s4);list-style:none;padding:0;margin:0;max-width:none}
.pcards li{margin:0}
.pcards a{display:flex;flex-direction:column;gap:var(--s3);height:100%;background:var(--surface);
  border:1px solid var(--ink-200);border-radius:var(--radius);padding:var(--s4);text-decoration:none;color:var(--ink-700)}
.pcards a:hover{border-color:var(--heat-500)}
.pcards .art{background:var(--surface-sunk);border-radius:var(--radius);}
/* A family that has a photograph paints its panel the photograph's own ground.
   The sunk warm grey is what a line drawing sits on; under a photograph it
   frames the studio white as a rectangle pasted onto the card. */
.pcards .art-photo{background:var(--art-bg,var(--surface-sunk))}
/* A photograph of the family instead of the line drawing. Fixed height so the
   eight cards line their titles up whatever shape the part happens to be, and
   the same no-upscaling rule as the option shots: at 390 px the cards go single
   column and are drawn wider than the desktop grid draws them. */
.pcards .art-photo{display:flex;align-items:center;justify-content:center;height:116px}
.pcards .art-photo img{max-width:100%;max-height:100%;width:auto;height:auto}
.pcards strong{display:block;font-family:"Archivo Narrow",sans-serif;font-size:1.2rem;color:var(--ink-900)}
.pcards span{font-size:.88rem;color:var(--ink-600)}
.pcards .meta{font-size:.76rem;color:var(--ink-500);text-transform:uppercase;letter-spacing:.07em;margin-top:auto}
section.band.alt .pcards a{background:var(--paper)}
section.band.alt .pcards .art{background:var(--surface)}
section.band.alt .pcards .art-photo{background:var(--art-bg,var(--surface))}

/* ---------- product finder ---------- */
.finder{background:var(--surface);border:1px solid var(--ink-200);border-radius:var(--radius);padding:var(--s5);margin-bottom:var(--s6)}
section.band.alt .finder{background:var(--paper)}
.finder h2{font-size:1.15rem;margin-bottom:var(--s2)}
.finder .facets{display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:var(--s4);margin-top:var(--s4)}
.finder label{display:block;font-size:.8rem;font-weight:600;color:var(--ink-700);margin-bottom:var(--s2)}
.finder select,.finder input{width:100%;min-height:44px;padding:var(--s3);font:inherit;font-size:.92rem;
  background:var(--surface);border:1px solid var(--ink-300);border-radius:var(--radius);color:var(--ink-900)}
.finder .count{font-size:.85rem;color:var(--ink-600);margin:var(--s4) 0 0}
.pcards li[hidden]{display:none}

/* ---------- process flow, industry pages ---------- */
.flow{background:var(--surface);border:1px solid var(--ink-200);border-radius:var(--radius);padding:var(--s5);margin-bottom:var(--s5)}
/* A six zone diagram scaled to a 390px phone puts the labels at three pixels.
   It scrolls sideways at its own size instead, with an edge fade so it is
   obvious there is more of it. */
.flow .scroller{overflow-x:auto;position:relative}
.flow svg{width:100%}
.flow .hint{font-size:.8rem;color:var(--ink-600);margin:var(--s3) 0 0}
@media (min-width:1180px){.flow .hint{display:none}}
section.band.alt .flow{background:var(--paper)}
.legend{display:flex;flex-wrap:wrap;gap:var(--s4);list-style:none;padding:0;margin:var(--s4) 0 0;max-width:none;font-size:.8rem;color:var(--ink-600)}
.legend li{display:flex;align-items:center;gap:var(--s2);margin:0}
.legend .sw{width:14px;height:14px;border-radius:2px;border:1px solid var(--ink-300);display:block}

/* ---------- concept icon cards ---------- */
/* The icons are decorative: aria-hidden, and the card says the same thing in
   words. A blocked image costs nothing. */
.iconcards{display:grid;grid-template-columns:repeat(auto-fit,minmax(240px,1fr));gap:var(--s5);
  list-style:none;padding:0;margin:0;max-width:none}
.iconcards li{margin:0;background:var(--surface);border:1px solid var(--ink-200);
  border-radius:var(--radius);padding:var(--s5)}
section.band.alt .iconcards li{background:var(--paper)}
.iconcards img{width:44px;height:44px;display:block;margin:0 0 var(--s4)}
.iconcards h3{margin-bottom:var(--s2)}
.iconcards p{font-size:.92rem;color:var(--ink-600);margin:0;max-width:none}
.iconcards .n{font-family:"Archivo Narrow",sans-serif;font-size:.85rem;color:var(--heat-700);
  letter-spacing:.1em;display:block;margin-bottom:var(--s2)}

/* ---------- checklist ---------- */
.check{list-style:none;padding:0;margin:0 0 var(--s5);max-width:64ch}
.check li{position:relative;padding-left:30px;margin-bottom:var(--s3)}
.check li::before{content:"";position:absolute;left:0;top:.45em;width:16px;height:16px;border-radius:2px;
  border:2px solid var(--heat-600)}

/* ---------- downloads ---------- */
.dl{list-style:none;padding:0;margin:0;max-width:64ch}
.dl li{margin:0;border-bottom:1px solid var(--ink-200)}
.dl a{display:flex;justify-content:space-between;gap:var(--s4);padding:var(--s4) 0;text-decoration:none;
  color:var(--ink-900);font-weight:500;align-items:baseline;min-height:44px}
.dl a:hover{color:var(--heat-700)}
.dl .meta{font-size:.8rem;color:var(--ink-500);white-space:nowrap;font-weight:400}
.dl span[aria-disabled]{display:flex;justify-content:space-between;gap:var(--s4);padding:var(--s4) 0;
  color:var(--ink-600);align-items:baseline;min-height:44px}

/* ---------- steps, numbered ---------- */
/* Scoped to ol deliberately: the list builder has its own .steps container,
   a div, and an unscoped rule here numbered and boxed its family tiles. */
ol.steps{list-style:none;counter-reset:step;padding:0;margin:0;max-width:none;
  display:grid;grid-template-columns:repeat(auto-fit,minmax(280px,1fr));gap:var(--s5)}
ol.steps > li{counter-increment:step;margin:0;background:var(--surface);border:1px solid var(--ink-200);
  border-radius:var(--radius);padding:var(--s5);position:relative}
section.band.alt ol.steps > li{background:var(--paper)}
ol.steps > li::before{content:counter(step,decimal-leading-zero);font-family:"Archivo Narrow",sans-serif;
  font-size:1.5rem;color:var(--heat-400);line-height:1;display:block;margin-bottom:var(--s3)}
ol.steps h3{margin-bottom:var(--s2)}
ol.steps p{font-size:.92rem;color:var(--ink-600);margin:0;max-width:none}

/* ---------- enquiry ---------- */
.rfq{background:var(--ink-900);color:hsl(214 18% 84%)}
.rfq h2,.rfq h3,.rfq legend{color:#fff}
.rfq .two{gap:var(--s7)}
.rfq p{color:hsl(214 16% 78%)}
.rfq a{color:hsl(30 90% 78%)}
fieldset{border:0;padding:0;margin:0 0 var(--s6);min-width:0}
legend{font-family:"Archivo Narrow",sans-serif;font-size:1.05rem;font-weight:700;padding:0;margin-bottom:var(--s4);
  display:flex;align-items:baseline;gap:var(--s3)}
legend .idx{color:var(--heat-500)}
.fields{display:grid;grid-template-columns:repeat(auto-fit,minmax(190px,1fr));gap:var(--s4)}
.field{display:flex;flex-direction:column;gap:var(--s2);min-width:0}
.field label{font-size:.82rem;font-weight:500;color:hsl(214 18% 84%)}
.field .hint{font-size:.75rem;color:hsl(214 14% 60%)}
.field input,.field select,.field textarea{
  background:hsl(214 30% 15%);border:1px solid hsl(214 24% 26%);border-radius:var(--radius);
  color:#fff;padding:var(--s3);font:inherit;font-size:.92rem;min-height:44px;width:100%}
.field textarea{min-height:88px;resize:vertical}
.field input:focus-visible,.field select:focus-visible,.field textarea:focus-visible{border-color:var(--heat-500)}
.field-wide{grid-column:1 / -1}
.req{color:var(--heat-500)}
.preview{background:hsl(214 30% 15%);border:1px solid hsl(214 24% 26%);border-radius:var(--radius);padding:var(--s5);position:sticky;top:calc(var(--header-offset) + var(--s5))}
.preview h3{font-size:1rem;margin-bottom:var(--s2)}
.preview .cap{font-size:.8rem;color:hsl(214 14% 62%);margin-bottom:var(--s4)}
.preview pre{background:var(--ink-900);border:1px solid hsl(214 24% 22%);border-radius:var(--radius);
  padding:var(--s4);font-family:ui-monospace,Menlo,monospace;font-size:.78rem;line-height:1.6;
  color:hsl(160 40% 78%);white-space:pre-wrap;word-break:break-word;max-height:340px;overflow:auto;margin:0 0 var(--s4)}

/* ---------- contact blocks ---------- */
.contactcard{background:var(--surface);border:1px solid var(--ink-200);border-radius:var(--radius);padding:var(--s5)}
section.band.alt .contactcard{background:var(--paper)}
.contactcard dl{margin:0}
.contactcard dt{font-size:.76rem;text-transform:uppercase;letter-spacing:.07em;color:var(--ink-500);font-weight:600;margin-top:var(--s4)}
.contactcard dt:first-child{margin-top:0}
.contactcard dd{margin:var(--s1) 0 0;font-size:1rem;color:var(--ink-900)}
.contactcard dd a{display:inline-flex;align-items:center;min-height:44px}
/* ---------- footer ---------- */
footer.site{background:var(--ink-900);color:hsl(214 16% 70%);padding:var(--s8) 0 var(--s6);font-size:.9rem}
footer.site .cols{display:grid;grid-template-columns:repeat(auto-fit,minmax(210px,1fr));gap:var(--s6)}
footer.site h3{color:#fff;font-size:1rem}
footer.site a{color:hsl(214 16% 82%);text-decoration:none}
footer.site a:hover{color:#fff;text-decoration:underline}
footer.site ul{list-style:none;padding:0;max-width:none}
footer.site li{margin-bottom:var(--s2)}
footer.site .tbd{color:var(--heat-200)} /* .tbd is dark orange for light grounds; lighten on the dark footer */
footer.site .legal{border-top:1px solid hsl(214 24% 22%);margin-top:var(--s7);padding-top:var(--s5);
  display:flex;flex-wrap:wrap;gap:var(--s4);justify-content:space-between;font-size:.82rem}
footer.site .legal p{margin:0;color:hsl(214 14% 62%)}

/* ---------- responsive ---------- */
@media (max-width:480px){
  /* the letterspaced strapline is the wider half of the lockup at this size,
     so tighten it rather than shrinking the logo itself */
  .logo small{letter-spacing:.06em}
  .logo img{width:150px}
  /* three utility links wrap onto two rows at 360; start them left so the
     email is not marooned on the right of an otherwise empty row */
  .topbar .wrap{justify-content:flex-start;gap:var(--s2) var(--s4)}
}
@media (max-width:980px){
  /* house rule: 44px minimum tap target on touch widths */
  .topbar .wrap{gap:var(--s4)}
  .topbar a{display:inline-flex;align-items:center;min-height:44px}
  .topbar .where{display:none}
  /* Tap target is the row itself. Extra padding was stacking to a 76px band. */
  .crumb{padding:0}
  .crumb ol,.crumb a,.crumb li{min-height:44px}
  .crumb a{display:inline-flex;align-items:center}
  /* padding rather than a height, so the lockup keeps its own proportions
     while the anchor still meets the 44px tap target */
  .logo{min-height:44px;padding:var(--s1) 0}
  .hero .grid{grid-template-columns:1fr;gap:var(--s6)}
  .preview{position:static}
  .navtoggle{display:inline-flex}
  .mainnav{margin-left:0;width:100%;order:3;border-top:1px solid var(--ink-200);padding:var(--s2) 0 var(--s4)}
  .mainnav[hidden]{display:none}
  .mainnav > ul{display:block}
  .mainnav a{padding:var(--s3) var(--s2);min-height:44px;display:flex;align-items:center;border-radius:0;border-bottom:1px solid var(--ink-100)}
  .mainnav .cta a{margin-top:var(--s3);justify-content:center;border-bottom:0}
  .mainnav .has-sub{display:grid;grid-template-columns:minmax(0,1fr) 44px}
  .mainnav .has-sub > a::after{display:none}
  .mainnav .subtoggle{display:inline-flex;border-bottom:1px solid var(--ink-100)}
  .mainnav .subtoggle:hover{background:var(--ink-100);color:var(--ink-900)}
  .mainnav .has-sub.is-open > .subtoggle svg{transform:rotate(180deg)}
  .mainnav .submenu{display:none;position:static;min-width:0;grid-column:1 / -1;
    border:0;border-radius:0;box-shadow:none;padding:0 0 0 var(--s4);background:transparent}
  .mainnav .has-sub:hover > .submenu,
  .mainnav .has-sub:focus-within > .submenu{display:none}
  .mainnav .has-sub.is-open > .submenu{display:block}
  .mainnav .has-sub.is-closed > .submenu{display:none}
  .mainnav .submenu a{font-size:.92rem}
  .masthead .wrap{flex-wrap:wrap}
}
/* Without JS the toggle cannot work, so the nav must never be hidden. */
.nojs .navtoggle{display:none}
.nojs .mainnav{display:block}
.nojs .subtoggle{display:none}
@media (max-width:980px){
  .nojs .mainnav .submenu{display:block}
}

@media print{
  .topbar,.masthead,.jump,.crumb,footer.site,.actions,.rfq,.gallery{display:none}
  body{background:#fff}
  section.band{border:0;padding:var(--s5) 0}
}
