/* ============================================================
   SANWA METAL POWDERS — COMPONENTS, v1
   Requires tokens.css. Every value here is a token; there are no
   literal colours, sizes or durations below this line except the
   media-query breakpoints, which CSS cannot read from a custom
   property. Those use the documented values in tokens.css §4.

   Order:
     0  base and reset
     1  layout: container, grid, section, panel
     2  the measurement grid
     3  logo lockups and brand primitives
     4  element tiles
     5  family markers and the family rule
     6  the pattern: cells under the curve
     7  buttons and links
     8  site header, desktop and phone
     9  footer
    10  breadcrumb
    11  family list row and family card
    12  grade chip
    13  grade table and the composition bar
    14  spec figure
    15  proof strip
    16  callout, note, tag, badge
    17  tabs
    18  form controls and the enquiry form
    19  the 25 kg drum label
    20  the business card
   ============================================================ */


/* ============================================================
   0 · BASE
   ============================================================ */

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

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--ground);
  color: var(--fg);
  font-family: var(--text);
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  overflow-x: hidden;
}

img, svg { display: block; max-width: 100%; }
img { height: auto; }
table { border-collapse: collapse; }
a { color: inherit; }
::selection { background: var(--graphite); color: var(--stone); }

h1, h2, h3, h4, h5, h6 { font-family: var(--display); }

/* One focus treatment for the whole system: the orange ring. On a
   graphite ground it swaps to the lift, because the orange itself
   is only 4.72:1 there and a focus ring has to be unmissable. */
:where(a, button, summary, input, select, textarea, [tabindex]):focus-visible,
.is-focus {
  outline: var(--focus-w) solid var(--focus);
  outline-offset: var(--focus-offset);
}
:where(.on-graphite, .hdr, .ftr, .proof) :where(a, button, summary, input, select, textarea, [tabindex]):focus-visible,
:where(.on-graphite, .hdr, .ftr, .proof) .is-focus {
  outline-color: var(--focus-on-dark);
}

.skip {
  position: fixed; top: var(--sp-2); left: var(--sp-2); z-index: var(--z-skip);
  transform: translateY(-160%);
  background: var(--graphite); color: var(--bone);
  padding: var(--sp-3) var(--sp-4);
  font: var(--w-bold) var(--fs-label) / var(--lh-flat) var(--display);
  letter-spacing: var(--tr-label); text-transform: uppercase;
  text-decoration: none; border-radius: var(--r);
}
.skip:focus { transform: none; }

/* a label read by a screen reader only */
.vh {
  position: absolute; width: 1px; height: 1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap;
}

/* every figure in this system is tabular */
.tnum { font-variant-numeric: tabular-nums; }


/* ============================================================
   1 · LAYOUT
   ============================================================ */

.wrap {
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: var(--gutter);
}
.wrap--text { max-width: calc(var(--container-text) + var(--gutter) * 2); }

/* the 12-column grid. Children opt in with --span. */
.grid {
  display: grid;
  grid-template-columns: repeat(var(--grid-cols), minmax(0, 1fr));
  gap: var(--grid-gap);
}
.grid > * { min-width: 0; grid-column: span var(--span, var(--grid-cols)); }
@media (max-width: 899px) { .grid > * { grid-column: span var(--span-m, var(--grid-cols)); } }

/* simpler column sets, for everything that is not on the 12 */
.cols { display: grid; gap: var(--sp-gap); }
.cols > * { min-width: 0; }
@media (min-width: 760px) { .cols--2 { grid-template-columns: 1fr 1fr; } }
@media (min-width: 900px) {
  .cols--3 { grid-template-columns: repeat(3, 1fr); }
  .cols--a { grid-template-columns: 1.15fr 1fr; }
}

.stack { display: grid; gap: var(--sp-4); align-content: start; }
.stack > * { min-width: 0; }
.stack--s { gap: var(--sp-2); }
.stack--l { gap: var(--sp-7); }

/* a numbered spec-sheet section — the Laboratory layer */
.sec { padding-top: var(--sp-sec); position: relative; }
.sec__head {
  display: flex; align-items: baseline; gap: var(--sp-4);
  margin-bottom: var(--sp-head);
  border-top: var(--bw-hairline) solid var(--border-quiet);
  padding-top: var(--sp-4);
}
.sec:first-child .sec__head { border-top: 0; padding-top: 0; }
.sec__n {
  flex: none;
  font: var(--w-regular) var(--fs-mono-s) / var(--lh-flat) var(--mono);
  letter-spacing: var(--tr-label);
  color: var(--pr-text);
  border-bottom: var(--bw-rule) solid var(--pr-rule);
  padding-bottom: 3px;
}
.sec__t {
  margin: 0;
  font-weight: var(--w-bold); text-transform: uppercase;
  letter-spacing: var(--tr-head);
  font-size: var(--fs-h-l); line-height: var(--lh-head);
}
.sec__note {
  margin: calc(var(--sp-2) * -0.75) 0 var(--sp-head);
  max-width: var(--measure); color: var(--muted); font-size: var(--fs-body-s);
}
@media (max-width: 599px) { .sec__head { flex-wrap: wrap; gap: var(--sp-1) var(--sp-3); } }

.lede { max-width: var(--measure-lede); font-size: var(--fs-lede); }
.muted { color: var(--muted); }

.panel {
  background: var(--surface);
  border: var(--bw-hairline) solid var(--border-quiet);
  border-radius: var(--r);
  padding: var(--sp-panel);
}
.panel > :last-child { margin-bottom: 0; }
.panel h3, .panel h4 {
  margin: 0 0 var(--sp-3);
  font-size: var(--fs-h-s); font-weight: var(--w-bold);
  text-transform: uppercase; letter-spacing: var(--tr-head-2);
}
.panel--flush { padding-bottom: var(--sp-3); }

/* a graphite field: the one dark surface in the system */
.on-graphite {
  background: var(--band-bg); color: var(--band-fg);
  border-radius: var(--r);
}
.on-graphite .muted { color: var(--band-muted); }


/* ============================================================
   2 · THE MEASUREMENT GRID
   16 px, behind charts, tables and label property blocks ONLY.
   Never behind the page, never behind running text.

   v1.2 — the grid lives in a GUTTER at the ends of the panel.
   .datagrid gives its panel --grid-gutter of inline padding — 4
   cells from 1500px, 3 from 620px, 2 on a phone — and the grid is
   drawn behind it on a pseudo-element at --grid-alpha, near its
   v1.0 strength. --grid-mask-x holds that solid across every cell
   of the gutter but the last, ramps the last cell to zero, and
   keeps it at zero across the whole middle, so the grid stops
   exactly where the content starts. The mask is on the
   pseudo-element, never on the content, so nothing fades the text
   itself and its contrast is measured against plain chalk.

   Three background layers, so both ends read as whole cells: the
   horizontal rules run the full width in one continuous 16 px
   rhythm from the top, and the vertical rules are drawn twice,
   once anchored to the left edge and once to the right, each
   confined to its own gutter. Neither end can finish on a sliver,
   and the two vertical sets never meet, because the middle they
   would overlap in is the part the mask clears.
   ============================================================ */

.datagrid { position: relative; padding-inline: var(--grid-gutter); }
.datagrid::before {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  opacity: var(--grid-alpha);
  background-image:
    /* the horizontal rules, full width, anchored to the top */
    repeating-linear-gradient(to bottom,
      var(--grid-ink) 0 var(--bw-hairline), transparent var(--bw-hairline) var(--grid-step)),
    /* the vertical rules of the left gutter, anchored left */
    repeating-linear-gradient(to right,
      var(--grid-ink) 0 var(--bw-hairline), transparent var(--bw-hairline) var(--grid-step)),
    /* the vertical rules of the right gutter, anchored right */
    repeating-linear-gradient(to left,
      var(--grid-ink) 0 var(--bw-hairline), transparent var(--bw-hairline) var(--grid-step));
  background-size: 100% 100%, var(--grid-gutter) 100%, var(--grid-gutter) 100%;
  background-position: left top, left top, right top;
  background-repeat: no-repeat;
  -webkit-mask-image: var(--grid-mask-x);
          mask-image: var(--grid-mask-x);
  -webkit-mask-size: 100% 100%;
          mask-size: 100% 100%;
  -webkit-mask-repeat: no-repeat;
          mask-repeat: no-repeat;
}
.datagrid > * { position: relative; z-index: var(--z-grid); }

/* The four-edge alternative, opt-in. The same two end gutters
   plus a band of --grid-gutter-y (2 cells) along the top and the
   bottom, so the grid frames the panel on all four sides and the
   middle stays clear. The two masks are UNIONED — the default
   mask-composite, not the v1.1 intersect — because a frame needs
   the whole band, not only the corners; the block padding keeps
   the content out of it. Two more vertical layers fill the bands
   between the gutters, sized to the span between them so they
   cannot double up against the right gutter's own rules.
   Offered for tall panels such as the stacked phone records and
   the drum label, where two side bands alone leave a long
   unanchored column. */
.datagrid--frame { padding-block: var(--grid-gutter-y); }
.datagrid--frame::before {
  background-image:
    repeating-linear-gradient(to bottom,
      var(--grid-ink) 0 var(--bw-hairline), transparent var(--bw-hairline) var(--grid-step)),
    repeating-linear-gradient(to right,
      var(--grid-ink) 0 var(--bw-hairline), transparent var(--bw-hairline) var(--grid-step)),
    repeating-linear-gradient(to left,
      var(--grid-ink) 0 var(--bw-hairline), transparent var(--bw-hairline) var(--grid-step)),
    repeating-linear-gradient(to right,
      var(--grid-ink) 0 var(--bw-hairline), transparent var(--bw-hairline) var(--grid-step)),
    repeating-linear-gradient(to right,
      var(--grid-ink) 0 var(--bw-hairline), transparent var(--bw-hairline) var(--grid-step));
  background-size:
    100% 100%,
    var(--grid-gutter) 100%,
    var(--grid-gutter) 100%,
    calc(100% - var(--grid-gutter) * 2) var(--grid-gutter-y),
    calc(100% - var(--grid-gutter) * 2) var(--grid-gutter-y);
  background-position: left top, left top, right top, center top, center bottom;
  -webkit-mask-image: var(--grid-mask-x), var(--grid-mask-y);
          mask-image: var(--grid-mask-x), var(--grid-mask-y);
  -webkit-mask-size: 100% 100%, 100% 100%;
          mask-size: 100% 100%, 100% 100%;
  -webkit-mask-repeat: no-repeat, no-repeat;
          mask-repeat: no-repeat, no-repeat;
}

/* A chart is allowed a little more grid than a table: the plot is
   the one place the grid is doing measurement rather than
   decoration, so it runs at full strength. The gutter and the
   mask are the panel's, so the extra strength lands in the end
   bands only — the axis, the value labels and the caption all sit
   on the cleared middle. */
.fig__plot.datagrid { padding-inline: var(--grid-gutter); }
.fig__plot.datagrid::before { opacity: var(--grid-alpha-plot); }

/* The pre-v1.1 rendering: full strength, unmasked, no gutter, a
   field behind everything — one continuous grid tiled from the
   top left exactly as version 1.0 drew it. Kept for the "before"
   comparison in section 1.6 of design-system.html and used
   nowhere else. */
.datagrid--full { padding-inline: var(--sp-panel); }
.datagrid--full::before {
  opacity: 1;
  background-image:
    repeating-linear-gradient(to bottom,
      var(--grid-ink) 0 var(--bw-hairline), transparent var(--bw-hairline) var(--grid-step)),
    repeating-linear-gradient(to right,
      var(--grid-ink) 0 var(--bw-hairline), transparent var(--bw-hairline) var(--grid-step));
  background-size: 100% 100%, 100% 100%;
  background-position: left top, left top;
  -webkit-mask-image: none;
          mask-image: none;
}


/* ============================================================
   3 · LOGO LOCKUPS
   One SVG, recoloured through a CSS mask. The wordmark is never
   redrawn, never retyped and never recoloured by editing the file.
   ============================================================ */

.wm {
  display: block;
  width: var(--wm, 200px);
  aspect-ratio: 998 / 328;              /* the artwork's own ratio */
  background-color: var(--wm-ink, var(--pr-ink));
  -webkit-mask: url(media/logo/sanwa-wordmark.svg) no-repeat center / contain;
          mask: url(media/logo/sanwa-wordmark.svg) no-repeat center / contain;
}
.mono-s {
  display: block;
  width: var(--ms, 40px);
  aspect-ratio: 150 / 268;
  background-color: currentColor;
  -webkit-mask: url(media/logo/sanwa-s.svg) no-repeat center / contain;
          mask: url(media/logo/sanwa-s.svg) no-repeat center / contain;
}

/* the lockup: wordmark, a rule, then "Metal Powders" in Chivo,
   justified to the wordmark's exact width. Every measurement is a
   ratio of --wm, so the lockup scales as one object.

   Three colours, three roles (client decision, 9 Oct 2026):
   the mark is the orange, "Metal Powders" is the cool steel
   --lockup-steel, and the rule between them stays graphite. The
   words and the rule are no longer the same value, so .mp sets
   both its own colour and its own border-top-color rather than
   inheriting either through currentColor. */
.lock {
  display: inline-block;
  width: var(--wm, 200px);
  flex: none; align-self: flex-start;
  color: var(--fg);
}
/* The lockup is a link in the header, the phone bar and the specimen. The
   browser's default underline lands under "METAL POWDERS" and reads as a
   second rule below the designed one, so it is off in every state. The
   rule between the wordmark and "Metal Powders" is drawn by .lock .mp and
   is unaffected; the focus ring comes from the global :focus-visible. */
.lock, .lock:hover, .lock:focus, .lock:focus-visible, .lock:active, .lock:visited {
  text-decoration: none;
}
.lock .wm { width: 100%; }
.lock .mp {
  display: block;
  color: var(--lockup-steel);
  margin-top: calc(var(--wm, 200px) / 26);
  padding-top: calc(var(--wm, 200px) / 30);
  border-top: max(var(--bw-hairline), calc(var(--wm, 200px) / 140)) solid var(--lockup-rule);
  font: var(--w-bold) calc(var(--wm, 200px) / 11.2) / var(--lh-flat) var(--display);
  letter-spacing: var(--tr-lockup);
  text-transform: uppercase;
  text-align: justify; text-align-last: justify;
}

/* the home-page variant: the five-part family rule replaces the
   single rule, so the lockup states the range at a glance */
.lock--fam .mp { border-top: 0; padding-top: calc(var(--wm, 200px) / 22); }
.lock__fam {
  display: flex;
  height: max(3px, calc(var(--wm, 200px) / 44));
  margin-top: calc(var(--wm, 200px) / 26);
}
.lock__fam i { flex: 1; font-style: normal; }

/* reversed on graphite: the wordmark takes the lift at 8.84:1 and
   the words the light steel at 13.80:1, with the rule left bone */
.lock--rev { color: var(--bone); --wm-ink: var(--pr-lift); }
.lock--rev .mp {
  color: var(--lockup-steel-rev);
  border-top-color: var(--lockup-rule-rev);
}

/* the favicon: the "S" in graphite on the orange at 4.72:1. Bone
   on the orange is only 3.30:1, and a 16 px tab strip needs the
   dark monogram. */
.fav {
  width: 32px; height: 32px; flex: none;
  display: grid; place-items: center;
  background: var(--fav-bg); color: var(--fav-fg);
  border-radius: 2px;
}
.fav--16 { width: 16px; height: 16px; border-radius: 1px; }

/* clear space: one "S" width on all four sides */
.clearspace { position: relative; display: inline-flex; }
.clearspace__pad { position: relative; padding: var(--cs, 26px); }
.clearspace__pad::before {
  content: ""; position: absolute; inset: 0;
  border: var(--bw-hairline) dashed var(--border);
}


/* ============================================================
   4 · ELEMENT TILES
   The eight elements that actually appear in the grade tables.
   They label families, head sections and sit on the drum labels.
   ============================================================ */

.etiles { display: flex; flex-wrap: wrap; gap: var(--sp-2); }
.etile {
  display: grid; gap: 2px;
  min-width: 78px; padding: var(--sp-3) 11px 9px;
  background: var(--surface); color: var(--fg);
  border: var(--bw-hairline) solid var(--border);
  border-radius: var(--r);
}
.etile b { font: var(--w-bold) 27px / var(--lh-flat) var(--display); letter-spacing: -0.01em; }
.etile .z { font: var(--w-regular) var(--fs-mono-xs) / var(--lh-flat) var(--mono); color: var(--muted); }
.etile .nm { font: var(--w-regular) var(--fs-mono-s) / var(--lh-tight) var(--mono); color: var(--muted); }
.etile--sm { min-width: 58px; padding: 7px var(--sp-2) 6px; }
.etile--sm b { font-size: 18px; }
/* on graphite or on the orange card back */
.on-graphite .etile, .bc--back .etile {
  background: transparent; border-color: var(--card-line); color: var(--card-fg);
}
.on-graphite .etile { border-color: var(--band-line-2); color: var(--band-fg); }
.on-graphite .etile .z { color: var(--band-muted); }
.bc--back .etile .z { color: var(--card-dim); }


/* ============================================================
   5 · FAMILY MARKERS AND THE FAMILY RULE
   One class binds a family's two values. Markers are small by
   rule: a row edge, a chip edge, a swatch photo, the family name
   in its own row, the family rule, a drum band. Never a field.
   ============================================================ */

.f-bronze   { --c: var(--bronze);     --cfill: var(--bronze-fill); }
.f-prealloy { --c: var(--prealloy);   --cfill: var(--prealloy-fill); }
.f-pure     { --c: var(--puremetals); --cfill: var(--puremetals-fill); }
.f-cocr     { --c: var(--cocr);       --cfill: var(--cocr-fill); }
.f-steel    { --c: var(--steel);      --cfill: var(--steel-fill); }

/* the five-part rule, in range order */
.famrule { display: flex; height: 10px; margin: 0; }
.famrule i { flex: 1; font-style: normal; }
.famrule--wide { height: 14px; }
.famrule--thin { height: 6px; }
.famrule i:nth-child(1), .lock__fam i:nth-child(1) { background: var(--bronze); }
.famrule i:nth-child(2), .lock__fam i:nth-child(2) { background: var(--prealloy); }
.famrule i:nth-child(3), .lock__fam i:nth-child(3) { background: var(--puremetals); }
.famrule i:nth-child(4), .lock__fam i:nth-child(4) { background: var(--cocr); }
.famrule i:nth-child(5), .lock__fam i:nth-child(5) { background: var(--steel); }

/* a marker specimen: the colour as an edge, with its values */
.mark {
  display: flex; align-items: center; gap: var(--sp-3);
  background: var(--surface);
  border: var(--bw-hairline) solid var(--border-quiet);
  border-radius: var(--r);
  padding: var(--sp-2) 11px var(--sp-2) 0;
}
.mark i {
  width: 7px; align-self: stretch; flex: none;
  background: var(--c); font-style: normal;
  border-radius: var(--r) 0 0 var(--r);
}
.mark span { font: var(--w-regular) var(--fs-mono-xs) / 1.45 var(--mono); color: var(--muted); }
.mark b { display: block; font: var(--w-regular) var(--fs-mono-s) / var(--lh-tight) var(--mono); color: var(--c); }
.marks { display: grid; gap: var(--sp-2); grid-template-columns: repeat(auto-fit, minmax(126px, 1fr)); }


/* ============================================================
   6 · THE PATTERN: CELLS UNDER THE CURVE
   The cumulative undersize curve is the edge of a shape, and the
   region between it and the baseline is filled with grain cells —
   the same Voronoi net, clipped to that region. Above the curve
   is empty. The measurement is made of the material.

   Rules the CSS enforces: the pattern is always BOUNDED (a band,
   a strip, a panel), never an all-over tint, and never behind
   running text. Hairlines keep one weight at every scale through
   vector-effect: non-scaling-stroke.
   ============================================================ */

.pf-frame, .pf-tick, .pf-freq, .pf-cum, .pf-net, .pf-twin, .pf-cell, .pf-cellt {
  vector-effect: non-scaling-stroke;
}
.pf-frame { fill: none; stroke: var(--pat-ink); stroke-width: 1;   opacity: var(--op-frame); }
.pf-tick  { fill: none; stroke: var(--pat-ink); stroke-width: 1;   opacity: var(--op-tick); }
.pf-freq  { fill: none; stroke: var(--pat-ink); stroke-width: 1;   opacity: var(--op-freq); }
.pf-cum   { fill: none; stroke: var(--pat-ink); stroke-width: 1.3; opacity: var(--op-cum); }
.pf-net   { fill: none; stroke: var(--pat-ink); stroke-width: 1.1; opacity: var(--op-net); stroke-linejoin: round; }
.pf-twin  { fill: none; stroke: var(--pat-ink); stroke-width: 1.1; opacity: var(--op-twin); }
.pf-pore  { fill: var(--pat-ink); opacity: var(--op-pore); }

/* the three bounded containers the pattern is allowed in */
.pat-band {              /* a band across a hero or a section    */
  position: relative; overflow: hidden;
  border-top: var(--bw-hairline) solid var(--border-quiet);
}
.pat-strip {             /* a strip at the foot of a drum label  */
  position: relative; overflow: hidden;
  border-top: var(--bw-hairline) solid var(--border-quiet);
}
.pat-panel {             /* a bounded panel, e.g. a tile specimen */
  position: relative; overflow: hidden;
  background: var(--surface);
  border: var(--bw-hairline) solid var(--border-quiet);
  border-radius: var(--r);
}
.pat-band > svg, .pat-strip > svg, .pat-panel > svg {
  position: absolute; inset: 0; width: 100%; height: 100%;
  opacity: var(--field-op);
}
/* a band that carries type beside it fades out under the text side */
.pat-band--fade {
  -webkit-mask-image: linear-gradient(to right, #000 0, #000 58%, rgba(0,0,0,0.12) 100%);
          mask-image: linear-gradient(to right, #000 0, #000 58%, rgba(0,0,0,0.12) 100%);
}
/* the 16 px texture rule: the pattern reduced to one hairline row */
.pat-rule { position: relative; height: var(--grid-step); overflow: hidden; }
.pat-rule > svg { position: absolute; inset: 0; width: 100%; height: 100%; opacity: var(--field-op); }
/* a caption is mandatory wherever the curves could be read as data */
.pat-cap {
  font: var(--w-regular) var(--fs-mono-xs) / 1.4 var(--mono);
  letter-spacing: var(--tr-mono-2); text-transform: uppercase;
  color: var(--muted); margin: var(--sp-2) 0 0;
}


/* ============================================================
   7 · BUTTONS AND LINKS

   One action, one primary button. The orange fill is the only
   solid button in the system and it carries a graphite label at
   4.72:1. On hover the FILL LIGHTENS to #fd7000 and the ratio
   rises to 6.57:1 — contrast never drops on a state change.
   ============================================================ */

.btn {
  display: inline-flex; align-items: center; justify-content: center;
  gap: var(--sp-3);
  min-height: var(--control-h); padding-inline: 22px;
  background: var(--btn-bg); color: var(--btn-fg);
  border: var(--bw-hairline) solid var(--btn-bg);
  border-radius: var(--r);
  font: var(--w-bold) var(--fs-label) / var(--lh-flat) var(--display);
  letter-spacing: var(--tr-label); text-transform: uppercase;
  text-decoration: none; cursor: pointer;
  transition: background-color var(--dur-1) var(--ease),
              border-color var(--dur-1) var(--ease),
              color var(--dur-1) var(--ease);
}
.btn:hover, .btn.is-hover { background: var(--btn-bg-hover); border-color: var(--btn-bg-hover); color: var(--btn-fg-hover); }
.btn:active, .btn.is-active { background: var(--pr-ink); border-color: var(--graphite); }

/* ghost: the default for every secondary action. Graphite label on
   stone at 16.16:1, going to paper at 14.50:1 on hover — the
   ground darkens, the label does not move. */
.btn--ghost { background: transparent; color: var(--ghost-fg); border-color: var(--ghost-border); }
.btn--ghost:hover, .btn--ghost.is-hover { background: var(--ghost-hover); border-color: var(--fg); color: var(--ghost-fg); }
.btn--ghost:active, .btn--ghost.is-active { background: var(--ghost-hover); border-color: var(--fg); box-shadow: inset 0 0 0 var(--bw-hairline) var(--fg); }

/* text button: the lightest weight of action, same label grammar */
.btn--text {
  background: transparent; border-color: transparent; color: var(--fg);
  padding-inline: var(--sp-2); min-height: var(--target-touch);
}
.btn--text:hover, .btn--text.is-hover { background: var(--ghost-hover); border-color: transparent; color: var(--fg); }

/* icon button: square, 44 px, the icon inherits currentColor */
.btn--icon {
  width: var(--target-touch); height: var(--target-touch);
  min-height: 0; padding: 0; gap: 0;
  background: transparent; color: var(--fg); border-color: var(--ghost-border);
}
.btn--icon:hover, .btn--icon.is-hover { background: var(--ghost-hover); border-color: var(--fg); color: var(--fg); }
.btn--icon svg { width: 18px; height: 18px; }

.btn--s { min-height: var(--control-h-s); padding-inline: var(--sp-4); font-size: var(--fs-label-s); }
.btn--l { min-height: var(--control-h-l); padding-inline: var(--sp-8); }
.btn--block { width: 100%; }

/* disabled is the only state allowed to lose contrast */
.btn:disabled, .btn[aria-disabled="true"] {
  background: var(--paper); color: var(--rule); border-color: var(--border-quiet);
  cursor: not-allowed;
}
.btn:disabled:hover, .btn[aria-disabled="true"]:hover {
  background: var(--paper); color: var(--rule); border-color: var(--border-quiet);
}

/* on a graphite band the solid button inverts to bone, because an
   orange fill on graphite is only 4.72:1 as a field and the bar
   already carries the orange in the wordmark */
.on-graphite .btn, .hdr .btn { background: var(--band-btn-bg); color: var(--band-btn-fg); border-color: var(--band-btn-bg); }
.on-graphite .btn:hover, .hdr .btn:hover,
.on-graphite .btn.is-hover, .hdr .btn.is-hover { background: var(--stone); border-color: var(--stone); color: var(--graphite); }
.on-graphite .btn--ghost, .hdr .btn--ghost { background: transparent; color: var(--band-fg); border-color: var(--band-line-2); }
.on-graphite .btn--ghost:hover, .hdr .btn--ghost:hover,
.on-graphite .btn--ghost.is-hover, .hdr .btn--ghost.is-hover { background: var(--band-hover); border-color: var(--band-fg); color: var(--band-fg); }

.btnrow { display: flex; flex-wrap: wrap; gap: var(--sp-3); align-items: center; }

/* --- links ---------------------------------------------------
   A link is graphite with an orange underline. On hover the
   underline thickens from 1.5 px to 3 px and the graphite does
   not move: there is no orange text value to move it to. ------- */

.link {
  color: var(--pr-text);
  text-decoration: underline;
  text-decoration-color: var(--pr-rule);
  text-decoration-thickness: var(--bw-underline);
  text-underline-offset: 3px;
  transition: text-decoration-thickness var(--dur-1) var(--ease);
}
.link:hover, .link.is-hover { color: var(--pr-text-hover); text-decoration-thickness: 3px; }
.link:active, .link.is-active { text-decoration-color: var(--graphite); text-decoration-thickness: 3px; }

/* a link inside running text, where an underline is already implied */
.link--quiet { text-decoration-color: var(--border); }
.link--quiet:hover, .link--quiet.is-hover { text-decoration-color: var(--pr-rule); text-decoration-thickness: 3px; }

.on-graphite .link { color: var(--band-fg); text-decoration-color: var(--pr-lift); }
.on-graphite .link:hover { color: var(--band-fg); text-decoration-thickness: 3px; }


/* ============================================================
   8 · SITE HEADER

   Two tiers, because the five families are the spine of the range
   and deserve their own row with their markers — "know it by
   colour" is the brand line, so the colours are in the chrome.
   Tier 1 carries the lockup, the site-wide links and the one CTA.
   Tier 2 carries the families, each under its own marker.
   ============================================================ */

.hdr {
  position: relative; z-index: var(--z-header);
  background: var(--band-bg); color: var(--band-fg);
  --wm-ink: var(--pr-lift);
  /* the header answers to its own width, not the viewport's, so it is correct
     inside a narrow frame or column as well as across a page */
  container-type: inline-size;
}
/* The block padding is asymmetric on purpose: the lockup's last line is
   "METAL POWDERS" in caps, so its optical bottom sits on the baseline and
   the measured gap below reads smaller than the same gap above. 16/20
   puts equal air on both sides of the mark. */
.hdr__top {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--sp-6);
  min-height: 88px; padding-block: var(--sp-4) var(--sp-5);
  padding-inline: var(--gutter);
  border-bottom: var(--bw-hairline) solid var(--band-line);
}
.hdr__in { max-width: var(--container); margin-inline: auto; width: 100%; }
.hdr__nav { display: flex; align-items: center; gap: var(--sp-7); }
.hdr__nav a {
  font: var(--w-bold) 12px / var(--lh-flat) var(--display);
  letter-spacing: var(--tr-label); text-transform: uppercase;
  color: var(--band-fg); text-decoration: none;
  display: inline-flex; align-items: center;
  min-height: var(--target-touch);
  border-bottom: var(--bw-rule) solid transparent;
  transition: border-color var(--dur-1) var(--ease), color var(--dur-1) var(--ease);
}
.hdr__nav a:hover, .hdr__nav a.is-hover { border-bottom-color: var(--pr-lift); color: var(--band-fg); }
.hdr__nav a[aria-current] { border-bottom-color: var(--pr-lift); }

/* tier 2: the families */
.hdr__fams { background: var(--band-hover); border-bottom: var(--bw-hairline) solid var(--band-line); }
.hdr__famlist {
  display: flex; gap: 0; margin: 0; padding-inline: var(--gutter); list-style: none;
  max-width: var(--container); margin-inline: auto;
  overflow-x: auto; scrollbar-width: none;
}
.hdr__famlist::-webkit-scrollbar { display: none; }
.hdr__famlist a {
  display: grid; gap: var(--sp-2); justify-items: start;
  padding: var(--sp-3) var(--sp-5) var(--sp-3) 0;
  margin-right: var(--sp-5);
  color: var(--band-fg); text-decoration: none; white-space: nowrap;
  font: var(--w-bold) var(--fs-label-s) / var(--lh-flat) var(--display);
  letter-spacing: var(--tr-head-2); text-transform: uppercase;
  min-height: var(--target-touch); align-content: center;
}
/* The marker is the signal, and it is the thing that moves on hover: a 26 px
   tick that runs out to the full width of the label.

   The box stays full width at every moment and the growth is painted, not laid
   out — the fill is a background whose SIZE is what animates. Animating the
   element's own width instead would invalidate layout on every frame for a
   purely cosmetic change. The 26 px resting tick is a fixed length on purpose:
   it reads the same under all five labels, which are different widths. */
.hdr__famlist a::before {
  content: ""; display: block;
  width: 100%; height: var(--bw-marker);
  background: linear-gradient(var(--cfill), var(--cfill)) no-repeat left center / 26px 100%;
  transition: background-size var(--dur-1) var(--ease);
}
.hdr__famlist a:hover::before, .hdr__famlist a.is-hover::before { background-size: 100% 100%; }
.hdr__famlist a[aria-current]::before { background-size: 100% 100%; }
.hdr__famlist a[aria-current] { color: var(--band-fg); }

/* --- the phone header and its drawer -------------------------- */
/* the phone bar takes the same 12/16 balance around its smaller lockup;
   the drawer head below repeats it exactly, so opening the drawer does not
   move the mark */
.hdr__bar {
  display: none;
  align-items: center; justify-content: space-between;
  gap: var(--sp-4);
  min-height: 64px;
  padding-block: var(--sp-3) var(--sp-4);
  padding-inline: var(--sp-4);
  border-bottom: var(--bw-hairline) solid var(--band-line);
}
.hdr__burger {
  width: var(--target-touch); height: var(--target-touch);
  display: grid; align-content: center; gap: 5px; justify-items: stretch;
  padding: 0 10px;
  background: transparent; border: 0; cursor: pointer; color: var(--band-fg);
}
.hdr__burger i { height: 2px; background: currentColor; border-radius: 1px; font-style: normal; }

.drawer {
  position: fixed; inset: 0; z-index: var(--z-drawer);
  display: none;
  background: var(--band-bg); color: var(--band-fg);
  overflow-y: auto;
  padding: 0 var(--sp-4) var(--sp-12);
}
.drawer[open], .drawer.is-open { display: block; }
/* the head owns the block padding so it matches .hdr__bar line for line */
.drawer__head {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--sp-4); min-height: 64px;
  padding-block: var(--sp-3) var(--sp-4);
}
.drawer__close {
  width: var(--target-touch); height: var(--target-touch);
  display: grid; place-items: center;
  background: transparent; border: var(--bw-hairline) solid var(--band-line-2);
  border-radius: var(--r); color: var(--band-fg); cursor: pointer;
}
.drawer__close svg { width: 16px; height: 16px; }
.drawer__list { margin: var(--sp-6) 0 0; padding: 0; list-style: none; }
.drawer__list li { border-top: var(--bw-hairline) solid var(--band-line); }
.drawer__list a {
  display: flex; align-items: center; gap: var(--sp-3);
  min-height: var(--target-touch); padding: var(--sp-3) 0;
  color: var(--band-fg); text-decoration: none;
  font: var(--w-bold) 14px / var(--lh-flat) var(--display);
  letter-spacing: var(--tr-head-2); text-transform: uppercase;
}
.drawer__list a:hover { color: var(--pr-lift); }
.drawer__list i { width: var(--sp-2); height: 22px; flex: none; background: var(--cfill); font-style: normal; }
.drawer__cta { margin-top: var(--sp-6); }

@container (max-width: 1199px) {
  .hdr__top, .hdr__fams { display: none; }
  .hdr__bar { display: flex; }
}


/* ============================================================
   9 · FOOTER
   ============================================================ */

.ftr {
  background: var(--band-bg); color: var(--band-fg);
  --wm-ink: var(--pr-lift);
  padding-block: var(--sp-sec) var(--sp-10);
}
.ftr__in { max-width: var(--container); margin-inline: auto; padding-inline: var(--gutter); }
.ftr__grid { display: grid; gap: var(--sp-8); }
@media (min-width: 760px)  { .ftr__grid { grid-template-columns: 1fr 1fr; } }
@media (min-width: 1200px) { .ftr__grid { grid-template-columns: 1.2fr 1fr 1fr 1fr; } }
.ftr h2 {
  margin: 0 0 var(--sp-4);
  font-size: var(--fs-h-s); font-weight: var(--w-bold);
  text-transform: uppercase; letter-spacing: var(--tr-label);
  color: var(--band-muted);
}
.ftr__list { margin: 0; padding: 0; list-style: none; }
.ftr__list li { margin-bottom: var(--sp-2); }
.ftr__list a {
  color: var(--band-fg); text-decoration: none;
  display: inline-flex; align-items: center; min-height: var(--target-min);
  border-bottom: var(--bw-hairline) solid transparent;
}
.ftr__list a:hover, .ftr__list a.is-hover { border-bottom-color: var(--pr-lift); }
.ftr__c { margin: 0; font: var(--w-regular) var(--fs-mono) / 1.75 var(--mono); color: var(--band-fg); }
.ftr__c a { color: inherit; text-decoration: underline; text-decoration-color: var(--pr-lift); text-underline-offset: 3px; }
.ftr__c a:hover { text-decoration-thickness: 3px; }
.ftr__legal {
  margin-top: var(--sp-10); padding-top: var(--sp-5);
  border-top: var(--bw-hairline) solid var(--band-line);
  display: flex; flex-wrap: wrap; gap: var(--sp-2) var(--sp-7);
  font: var(--w-regular) var(--fs-mono-s) / var(--lh-mono) var(--mono);
  color: var(--band-muted);
}
.ftr__legal b { color: var(--band-fg); font-weight: var(--w-regular); }


/* ============================================================
   10 · BREADCRUMB
   ============================================================ */

.crumb { margin: 0; padding: var(--sp-4) 0; }
.crumb ol {
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-2) var(--sp-3);
  margin: 0; padding: 0; list-style: none;
  font: var(--w-regular) var(--fs-mono-s) / var(--lh-mono) var(--mono);
  letter-spacing: var(--tr-mono-2); text-transform: uppercase;
}
.crumb li { display: flex; align-items: center; gap: var(--sp-3); color: var(--muted); }
.crumb li + li::before { content: "/"; color: var(--border); }
.crumb a {
  color: var(--pr-text); text-decoration: underline;
  text-decoration-color: var(--pr-rule);
  text-decoration-thickness: var(--bw-underline); text-underline-offset: 3px;
  display: inline-flex; align-items: center; min-height: var(--target-min);
}
.crumb a:hover, .crumb a.is-hover { text-decoration-thickness: 3px; }
.crumb [aria-current] { color: var(--fg); }


/* ============================================================
   11 · FAMILY LIST ROW AND FAMILY CARD
   ============================================================ */

/* the row: a marker edge, the swatch photograph, the name in the
   family's own colour, and the count. Used on the home page and
   as the family index. */
.famrow {
  display: grid; grid-template-columns: var(--sp-2) 64px minmax(0, 1fr) auto;
  gap: 0 var(--sp-4); align-items: center;
  min-height: 72px;
  background: var(--surface);
  border: var(--bw-hairline) solid var(--border-quiet);
  border-radius: var(--r);
  overflow: hidden;
  color: var(--fg); text-decoration: none;
  transition: background-color var(--dur-1) var(--ease), border-color var(--dur-1) var(--ease);
}
.famrow > i { align-self: stretch; background: var(--c); font-style: normal; }
.famrow img { width: 64px; height: 64px; border-radius: 50%; object-fit: cover; }
.famrow b {
  font: var(--w-bold) 13px / var(--lh-head) var(--display);
  letter-spacing: var(--tr-head-2); text-transform: uppercase;
  color: var(--c); padding-block: var(--sp-3);
}
.famrow span {
  font: var(--w-regular) var(--fs-mono-s) / var(--lh-tight) var(--mono);
  color: var(--muted); padding-right: var(--sp-4); text-align: right;
}
a.famrow:hover, a.famrow.is-hover { background: var(--pr-wash); border-color: var(--border); }
a.famrow:active, a.famrow.is-active { background: var(--pr-wash); border-color: var(--fg); }
@media (max-width: 479px) {
  .famrow { grid-template-columns: var(--sp-2) 48px minmax(0, 1fr); }
  .famrow img { width: 48px; height: 48px; }
  .famrow span { grid-column: 3; text-align: left; padding-bottom: var(--sp-3); }
  .famrow b { padding-bottom: 0; }
}

/* the card: the same family, given room for the benefit line */
.famcard {
  display: grid; align-content: start;
  background: var(--surface);
  border: var(--bw-hairline) solid var(--border-quiet);
  border-radius: var(--r);
  overflow: hidden;
  color: var(--fg); text-decoration: none;
  transition: border-color var(--dur-1) var(--ease);
}
.famcard__band { height: var(--sp-2); background: var(--cfill); }
.famcard__in { padding: var(--sp-5) var(--sp-5) var(--sp-5); display: grid; gap: var(--sp-3); }
.famcard img {
  width: 72px; height: 72px; border-radius: 50%; object-fit: cover;
  border: var(--bw-hairline) solid var(--border-quiet);
}
.famcard h3 {
  margin: 0;
  font: var(--w-bold) 15px / var(--lh-head) var(--display);
  letter-spacing: var(--tr-head-2); text-transform: uppercase;
  color: var(--c);
}
.famcard p { margin: 0; font-size: var(--fs-s); color: var(--muted); }
.famcard__meta {
  margin: 0; padding-top: var(--sp-3);
  border-top: var(--bw-hairline) solid var(--border-quiet);
  font: var(--w-regular) var(--fs-mono-s) / var(--lh-mono) var(--mono);
  color: var(--muted);
}
a.famcard:hover, a.famcard.is-hover { border-color: var(--border); }
a.famcard:hover h3, a.famcard.is-hover h3 { text-decoration: underline; text-decoration-color: var(--pr-rule); text-decoration-thickness: var(--bw-rule); text-underline-offset: 3px; }


/* ============================================================
   12 · GRADE CHIP
   A grade code, with its family on the left edge.
   ============================================================ */

.chip {
  display: inline-flex; align-items: center; gap: var(--sp-2);
  min-height: var(--target-min); padding: var(--sp-1) var(--sp-3) var(--sp-1) 0;
  background: var(--surface);
  border: var(--bw-hairline) solid var(--border-quiet);
  border-left: var(--bw-marker) solid var(--c);
  border-radius: 0 var(--r) var(--r) 0;
  font: var(--w-regular) var(--fs-mono) / var(--lh-flat) var(--mono);
  font-variant-numeric: tabular-nums;
  color: var(--fg); text-decoration: none;
  transition: background-color var(--dur-1) var(--ease), border-color var(--dur-1) var(--ease);
}
.chip > span:first-of-type { padding-left: var(--sp-3); }
.chip em {
  font-style: normal; color: var(--muted); font-size: var(--fs-mono-xs);
  letter-spacing: var(--tr-mono-2); text-transform: uppercase;
}
a.chip:hover, button.chip:hover, .chip.is-hover { background: var(--pr-wash); border-color: var(--border); border-left-color: var(--c); }
a.chip:active, button.chip:active, .chip.is-active { background: var(--pr-wash); border-color: var(--fg); border-left-color: var(--c); }
.chip[aria-pressed="true"], .chip--on { background: var(--pr-wash); border-color: var(--fg); border-left-color: var(--c); }
.chip:disabled, .chip[aria-disabled="true"] { background: var(--paper); color: var(--rule); border-color: var(--border-quiet); border-left-color: var(--border); cursor: not-allowed; }
.chiprow { display: flex; flex-wrap: wrap; gap: var(--sp-2); }


/* ============================================================
   13 · GRADE TABLE
   Scrolls sideways on a tablet, becomes one record per grade
   under 720 px. The grade column is sticky and carries the
   family marker. All figures are DM Mono, tabular.

   Let the table talk: the caption is graphite, not orange, and
   the only colour in it is the family edge and the orange wash
   on the row under the pointer.
   ============================================================ */

.gt-wrap {
  overflow-x: auto; -webkit-overflow-scrolling: touch;
  /* records vs columns is decided by the table's own width. In record form the
     table is width:100%/min-width:0, so this never shows a scrollbar there. */
  container-type: inline-size;
}
.gt {
  width: 100%; min-width: 560px;
  font-family: var(--mono); font-size: var(--fs-mono);
  font-variant-numeric: tabular-nums;
}
.gt caption {
  text-align: left; padding-bottom: var(--sp-4);
  font: var(--w-bold) var(--fs-mono-s) / var(--lh-flat) var(--display);
  letter-spacing: var(--tr-mono); text-transform: uppercase;
  color: var(--accent-ink);
}
.gt thead th {
  background: var(--surface-2); color: var(--muted);
  font: var(--w-regular) var(--fs-mono-xs) / var(--lh-head) var(--mono);
  letter-spacing: var(--tr-label); text-transform: uppercase;
  text-align: left; padding: 11px var(--sp-4) var(--sp-3); white-space: nowrap;
}
.gt thead th:first-child { position: sticky; left: 0; z-index: var(--z-sticky); background: var(--surface-2); }
.gt td { padding: var(--sp-3) var(--sp-4); border-bottom: var(--bw-hairline) solid var(--border-quiet); white-space: nowrap; }
.gt tbody th {
  position: sticky; left: 0; z-index: var(--z-sticky);
  background: var(--surface); color: var(--fg);
  text-align: left;
  font: var(--w-bold) var(--fs-mono) / var(--lh-flat) var(--display);
  letter-spacing: 0.055em;
  padding: var(--sp-3) var(--sp-4);
  border-bottom: var(--bw-hairline) solid var(--border-quiet);
  border-left: var(--bw-marker) solid var(--c, var(--bronze));
  white-space: nowrap;
}
.gt tbody tr:hover td, .gt tbody tr:hover th,
.gt tbody tr.is-hover td, .gt tbody tr.is-hover th { background: var(--row-hover); }
.gt tbody tr[aria-selected="true"] td, .gt tbody tr[aria-selected="true"] th { background: var(--row-hover); }
.gt tfoot td {
  border-bottom: 0; color: var(--muted);
  font-size: var(--fs-mono-s); white-space: normal; padding-top: var(--sp-4);
}

@container (max-width: 719px) {
  .gt { min-width: 0; width: 100%; }
  .gt thead { display: none; }
  .gt tbody tr {
    display: grid; gap: var(--bw-hairline);
    margin-bottom: var(--sp-3); padding-block: var(--sp-1);
    background: var(--surface); border-radius: var(--r); overflow: hidden;
  }
  .gt tbody td, .gt tbody th {
    display: flex; justify-content: space-between; gap: var(--sp-4);
    border-bottom: 0; white-space: normal; text-align: left;
  }
  .gt tbody td::before {
    content: attr(data-label); color: var(--muted); flex: none;
    font-size: var(--fs-mono-s); letter-spacing: var(--tr-head);
    text-transform: uppercase;
  }
  .gt tbody th {
    position: static; background: transparent;
    border-left: var(--bw-marker-l) solid var(--c, var(--bronze)); border-bottom: 0;
    padding: 11px var(--sp-4) 9px; font-size: 15px;
  }
  .gt tbody td { padding: 7px var(--sp-4); }
  .gt tbody tr:hover td, .gt tbody tr:hover th { background: transparent; }
  .gt tfoot td { padding-left: 0; }
}

/* --- the composition bar -------------------------------------
   A grade's composition as proportion. Filled segments, a
   hairline between neighbours so two light fills stay separate,
   and the figures repeated in the key because a bar at this size
   cannot hold a label. ----------------------------------------- */

.cbar { display: grid; gap: var(--sp-2); }
.cbar__track {
  display: flex; height: 34px; overflow: hidden;
  border: var(--bw-hairline) solid var(--border-quiet); border-radius: var(--r);
}
.cbar__seg {
  display: grid; place-items: center; min-width: 0; overflow: hidden;
  font: var(--w-regular) var(--fs-mono-xs) / var(--lh-flat) var(--mono);
}
.cbar__seg + .cbar__seg { border-left: var(--bw-hairline) solid var(--border); }
.cbar__key {
  display: flex; flex-wrap: wrap; gap: var(--sp-1) var(--sp-4);
  font: var(--w-regular) var(--fs-mono-s) / var(--lh-mono) var(--mono);
  color: var(--muted);
}
.cbar__key b { color: var(--fg); font-weight: var(--w-regular); }
.cbar__key i {
  width: 10px; height: 10px; flex: none; display: inline-block;
  margin-right: 7px; border-radius: 2px; font-style: normal;
}


/* ============================================================
   14 · SPEC FIGURE
   A chart with a numbered "Fig." caption, on the 16 px grid.
   Data is always filled, never an outline.
   ============================================================ */

.fig { margin: 0; display: grid; gap: var(--sp-3); }
.fig__plot {
  position: relative;
  background: var(--surface);
  border: var(--bw-hairline) solid var(--border-quiet);
  border-radius: var(--r);
  padding: var(--sp-5) var(--sp-5) var(--sp-4);
}
.fig__plot svg { width: 100%; height: auto; }
.fig__cap {
  display: grid; gap: var(--sp-1);
  font-size: var(--fs-s); color: var(--muted);
  max-width: var(--measure-note);
}
.fig__n {
  font: var(--w-regular) var(--fs-mono-xs) / var(--lh-flat) var(--mono);
  letter-spacing: var(--tr-mono); text-transform: uppercase;
  color: var(--pr-text);
  border-bottom: var(--bw-rule) solid var(--pr-rule);
  padding-bottom: 3px; justify-self: start;
}
/* chart primitives — filled bars, one hairline axis, no gridlines
   beyond the measurement grid itself */
.ch-bar  { fill: var(--cfill, var(--bronze-fill)); }
.ch-bar-2 { fill: var(--graphite); }
.ch-axis { stroke: var(--border); stroke-width: 1; fill: none; }
.ch-tick { stroke: var(--border-quiet); stroke-width: 1; fill: none; }
.ch-line { stroke: var(--pr-ink); stroke-width: 2; fill: none; }
.ch-dot  { fill: var(--pr-ink); }
.ch-lab  { font: var(--w-regular) var(--fs-mono-xs) var(--mono); fill: var(--muted); }
.ch-val  { font: var(--w-regular) var(--fs-mono-s) var(--mono); fill: var(--fg); font-variant-numeric: tabular-nums; }


/* ============================================================
   15 · PROOF STRIP
   Four claims, all of them provable. On graphite, with the one
   that is about us taking the lift.
   ============================================================ */

.proof {
  background: var(--band-bg); color: var(--band-fg);
  border-top: var(--bw-hairline) solid var(--band-line);
}
.proof__in {
  max-width: var(--container); margin-inline: auto; padding: var(--sp-8) var(--gutter);
  display: grid; gap: var(--sp-6);
}
@media (min-width: 620px)  { .proof__in { grid-template-columns: 1fr 1fr; } }
@media (min-width: 1000px) { .proof__in { grid-template-columns: repeat(4, 1fr); gap: var(--sp-10); } }
.proof dl { margin: 0; }
.proof dt {
  font: var(--w-regular) var(--fs-mono-xs) / var(--lh-flat) var(--mono);
  letter-spacing: var(--tr-mono); text-transform: uppercase;
  color: var(--band-muted); margin-bottom: var(--sp-2);
}
.proof dd {
  margin: 0;
  font: var(--w-bold) 14px / var(--lh-tight) var(--display);
  letter-spacing: var(--tr-head-2); text-transform: uppercase;
  color: var(--band-fg); max-width: 22ch;
}
.proof .is-brand dd { color: var(--pr-lift); }


/* ============================================================
   16 · CALLOUT, NOTE, TAG, BADGE
   No coloured left bar on a rounded card. A note is set apart by
   its ground and a rule above it, which is how everything else in
   this system is set apart.
   ============================================================ */

.note {
  background: var(--surface);
  border-top: var(--bw-rule) solid var(--pr-rule);
  border-radius: 0 0 var(--r) var(--r);
  padding: var(--sp-4) var(--sp-5) var(--sp-5);
  display: grid; gap: var(--sp-2);
}
.note__k {
  display: flex; align-items: center; gap: var(--sp-2);
  font: var(--w-regular) var(--fs-mono-xs) / var(--lh-flat) var(--mono);
  letter-spacing: var(--tr-mono-2); text-transform: uppercase;
  color: var(--muted);
}
.note p { margin: 0; font-size: var(--fs-s); }
.note--alarm { border-top-color: var(--alarm); background: var(--alarm-wash); }
.note--alarm .note__k { color: var(--alarm); }
.note--ok { border-top-color: var(--graphite); background: var(--ok-bg); }
.note--quiet { border-top-color: var(--border); }

.tag {
  font: var(--w-regular) var(--fs-mono-xs) / var(--lh-flat) var(--mono);
  letter-spacing: var(--tr-mono-2); text-transform: uppercase;
  color: var(--muted);
}
.tag--above { display: block; margin-bottom: var(--sp-3); }
.tag--note {
  display: block; margin-top: var(--sp-3);
  text-transform: none; letter-spacing: 0.02em;
  line-height: var(--lh-mono); max-width: var(--measure-note);
}

/* a badge states a fact about a thing, not an action on it */
.badge {
  display: inline-flex; align-items: center; gap: var(--sp-2);
  min-height: var(--target-min); padding: 5px var(--sp-3) 4px;
  background: var(--surface-2); color: var(--fg);
  border: var(--bw-hairline) solid var(--border-quiet); border-radius: var(--r);
  font: var(--w-regular) var(--fs-mono-xs) / var(--lh-flat) var(--mono);
  letter-spacing: var(--tr-mono-2); text-transform: uppercase;
}
.badge i { width: 10px; height: 10px; flex: none; background: var(--c); font-style: normal; border-radius: 2px; }
.badge--solid { background: var(--graphite); color: var(--bone); border-color: var(--graphite); }
.badge--primary { background: var(--pr-ink); color: var(--graphite); border-color: var(--pr-ink); }


/* ============================================================
   17 · TABS
   For a family page: grades / applications / packing.
   The active tab is graphite with an orange rule under it. No tab
   ever changes its label colour to signal state.
   ============================================================ */

.tabs { display: grid; gap: var(--sp-5); }
.tabs__list {
  display: flex; flex-wrap: wrap; gap: var(--sp-1);
  margin: 0; padding: 0; list-style: none;
  border-bottom: var(--bw-hairline) solid var(--border-quiet);
}
.tabs__list button {
  appearance: none; background: transparent; border: 0; cursor: pointer;
  color: var(--fg);
  min-height: var(--target-touch); padding: 0 var(--sp-4);
  font: var(--w-bold) var(--fs-label) / var(--lh-flat) var(--display);
  letter-spacing: var(--tr-label); text-transform: uppercase;
  border-bottom: var(--bw-rule) solid transparent;
  margin-bottom: calc(var(--bw-hairline) * -1);
  transition: background-color var(--dur-1) var(--ease), border-color var(--dur-1) var(--ease);
}
.tabs__list button:hover, .tabs__list button.is-hover { background: var(--ghost-hover); border-bottom-color: var(--border); }
.tabs__list button[aria-selected="true"] { border-bottom-color: var(--pr-rule); background: transparent; }
.tabs__list button:disabled { color: var(--rule); cursor: not-allowed; }
.tabs__list button:disabled:hover { background: transparent; border-bottom-color: transparent; }
.tabs__panel:focus-visible { outline: var(--focus-w) solid var(--focus); outline-offset: var(--focus-offset); }


/* ============================================================
   18 · FORM CONTROLS AND THE ENQUIRY FORM

   States, and what moves in each:
     default   1 px rule border on chalk
     hover     the border goes graphite
     focus     a 2 px orange ring, offset 3 px, border graphite
     error     a 2 px alarm border, an alarm-wash ground, and a
               message with a filled alarm tick
     checked   the primary wash ground, a 2 px graphite border and
               a filled graphite tick. There is no success green
               in this system; see tokens.css §1.7
     disabled  paper ground, rule-coloured text — the one state
               allowed to lose contrast
   ============================================================ */

.field { display: grid; gap: var(--sp-2); }
.field__l {
  font: var(--w-bold) var(--fs-label-s) / var(--lh-flat) var(--display);
  letter-spacing: var(--tr-head-2); text-transform: uppercase;
  color: var(--fg);
}
.field__l .req { color: var(--pr-text); }
.field__l .req::after {
  content: ""; display: inline-block; vertical-align: middle;
  width: var(--sp-2); height: var(--bw-marker); margin-left: 6px;
  background: var(--pr-rule);
}
.field__hint { font: var(--w-regular) var(--fs-mono-s) / var(--lh-mono) var(--mono); color: var(--muted); }

.input, .select, .textarea {
  width: 100%; min-height: var(--control-h);
  padding: var(--sp-3) var(--sp-4);
  background: var(--surface); color: var(--fg);
  border: var(--bw-hairline) solid var(--border); border-radius: var(--r);
  font: var(--w-regular) var(--fs-body) / var(--lh-tight) var(--text);
  transition: border-color var(--dur-1) var(--ease), background-color var(--dur-1) var(--ease);
}
.input::placeholder, .textarea::placeholder { color: var(--muted); opacity: 1; }
.input:hover, .select:hover, .textarea:hover,
.input.is-hover, .select.is-hover, .textarea.is-hover { border-color: var(--fg); }
.input:focus-visible, .select:focus-visible, .textarea:focus-visible,
.input.is-focus, .select.is-focus, .textarea.is-focus { border-color: var(--fg); }
.textarea { min-height: 128px; resize: vertical; line-height: var(--lh-body); }

/* figures and codes are entered in mono, like everything numeric */
.input--num { font-family: var(--mono); font-variant-numeric: tabular-nums; }

/* the select keeps the native control and draws its own chevron on
   a wrapper, so there is no remote asset and no appearance hack
   that loses the keyboard behaviour */
.field__sel { position: relative; display: grid; }
.select { appearance: none; -webkit-appearance: none; padding-right: var(--sp-10); }
.field__sel::after {
  content: ""; position: absolute; right: 20px; top: 50%;
  width: 8px; height: 8px; margin-top: -6px;
  border-right: var(--bw-rule) solid var(--fg);
  border-bottom: var(--bw-rule) solid var(--fg);
  transform: rotate(45deg); pointer-events: none;
}

/* error */
.field--error .input, .field--error .select, .field--error .textarea {
  border-width: var(--bw-rule); border-color: var(--alarm); background: var(--alarm-wash);
}
.field__err {
  display: flex; align-items: flex-start; gap: var(--sp-2);
  font: var(--w-regular) var(--fs-mono-s) / var(--lh-mono) var(--mono);
  color: var(--alarm);
}
.field__err::before {
  content: ""; flex: none; width: 14px; height: 14px; margin-top: 3px;
  background: var(--alarm);
  -webkit-mask: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 14 14"><path d="M7 1.6l6 10.8H1z" fill="none" stroke="black" stroke-width="1.6" stroke-linejoin="round"/><path d="M7 5.6v3.1" stroke="black" stroke-width="1.6" stroke-linecap="round"/><circle cx="7" cy="10.6" r=".95" fill="black"/></svg>') no-repeat center / contain;
          mask: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 14 14"><path d="M7 1.6l6 10.8H1z" fill="none" stroke="black" stroke-width="1.6" stroke-linejoin="round"/><path d="M7 5.6v3.1" stroke="black" stroke-width="1.6" stroke-linecap="round"/><circle cx="7" cy="10.6" r=".95" fill="black"/></svg>') no-repeat center / contain;
}

/* checked / acknowledged */
.field--ok .input, .field--ok .select, .field--ok .textarea {
  border-width: var(--bw-rule); border-color: var(--ok-border); background: var(--ok-bg);
}
.field__ok {
  display: flex; align-items: flex-start; gap: var(--sp-2);
  font: var(--w-regular) var(--fs-mono-s) / var(--lh-mono) var(--mono);
  color: var(--fg);
}
.field__ok::before {
  content: ""; flex: none; width: 14px; height: 14px; margin-top: 3px;
  background: var(--fg);
  -webkit-mask: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 14 14"><path d="M2 7.6l3.2 3.2L12 4" fill="none" stroke="black" stroke-width="2.2"/></svg>') no-repeat center / contain;
          mask: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 14 14"><path d="M2 7.6l3.2 3.2L12 4" fill="none" stroke="black" stroke-width="2.2"/></svg>') no-repeat center / contain;
}

/* disabled */
.input:disabled, .select:disabled, .textarea:disabled {
  background: var(--paper); color: var(--rule); border-color: var(--border-quiet);
  cursor: not-allowed;
}
.input:disabled::placeholder { color: var(--rule); }

/* --- checkbox and radio --------------------------------------
   Drawn at 24 px inside a 44 px row, so the mark meets the
   minimum target and the row meets the touch target. The checkbox
   is square like the rest of the system; the radio is the one
   circle, because a round radio is what the control means. ----- */

.check { display: flex; align-items: center; gap: var(--sp-3); min-height: var(--target-touch); cursor: pointer; }
.check input {
  appearance: none; -webkit-appearance: none; margin: 0;
  width: var(--target-min); height: var(--target-min); flex: none;
  background: var(--surface);
  border: var(--bw-hairline) solid var(--border); border-radius: 2px;
  cursor: pointer;
  transition: background-color var(--dur-1) var(--ease), border-color var(--dur-1) var(--ease);
}
.check input[type="radio"] { border-radius: 50%; }
.check:hover input, .check.is-hover input { border-color: var(--fg); }
.check input:checked { background: var(--pr-ink); border-color: var(--pr-ink); }
/* the tick is graphite on the orange at 4.72:1 */
.check input[type="checkbox"]:checked {
  -webkit-mask: none; mask: none;
  background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M5 12.5l4.2 4.2L19 7" fill="none" stroke="%2316140f" stroke-width="2.6"/></svg>');
  background-repeat: no-repeat; background-position: center; background-size: 20px 20px;
}
.check input[type="radio"]:checked {
  background-image: radial-gradient(circle at center, var(--graphite) 5px, transparent 5.5px);
}
.check input:disabled { background: var(--paper); border-color: var(--border-quiet); cursor: not-allowed; }
.check input:disabled + span { color: var(--rule); }
.check span { font-size: var(--fs-body-s); }
.checkgroup { display: grid; gap: var(--sp-1); }

/* a radio set used as a choice of request type */
.radiorow { display: grid; gap: var(--sp-2); }
@media (min-width: 620px) { .radiorow { grid-template-columns: repeat(3, 1fr); gap: var(--sp-3); } }
.radiocard {
  display: flex; align-items: center; gap: var(--sp-3);
  min-height: var(--target-touch); padding: var(--sp-3) var(--sp-4);
  background: var(--surface);
  border: var(--bw-hairline) solid var(--border); border-radius: var(--r);
  cursor: pointer;
  transition: border-color var(--dur-1) var(--ease), background-color var(--dur-1) var(--ease);
}
.radiocard:hover, .radiocard.is-hover { border-color: var(--fg); }
.radiocard:has(input:checked) { background: var(--pr-wash); border-color: var(--fg); border-width: var(--bw-rule); padding: 11px 15px; }
.radiocard span { font: var(--w-bold) var(--fs-label-s) / var(--lh-flat) var(--display); letter-spacing: var(--tr-head-2); text-transform: uppercase; }

/* --- file upload ---------------------------------------------
   A ghost button plus the chosen filename. The native input is
   hidden from sight but not from the keyboard. --------------- */

.upload { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-3); }
.upload input[type="file"] {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip: rect(0 0 0 0); white-space: nowrap;
}
.upload input[type="file"]:focus-visible + .btn { outline: var(--focus-w) solid var(--focus); outline-offset: var(--focus-offset); }
.upload__name { font: var(--w-regular) var(--fs-mono-s) / var(--lh-mono) var(--mono); color: var(--muted); }

/* --- the enquiry form ---------------------------------------- */

.enq { display: grid; gap: var(--sp-6); }
.enq__set { border: 0; margin: 0; padding: 0; display: grid; gap: var(--sp-4); }
.enq__legend {
  padding: 0; margin-bottom: var(--sp-1);
  font: var(--w-regular) var(--fs-mono-xs) / var(--lh-flat) var(--mono);
  letter-spacing: var(--tr-mono); text-transform: uppercase;
  color: var(--pr-text);
  border-bottom: var(--bw-rule) solid var(--pr-rule); padding-bottom: 3px;
}
.enq__pair { display: grid; gap: var(--sp-4); }
@media (min-width: 620px) { .enq__pair { grid-template-columns: 1fr 1fr; } }
.enq__foot {
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-4);
  padding-top: var(--sp-5);
  border-top: var(--bw-hairline) solid var(--border-quiet);
}
.enq__foot .btn { min-height: var(--target-touch); }


/* ============================================================
   19 · THE 25 KG DRUM LABEL
   A5. The family band at the head, the grade at 48 px, numbered
   property blocks on the measurement grid, and a pattern strip at
   the foot. Printed, so every value is in millimetres of the real
   artwork scaled by a container query.
   ============================================================ */

.dlabel { container-type: inline-size; width: 100%; max-width: 420px; }
.dlabel__frame {
  position: relative; width: 100%; aspect-ratio: 148 / 210;
  overflow: hidden; border: var(--bw-hairline) solid var(--border);
}
.dlabel__canvas {
  position: absolute; inset: 0;
  width: 592px; height: 840px;
  transform-origin: 0 0; transform: scale(calc(100cqw / 592px));
  line-height: var(--lh-mono);
}

.lb {
  position: absolute; inset: 0;
  display: flex; flex-direction: column;
  background: var(--surface); color: var(--fg); font-family: var(--text);
}
.lb__band {
  height: 30px; background: var(--cfill);
  display: flex; align-items: center; justify-content: space-between;
  padding-inline: 26px;
}
.lb__band span {
  font: var(--w-bold) 11px / var(--lh-flat) var(--display);
  letter-spacing: var(--tr-band); text-transform: uppercase;
  color: var(--graphite);
}
.lb__in { flex: 1; display: flex; flex-direction: column; padding: 22px 26px 20px; }
.lb__head {
  display: flex; justify-content: space-between; align-items: flex-start; gap: var(--sp-4);
  padding-bottom: var(--sp-4);
  border-bottom: var(--bw-hairline) solid var(--border);
}
.lb__sec {
  display: flex; align-items: center; gap: 9px; margin: var(--sp-4) 0 0;
  font: var(--w-regular) var(--fs-mono-xs) / var(--lh-flat) var(--mono);
  letter-spacing: var(--tr-eyebrow); text-transform: uppercase;
  color: var(--pr-text);
}
.lb__sec::before { content: ""; width: 14px; height: var(--bw-marker); flex: none; background: var(--pr-rule); }
.lb__grade {
  margin: var(--sp-2) 0 6px;
  font: var(--w-black) 48px / var(--lh-grade) var(--display);
  letter-spacing: var(--tr-grade); color: var(--fg);
}
.lb__fam {
  margin: 0;
  font: var(--w-regular) 11px / 1.4 var(--mono);
  letter-spacing: var(--tr-mono); text-transform: uppercase; color: var(--muted);
}
/* The property block carries the measurement grid. The label is a
   fixed 592 px artwork that is only ever scaled, never reflowed,
   so its gutter is PINNED at 3 cells instead of following the
   viewport: .datagrid supplies the inline padding from the
   --grid-gutter redefined here, and the grid's last cell ramps
   out exactly at the first property name — the same contract as
   a panel. */
.lb__tblwrap { margin-top: var(--sp-5); padding-block: 6px; }
.lb__tblwrap.datagrid { --grid-gutter: calc(var(--grid-step) * 3); }
.lb__tbl { width: 100%; font: var(--w-regular) var(--fs-xs) / 1.4 var(--mono); font-variant-numeric: tabular-nums; }
.lb__tbl th {
  text-align: left; font-weight: var(--w-regular); color: var(--muted);
  padding: 7px var(--sp-3) 7px 0; border-bottom: var(--bw-hairline) solid var(--border-quiet);
}
.lb__tbl td { text-align: right; padding-block: 7px; border-bottom: var(--bw-hairline) solid var(--border-quiet); }
.lb__fields { display: grid; grid-template-columns: 1fr 1fr; gap: var(--sp-3); margin-top: var(--sp-5); }
.lb__field {
  border: var(--bw-hairline) solid var(--border); border-radius: var(--r);
  padding: var(--sp-3) var(--sp-3) var(--sp-3);
}
.lb__field .tag { display: block; margin-bottom: 7px; }
.lb__field b { font: var(--w-regular) var(--fs-mono-l) / var(--lh-flat) var(--mono); }
.lb__pat { margin-top: auto; height: 58px; }
.lb__foot {
  display: flex; justify-content: space-between; gap: var(--sp-4);
  padding-top: var(--sp-4);
  font: var(--w-regular) var(--fs-mono-xs) / var(--lh-mono) var(--mono); color: var(--muted);
}
.lb__foot > span:first-child { flex: 0 1 54%; }
.lb__foot > span:last-child  { flex: 0 0 42%; text-align: right; }


/* ============================================================
   20 · THE BUSINESS CARD
   88 × 55 mm. The back is the orange at full strength with
   graphite type at 4.72:1 — at this size it is exactly a safety
   label, which is the clearest argument for the colour.
   ============================================================ */

.bcard { container-type: inline-size; width: 100%; }
.bcard__frame {
  position: relative; width: 100%; aspect-ratio: 88 / 55;
  overflow: hidden; border: var(--bw-hairline) solid var(--border);
}
.bcard__canvas {
  position: absolute; inset: 0;
  width: 704px; height: 440px;
  transform-origin: 0 0; transform: scale(calc(100cqw / 704px));
  line-height: var(--lh-mono);
}
.cardpair { display: grid; gap: var(--sp-gap-s); grid-template-columns: repeat(auto-fit, minmax(238px, 1fr)); }

.bc {
  position: absolute; inset: 0;
  display: flex; flex-direction: column; justify-content: space-between;
  padding: 42px 44px;
  background: var(--ground); color: var(--fg); font-family: var(--text);
}
.bc--back { background: var(--card-bg); color: var(--card-fg); }
.bc__name {
  margin: 0;
  font: var(--w-bold) 21px / var(--lh-head) var(--display);
  letter-spacing: var(--tr-head-2); text-transform: uppercase;
}
.bc__title { margin: 7px 0 0; font: var(--w-regular) var(--fs-mono) / 1.4 var(--mono); color: var(--muted); }
.bc__c { margin: 0; font: var(--w-regular) 13.5px / 1.75 var(--mono); color: var(--card-fg); }
.bc__tag {
  margin: 0;
  font: var(--w-regular) var(--fs-mono-xs) / var(--lh-flat) var(--mono);
  letter-spacing: var(--tr-mono-2); text-transform: uppercase; color: var(--card-dim);
}
.bc__els { display: flex; gap: 6px; }


/* ============================================================
   PRINT
   ============================================================ */

@media print {
  .skip, .hdr, .drawer { display: none; }
  body { background: #fff; }
  .panel, .famcard, .famrow { break-inside: avoid; }
}

/* ============================================================
   STATE PREVIEW HOOKS
   .is-hover, .is-active and .is-focus are grouped INTO the real
   selectors above rather than redeclared down here, so a cell in
   the living specimen renders the identical declarations a live
   control does, and the two can never drift apart.

   They exist for design-system.html. No product page uses them.
   ============================================================ */
