/* ═══════════════════════════════════════════════════════════════════
   VAULT TIN CO — stylesheet

   Shared by every page. Tokens live in :root and nothing below
   hardcodes a colour or a size.

   Contents
     01  tokens
     02  base + typography
     03  page transitions
     04  navigation
     05  buttons
     06  hero + collage
     07  rotating showcase
     08  range bands + technical elevation
     09  catalogue grid + filters
     10  product page
     11  index rows + asset slots
     12  eco / inverted / stats
     13  definition lists + forms
     14  footer
     15  reveal, focus, reduced motion
   ═══════════════════════════════════════════════════════════════════ */

/* ── 01  tokens ──────────────────────────────────────────────────── */
*,*::before,*::after{box-sizing:border-box;margin:0;padding:0}
:root{
  --paper:#f4f2ee;--paper-2:#eae6e0;--white:#fdfcfa;
  --ink:#1c1a18;--umber:#2f2b27;--slate:#5b5550;
  /* Small text darkened to clear WCAG AA on paper. The previous
     values were 2.4-4.0:1 — pretty at 10px and genuinely hard to
     read. Contrast against --paper now: steel 5.8, ash 5.0. */
  --steel:#635d57;--ash:#6e6760;--mist:#d6d1c9;
  /* signal — copper. The accent is a metal, so it reinforces the
     material instead of being an arbitrary brand colour. Logo dot,
     eyebrows, dimension callouts, hover and focus. Never a button
     fill, never body text. --dk for small text on paper (5.6:1),
     --lt for anything on the dark chapters (5.7:1). */
  --signal:#a9673a;--signal-dk:#8a5228;--signal-lt:#d1904f;
  /* --dp, deep: dimension callouts sit on the product plate, which is
     now mid-tone. Holds 4.9:1 there, where --dk managed only 2.5:1. */
  --signal-dp:#4f2c12;
  /* pewter and graphite — the metal tones. Graphite is the ground
     for every large dark surface; it is cooler than the warm umber
     it replaced, which is what makes it read as tinplate. */
  --pewter:#5f6a72;--graphite:#22262a;
  /* pewter-lt keeps the old lighter tone for the places it is
     decoration rather than text — scrollbar, rules, inverted cards. */
  --pewter-lt:#8a949c;
  /* inverted product ground, for the dark card hover */
  --steel-inv:#2b3138;--steel-inv-line:#93a0a9;
  --steel-inv-grid:rgba(255,255,255,.05);
  /* moss stays green and now means exactly one thing: Eco. */
  --moss:#4d6b3c;--moss-bg:#e8eee1;
  /* The plate every product sits on, photographed or drawn. Sampled
     from the Round tin shot (#ada193, uniform across the frame) so a
     photograph and an elevation share one ground and the grid reads as
     a set. Separation from paper is now by value, not temperature.
     The stroke darkened to hold 4.5:1 on the heavier plate — the
     product stays cool against a warm ground, as before. */
  --steel-bg:#ada193;--steel-line:#343b42;--steel-grid:rgba(40,54,66,.08);
  --line:rgba(28,26,24,.11);--line-2:rgba(28,26,24,.22);--line-inv:rgba(255,255,255,.13);
  --disp:'Fraunces',Georgia,serif;--sans:'IBM Plex Sans',system-ui,sans-serif;
  --mono:'IBM Plex Mono',ui-monospace,monospace;
  --gutter:clamp(20px,5vw,72px);--sec:clamp(80px,10.5vw,156px);--blk:clamp(34px,4.4vw,64px);
  /* added for the multi-page build */
  --nav-h:78px;
  --radius:3px;
  --ease:cubic-bezier(.22,.85,.28,1);
  --ease-soft:cubic-bezier(.2,.7,.3,1);
}

/* ── 02  base + typography ───────────────────────────────────────── */
html{-webkit-text-size-adjust:100%;scroll-behavior:smooth}
/* ── clearing the sticky nav ─────────────────────────────────────
   The bar is sticky and translucent, so anything it would come to
   rest on top of has to start below it. Every heading and every
   anchor target inside the page carries the offset.

   scroll-margin on the target, not scroll-padding on the scrollport:
   the two ADD rather than override, and having both is how an anchor
   ends up landing 200px below where it should. One mechanism.

   `main` scopes it so the nav's own links are unaffected. */
main :is(h1,h2,h3,h4,[id]){scroll-margin-top:calc(var(--nav-h) + 26px)}
/* A section's own top padding is 80px at its smallest, which already
   clears the 78px bar — except where a section overrides it. Nothing
   may set less than this. */
main > section{padding-top:max(var(--nav-h),var(--sec))}
/* Details nobody names but everybody registers. Default browser blue
   selection on a warm page is the single loudest "unfinished" signal. */
::selection{background:var(--signal);color:#fff}
::-moz-selection{background:var(--signal);color:#fff}
::-webkit-scrollbar{width:11px;height:11px}
::-webkit-scrollbar-track{background:var(--paper-2)}
::-webkit-scrollbar-thumb{background:var(--mist);border-radius:6px;
  border:3px solid var(--paper-2)}
::-webkit-scrollbar-thumb:hover{background:var(--pewter)}
html{scrollbar-color:var(--mist) var(--paper-2);scrollbar-width:thin}
/* optical sizing on the display face — Fraunces is a variable font and
   this is what stops large headings looking like scaled-up small ones */
h1,h2,.statement,.chapter__h,.specimen__n{font-optical-sizing:auto}
body{font-family:var(--sans);background:var(--paper);color:var(--ink);line-height:1.65;
  -webkit-font-smoothing:antialiased;overflow-x:hidden}
.wrap{max-width:1300px;margin:0 auto;padding:0 var(--gutter)}
.narrow{max-width:880px}
section{padding:var(--sec) 0}
.rule{border-top:1px solid var(--line)}
[hidden]{display:none!important}

h1,h2,h3{font-family:var(--disp);font-weight:500;letter-spacing:-.022em;line-height:1.02;
  font-variation-settings:'opsz' 120,'SOFT' 20,'WONK' 0}
h1{font-size:clamp(48px,9vw,124px);line-height:.9;letter-spacing:-.035em}
h2{font-size:clamp(30px,4.6vw,58px)}
h3{font-size:clamp(19px,1.8vw,23px);line-height:1.18;letter-spacing:-.015em}
h1 em,h2 em,h3 em{font-style:italic;font-weight:400}

/* kinetic headline — each line rises from its own mask */
.kin{display:block;overflow:hidden}
.kin>span{display:block;transform:translateY(105%);opacity:0;
  animation:rise .95s var(--ease) forwards}
.kin:nth-of-type(2)>span{animation-delay:.10s}
.kin:nth-of-type(3)>span{animation-delay:.20s}
@keyframes rise{to{transform:none;opacity:1}}

p{margin-bottom:1.05em;max-width:60ch;color:var(--slate)}
p:last-child{margin-bottom:0}
.lede{font-size:clamp(16.5px,1.5vw,20px);color:var(--slate);max-width:48ch;line-height:1.58}
.big{font-size:clamp(19px,2.1vw,27px);line-height:1.42;color:var(--ink);max-width:34ch;
  letter-spacing:-.012em}
.pull{max-width:24ch;font-family:var(--disp);font-weight:400;font-style:italic;
  font-size:clamp(26px,3.6vw,46px);line-height:1.14;letter-spacing:-.02em;color:var(--ink)}
.label{font-family:var(--mono);font-size:10px;font-weight:600;letter-spacing:.17em;
  text-transform:uppercase;color:var(--steel)}
.label--a{color:var(--signal-dk)}

.grid{display:grid;gap:clamp(18px,2.4vw,34px)}
.g2{grid-template-columns:repeat(2,1fr)}
.g3{grid-template-columns:repeat(3,1fr)}
.g4{grid-template-columns:repeat(4,1fr)}
/* deliberately uneven — never 50/50 */
.split-a{grid-template-columns:1.15fr .85fr;gap:clamp(30px,6vw,96px);align-items:end}
.split-b{grid-template-columns:.8fr 1.2fr;gap:clamp(30px,6vw,88px);align-items:center}
.split-c{grid-template-columns:1.3fr .7fr;gap:clamp(28px,5vw,72px);align-items:start}
@media(max-width:1000px){.g4{grid-template-columns:repeat(2,1fr)}.g3{grid-template-columns:repeat(2,1fr)}}
@media(max-width:680px){.g2,.g3,.g4,.split-a,.split-b,.split-c{grid-template-columns:1fr}}

/* ── 03  page transitions ────────────────────────────────────────── */
/* Cross-document view transitions. Supported browsers cross-fade
   between pages; everywhere else navigation is simply instant, which
   is the current behaviour. No scroll position is ever hijacked. */
@view-transition{navigation:auto}
::view-transition-old(root),::view-transition-new(root){
  animation-duration:.34s;animation-timing-function:var(--ease-soft);
  mix-blend-mode:normal}
::view-transition-old(root){animation-name:vtOut}
::view-transition-new(root){animation-name:vtIn}
@keyframes vtOut{to{opacity:0;transform:translateY(-8px)}}
@keyframes vtIn{from{opacity:0;transform:translateY(12px)}}
/* the chrome persists across the change rather than fading with it */
.nav{view-transition-name:nav}
.foot{view-transition-name:foot}

/* ── 04  navigation ──────────────────────────────────────────────── */
.nav{position:sticky;top:0;z-index:70;padding:14px 0 0;background:transparent;border:none}
.nav__in{display:flex;align-items:center;gap:clamp(18px,3vw,40px);
  padding:11px 12px 11px 24px;background:rgba(253,252,250,.82);
  backdrop-filter:saturate(1.6) blur(20px);-webkit-backdrop-filter:saturate(1.6) blur(20px);
  border-radius:100px;
  box-shadow:0 1px 2px rgba(28,26,24,.05),0 10px 34px rgba(28,26,24,.07);
  border:1px solid rgba(255,255,255,.8);
  transition:box-shadow .35s ease,background .35s ease}
/* settles into a firmer state once the page has moved */
.nav.is-stuck .nav__in{background:rgba(253,252,250,.94);
  box-shadow:0 1px 2px rgba(28,26,24,.06),0 14px 40px rgba(28,26,24,.11)}
.brand{font-family:var(--disp);font-weight:600;font-size:19px;letter-spacing:-.03em;
  text-decoration:none;color:var(--ink);display:flex;align-items:center;gap:10px;
  font-variation-settings:'opsz' 20;cursor:pointer;white-space:nowrap}
/* The mark, masked rather than embedded, so it inherits whatever colour
   the brand is set in — ink on paper, paper on graphite — from one file.
   Replaces the copper dot that stood in before there was a real mark. */
.brand::before{content:"";width:23px;height:23px;flex:none;background:currentColor;
  -webkit-mask:url(logo-mark.svg) center/contain no-repeat;
  mask:url(logo-mark.svg) center/contain no-repeat;
  transition:opacity .3s var(--ease)}
.brand:hover::before{opacity:.62}
.nl{display:flex;gap:clamp(16px,2.2vw,28px);margin-left:auto}
.nl a{font-size:13px;color:var(--slate);text-decoration:none;transition:color .2s;
  cursor:pointer;letter-spacing:.005em;position:relative}
.nl a:hover,.nl a[aria-current]{color:var(--ink)}
/* current page marked by the accent dot, not an underline */
.nl a[aria-current]::after{content:"";position:absolute;left:50%;bottom:-7px;
  width:4px;height:4px;margin-left:-2px;border-radius:50%;background:var(--signal)}
.nav__cta{font-family:var(--mono);font-size:10.5px;font-weight:600;letter-spacing:.13em;
  text-transform:uppercase;background:var(--umber);color:var(--paper);
  padding:11px 20px;border-radius:100px;text-decoration:none;white-space:nowrap;
  transition:background .22s}
.nav__cta:hover{background:var(--ink)}

/* mobile menu — the nav collapses rather than shrinking to unreadable */
.nav__burger{display:none;margin-left:auto;width:40px;height:40px;border:none;
  background:transparent;cursor:pointer;position:relative;border-radius:50%}
.nav__burger span{position:absolute;left:11px;width:18px;height:1.5px;background:var(--ink);
  transition:transform .3s var(--ease),opacity .2s}
.nav__burger span:nth-child(1){top:16px}
.nav__burger span:nth-child(2){top:22px}
.nav__burger[aria-expanded="true"] span:nth-child(1){transform:translateY(3px) rotate(45deg)}
.nav__burger[aria-expanded="true"] span:nth-child(2){transform:translateY(-3px) rotate(-45deg)}
.nav__panel{display:none}
@media(max-width:820px){
  .nl{display:none}
  .nav__cta{display:none}
  .nav__burger{display:block}
  .nav__panel{display:block;position:fixed;inset:var(--nav-h) 0 0;z-index:69;
    background:var(--paper);padding:var(--gutter);
    opacity:0;visibility:hidden;transform:translateY(-10px);
    transition:opacity .3s ease,transform .3s var(--ease),visibility .3s}
  .nav__panel.is-open{opacity:1;visibility:visible;transform:none}
  .nav__panel a{display:block;font-family:var(--disp);font-weight:500;
    font-size:clamp(30px,8vw,44px);letter-spacing:-.03em;color:var(--ink);
    text-decoration:none;padding:14px 0;border-bottom:1px solid var(--line)}
  .nav__panel .nav__panel-cta{font-family:var(--mono);font-size:11px;font-weight:600;
    letter-spacing:.14em;text-transform:uppercase;border:none;color:var(--signal-dk);
    padding-top:26px}
  body.nav-open{overflow:hidden}
}

/* ── 05  buttons ─────────────────────────────────────────────────── */
.btn{display:inline-block;font-family:var(--mono);font-size:11px;font-weight:600;
  letter-spacing:.13em;text-transform:uppercase;padding:14px 24px;border-radius:2px;
  text-decoration:none;border:1px solid var(--umber);color:var(--umber);background:transparent;
  cursor:pointer;transition:background .22s,color .22s}
.btn:hover{background:var(--umber);color:var(--paper)}
.btn--s{background:var(--umber);color:var(--paper)}
.btn--s:hover{background:var(--ink)}
.btns{display:flex;gap:11px;flex-wrap:wrap;margin-top:var(--blk)}
.inv .btn{border-color:rgba(255,255,255,.4);color:#faf8f5}
.inv .btn:hover{background:#faf8f5;color:var(--umber)}

/* ── 06  hero + collage ──────────────────────────────────────────── */
.hero{position:relative;overflow:hidden;padding:clamp(46px,6vw,86px) 0 clamp(56px,7vw,104px)}
.hero__in{display:grid;grid-template-columns:1.02fr .98fr;gap:clamp(24px,4vw,60px);
  align-items:center;position:relative}
.hero__txt{position:relative;z-index:2}
.hero__meta{font-family:var(--mono);font-size:10.5px;letter-spacing:.12em;
  text-transform:uppercase;color:var(--steel);margin-top:22px}
.collage{position:relative;height:clamp(360px,42vw,560px)}
.cl{position:absolute;color:var(--steel-line);opacity:0;
  animation:clIn .9s var(--ease) forwards}
.cl svg{width:100%;height:100%;overflow:visible}
.cl .s{fill:var(--steel-bg);stroke:currentColor;stroke-width:1.6;vector-effect:non-scaling-stroke}
.cl .t{fill:#f5f7f9;stroke:currentColor;stroke-width:1.6;vector-effect:non-scaling-stroke}
.cl .h{fill:none;stroke:currentColor;stroke-width:.9;opacity:.42;vector-effect:non-scaling-stroke}
@keyframes clIn{from{opacity:0;transform:translateY(26px) scale(.94) rotate(var(--r))}
  to{opacity:1;transform:translateY(0) scale(1) rotate(var(--r))}}
.cl.float{animation:clIn .9s var(--ease) forwards,bob var(--d) ease-in-out infinite alternate}
@keyframes bob{from{transform:translateY(0) rotate(var(--r))}
  to{transform:translateY(-14px) rotate(calc(var(--r) + 1.6deg))}}
@media(max-width:900px){
  .hero__in{grid-template-columns:1fr}
  .collage{height:300px;margin-top:8px;order:2}
}

/* ── 07b  the landing screen ─────────────────────────────────────
   Paper, ink and the same conventions as every other section, with the
   range shot behind the words.

   That only works because the photograph's ground was levelled to
   --paper. There is no picture edge to conceal and no scrim needed:
   the tins are pale silver, the type is ink, and both sit on the same
   surface. A scrim would have greyed the tins and defeated the point
   of showing them. */
/* Runs up under the nav so the picture reaches the top of the page.
   Left where it was, the image began below the bar and drew a hard
   line across the full width — an edge the mask cannot help with,
   because it is the top of the element. */
.lead{position:relative;background:var(--paper);overflow:hidden;
  min-height:min(88vh,800px);min-height:min(88dvh,800px);
  display:flex;align-items:center;
  margin-top:calc(-1 * (var(--nav-h) + 14px));
  padding:calc(var(--nav-h) + clamp(76px,9vw,132px)) 0 clamp(48px,6vw,88px)}
.lead__in{position:relative;z-index:2;width:100%}

/* The ground. This shot is a studio gradient, not a white sweep —
   it runs from 201 at the top left down to 97 at the top right — so
   the trick that worked on the last one, levelling white onto paper,
   would only have flattened the tins into their own background.

   It dissolves instead. A radial mask centred right of the type takes
   it to nothing at every edge, so there is no boundary anywhere: the
   warm field simply emerges from the page and fades back into it. The
   type sits where the mask has already reached zero, on clean paper. */
.lead__bg{position:absolute;inset:0;z-index:0;pointer-events:none;
  /* Sized to the full width, anchored to the top. Cover cropped the
     lineup to about half of it — the whole point of the picture is that
     you can count the formats, so width wins over filling the box. Top
     anchored because that edge is the top of the page and needs no
     fade; whatever falls short at the bottom is inside the fade. */
  background:no-repeat top center / 100% auto;
  /* tight enough to reach zero before the type column starts, so the
     headline and the line under it are on clean paper, not on tins */
  /* Opaque at the top and the right, where the picture meets the top
     of the page and the edge of the screen and is meant to bleed;
     fading to nothing down the left and across the bottom, where it
     meets type and the next section. */
  -webkit-mask:radial-gradient(64% 88% at 86% 30%,
    #000 0 34%,rgba(0,0,0,.62) 60%,rgba(0,0,0,.2) 78%,transparent 94%);
  mask:radial-gradient(64% 88% at 86% 30%,
    #000 0 34%,rgba(0,0,0,.62) 60%,rgba(0,0,0,.2) 78%,transparent 94%)}
/* nothing to show yet — the screen still stands on its own */
.lead__bg--empty{display:none}

.lead__h{margin-top:clamp(18px,2.2vw,30px);max-width:13ch}
.lead__sub{margin-top:clamp(20px,2.4vw,30px);max-width:36ch}
.lead__btns{margin-top:clamp(26px,3.2vw,42px)}

@media(max-width:820px){
  /* one column, so the fade turns through ninety degrees: type at the
     top on clean paper, the lineup along the bottom. Sized to the full
     width there, because cover would crop away most of the range. */
  /* the nav compensation has to survive here too — overriding
     padding-top on its own slid the headline up under the bar */
  .lead{min-height:min(88vh,760px);min-height:min(88dvh,760px);
    padding-top:calc(var(--nav-h) + clamp(28px,7vw,56px));align-items:flex-start}
  .lead__h{max-width:none}
  /* One column, so the fade turns through ninety degrees. The element
     is given the picture's own aspect and pinned to the bottom, rather
     than covering the section — that way the mask fades the picture's
     actual top edge instead of a point somewhere near it, and there is
     no line to find. Full width, because cropping to fill would take
     most of the range away. */
  .lead__bg{top:auto;bottom:0;aspect-ratio:1800/1005;
    background:no-repeat center bottom / 100% auto;
    -webkit-mask:linear-gradient(180deg,transparent 0,rgba(0,0,0,.34) 24%,#000 52%,#000 90%,transparent 100%);
    mask:linear-gradient(180deg,transparent 0,rgba(0,0,0,.34) 24%,#000 52%,#000 90%,transparent 100%)}
}

/* ── the stacking stage ──────────────────────────────────────────
   A tall track with one sticky stage pinned in it. Scroll advances the
   step; the stage itself never moves and never touches the scroll
   event. Sticky positioning, not scroll-jacking.

   This is where the site returns to its own palette. The hero is the
   only dark screen on the page — everything here is paper, ink and the
   green accent, the same as the range and the content pages. */
/* padding:0 overrides the global section rule. That rule was putting
   --sec of paper above the gradient, which left a pale band between
   the dark hero and the hand-off meant to carry it — the one seam this
   section exists to avoid. */
.stack{position:relative;background:var(--paper);padding:0}
/* was a gradient carrying the dark hero into paper. The hero is paper
   now, so there is nothing to carry — it is just the gap above the
   first step. */
.stack__lead{height:clamp(40px,6vw,96px)}
.stack__track{height:560vh;position:relative}
.stack__stage{position:sticky;top:0;height:100vh;height:100dvh;
  display:flex;align-items:center;overflow:hidden}
/* The picture takes the larger share and the gap is tight, so it
   reaches back toward the word instead of floating away from it. */
.stack__grid{display:grid;grid-template-columns:.74fr 1.26fr;
  gap:clamp(20px,2.6vw,44px);align-items:center;width:100%}

/* ── the words ───────────────────────────────────────────────────
   They accumulate. Each one stays once it has arrived, and dims when
   it is no longer the newest — without that the finished stack
   competes with itself and the eye has nowhere to go. */
.stack__words{display:flex;flex-direction:column;gap:clamp(2px,.5vw,8px)}
.sw{font-family:var(--disp);font-weight:400;
  font-size:clamp(34px,5.6vw,88px);line-height:1.06;letter-spacing:-.02em;
  color:var(--slate);margin:0;max-width:none;
  opacity:0;transform:translateY(26px);
  transition:opacity .75s var(--ease-soft),transform .75s var(--ease-soft),
    color .6s ease}
.sw.is-on{opacity:1;transform:none}
/* the newest is ink, everything before it is muted */
.sw.is-cur{color:var(--ink)}

/* ── the frame ───────────────────────────────────────────────────
   One plate, six images stacked in it. Only the current one is up. */
/* 16:9, and it runs off the right edge of the screen. The photography
   is ultra-wide — a 4:3 frame cropped 43% off this one — and bleeding
   past the gutter buys the width back rather than shrinking the shot
   to fit a column. Capped at the height the brief set. */
.stack__frame{position:relative;aspect-ratio:16/9;max-height:min(72vh,620px);
  /* to the actual screen edge, not the wrap edge — .wrap caps at
     1300px and centres, so past that width the gutter alone leaves a
     sliver of paper outside the picture */
  margin-right:calc(-1 * (var(--gutter) + max(0px,(100vw - 1300px) / 2)));
  border-radius:var(--radius) 0 0 var(--radius);
  border-radius:var(--radius);overflow:hidden;
  box-shadow:inset 0 0 0 1px rgba(28,26,24,.055),
    0 1px 2px rgba(28,26,24,.04),0 12px 32px -12px rgba(28,26,24,.16)}
.sf{position:absolute;inset:0;opacity:0;transform:scale(1.05);
  /* wipes up from the bottom: the mask is three times the box so its
     soft edge has somewhere to travel from */
  -webkit-mask-image:linear-gradient(to top,#000 0%,#000 52%,transparent 76%);
  mask-image:linear-gradient(to top,#000 0%,#000 52%,transparent 76%);
  -webkit-mask-size:100% 300%;mask-size:100% 300%;
  -webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;
  -webkit-mask-position:0 0;mask-position:0 0;
  transition:opacity 1s var(--ease-soft),transform 1.3s var(--ease-soft),
    -webkit-mask-position 1.3s var(--ease-soft),mask-position 1.3s var(--ease-soft)}
.sf.is-on{opacity:1;transform:none;
  -webkit-mask-position:0 100%;mask-position:0 100%;z-index:2}
.sf img{width:100%;height:100%;object-fit:cover;display:block}
/* the neutral plate a step shows until its photograph lands — the
   same ground and grid the product plates use, so an empty step reads
   as a frame waiting rather than as something broken */
.sf--empty{background:var(--steel-bg);
  background-image:linear-gradient(var(--steel-grid) 1px,transparent 1px),
    linear-gradient(90deg,var(--steel-grid) 1px,transparent 1px);
  background-size:26px 26px}

/* ── the rail ────────────────────────────────────────────────────
   Six bars, bottom left, filling in the green accent as their step is
   reached. Quiet enough to be a position indicator and nothing more. */
.stack__rail{position:absolute;left:var(--gutter);bottom:clamp(26px,4vw,52px);
  display:flex;gap:7px;z-index:3}
.sr{width:26px;height:2px;background:rgba(28,26,24,.14);border-radius:2px;
  transition:background .5s ease}
.sr.is-on{background:var(--moss)}

@media(max-width:820px){
  .stack__track{height:520vh}
  .stack__grid{grid-template-columns:1fr;gap:clamp(20px,4vw,32px)}
  /* image on top, words beneath */
  /* no bleed on a phone — the picture already spans the column, and
     running off one side only reads as a mistake. The 38vh from the
     brief is the cap rather than the height, so 16:9 survives. */
  .stack__frame{order:-1;max-height:38vh;margin-right:0;
    border-radius:var(--radius)}
  .sw{font-size:clamp(28px,7.6vw,46px)}
  .stack__stage{align-items:center}
}

@media (prefers-reduced-motion:reduce){
  /* the whole sentence and the last photograph, held still. The track
     collapses so there is nothing to scroll through. */
  .stack__track{height:auto}
  .stack__stage{position:static;height:auto;padding:var(--sec) 0}
  .sw{opacity:1;transform:none;transition:none}
  .sf{transition:none}
  .stack__rail{display:none}
}

/* ── 08  range bands + technical elevation ───────────────────────── */
.rail{height:1px;background:var(--line);margin:0 0 clamp(30px,4vw,54px);position:relative}
.rail__fill{position:absolute;inset:0;background:var(--signal);transform:scaleX(0);
  transform-origin:left;transition:transform .12s linear}

.band{display:grid;grid-template-columns:58px minmax(230px,.85fr) minmax(280px,1.15fr);
  gap:clamp(20px,3.4vw,58px);align-items:center;
  padding:clamp(38px,5vw,72px) 0;border-bottom:1px solid var(--line);
  text-decoration:none;color:inherit;cursor:pointer}
.band:first-child{border-top:1px solid var(--line)}
.band__i{font-family:var(--mono);font-size:11px;color:var(--mist);letter-spacing:.14em;
  align-self:start;padding-top:8px;transition:color .45s}
.band.lit .band__i{color:var(--signal-dk)}
.band__n{font-family:var(--disp);font-weight:500;font-size:clamp(26px,3.4vw,44px);
  letter-spacing:-.028em;line-height:1.02;font-variation-settings:'opsz' 90;
  transition:color .3s}
.band:hover .band__n{color:var(--signal-dk)}
.band__eco{display:block;font-family:var(--mono);font-style:normal;font-size:8.5px;
  letter-spacing:.16em;text-transform:uppercase;color:var(--moss);margin-top:10px}
.band__dim{font-size:clamp(15px,1.5vw,18px);font-weight:500;color:var(--ink);
  margin-top:16px;font-variant-numeric:tabular-nums;letter-spacing:-.012em}
.band__mm{font-family:var(--mono);font-size:10.5px;color:var(--ash);margin-top:4px;
  letter-spacing:.04em}
.band__u{font-size:13px;color:var(--steel);margin-top:14px;line-height:1.5;max-width:30ch}
.band__cta{display:inline-block;font-family:var(--mono);font-size:10px;font-weight:600;
  letter-spacing:.14em;text-transform:uppercase;color:var(--ash);margin-top:20px;
  transition:color .3s,transform .3s}
.band:hover .band__cta{color:var(--ink);transform:translateX(4px)}

/* Product sits on a cool ground against the warm page. This is the
   whole "warm ground, cool product" idea, finally doing something. */
.band__fig,.fig{position:relative;background:var(--steel-bg);border-radius:var(--radius);
  overflow:hidden;box-shadow:inset 0 0 0 1px rgba(40,54,66,.08);
  display:grid;place-items:center;
  background-image:linear-gradient(var(--steel-grid) 1px,transparent 1px),
    linear-gradient(90deg,var(--steel-grid) 1px,transparent 1px);
  background-size:26px 26px}
.band__fig{aspect-ratio:16/11}
/* Positioned, not a grid item. As a centred grid item a percentage
   height has no definite box to resolve against, so a square photograph
   fell back to its intrinsic 1:1, overflowed the 4/3 plate and got
   clipped by overflow:hidden. Absolute against the plate gives height
   something real; object-fit:contain then letterboxes it centred. */
/* cover, not contain: the product is the subject, so the photograph
   fills the plate and the surplus ground is trimmed. contain left bare
   plate either side of a square shot and made the tin read small. */
.band__fig img,.fig img{position:absolute;inset:0;width:100%;height:100%;
  object-fit:cover;display:block}

/* the technical drawing */
.tech{width:88%;height:88%;color:var(--steel-line);overflow:visible}
.tech .ln{stroke-dasharray:1400;stroke-dashoffset:1400;
  transition:stroke-dashoffset 1.15s cubic-bezier(.25,.8,.35,1)}
.lit .tech .ln{stroke-dashoffset:0}
.tech .ln:nth-of-type(2){transition-delay:.14s}
.tech .dim{opacity:.55}
.tech .dims{opacity:0;transition:opacity .6s ease .95s}
.lit .tech .dims{opacity:1;color:var(--signal-dk)}
.tech .dtxt{font-family:var(--mono);font-size:12px;fill:var(--signal-dp);letter-spacing:.04em}
.tech .lid{transition:transform 1s cubic-bezier(.34,.9,.3,1) 1.15s}
.lit .tech .lid--lift{transform:translateY(-46px)}
.lit .tech .lid--slide{transform:translateX(76px)}
.lit .tech .lid--hinge{transform:rotate(-46deg)}
.band:hover .tech .lid--lift,.fig--live:hover .tech .lid--lift{transform:translateY(-58px)}
.band:hover .tech .lid--slide,.fig--live:hover .tech .lid--slide{transform:translateX(92px)}
.band:hover .tech .lid--hinge,.fig--live:hover .tech .lid--hinge{transform:rotate(-58deg)}
.band:hover .tech .lid,.fig--live:hover .tech .lid{transition-delay:0s}
@media(max-width:900px){
  .band{grid-template-columns:40px 1fr;row-gap:24px}
  .band__fig{grid-column:1/-1;aspect-ratio:16/10}
}

/* ── 09  catalogue grid + filters ────────────────────────────────── */
.filters{display:flex;gap:8px;flex-wrap:wrap;align-items:center;
  margin-top:var(--blk);padding-bottom:clamp(24px,3vw,38px);
  border-bottom:1px solid var(--line)}
.chip{font-family:var(--mono);font-size:10px;font-weight:600;letter-spacing:.14em;
  text-transform:uppercase;padding:9px 16px;border-radius:100px;cursor:pointer;
  border:1px solid var(--line-2);background:transparent;color:var(--steel);
  transition:background .22s,color .22s,border-color .22s}
.chip:hover{border-color:var(--umber);color:var(--ink)}
.chip[aria-pressed="true"]{background:var(--umber);border-color:var(--umber);color:var(--paper)}
.chip--eco[aria-pressed="true"]{background:var(--moss);border-color:var(--moss)}
.filters__count{font-family:var(--mono);font-size:10px;letter-spacing:.14em;
  text-transform:uppercase;color:var(--ash);margin-left:auto;
  font-variant-numeric:tabular-nums;white-space:nowrap}
@media(max-width:680px){.filters__count{margin-left:0;width:100%;padding-top:6px}}

.cat{display:grid;grid-template-columns:repeat(3,1fr);gap:clamp(16px,2.2vw,30px);
  margin-top:clamp(28px,3.6vw,48px)}
/* compact four-across, for the home page — same information as the
   full-width bands in roughly a third of the scroll */
.cat--4{grid-template-columns:repeat(4,1fr)}
@media(max-width:1080px){.cat--4{grid-template-columns:repeat(3,1fr)}}
@media(max-width:900px){.cat{grid-template-columns:repeat(2,1fr)}
  .cat--4{grid-template-columns:repeat(2,1fr)}}
@media(max-width:560px){.cat{grid-template-columns:1fr}
  .cat--4{grid-template-columns:repeat(2,1fr)}}
.cat--4 .cat__n{font-size:clamp(17px,1.6vw,20px);margin-top:14px}
.cat--4 .cat__dim{font-size:13px;margin-top:8px}
.cat--4 .cat__meta{margin-top:11px;padding-top:10px;font-size:9px}
.cat__meta span:last-child{color:var(--pewter);text-align:right}
/* Home cards carry the closure line alone, so it is not the right-hand
   half of a pair any more — it leads, in the same weight the size count
   used to have. */
.cat__meta--solo{justify-content:flex-start}
.cat__meta--solo span:last-child{color:var(--steel);text-align:left}
.crumb span{color:var(--pewter)}
.row__a{color:var(--pewter)}
.cat__card{display:block;text-decoration:none;color:inherit}
.cat__card .fig{aspect-ratio:4/3}
.cat__n{font-family:var(--disp);font-weight:500;font-size:clamp(20px,2.1vw,26px);
  letter-spacing:-.026em;line-height:1.06;margin-top:18px;font-variation-settings:'opsz' 70}
.cat__eco{font-family:var(--mono);font-size:8.5px;letter-spacing:.16em;text-transform:uppercase;
  color:var(--moss);margin-left:9px;vertical-align:middle}
.cat__dim{font-size:14.5px;font-weight:500;color:var(--ink);margin-top:10px;
  font-variant-numeric:tabular-nums;letter-spacing:-.012em}
.cat__mm{font-family:var(--mono);font-size:10.5px;color:var(--ash);margin-top:3px;
  letter-spacing:.04em}
.cat__meta{font-family:var(--mono);font-size:10px;letter-spacing:.14em;text-transform:uppercase;
  color:var(--steel);margin-top:14px;display:flex;justify-content:space-between;gap:12px;
  padding-top:12px;border-top:1px solid var(--line)}
.cat__empty{padding:clamp(40px,6vw,80px) 0;text-align:center}
.cat__empty p{margin:0 auto;color:var(--steel)}

/* ── 10  product page ────────────────────────────────────────────── */
.crumb{font-family:var(--mono);font-size:10px;font-weight:600;letter-spacing:.15em;
  text-transform:uppercase;color:var(--ash);display:flex;gap:9px;flex-wrap:wrap}
.crumb a{color:var(--steel);text-decoration:none;transition:color .2s}
.crumb a:hover{color:var(--ink)}
.crumb span{color:var(--mist)}


/* ═══════════════════════════════════════════════════════════════════
   THE FORMAT PAGE — header, demo, spec builder, three actions

   Four sections and nothing else. The controls are real radios and
   checkboxes with the input taken out of the flow and the label doing
   the drawing, so keyboard focus, tab order and :checked all come for
   free and none of it depends on script.
   ═══════════════════════════════════════════════════════════════════ */

/* ── 1  header, with the demo beside it ──────────────────────────
   Name, one line, the closure, four facts, and the tin opening on the
   right. The facts line is the only place on the page numbers appear
   before the builder, and it is one line of mono rather than a row of
   tiles — a stat row here would be the third thing competing with the
   title.

   Uneven and media-heavy: the demo is what is worth looking at, and
   the title is a label on a page whose job is specifying a tin. Both
   columns are centred against each other so a short header does not
   leave the video hanging off the top of a tall block. */
.pf{padding:clamp(38px,4.6vw,72px) 0 clamp(44px,5.5vw,86px)}
.pf__grid{display:grid;grid-template-columns:.82fr 1.18fr;
  gap:clamp(28px,4.4vw,72px);align-items:center}
.pf__n{font-size:clamp(38px,4.9vw,72px);line-height:.94;letter-spacing:-.034em}
.pf__use{font-family:var(--disp);font-weight:400;font-style:italic;
  font-size:clamp(18px,2vw,26px);line-height:1.26;letter-spacing:-.02em;
  color:var(--slate);max-width:23ch;margin-top:clamp(15px,1.8vw,22px)}
.pf__mech{font-family:var(--mono);font-size:11px;font-weight:600;letter-spacing:.16em;
  text-transform:uppercase;color:var(--signal-dk);margin-top:clamp(20px,2.6vw,32px)}
.pf__facts{font-family:var(--mono);font-size:10.5px;font-weight:600;letter-spacing:.13em;
  text-transform:uppercase;color:var(--steel);line-height:2.1;
  margin-top:16px;padding-top:16px;border-top:1px solid var(--line-2)}
.pf__back{display:inline-block;margin-top:clamp(22px,2.6vw,34px);
  font-family:var(--mono);font-size:10px;font-weight:600;letter-spacing:.15em;
  text-transform:uppercase;color:var(--ash);text-decoration:none;transition:color .22s}
.pf__back::before{content:"\2190\00a0\00a0"}
.pf__back:hover,.pf__back:focus-visible{color:var(--ink)}
/* One column below 900px, title first. The header is four short
   lines, so the demo still opens within the first screen on a phone,
   and leading with the video would leave a visitor watching a tin
   before being told which one it is. */
@media(max-width:900px){
  .pf__grid{grid-template-columns:1fr;gap:clamp(26px,4vw,40px)}
  .pf__n{font-size:clamp(40px,8vw,66px)}
  .pf__use{max-width:32ch}
}

/* ── 2  mechanism demo ───────────────────────────────────────────
   Sits in the right-hand column of the header. The plate is the same
   ground the product photography is shot on, so a video, a pair of
   stills and the line drawing all sit in the same frame. */
.demo__stage{position:relative;width:100%;aspect-ratio:16/10;
  overflow:hidden;border-radius:var(--radius)}
/* footage sits in the frame it was shot to, so nothing is cropped */
.demo__stage--v{aspect-ratio:16/9}
.demo__v{width:100%;height:100%;object-fit:cover;display:block;background:var(--steel-bg)}
.demo__pair{position:relative;width:100%;height:100%;background:var(--steel-bg)}
.demo__pair img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
/* closed holds, opens, holds, closes. Long enough to read as a
   demonstration rather than a flicker — 9s round trip, and both
   halves are opaque so the crossfade never dips to the plate. */
.demo__open{opacity:0;animation:demoswap 9s var(--ease-soft) infinite}
@keyframes demoswap{0%,30%{opacity:0}40%,76%{opacity:1}86%,100%{opacity:0}}
.demo__fig{width:100%;height:100%}
@media(prefers-reduced-motion:reduce){.demo__open{animation:none;opacity:1}}
/* the drawing gets taller on a phone, where a 16:10 letterbox leaves
   it too small to read. Footage keeps the frame it was shot to. */
@media(max-width:680px){.demo__stage:not(.demo__stage--v){aspect-ratio:4/3}}

/* ── 3  spec builder ─────────────────────────────────────────────
   Steps on the left, the specification on the right, and on a narrow
   screen the specification drops underneath rather than shrinking to
   a column nobody can read. */
/* a hairline, not a gap. The header above it is one screen and this is
   the next thing; without a rule the two run together. */
.bs{border-top:1px solid var(--line);padding-top:clamp(44px,5.5vw,86px)}
.bs__grid{display:grid;grid-template-columns:1.22fr .78fr;
  gap:clamp(28px,4.4vw,76px);align-items:start}
.bs__steps{border:none;padding:0;margin:0}
.bs__step{border:none;border-top:1px solid var(--line-2);margin:0;
  padding:clamp(26px,3.2vw,46px) 0 0}
.bs__step + .bs__step{margin-top:clamp(26px,3.2vw,46px)}
.bs__step:first-child{border-top:none;padding-top:0}
/* a legend is a hostile box to lay out — block only, never flex */
.bs__lg{display:block;width:100%;padding:0;
  font-family:var(--disp);font-weight:500;font-size:clamp(22px,2.5vw,31px);
  letter-spacing:-.024em;line-height:1.1;color:var(--ink)}
.bs__n{font-family:var(--mono);font-size:10px;font-weight:600;letter-spacing:.16em;
  color:var(--signal-dk);margin-right:15px;vertical-align:middle}
.bs__note{font-size:13px;line-height:1.6;color:var(--slate);max-width:54ch;margin-top:12px}
.bs__lg + .opts,.bs__note + .opts,.bs__lg + .qty,.bs__note + .qty{margin-top:clamp(18px,2.2vw,28px)}

.opts{display:flex;flex-wrap:wrap;gap:10px}
.opts--size{display:grid;grid-template-columns:repeat(auto-fill,minmax(212px,1fr))}
.opts--sw{display:grid;grid-template-columns:repeat(auto-fill,minmax(136px,1fr))}
/* the input is present and focusable, just not drawn — the label is */
.opt{position:relative;display:block;cursor:pointer}
.opt input{position:absolute;width:1px;height:1px;opacity:0;margin:0}
.opt__b{display:block;height:100%;background:var(--white);border:1px solid var(--line-2);
  border-radius:var(--radius);transition:border-color .2s,box-shadow .2s,color .2s}
.opt:hover .opt__b{border-color:var(--umber)}
.opt input:checked + .opt__b{border-color:var(--signal);box-shadow:inset 0 0 0 1px var(--signal)}
.opt input:focus-visible + .opt__b{outline:2px solid var(--signal);outline-offset:3px}

.opt--chip .opt__b{padding:12px 19px;font-family:var(--mono);font-size:10px;font-weight:600;
  letter-spacing:.14em;text-transform:uppercase;color:var(--steel)}
.opt--chip input:checked + .opt__b{color:var(--ink)}
.opt--size .opt__b{padding:16px 18px}
.opt__t{display:block;font-family:var(--mono);font-size:9.5px;font-weight:600;
  letter-spacing:.15em;text-transform:uppercase;color:var(--steel)}
.opt__in{display:block;font-size:15.5px;font-weight:500;color:var(--ink);margin-top:10px;
  font-variant-numeric:tabular-nums;letter-spacing:-.012em}
.opt__mm{display:block;font-family:var(--mono);font-size:10.5px;letter-spacing:.05em;
  color:var(--pewter);margin-top:5px}
.opt--sw .opt__b{display:flex;align-items:center;gap:11px;padding:11px 14px}
.opt--sw .opt__t{margin:0}
.opt__dot{width:21px;height:21px;border-radius:50%;flex:none;
  box-shadow:inset 0 0 0 1px rgba(28,26,24,.16)}

/* quantity — six stops, not a continuous range, because the price
   table has six rows and a value between them would be a guess */
.qty__r{-webkit-appearance:none;appearance:none;width:100%;height:2px;
  background:var(--line-2);border-radius:2px;outline:none;cursor:pointer}
.qty__r::-webkit-slider-thumb{-webkit-appearance:none;width:24px;height:24px;border-radius:50%;
  background:var(--umber);border:4px solid var(--paper);cursor:pointer;
  box-shadow:0 1px 7px rgba(28,26,24,.28)}
.qty__r::-moz-range-thumb{width:24px;height:24px;border-radius:50%;background:var(--umber);
  border:4px solid var(--paper);cursor:pointer;box-shadow:0 1px 7px rgba(28,26,24,.28)}
.qty__r:focus-visible{outline:2px solid var(--signal);outline-offset:8px}
.qty__ticks{display:flex;margin-top:18px;font-family:var(--mono);font-size:9.5px;
  font-weight:600;letter-spacing:.08em;color:var(--pewter);
  font-variant-numeric:tabular-nums}
.qty__ticks span{flex:1;text-align:center}
.qty__ticks span:first-child{text-align:left}
.qty__ticks span:last-child{text-align:right}

/* the panel. Rendered at build time and updated in place, so it is
   readable with no script at all. */
.bs__panel{position:sticky;top:calc(var(--nav-h) + 22px);
  background:var(--white);border:1px solid var(--line);
  padding:clamp(22px,2.7vw,34px)}
.bs__ref{font-family:var(--mono);font-size:12px;font-weight:600;letter-spacing:.09em;
  color:var(--signal-dk);margin-top:14px;word-break:break-all}
.bs__rows{margin-top:clamp(18px,2.2vw,26px);border-top:1px solid var(--line-2)}
.bs__row{display:grid;grid-template-columns:94px 1fr;gap:16px;padding:11px 0;
  border-bottom:1px solid var(--line)}
.bs__row dt{font-family:var(--mono);font-size:9.5px;font-weight:600;letter-spacing:.14em;
  text-transform:uppercase;color:var(--steel)}
.bs__row dd{font-size:14px;color:var(--ink)}
.bs__row dd span{display:block;font-family:var(--mono);font-size:10.5px;letter-spacing:.05em;
  color:var(--pewter);margin-top:4px}
/* an indicative price band sat under the rows and came off with the
   table behind it. What is left is the one line saying what happens
   next, which is why the rule moved onto it. */
.bs__fine{font-size:11.5px;line-height:1.55;color:var(--ash);
  margin-top:clamp(18px,2.2vw,26px);padding-top:clamp(16px,1.8vw,22px);
  border-top:1px solid var(--line-2)}
@media(max-width:900px){
  .bs__grid{grid-template-columns:1fr}
  .bs__panel{position:static;margin-top:var(--blk)}
}

/* ── 4  three actions ────────────────────────────────────────────
   Side by side, equal height, one line of explanation each. The
   render is filled because it is the only one of the three that costs
   a buyer nothing and shows them their own brand on the tin. */
.acts{border-top:1px solid var(--line)}
.acts__grid{display:grid;grid-template-columns:repeat(3,1fr);gap:clamp(16px,2.2vw,30px)}
.act{display:flex;flex-direction:column;text-decoration:none;color:inherit;
  background:var(--white);border:1px solid var(--line);padding:clamp(24px,3vw,40px);
  border-radius:var(--radius);
  transition:border-color .25s,transform .25s var(--ease-soft),box-shadow .25s,background .25s}
.act:hover{border-color:var(--umber);transform:translateY(-2px);
  box-shadow:0 12px 34px rgba(28,26,24,.08)}
.act--p{background:var(--umber);border-color:var(--umber);color:var(--paper)}
.act--p:hover{background:var(--ink);border-color:var(--ink)}
.act__t{font-family:var(--disp);font-weight:500;font-size:clamp(20px,2.1vw,27px);
  letter-spacing:-.026em;line-height:1.12}
.act__p{font-size:13.5px;line-height:1.6;color:var(--slate);margin-top:14px;flex:1}
.act--p .act__p{color:rgba(244,242,238,.82)}
.act__go{font-family:var(--mono);font-size:10px;font-weight:600;letter-spacing:.16em;
  text-transform:uppercase;color:var(--signal-dk);margin-top:clamp(22px,2.6vw,34px)}
.act__go::after{content:"\00a0\2192"}
.act--p .act__go{color:var(--paper)}
@media(max-width:820px){.acts__grid{grid-template-columns:1fr}}
@media(prefers-reduced-motion:reduce){.act:hover{transform:none}}

/* spec list — mono keys, plain values, no adjectives */
.spec{border-top:1px solid var(--line-2);margin-top:var(--blk)}
.spec__row{display:grid;grid-template-columns:150px 1fr;gap:24px;padding:15px 0;
  border-bottom:1px solid var(--line)}
.spec__row dt{font-family:var(--mono);font-size:10px;font-weight:600;letter-spacing:.15em;
  text-transform:uppercase;color:var(--steel)}
.spec__row dd{font-size:14.5px;color:var(--ink)}
@media(max-width:560px){.spec__row{grid-template-columns:1fr;gap:5px}}

/* ── 11  index rows + asset slots ────────────────────────────────── */
.index{border-top:1px solid var(--line-2);margin-top:var(--blk)}
.slot{position:relative;background:var(--steel-bg);border-radius:var(--radius);overflow:hidden;
  box-shadow:inset 0 0 0 1px rgba(28,26,24,.06);display:block}
.slot img{width:100%;height:100%;object-fit:contain;display:block}
.slot--hero{aspect-ratio:1;margin-bottom:26px}
.gallery{display:grid;grid-template-columns:repeat(3,1fr);gap:clamp(14px,2vw,26px);
  margin-top:var(--blk)}
.gallery .slot{aspect-ratio:3/2;margin:0}
@media(max-width:820px){.gallery{grid-template-columns:1fr}}
.row{display:grid;grid-template-columns:46px minmax(150px,1.05fr) 172px minmax(140px,1fr) 78px 22px;
  gap:clamp(14px,2.2vw,34px);align-items:baseline;
  padding:clamp(20px,2.3vw,30px) 4px;border-bottom:1px solid var(--line);
  text-decoration:none;color:inherit;cursor:pointer;transition:background .25s}
.row:hover{background:rgba(28,26,24,.024)}
.row__t{width:62px;height:62px;border-radius:var(--radius);background:var(--steel-bg);overflow:hidden;
  box-shadow:inset 0 0 0 1px rgba(28,26,24,.07);align-self:center}
.row__t img{width:100%;height:100%;object-fit:contain;display:block}
.index--thumbs .row{grid-template-columns:46px 62px minmax(140px,1fr) 172px minmax(130px,1fr) 78px 22px}
.row__i{font-family:var(--mono);font-size:10.5px;color:var(--ash);letter-spacing:.1em}
.row__n{font-family:var(--disp);font-weight:500;font-size:clamp(21px,2.5vw,31px);
  letter-spacing:-.026em;line-height:1.05;font-variation-settings:'opsz' 70}
.row__eco{font-family:var(--mono);font-style:normal;font-size:8.5px;letter-spacing:.14em;
  text-transform:uppercase;color:var(--moss);vertical-align:middle;margin-left:10px}
.row__dim{font-size:13.5px;font-weight:500;color:var(--ink);font-variant-numeric:tabular-nums}
.row__dim em{display:block;font-family:var(--mono);font-style:normal;font-size:10.5px;
  color:var(--ash);margin-top:3px;letter-spacing:.02em}
.row__u{font-size:12.5px;color:var(--steel);line-height:1.5}
.row__c{font-family:var(--mono);font-size:10.5px;color:var(--steel);white-space:nowrap}
.row__a{font-family:var(--mono);font-size:14px;color:var(--mist);
  transition:transform .25s,color .25s;text-align:right}
.row:hover .row__a{transform:translateX(5px);color:var(--ink)}
.row:hover .row__n{color:var(--signal-dk)}
@media(max-width:1080px){
  .index--thumbs .row{grid-template-columns:40px 62px 1fr 150px}
  .row{grid-template-columns:40px 1fr 150px;row-gap:9px}
  .row__u{grid-column:2/-1}.row__c{grid-column:2/3}.row__a{display:none}
}
@media(max-width:600px){
  .index--thumbs .row{grid-template-columns:34px 62px 1fr}
  .row{grid-template-columns:34px 1fr}
  .row__dim,.row__u,.row__c{grid-column:2/-1}
}

/* ── 12  eco / inverted / stats ──────────────────────────────────── */
.inv{background:var(--graphite);color:#e4e6e8}
.inv h1,.inv h2,.inv h3{color:#faf8f5}
.inv p{color:#b0a9a1}
.inv .label{color:var(--mist)}
.inv .pull{color:#faf8f5}
.stats{display:grid;grid-template-columns:repeat(4,1fr);gap:1px;background:var(--line-inv);
  margin-top:var(--blk);border:1px solid var(--line-inv)}
@media(max-width:820px){.stats{grid-template-columns:repeat(2,1fr)}}
.stat{background:var(--graphite);padding:30px 22px 26px}
.stat b{display:block;font-family:var(--disp);font-weight:500;font-size:clamp(32px,4vw,50px);
  letter-spacing:-.035em;line-height:1;color:#faf8f5;font-variation-settings:'opsz' 120;
  font-variant-numeric:tabular-nums}
.stat span{display:block;margin-top:12px}

.eco{background:var(--paper-2);border-top:1px solid var(--line);border-bottom:1px solid var(--line)}
.eco .label{color:var(--moss)}
.eco h2{color:var(--ink)}
.eco p{color:var(--slate)}
/* .ecolist and .ecoitem drew the four Eco cards on the range index.
   That block is a page now — /eco/ — and the range index carries a
   short panel pointing at it. */

/* ═══════════════════════════════════════════════════════════════════
   /eco/  —  a materials page

   Same warm paper as everywhere else. No green ground, no leaf, no
   photograph of a forest: the argument is that the tin is one metal,
   and dressing it in the colour of the thing it is not arguing about
   would be the first unverifiable claim on the page. --moss appears
   exactly where it appears elsewhere — small, on a label.
   ═══════════════════════════════════════════════════════════════════ */
.label--moss{color:var(--moss)}
/* the line under the lede. Carries the terms this page is written to
   be found for, at a size that reads as a subtitle rather than as a
   second lede competing with the first. */
.eco__sub{font-size:14.5px;line-height:1.6;color:var(--steel);max-width:52ch;margin-top:18px}

/* the three mechanisms. A statement, what happens, and why that
   matters — three sizes of type doing three different jobs. */
.mechs{display:grid;grid-template-columns:repeat(3,1fr);gap:1px;
  background:var(--line);border-top:1px solid var(--line-2);
  border-bottom:1px solid var(--line-2);margin-top:var(--blk)}
.mech{background:var(--paper);padding:clamp(26px,3.2vw,42px) clamp(20px,2.4vw,32px)}
.mech__h{font-family:var(--disp);font-weight:500;font-size:clamp(22px,2.3vw,30px);
  letter-spacing:-.026em;line-height:1.08;color:var(--ink)}
.mech__a{font-size:15.5px;line-height:1.55;color:var(--ink);margin-top:16px;max-width:30ch}
.mech__b{font-size:13.5px;line-height:1.6;color:var(--steel);margin-top:12px;max-width:34ch}
@media(max-width:820px){.mechs{grid-template-columns:1fr}}
/* the qualifier that keeps the three mechanisms above from reading as
   a complaint about our own standard range */
.mechs__note{font-size:13.5px;line-height:1.65;color:var(--steel);max-width:62ch;
  margin-top:clamp(22px,2.6vw,32px)}

/* the four figures. Display serif at scale, mono label beneath —
   the same pairing the rest of the site uses for instrumentation. */
.figs{display:grid;grid-template-columns:repeat(4,1fr);gap:clamp(18px,2.6vw,40px);
  margin-top:var(--blk)}
.fig4{border-top:1px solid var(--line-2);padding-top:clamp(16px,2vw,24px)}
.fig4__v{display:block;font-family:var(--disp);font-weight:500;
  font-size:clamp(44px,5.6vw,80px);letter-spacing:-.04em;line-height:1;color:var(--ink);
  font-variation-settings:'opsz' 120;font-variant-numeric:tabular-nums}
.fig4__l{display:block;font-family:var(--mono);font-size:9.5px;font-weight:600;
  letter-spacing:.15em;text-transform:uppercase;color:var(--moss);margin-top:16px;
  line-height:1.7}
.fig4__n{font-size:12.5px;line-height:1.55;color:var(--steel);margin-top:10px}
@media(max-width:860px){.figs{grid-template-columns:repeat(2,1fr)}}
@media(max-width:480px){.figs{grid-template-columns:1fr}}
/* the qualifier, and then the citations. Small, but not hidden — a
   page that argues from numbers has to show where they came from. */
.figs__note{font-size:13.5px;line-height:1.6;color:var(--ink);max-width:56ch;
  margin-top:clamp(24px,3vw,38px);padding-top:clamp(16px,2vw,22px);
  border-top:1px solid var(--line)}
.figs__src{list-style:none;margin-top:18px;padding:0;
  font-size:11.5px;line-height:1.7;color:var(--ash);max-width:64ch}
.figs__src b{font-family:var(--mono);font-weight:600;letter-spacing:.06em;
  color:var(--steel);margin-right:8px}

/* standard against Eco. Two columns, one rule between them, no tick
   marks and no crossed-out column — this is a difference, not a
   scorecard. */
.vs{display:grid;grid-template-columns:1fr 1fr;gap:1px;background:var(--line);
  border-top:1px solid var(--line-2);border-bottom:1px solid var(--line-2);
  margin-top:var(--blk)}
/* Both columns are the same ground. The Eco one used to sit on white
   and that alone read as "this is the better one" — most of the range
   has a liner, the liner is doing a job, and the page is not here to
   apologise for it. */
.vs__col{background:var(--paper);padding:clamp(24px,3vw,38px)}
.vs__p{font-size:15.5px;line-height:1.55;color:var(--ink);margin-top:16px;max-width:34ch}
.vs__q{font-size:13px;line-height:1.6;color:var(--steel);margin-top:14px;padding-top:14px;
  border-top:1px solid var(--line);max-width:36ch}
@media(max-width:680px){.vs{grid-template-columns:1fr}}
/* the line under the comparison. It used to be a "what it costs"
   block spelling out which build suits what; that is a phone call,
   not website copy, and this is the invitation to make it. */
.vs__spec{font-size:14px;line-height:1.65;color:var(--slate);max-width:62ch;
  margin-top:var(--blk);border-left:2px solid var(--moss);
  padding:2px 0 2px clamp(18px,2.2vw,26px)}

/* the four lines, as rows rather than cards — they differ by size
   range, and rows put those ranges in a column you can read down. */
.ecolines{border-top:1px solid var(--line-2);margin-top:var(--blk)}
.ecoline{display:grid;grid-template-columns:1.05fr .9fr 1.5fr auto;
  gap:clamp(16px,2.6vw,38px);align-items:baseline;padding:clamp(18px,2.2vw,26px) 4px;
  border-bottom:1px solid var(--line);text-decoration:none;color:inherit;
  transition:background .22s}
.ecoline:hover{background:rgba(28,26,24,.024)}
.ecoline__t b{display:block;font-family:var(--disp);font-weight:500;font-size:20px;
  letter-spacing:-.024em;color:var(--ink);transition:color .22s}
.ecoline:hover .ecoline__t b{color:var(--moss)}
.ecoline__t span{display:block;font-family:var(--mono);font-size:9.5px;font-weight:600;
  letter-spacing:.14em;text-transform:uppercase;color:var(--moss);margin-top:8px}
.ecoline__in{display:block;font-size:14.5px;font-weight:500;color:var(--ink);
  font-variant-numeric:tabular-nums;letter-spacing:-.012em}
.ecoline__mm{display:block;font-family:var(--mono);font-size:10.5px;color:var(--ash);
  margin-top:4px;letter-spacing:.04em}
.ecoline__u p{font-size:13px;line-height:1.55;color:var(--steel)}
/* the opening action, on the one line the factory has documented it
   for. Set apart by a rule rather than a heading, since three of the
   four rows have no such line. */
.ecoline__open{border-top:1px solid var(--line);padding-top:10px;margin-top:11px;
  font-size:12px;color:var(--ash);max-width:46ch}
.ecoline__go{font-family:var(--mono);font-size:9.5px;font-weight:600;letter-spacing:.15em;
  text-transform:uppercase;color:var(--signal-dk);white-space:nowrap}
.ecoline__go::after{content:"\00a0\2192"}
@media(max-width:900px){
  .ecoline{grid-template-columns:1fr 1fr;row-gap:12px}
  .ecoline__u{grid-column:1/3}
  .ecoline__go{grid-column:1/3}
}

/* ── 13  definition lists + forms ────────────────────────────────── */
.deflist{border-top:1px solid var(--line)}
.defrow{display:grid;grid-template-columns:220px 1fr;gap:28px;padding:24px 0;
  border-bottom:1px solid var(--line)}
@media(max-width:720px){.defrow{grid-template-columns:1fr;gap:8px}}
.defrow dt{font-family:var(--mono);font-size:10px;font-weight:600;letter-spacing:.15em;
  text-transform:uppercase;color:var(--steel);padding-top:5px}
.defrow dd p{margin-bottom:.7em}
.deflist--tight .defrow{grid-template-columns:110px 1fr}
.deflist--tight a{color:var(--ink);text-decoration:none;border-bottom:1px solid var(--line-2);
  transition:border-color .2s}
.deflist--tight a:hover{border-color:var(--umber)}

.form{display:grid;gap:20px;max-width:560px}
.field{display:grid;gap:8px}
.field label{font-family:var(--mono);font-size:10px;font-weight:600;letter-spacing:.15em;
  text-transform:uppercase;color:var(--steel)}
.field input,.field select,.field textarea{font-family:var(--sans);font-size:15px;
  color:var(--ink);background:var(--white);border:1px solid var(--line-2);border-radius:2px;
  padding:13px 15px;width:100%;transition:border-color .2s}
.field input:focus,.field select:focus,.field textarea:focus{outline:none;border-color:var(--umber)}
.field textarea{resize:vertical;min-height:118px;line-height:1.6}
/* the specification handed over from a format page. Mono because it
   is a specification, and editable because a buyer should be able to
   correct it before it becomes an enquiry. */
.field__mono{font-family:var(--mono)!important;font-size:12.5px!important;line-height:1.85!important}
/* file input — the browser's own button, restrained rather than
   replaced. A custom one is a label, an input and a name readout to
   maintain, and none of that is worth it for one field. */
.field input[type=file]{padding:11px 12px;font-size:13px;cursor:pointer}
.field input[type=file]::file-selector-button{font-family:var(--mono);font-size:10px;
  font-weight:600;letter-spacing:.14em;text-transform:uppercase;color:var(--paper);
  background:var(--umber);border:none;border-radius:100px;padding:9px 16px;margin-right:14px;
  cursor:pointer;transition:background .22s}
.field input[type=file]::file-selector-button:hover{background:var(--ink)}
.field--row{display:grid;grid-template-columns:1fr 1fr;gap:16px}
@media(max-width:560px){.field--row{grid-template-columns:1fr}}
.hint{font-size:12px;color:var(--ash);margin-top:-2px}

/* ── 14  footer ──────────────────────────────────────────────────── */
.foot{background:var(--white);border-top:1px solid var(--line);padding:64px 0 40px}
.fg{display:grid;grid-template-columns:2fr 1fr 1fr 1fr;gap:34px}
@media(max-width:820px){.fg{grid-template-columns:1fr 1fr}}
.foot h4{font-family:var(--mono);font-size:10px;font-weight:600;letter-spacing:.16em;
  text-transform:uppercase;color:var(--steel);margin-bottom:16px}
.foot ul{list-style:none}
.foot li{margin-bottom:9px}
.foot a{font-size:13.5px;color:var(--slate);text-decoration:none;cursor:pointer;
  transition:color .2s}
.foot a:hover{color:var(--ink)}
.ftag{font-family:var(--mono);font-size:10px;letter-spacing:.16em;text-transform:uppercase;
  color:var(--steel);margin-top:12px}
.fb{display:flex;justify-content:space-between;gap:18px;flex-wrap:wrap;margin-top:48px;
  padding-top:24px;border-top:1px solid var(--line);font-size:12.5px;color:var(--ash)}

/* ── 15  presence ────────────────────────────────────────────────
   Weight, depth and rhythm. The restraint stays; the page stops
   looking like a document and starts looking like a product. */

/* paper grain — barely there, but it kills the flat-white screen look */
body::before{content:"";position:fixed;inset:0;z-index:1;pointer-events:none;opacity:.05;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.82' numOctaves='3'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)'/%3E%3C/svg%3E")}

/* ── spec-sheet hero ─────────────────────────────────────────────
   The first screen reads as a controlled engineering document, not a
   marketing banner. Nobody in this category opens like this. */
.sheet{border:1px solid var(--line-2);background:var(--white);border-radius:var(--radius);
  overflow:hidden}
.sheet__top{display:flex;justify-content:space-between;align-items:center;gap:16px;
  padding:13px clamp(18px,2.4vw,30px);border-bottom:1px solid var(--line-2);
  background:var(--paper-2)}
.sheet__top span{font-family:var(--mono);font-size:9.5px;font-weight:600;letter-spacing:.2em;
  text-transform:uppercase;color:var(--steel)}
.sheet__top span:first-child{color:var(--ink)}
.sheet__body{display:grid;grid-template-columns:1.15fr .85fr;gap:0}
@media(max-width:900px){.sheet__body{grid-template-columns:1fr}}
.sheet__txt{padding:clamp(26px,3.6vw,52px);border-right:1px solid var(--line)}
@media(max-width:900px){.sheet__txt{border-right:none;border-bottom:1px solid var(--line)}}
.sheet__h{font-family:var(--disp);font-weight:500;letter-spacing:-.035em;line-height:.95;
  font-size:clamp(38px,5.4vw,74px);font-variation-settings:'opsz' 120}
.sheet__h em{font-style:italic;font-weight:400}
.sheet__specs{display:grid;grid-template-columns:repeat(2,1fr);
  border-top:1px solid var(--line);margin-top:clamp(26px,3.4vw,42px)}
.sheet__specs div{padding:13px 0 12px;border-bottom:1px solid var(--line)}
.sheet__specs div:nth-child(odd){padding-right:16px;border-right:1px solid var(--line)}
.sheet__specs div:nth-child(even){padding-left:20px}
.sheet__specs span{display:block;font-family:var(--mono);font-size:8.5px;font-weight:600;
  letter-spacing:.19em;text-transform:uppercase;color:var(--pewter)}
.sheet__specs b{display:block;font-family:var(--mono);font-size:13px;font-weight:600;
  color:var(--ink);margin-top:5px;letter-spacing:.02em;font-variant-numeric:tabular-nums}
.sheet__fig{position:relative;background:var(--steel-bg);display:grid;place-items:center;
  background-image:linear-gradient(var(--steel-grid) 1px,transparent 1px),
    linear-gradient(90deg,var(--steel-grid) 1px,transparent 1px);
  background-size:26px 26px;min-height:clamp(260px,32vw,440px)}
.sheet__fig .tech{width:82%;height:82%;color:var(--steel-line)}

/* ── find your format ────────────────────────────────────────────
   Three questions, live filtering. Engagement from utility. */
.finder{background:var(--paper-2);border-top:1px solid var(--line);
  border-bottom:1px solid var(--line)}
.fq{border-top:1px solid var(--line);padding:clamp(20px,2.6vw,30px) 0}
.fq:first-of-type{border-top:1px solid var(--line-2)}
.fq__n{font-family:var(--mono);font-size:10px;font-weight:600;letter-spacing:.17em;
  text-transform:uppercase;color:var(--steel);margin-bottom:16px}
.fq__n b{color:var(--signal-dk);font-weight:600}
.fq__opts{display:flex;gap:9px;flex-wrap:wrap}
.fr{border-top:1px solid var(--line-2);margin-top:clamp(26px,3vw,40px);
  padding-top:clamp(26px,3vw,40px)}
.fr__head{display:flex;justify-content:space-between;align-items:baseline;gap:20px;
  flex-wrap:wrap;margin-bottom:clamp(20px,2.4vw,30px)}
.fr__n{font-family:var(--mono);font-size:10px;font-weight:600;letter-spacing:.16em;
  text-transform:uppercase;color:var(--signal-dk);font-variant-numeric:tabular-nums}
.fr__grid{display:grid;grid-template-columns:repeat(3,1fr);gap:clamp(14px,2vw,24px)}
@media(max-width:860px){.fr__grid{grid-template-columns:repeat(2,1fr)}}
@media(max-width:520px){.fr__grid{grid-template-columns:1fr}}
.fr__card{display:block;text-decoration:none;color:inherit;background:var(--paper);
  border:1px solid var(--line);border-radius:var(--radius);padding:20px 20px 18px;
  transition:border-color .25s,background .25s}
.fr__card:hover{border-color:var(--umber);background:var(--white)}
.fr__card b{font-family:var(--disp);font-weight:500;font-size:20px;letter-spacing:-.024em;
  display:block;transition:color .25s}
.fr__card:hover b{color:var(--signal-dk)}
.fr__card p{font-size:12.5px;color:var(--steel);margin:9px 0 0;line-height:1.5}
.fr__card em{display:block;font-family:var(--mono);font-style:normal;font-size:10px;
  letter-spacing:.13em;text-transform:uppercase;color:var(--pewter);margin-top:12px;
  padding-top:11px;border-top:1px solid var(--line)}
.fr__none{font-size:14px;color:var(--steel);max-width:48ch}
.fr__reset{font-family:var(--mono);font-size:10px;font-weight:600;letter-spacing:.14em;
  text-transform:uppercase;background:none;border:none;color:var(--steel);cursor:pointer;
  padding:4px 0;transition:color .2s}
.fr__reset:hover{color:var(--signal-dk)}
.sheet__fig{position:relative}

/* hero product lineup — static, no float, no bob. Four real
   elevations arranged as a lineup rather than scattered abstractions. */
.lineup{display:grid;grid-template-columns:1fr 1fr;gap:clamp(10px,1.4vw,18px)}
.lineup .fig{aspect-ratio:1}
@media(max-width:900px){.lineup{grid-template-columns:repeat(4,1fr);margin-top:30px}}
@media(max-width:560px){.lineup{grid-template-columns:1fr 1fr}}

/* Tile card. The by-product grid it was written for came off the home
   page; the ordering block on the same page still uses it, laid out by
   .g4 rather than by a grid of its own. */
.use{background:var(--paper);padding:clamp(24px,3vw,34px);text-decoration:none;color:inherit;
  display:block;transition:background .25s}
.use:hover{background:var(--white)}
.use b{font-family:var(--disp);font-weight:500;font-size:21px;letter-spacing:-.022em;
  display:block}
.use span{font-family:var(--mono);font-size:9.5px;font-weight:600;letter-spacing:.15em;
  text-transform:uppercase;color:var(--signal-dk);display:block;margin-bottom:12px}
.use p{font-size:13.5px;margin-top:10px;line-height:1.55;color:var(--steel)}
/* no plate to carry the mark, so it goes on the name */
.use b::after{content:"→";font-family:var(--mono);font-size:13.5px;font-weight:600;
  color:var(--signal-dk);margin-left:10px;display:inline-block;
  transition:transform .25s var(--ease)}
.use:hover b::after,.use:focus-visible b::after{transform:translateX(4px)}
@media(prefers-reduced-motion:reduce){.use b::after{transition:none}}

/* hero holds the screen */
.hero{min-height:min(92vh,920px);display:flex;flex-direction:column;justify-content:center;
  padding-top:clamp(40px,7vw,96px);padding-bottom:clamp(28px,3vw,44px)}
.hero__in{flex:1;align-content:center}
.hero h1{font-size:clamp(54px,11.5vw,168px);letter-spacing:-.042em}
.hero .lede{max-width:42ch}
@media(max-width:900px){.hero{min-height:auto}}

/* instrumentation strip along the base of the hero */
.hero__strip{display:grid;grid-template-columns:repeat(4,1fr);gap:clamp(14px,2vw,30px);
  border-top:1px solid var(--line-2);padding-top:clamp(18px,2.2vw,28px);
  margin-top:clamp(30px,4vw,56px)}
.hero__strip b{display:block;font-family:var(--disp);font-weight:500;
  font-size:clamp(26px,3.4vw,46px);letter-spacing:-.035em;line-height:1;color:var(--ink);
  font-variation-settings:'opsz' 120;font-variant-numeric:tabular-nums}
.hero__strip span{display:block;font-family:var(--mono);font-size:9.5px;font-weight:600;
  letter-spacing:.16em;text-transform:uppercase;color:var(--steel);margin-top:11px}
@media(max-width:680px){
  .hero__strip{grid-template-columns:repeat(2,1fr);row-gap:22px}
}

/* figures sit on the page rather than in it */
.fig,.band__fig{box-shadow:inset 0 0 0 1px rgba(28,26,24,.055),
  0 1px 2px rgba(28,26,24,.04),0 12px 32px -12px rgba(28,26,24,.16);
  transition:box-shadow .4s var(--ease-soft),transform .4s var(--ease-soft)}
.cat__card:hover .fig{box-shadow:inset 0 0 0 1px rgba(28,26,24,.09),
  0 2px 4px rgba(28,26,24,.05),0 22px 48px -16px rgba(28,26,24,.24);
  transform:translateY(-3px)}
.band:hover .band__fig{box-shadow:inset 0 0 0 1px rgba(28,26,24,.09),
  0 2px 4px rgba(28,26,24,.05),0 22px 48px -16px rgba(28,26,24,.22)}

/* the dark sections carry more weight */
.inv{position:relative}
.inv::before{content:"";position:absolute;inset:0;pointer-events:none;
  background:radial-gradient(120% 80% at 15% 0%,rgba(255,255,255,.055),transparent 60%)}
.inv>*{position:relative}

/* reveal arrives with a little more travel and a stagger */
.rv{transform:translateY(24px)}
.rv.in{transition:opacity .9s ease,transform .9s var(--ease-soft)}
section > .wrap > *:nth-child(2).rv.in{transition-delay:.06s}
section > .wrap > *:nth-child(3).rv.in{transition-delay:.12s}

/* ── 16  art direction ───────────────────────────────────────────
   Chapters, specimen type, broken grid, colour blocks. Scale and
   contrast do the work — the palette and the restraint don't move. */

/* full-bleed dark chapter between sections */

/* ── customisation ───────────────────────────────────────────────
   Three capabilities at equal weight. No card treatment — a rule
   above each is enough to separate them. */
.cust{display:grid;grid-template-columns:repeat(3,1fr);
  gap:clamp(24px,3.4vw,52px);margin-top:var(--blk)}
.cust__b{border-top:1px solid var(--line-2);padding-top:clamp(18px,2.2vw,28px)}
.cust__t{font-family:var(--disp);font-weight:500;font-size:clamp(19px,1.9vw,24px);
  letter-spacing:-.02em;margin:0 0 12px}
.cust__b p{font-size:13.5px;line-height:1.6;max-width:38ch}
.cust__a{display:inline-block;margin-top:14px;
  font-family:var(--mono);font-size:10px;font-weight:600;letter-spacing:.15em;
  text-transform:uppercase;color:var(--signal-dk);text-decoration:none;
  transition:color .22s}
.cust__a::after{content:" \2192"}
.cust__a:hover,.cust__a:focus-visible{color:var(--ink)}
@media(max-width:900px){.cust{grid-template-columns:1fr;gap:clamp(20px,4vw,32px)}}

/* ── certification band ──────────────────────────────────────────
   Two rules and a sentence. This was a full graphite chapter, which
   made sense when the page opened on a dark screen and read as a rhyme
   — with the landing screen on paper it was the only dark thing left
   and it stopped the page dead.

   The argument itself lives on certification.html. Here it only needs
   to be stated once and pointed at, so the page keeps moving. */
/* no top padding — the section above already provides it — but a
   little below, so the closing rule is not flush against whatever
   colour the next section brings. On the home page that is the green
   of the Eco band, and flush read as an accident. */
.cert{padding:0 0 clamp(26px,3vw,48px)}
.cert__in{display:flex;align-items:baseline;justify-content:space-between;
  gap:clamp(20px,4vw,60px);flex-wrap:wrap;
  border-top:1px solid var(--line-2);border-bottom:1px solid var(--line-2);
  padding:clamp(30px,3.6vw,52px) 0}
.cert__t{font-family:var(--disp);font-weight:400;
  font-size:clamp(18px,2.05vw,27px);line-height:1.34;letter-spacing:-.014em;
  color:var(--ink);margin:0;max-width:36ch}
/* the second line steps back, so the claim leads and the qualifier
   supports it rather than sitting level with it */
.cert__t span{color:var(--slate)}
.cert__a{font-family:var(--mono);font-size:10px;font-weight:600;letter-spacing:.16em;
  text-transform:uppercase;color:var(--signal-dk);text-decoration:none;
  white-space:nowrap;transition:color .22s}
.cert__a::after{content:" \2192"}
.cert__a:hover,.cert__a:focus-visible{color:var(--ink)}
@media(max-width:640px){.cert__in{flex-direction:column;gap:18px}}

/* display type that breaks out of the measure */
.statement{font-family:var(--disp);font-weight:500;letter-spacing:-.038em;line-height:.96;
  font-size:clamp(38px,8vw,124px);max-width:none;color:var(--ink);margin:0}
.statement em{font-style:italic;font-weight:400}
.statement--q{font-weight:400;font-style:italic;font-size:clamp(32px,6.2vw,92px);
  line-height:1.04;max-width:16ch}

/* deliberate asymmetry — content that refuses to centre */
.offset-r{margin-left:auto;max-width:min(62%,620px)}
.offset-l{max-width:min(58%,560px)}
@media(max-width:860px){.offset-r,.offset-l{max-width:none;margin-left:0}}
.push{padding-top:clamp(48px,9vw,164px)}
.hang{margin-top:clamp(-90px,-7vw,-28px)}
@media(max-width:860px){.hang{margin-top:0}}

/* colour-blocked panels */
.block{padding:clamp(40px,5.5vw,84px);border-radius:var(--radius)}
.block--moss{background:var(--moss-bg)}
.block--paper{background:var(--paper-2)}
.block--umber{background:var(--umber);color:#e8e4de}
.block--umber h2,.block--umber h3{color:#faf8f5}
.block--umber p{color:#b0a9a1}

/* the eco panel on the range index becomes a real colour block. It is
   the one place on the site --moss covers an area rather than a word,
   and it is a signpost to /eco/ rather than an argument — the page
   itself is paper like everything else. */
.eco{background:var(--moss-bg)}

/* ── 17  card affordance ─────────────────────────────────────────
   These cards used to invert to graphite on hover: the ground, the
   name, the dimensions, the meta row and the product plate all
   recoloured at once. It read as the card changing state rather than
   as something you could open, and it buried the photography under a
   colour it was never shot for. Gone.

   What replaces it does two things the invert did badly.

   · The cue is PERMANENT. Hover does not exist on a phone, so an
     affordance that waits for a cursor tells half the audience
     nothing at all. Every plate carries an open mark whether or not
     anything is pointing at it.
   · Hover moves things, it does not recolour them. The card lifts,
     its shadow deepens, the mark shifts, and on a technical drawing
     the lid still opens to demonstrate the closure. No colour on the
     card changes at any point. */
.cat__card,.use{transition:background .25s ease,border-color .25s ease}
.cat__card{padding:12px;border-radius:var(--radius)}
.cat--4 .cat__card{padding:10px}

/* ── card crossfade ──────────────────────────────────────────────
   The open shot lies on top of the closed one and fades in. Both are
   absolutely positioned by the .fig img rule above, so the second
   frame adds no height and nothing shifts.

   In and out are deliberately different lengths. Arriving is 500ms,
   because the card should answer quickly; leaving is 700ms, because
   a pointer crossing a grid of six would otherwise strobe. The rule
   on the base state governs the way out, the rule on :hover governs
   the way in — that is the only way to give one transition two
   durations. */
.fig__open{opacity:0;transition:opacity .7s var(--ease-soft)}
.cat__card:hover .fig__open,
.cat__card:focus-visible .fig__open{opacity:1;transition:opacity .5s var(--ease-soft)}

/* No pointer, so no hover to wait for. The card opens when it comes
   into view and stays open — set by an observer in app.js, since CSS
   cannot ask whether something is on screen. */
@media (hover:none){
  .cat__card:hover .fig__open{opacity:0}
  .fig--seen .fig__open{opacity:1;transition:opacity .5s var(--ease-soft)}
}
@media (prefers-reduced-motion:reduce){
  .fig__open{transition:none}
  .cat__card:hover .fig__open,.fig--seen .fig__open{transition:none}
}

/* The card's own control. Not a new component — it is .btn at card
   scale, so a grid of six reads as the same system as "Request a
   sample" and "See all six" rather than as decoration invented for
   this one place.

   Permanent, like the corner mark it replaced: hover does not exist
   on a phone, and an affordance waiting for a cursor tells half the
   audience nothing. The card is already the link, so this is a span —
   a nested <a> would be a second tab stop to the same place. */
.cat__go{display:inline-block;margin-top:18px;
  font-family:var(--mono);font-size:9.5px;font-weight:600;letter-spacing:.16em;
  text-transform:uppercase;padding:10px 18px;border-radius:2px;
  border:1px solid var(--line-2);color:var(--umber);background:transparent;
  transition:background .25s var(--ease),color .25s var(--ease),
    border-color .25s var(--ease)}
/* the button fills; the card and the photograph do not */
.cat__card:hover .cat__go,.cat__card:focus-visible .cat__go{
  background:var(--umber);border-color:var(--umber);color:var(--paper)}
@media(max-width:560px){.cat__go{padding:9px 15px;margin-top:15px}}

/* decorative uses keep the lighter pewter */
::-webkit-scrollbar-thumb:hover{background:var(--pewter-lt)}

/* ── 18  reveal, focus, reduced motion ───────────────────────────── */
.rv{opacity:0;transform:translateY(16px)}
.rv.in{opacity:1;transform:none;transition:opacity .8s ease,transform .8s var(--ease-soft)}
:focus-visible{outline:2px solid var(--signal);outline-offset:3px;border-radius:1px}
.skip{position:absolute;left:-9999px;top:0;z-index:200;background:var(--umber);
  color:var(--paper);padding:12px 20px;font-family:var(--mono);font-size:11px;
  letter-spacing:.13em;text-transform:uppercase;text-decoration:none}
.skip:focus{left:var(--gutter);top:14px}

@media(prefers-reduced-motion:reduce){
  *{transition:none!important;animation:none!important}
  html{scroll-behavior:auto}
  .rv{opacity:1;transform:none}
  .kin>span{transform:none;opacity:1}
  .cl{opacity:1;transform:rotate(var(--r))}
  .reel__slide .pc{transform:rotate(var(--r))}
  .reel__dot[aria-current] i{transform:scaleX(1)}
  .tech .ln{stroke-dashoffset:0}
  .tech .dims{opacity:1}
  .cat__card.is-out{opacity:1;transform:none}
  @view-transition{navigation:none}
}
