.fab-stack{position:fixed;right:16px;bottom:16px;z-index:80;display:flex;flex-direction:column;
 gap:10px;align-items:flex-end}
/* HIDDEN MUST WIN.
   [hidden]{display:none} and .fab{display:grid} carry the same specificity, and .fab comes
   later, so the launchers ignored the attribute entirely: measured on the live site as
   hiddenAttr true, display grid, visible true. Every admin switch that "hid" a launcher was
   writing an attribute the stylesheet overruled, and a WhatsApp button with no number stayed
   tappable on a shop that had switched it off.
   NOTE: this CSS lives inside a JS template literal -- no backticks in here. */
.fab[hidden]{display:none !important}
.fab{width:54px;height:54px;border-radius:50%;border:0;cursor:pointer;display:grid;
 place-items:center;box-shadow:0 6px 22px rgba(6,19,72,.26);transition:transform .15s;
 position:relative;padding:0;color:#fff}
.fab:hover{transform:translateY(-2px)}
.fab:focus-visible{outline:3px solid var(--accent,#0b7d74);outline-offset:3px}
.fab svg{width:27px;height:27px;display:block}
.fab-wa{background:#25D366}
.fab-chat{background:var(--navy,#061348)}
.fab-chat .bdg{position:absolute;top:-2px;right:-2px;min-width:19px;height:19px;
 border-radius:19px;background:#e5484d;color:#fff;font:700 11px/19px system-ui;padding:0 5px;
 display:none}
.fab-chat .bdg.on{display:block}
.fab-lbl{position:absolute;right:64px;top:50%;transform:translateY(-50%) scale(.92);
 background:#131a24;color:#fff;font:600 12.5px system-ui;padding:6px 11px;border-radius:7px;
 white-space:nowrap;opacity:0;pointer-events:none;transition:.15s}
.fab:hover .fab-lbl{opacity:1;transform:translateY(-50%) scale(1)}

.cw{position:fixed;right:16px;bottom:16px;z-index:90;width:min(94vw,368px);
 height:min(74vh,560px);background:#fff;border:1px solid #e4e8ed;border-radius:16px;
 overflow:hidden;box-shadow:0 20px 60px rgba(6,19,72,.3);display:none;flex-direction:column}
.cw.open{display:flex}
.cw-h{background:var(--navy,#061348);color:#fff;padding:13px 15px;display:flex;
 align-items:center;gap:10px}
.cw-h b{font-size:14.5px;display:block;line-height:1.25}
.cw-h small{font-size:11.5px;opacity:.75}
.cw-x{margin-left:auto;background:0;border:0;color:#fff;font-size:21px;cursor:pointer;
 line-height:1;padding:0 2px;opacity:.8}
.cw-x:hover{opacity:1}
.cw-b{flex:1;overflow-y:auto;padding:14px;background:#f7f8fa;display:flex;
 flex-direction:column;gap:9px}
.cw-m{max-width:82%;padding:9px 12px;border-radius:13px;font-size:13.5px;line-height:1.45;
 word-wrap:break-word}
.cw-m.them{background:#fff;border:1px solid #e4e8ed;align-self:flex-start;
 border-bottom-left-radius:4px}
.cw-m.me{background:var(--navy,#061348);color:#fff;align-self:flex-end;
 border-bottom-right-radius:4px}
.cw-note{font-size:12px;color:#6b7785;text-align:center;padding:6px 10px}
.cw-id{padding:11px;border-top:1px solid #e4e8ed;background:#f7f9fc;display:grid;gap:7px}
.cw-id[hidden]{display:none}
.cw-id p{margin:0;font-size:12.5px;color:#55677e;line-height:1.4}
.cw-id input{border:1px solid #d6dce3;border-radius:9px;padding:9px 11px;font-size:14px;
  font-family:inherit;background:#fff}
.cw-id input:focus{outline:0;border-color:var(--navy,#061348)}
.cw-id button{border:0;border-radius:9px;padding:9px 12px;font-size:13.5px;font-weight:700;
  cursor:pointer;background:var(--navy,#061348);color:#fff}
.cw-f{display:flex;gap:8px;padding:11px;border-top:1px solid #e4e8ed;background:#fff}
.cw-f input{flex:1;border:1px solid #d6dce3;border-radius:9px;padding:10px 12px;
 font:14px inherit;min-width:0}
.cw-f input:focus{outline:0;border-color:var(--navy,#061348)}
/* The paperclip. The hidden file input must be exempted from the .cw-f input rule above,
   which is flex:1 -- otherwise it claims a share of the row and pushes the text field off. */
.cw-f input[type=file]{display:none;flex:none;width:0;padding:0;border:0}
.cw-clip{flex:none;display:flex;align-items:center;justify-content:center;width:38px;
  border:1px solid #d6dce3;border-radius:9px;background:#fff;cursor:pointer;font-size:17px;
  line-height:1;user-select:none}
.cw-clip:hover{border-color:var(--navy,#061348)}
.cw-f button{background:var(--navy,#061348);color:#fff;border:0;border-radius:9px;
 padding:0 15px;font:650 13.5px inherit;cursor:pointer}
@media(max-width:420px){
 .cw{right:8px;left:8px;bottom:8px;width:auto;height:min(80vh,560px)}
 .fab-stack{right:12px;bottom:12px}
}

/* Generated by tools/fonts.mjs. Latin and latin-ext only.
 * The -fallback faces below are not real files: they are the SYSTEM font, re-declared
 * with the web font's metrics, so the line box is the same size before and after the
 * swap and nothing on the page moves when it lands. */
@font-face{font-family:"IBM Plex Mono";font-style:normal;font-weight:500;font-display:swap;src:url(/assets/fonts/ibm-plex-mono-500-latin-ext.woff2) format("woff2");unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C4, U+2113, U+2C60-2C7F, U+A720-A7FF}
@font-face{font-family:"IBM Plex Mono";font-style:normal;font-weight:500;font-display:swap;src:url(/assets/fonts/ibm-plex-mono-500-latin.woff2) format("woff2");unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD}
@font-face{font-family:"IBM Plex Mono";font-style:normal;font-weight:600;font-display:swap;src:url(/assets/fonts/ibm-plex-mono-600-latin-ext.woff2) format("woff2");unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C4, U+2113, U+2C60-2C7F, U+A720-A7FF}
@font-face{font-family:"IBM Plex Mono";font-style:normal;font-weight:600;font-display:swap;src:url(/assets/fonts/ibm-plex-mono-600-latin.woff2) format("woff2");unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD}
@font-face{font-family:"IBM Plex Mono";font-style:normal;font-weight:700;font-display:swap;src:url(/assets/fonts/ibm-plex-mono-700-latin-ext.woff2) format("woff2");unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C4, U+2113, U+2C60-2C7F, U+A720-A7FF}
@font-face{font-family:"IBM Plex Mono";font-style:normal;font-weight:700;font-display:swap;src:url(/assets/fonts/ibm-plex-mono-700-latin.woff2) format("woff2");unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD}
@font-face{font-family:"Plus Jakarta Sans";font-style:normal;font-weight:400;font-display:swap;src:url(/assets/fonts/plus-jakarta-sans-400-latin-ext.woff2) format("woff2");unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C4, U+2113, U+2C60-2C7F, U+A720-A7FF}
@font-face{font-family:"Plus Jakarta Sans";font-style:normal;font-weight:400;font-display:swap;src:url(/assets/fonts/plus-jakarta-sans-400-latin.woff2) format("woff2");unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD}
@font-face{font-family:"Plus Jakarta Sans";font-style:normal;font-weight:500;font-display:swap;src:url(/assets/fonts/plus-jakarta-sans-500-latin-ext.woff2) format("woff2");unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C4, U+2113, U+2C60-2C7F, U+A720-A7FF}
@font-face{font-family:"Plus Jakarta Sans";font-style:normal;font-weight:500;font-display:swap;src:url(/assets/fonts/plus-jakarta-sans-500-latin.woff2) format("woff2");unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD}
@font-face{font-family:"Plus Jakarta Sans";font-style:normal;font-weight:600;font-display:swap;src:url(/assets/fonts/plus-jakarta-sans-600-latin-ext.woff2) format("woff2");unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C4, U+2113, U+2C60-2C7F, U+A720-A7FF}
@font-face{font-family:"Plus Jakarta Sans";font-style:normal;font-weight:600;font-display:swap;src:url(/assets/fonts/plus-jakarta-sans-600-latin.woff2) format("woff2");unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD}
@font-face{font-family:"Plus Jakarta Sans";font-style:normal;font-weight:700;font-display:swap;src:url(/assets/fonts/plus-jakarta-sans-700-latin-ext.woff2) format("woff2");unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C4, U+2113, U+2C60-2C7F, U+A720-A7FF}
@font-face{font-family:"Plus Jakarta Sans";font-style:normal;font-weight:700;font-display:swap;src:url(/assets/fonts/plus-jakarta-sans-700-latin.woff2) format("woff2");unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD}
@font-face{font-family:"Plus Jakarta Sans";font-style:normal;font-weight:800;font-display:swap;src:url(/assets/fonts/plus-jakarta-sans-800-latin-ext.woff2) format("woff2");unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C4, U+2113, U+2C60-2C7F, U+A720-A7FF}
@font-face{font-family:"Plus Jakarta Sans";font-style:normal;font-weight:800;font-display:swap;src:url(/assets/fonts/plus-jakarta-sans-800-latin.woff2) format("woff2");unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD}
@font-face{font-family:"Plus Jakarta Sans Fallback";src:local("Segoe UI"),local("Helvetica Neue"),local("Arial");ascent-override:97%;descent-override:24%;line-gap-override:0%;size-adjust:105%}
@font-face{font-family:"IBM Plex Mono Fallback";src:local("Segoe UI"),local("Helvetica Neue"),local("Arial");ascent-override:95%;descent-override:25%;line-gap-override:0%;size-adjust:101%}

*,*::before,*::after{box-sizing:border-box}
:root{
  /* surfaces, light is the dominant one */
  --paper:#ffffff;
  --paper-2:#f6f8fb;
  --paper-3:#eef2f7;
  --rule:#dde4ed;
  --rule-2:#c7d2e0;

  /* type, the navy, used as INK rather than as a background */
  --ink:#061348;
  --ink-2:#2b3a63;
  --ink-3:#5a6888;

  /* the two-token accent. signal = fills only. signal-ink = anything textual. */
  --signal:#0277e9;
  --signal-ink:#0247b8;
  --signal-deep:#021558;
  --signal-wash:#0247b80f;

  --ok:#0b7a52;
  --warn:#8a5a00;
  --stop:#a3222c;

  /* Plus Jakarta Sans for text, IBM Plex Mono for prices and figures. The old stack resolved
     to Segoe UI on Windows and read as an unstyled document. Tabular numerals on the mono
     matter: a column of prices that does not line up looks broken. */
  --ff:"Plus Jakarta Sans","Plus Jakarta Sans Fallback",system-ui,-apple-system,"Segoe UI",Roboto,sans-serif;
  --fm:"IBM Plex Mono","IBM Plex Mono Fallback",ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;
  --maxw:1180px;
  --gut:24px;
  --r:10px;
}
@media(max-width:640px){:root{--gut:16px}}

html{-webkit-text-size-adjust:100%}
body{margin:0;background:var(--paper);color:var(--ink-2);
  font:400 16px/1.65 var(--ff);letter-spacing:-.003em;
  -webkit-font-smoothing:antialiased}
img{max-width:100%;height:auto;display:block}
a{color:var(--signal-ink);text-underline-offset:2px}
a:hover{color:var(--signal-deep)}
h1,h2,h3,h4{color:var(--ink);line-height:1.2;letter-spacing:-.021em;margin:0}
h1{font-size:clamp(28px,4.2vw,42px);font-weight:800}
h2{font-size:clamp(21px,2.5vw,27px);font-weight:750}
h3{font-size:18px;font-weight:700}
p{margin:0 0 14px}
.wrap{max-width:var(--maxw);margin:0 auto;padding:0 var(--gut)}
.skip{position:absolute;left:-9999px}
.skip:focus{left:12px;top:12px;z-index:99;background:var(--ink);color:#fff;padding:10px 14px;border-radius:8px}
:focus-visible{outline:2px solid var(--signal-ink);outline-offset:2px;border-radius:4px}

/* ---------- header: white, with a hairline. The opposite of a dark bar. ---------- */
.announce{background:var(--ink);color:#dce6f7;font-size:13.5px;text-align:center;padding:7px 12px;letter-spacing:.01em}
.hdr{position:sticky;top:0;z-index:40;background:#fffffff2;backdrop-filter:saturate(150%) blur(8px);
  border-bottom:1px solid var(--rule)}
.hdr-in{display:flex;align-items:center;gap:18px;padding:12px 0;max-width:var(--maxw);margin:0 auto;padding-left:var(--gut);padding-right:var(--gut)}
.brand{display:flex;align-items:center;gap:9px;flex:0 0 auto;text-decoration:none;
  color:var(--ink)}
.brand img{height:34px;width:auto}
/* THE DRAWN BRANDMARK.
   Sized in em so the whole lockup scales from one font-size, and coloured from the theme
   tokens so it answers to the page rather than to a baked-in palette. */
.bm-mark{width:26px;height:33px;display:block;flex:0 0 auto}
.bm-type{display:flex;flex-direction:column;line-height:1;gap:3px}
.bm-name{font-family:var(--display,"Plus Jakarta Sans"),system-ui,sans-serif;
  font-weight:800;font-size:20px;letter-spacing:-.045em;color:var(--ink);
  text-transform:uppercase}
/* The small line is spaced WIDE on purpose: a short line set tight reads as an afterthought,
   the same line tracked out reads as a mark. */
.bm-sub{font-family:"IBM Plex Mono",ui-monospace,monospace;font-size:8.5px;font-weight:600;
  letter-spacing:.22em;text-transform:uppercase;color:var(--signal-ink,#0247b8);
  white-space:nowrap}
.brand:hover .bm-name{color:var(--signal-ink,#0247b8)}
@media (max-width:420px){
  /* The sub-line is the first thing to go: the name alone still identifies the shop, and a
     cramped two-line lockup on a 360px screen looks like a mistake rather than a mark. */
  .bm-name{font-size:17px}
  .bm-sub{display:none}
  .bm-mark{width:22px;height:28px}
}
.srch{flex:1 1 auto;display:flex;max-width:430px}
.srch input{flex:1;border:1px solid var(--rule-2);border-right:0;border-radius:8px 0 0 8px;
  padding:9px 12px;font:inherit;font-size:14.5px;color:var(--ink);background:var(--paper)}
.srch input::placeholder{color:var(--ink-3)}
.srch button{border:1px solid var(--signal-ink);background:var(--signal-ink);color:#fff;
  border-radius:0 8px 8px 0;padding:9px 15px;font:600 14.5px var(--ff);cursor:pointer}
.hdr-act{margin-left:auto;display:flex;align-items:center;gap:10px}
.basket{display:inline-flex;align-items:center;gap:7px;border:1px solid var(--rule-2);
  background:var(--paper);color:var(--ink);border-radius:8px;padding:8px 13px;
  font:600 14.5px var(--ff);text-decoration:none}
.basket:hover{border-color:var(--signal-ink);color:var(--signal-ink)}
.basket b{background:var(--signal-ink);color:#fff;border-radius:20px;
  font:700 11.5px/1 var(--ff);padding:3px 6px;min-width:18px;text-align:center}
.burger{display:none;border:1px solid var(--rule-2);background:var(--paper);border-radius:8px;
  padding:8px 11px;cursor:pointer;font:600 14px var(--ff);color:var(--ink)}

/* ---------- the family rail: a horizontal strip of the nine shelves ---------- */
.rail{border-bottom:1px solid var(--rule);background:var(--paper);position:relative}
/* NO overflow here. overflow-x:auto on this element created a clipping context that sliced
   the absolutely positioned dropdown panels off at the rail's bottom edge - they were
   rendering the whole time and being cut away. The rail wraps instead; the burger handles
   phones. */
.rail-in{max-width:var(--maxw);margin:0 auto;padding:0 var(--gut);display:flex;gap:2px;
  flex-wrap:wrap;overflow:visible}
.rail-in::-webkit-scrollbar{display:none}
.rail a{flex:0 0 auto;padding:11px 14px;font:600 14.5px var(--ff);color:var(--ink-2);
  text-decoration:none;border-bottom:2px solid transparent;white-space:nowrap}
.rail a:hover{color:var(--signal-ink);border-bottom-color:var(--rule-2)}
.rail a[aria-current]{color:var(--ink);border-bottom-color:var(--signal)}

/* ---------- the Compounds panel ----------
   Replaced the seven per-family dropdowns. Hover AND focus-within, so a keyboard reaches it,
   and a click handler on top so a touch screen can open it too. */
.rail-item{position:relative;flex:0 0 auto}
.rail-top{display:inline-flex;align-items:center;gap:5px}
.caret{width:0;height:0;border-left:4px solid transparent;border-right:4px solid transparent;
 border-top:4px solid currentColor;opacity:.55;transition:transform .15s}
.rail-item:hover .caret,.rail-item:focus-within .caret{transform:rotate(180deg);opacity:1}
@media(max-width:860px){
  /* no hover on a phone: the panel opens with the rest of the menu */
  .rail.is-open .rail-item{width:100%}
  .caret{display:none}
}
@media(max-width:860px){
  .srch{display:none}
  .burger{display:block}
  /* The bar collapses behind the button that exists to replace it. It used to render BOTH,
     which is three stacked rows of links under a Browse button, and it is also where the
     jump came from: with nothing to wrap there is nothing to re-wrap when the font lands. */
  .rail-in{gap:0;display:none;flex-direction:column;padding-bottom:8px}
  .rail.is-open .rail-in{display:flex}
  .rail{border-bottom:0}
  .rail.is-open{border-bottom:1px solid var(--rule)}
  .rail a,button.rail-top{width:100%;padding:12px 4px;border-bottom:1px solid var(--rule);
   justify-content:flex-start;text-align:left}
  .rail-item,.rail-item.has-mega{width:100%}
  /* The caret is hidden on a phone, so without this "Compounds" looks exactly like the five
     items beside it that go somewhere, and nothing says it opens. */
  button.rail-top{position:relative}
  button.rail-top::after{content:"";position:absolute;right:6px;top:50%;width:8px;height:8px;
   margin-top:-6px;border-right:2px solid currentColor;border-bottom:2px solid currentColor;
   transform:rotate(45deg);opacity:.5;transition:transform .15s}
  .has-mega.is-open button.rail-top::after{transform:rotate(-135deg);margin-top:-2px;opacity:1}
  /* and the search, which is hidden in the header at this width, lives in the menu */
  .rail-in .srch-rail{display:flex;margin:10px 0 6px}
  .rail-in .srch-rail input{font-size:16px}
  .mega{position:static;opacity:1;visibility:visible;transform:none;display:none;
   box-shadow:none;border-top:0}
  .has-mega.is-open .mega{display:block}
  .mega-in{grid-template-columns:1fr;padding:4px 0 10px 14px;gap:14px;max-width:none}
  .mega-col a{padding:5px 0}
  .mega-end{margin:0}
}

/* ---------- content ---------- */
main{padding:0 0 60px}
.crumb{font-size:13.5px;color:var(--ink-3);padding:16px 0 4px}
.crumb a{color:var(--ink-3);text-decoration:none}
.crumb a:hover{color:var(--signal-ink);text-decoration:underline}
.crumb span{padding:0 6px;opacity:.5}
.lede{font-size:clamp(17px,1.8vw,19.5px);line-height:1.55;color:var(--ink-2);
  max-width:66ch;margin:10px 0 22px}
.prose{max-width:72ch}
.prose h2{margin:30px 0 10px}
.prose h3{margin:20px 0 7px}
.prose ul,.prose ol{margin:0 0 15px;padding-left:21px}
.prose li{margin:5px 0}
.fine{font-size:13.5px;color:var(--ink-3);line-height:1.55}

/* ---------- the strength table: the shop's main selling surface ---------- */
.sizes{width:100%;border-collapse:separate;border-spacing:0;margin:0 0 20px;
  border:1px solid var(--rule);border-radius:var(--r);overflow:hidden;font-size:15px}
.sizes caption{caption-side:top;text-align:left;font:700 15px var(--ff);color:var(--ink);padding:0 0 8px}
.sizes th,.sizes td{padding:11px 14px;text-align:left;border-bottom:1px solid var(--rule)}
.sizes thead th{background:var(--paper-2);font:650 13px var(--ff);color:var(--ink-3);
  text-transform:uppercase;letter-spacing:.055em}
.sizes tbody tr:last-child th,.sizes tbody tr:last-child td{border-bottom:0}
.sizes tbody tr:hover{background:var(--signal-wash)}
.sizes th[scope=row]{font:700 15.5px var(--ff);color:var(--ink);white-space:nowrap}
.sizes .num{font:700 15.5px var(--fm);color:var(--ink);white-space:nowrap;font-variant-numeric:tabular-nums}
.sizes .permg{font:400 12.5px var(--fm);color:var(--ink-3);white-space:nowrap}
/* A price column wants to be tight, right-aligned and unbreakable. A column of prose
 * wants the opposite, and when this was the DEFAULT it turned a sentence into one
 * unbreakable line, set the table to the width of that sentence, and gave the whole
 * page a horizontal scrollbar. It did that on 57 pages. Price tables opt in now. */
.sizes.prices td:last-child{text-align:right;width:1%;white-space:nowrap}
.sizes td{overflow-wrap:anywhere}
/* The last line of defence. clip, not hidden: hidden would make this a scroll
   container and silently break the sticky order summary at checkout. */
html,body{overflow-x:clip;max-width:100%}
/* A peptide sequence has no spaces in it. Trp-Ala-Gly-Gly-Asp-Ala-Ser-Gly-Glu is 35
   characters, and the GH fragments are longer than the width of a phone. */
code,.num,samp{overflow-wrap:anywhere}
img,svg,video,table,iframe{max-width:100%}
/* and if a table still outgrows its column, it scrolls, not the document */
.prose .sizes{display:block;max-width:100%;overflow-x:auto}
.prose .sizes tbody,.prose .sizes thead{display:table;width:100%;table-layout:auto}
.pend{font:600 13px var(--ff);color:var(--warn)}

/* ---------- buttons ---------- */
.btn{display:inline-flex;align-items:center;justify-content:center;gap:7px;
  background:var(--signal-ink);color:#fff;border:1px solid var(--signal-ink);
  border-radius:8px;padding:9px 16px;font:650 14.5px var(--ff);
  text-decoration:none;cursor:pointer;transition:background .15s,border-color .15s}
.btn:hover{background:var(--signal-deep);border-color:var(--signal-deep);color:#fff}
.btn.sm{padding:7px 13px;font-size:13.5px}
.btn.ghost{background:transparent;color:var(--signal-ink);border-color:var(--rule-2)}
.btn.ghost:hover{background:var(--signal-wash);border-color:var(--signal-ink);color:var(--signal-ink)}
.btn[disabled]{opacity:.45;pointer-events:none}

/* ---------- product page ---------- */
.pdp{display:grid;grid-template-columns:minmax(0,340px) minmax(0,1fr);gap:40px;
  align-items:start;padding:18px 0 8px}
.pdp-shot{border:1px solid var(--rule);border-radius:var(--r);background:var(--paper-2);padding:18px}
/* The box is reserved by the ASPECT RATIO, not capped by max-height.
   The old rule was max-height:420px with width:auto, and both of those discard the box that
   the width and height attributes reserve: the browser cannot know the final size until the
   image has decoded, so the slot rendered 510px tall and then snapped to 420, dropping
   everything below it by 420px. Measured at CLS 0.33 on the product pages, intermittently,
   about one load in eight, which is exactly the kind of fault that survives casual checking.
   Declaring the ratio lets the height be computed from the width before a byte arrives. */
.pdp-shot img{display:block;margin:0 auto;width:100%;max-width:280px;height:auto;
 aspect-ratio:340/510}
.tag{display:inline-block;font:650 11.5px var(--ff);letter-spacing:.07em;text-transform:uppercase;
  color:var(--signal-ink);background:var(--signal-wash);border:1px solid var(--rule-2);
  border-radius:20px;padding:4px 10px;margin:0 0 10px}
.from{font:800 27px var(--fm);color:var(--ink);font-variant-numeric:tabular-nums}
.from small{font:500 14px var(--ff);color:var(--ink-3);margin-left:6px}
@media(max-width:820px){.pdp{grid-template-columns:1fr;gap:22px}}

/* ---------- the hero ----------
   Two columns: copy left, four real products right. The single-column version left a third of
   a 1180px page empty beside a narrow ribbon of text, which is why it read as a document. */
.hero{position:relative;padding:34px 0 28px;margin:0 0 34px;
 border-bottom:1px solid var(--rule)}
.hero::before{content:"";position:absolute;inset:0 calc(50% - 50vw);z-index:-1;
 background:linear-gradient(180deg,var(--paper-2) 0%,var(--paper) 100%)}
.hero-top{display:grid;grid-template-columns:minmax(0,1.05fr) minmax(0,.95fr);
 gap:40px;align-items:center}
.hero-copy h1{max-width:14ch}
.hero-copy .lede{margin:14px 0 20px;max-width:46ch}
.hero-cta{display:flex;gap:10px;flex-wrap:wrap;margin:0}
.hero-shots{display:grid;grid-template-columns:repeat(4,1fr);gap:10px}
.hero-shot{display:flex;flex-direction:column;align-items:center;text-decoration:none;
 background:var(--paper);border:1px solid var(--rule);border-radius:var(--r);
 padding:12px 8px 11px;transition:border-color .15s,transform .15s,box-shadow .15s}
.hero-shot:hover{border-color:var(--signal-ink);transform:translateY(-2px);
 box-shadow:0 8px 20px #0613481a}
.hero-shot img{height:104px;width:auto;object-fit:contain}
.hero-shot b{font:700 12.5px/1.25 var(--ff);color:var(--ink);text-align:center;margin:8px 0 2px}
.hero-shot span{font:700 12.5px var(--fm);color:var(--signal-ink)}
.trust{list-style:none;display:grid;grid-template-columns:repeat(auto-fit,minmax(170px,1fr));
 gap:14px 26px;margin:26px 0 0;padding:22px 0 0;border-top:1px solid var(--rule)}
.trust li{font-size:13px;color:var(--ink-3);line-height:1.45}
.trust b{display:block;font:800 16px var(--ff);color:var(--ink);letter-spacing:-.02em;
 margin:0 0 2px}
@media(max-width:900px){
  .hero-top{grid-template-columns:1fr;gap:26px}
  .hero-copy h1,.hero-copy .lede{max-width:none}
  .hero-shots{grid-template-columns:repeat(4,1fr)}
  .hero-shot img{height:78px}
}
@media(max-width:560px){
  .hero-shots{grid-template-columns:repeat(2,1fr)}
  .hero-shot img{height:96px}
}

/* ---------- product cards: the shop front ---------- */
.shelf{margin:0 0 38px}
.shelf-h{display:flex;align-items:baseline;justify-content:space-between;gap:16px;
 border-bottom:1px solid var(--rule);padding:0 0 8px;margin:0 0 6px}
.shelf-all{font:600 14px var(--ff);text-decoration:none;white-space:nowrap}
.shelf-all:hover{text-decoration:underline}
.shelf-b{font-size:14px;color:var(--ink-3);margin:0 0 14px;max-width:70ch}
.cards{display:grid;grid-template-columns:repeat(auto-fill,minmax(176px,1fr));gap:14px;margin:0 0 6px}
.card{display:flex;flex-direction:column;border:1px solid var(--rule);border-radius:var(--r);
 background:var(--paper);text-decoration:none;overflow:hidden;
 transition:border-color .15s,transform .15s,box-shadow .15s}
.card:hover{border-color:var(--signal-ink);transform:translateY(-2px);
 box-shadow:0 6px 18px #0613480f}
.card-img{display:block;background:var(--paper-2);padding:12px;text-align:center}
.card-img img{margin:0 auto;height:150px;width:auto;object-fit:contain}
.card-b{display:flex;flex-direction:column;gap:3px;padding:11px 13px 13px}
.card b{font:700 15px/1.3 var(--ff);color:var(--ink)}
.card-s{font-size:12.5px;color:var(--ink-3);line-height:1.4}
.card-p{margin-top:5px;font:700 15px var(--fm);color:var(--signal-ink);
 font-variant-numeric:tabular-nums}
.card-p.pend{font:600 13px var(--ff);color:var(--warn)}
@media(max-width:560px){
 .cards{grid-template-columns:repeat(auto-fill,minmax(145px,1fr));gap:10px}
 .card-img img{height:118px}
}
.home-note{margin-top:34px;padding-top:26px;border-top:1px solid var(--rule)}

/* ---------- card: a container with its own buy button ---------- */
.card{display:flex;flex-direction:column}
.card-link{display:flex;flex-direction:column;flex:1 1 auto;text-decoration:none}
.card-add{margin:0 11px 11px;border:1px solid var(--signal-ink);background:var(--signal-ink);
 color:#fff;border-radius:7px;padding:8px 10px;font:650 13px var(--ff);cursor:pointer;
 text-align:center;text-decoration:none;display:block;
 font-variant-numeric:tabular-nums;transition:background .15s}
.card-add:hover{background:var(--signal-deep);border-color:var(--signal-deep);color:#fff}
.card-add.ghost{background:transparent;color:var(--signal-ink)}
.card-add.is-added{background:var(--ok);border-color:var(--ok)}

.card-buy{display:flex;flex-direction:column;gap:7px;padding:0 11px 12px;margin-top:auto}
.card-pick{width:100%;max-width:none;padding:7px 9px;font-size:13.5px;
 flex:0 0 auto;height:auto;text-overflow:ellipsis}
.card-buy .card-p{margin:0;font-size:17px}
.card-buy .card-s{font-size:12.5px;color:var(--ink-3)}
.card-add{margin:0}
.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;
 clip:rect(0,0,0,0);white-space:nowrap;border:0}

/* ---------- reassurance at the button ---------- */
.assure{list-style:none;display:grid;grid-template-columns:repeat(auto-fit,minmax(166px,1fr));
 gap:9px 18px;margin:14px 0 0;padding:14px 0 0;border-top:1px solid var(--rule)}
.assure li{font-size:12.5px;color:var(--ink-3);line-height:1.45}
.assure b{display:block;font:650 13.5px var(--ff);color:var(--ink)}

/* a non-link counter in the shelf header */
.shelf-h span.shelf-all{color:var(--ink-3);font-weight:600}

/* ---------- the standards grid on the home page ---------- */
.std-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(248px,1fr));gap:16px}
.std{border:1px solid var(--rule);border-radius:var(--r);padding:16px 18px;background:var(--paper)}
.std h3{font:700 15.5px var(--ff);color:var(--ink);margin:0 0 6px}
.std p{margin:0;font-size:14px;color:var(--ink-2);line-height:1.55}
/* Two columns on a wide screen. A 72ch block on an 1180px page is a ribbon down the left. */
.home-intro{margin:0 0 38px;max-width:none}
.home-intro h2{margin-top:0;column-span:all}
.home-intro p{margin:0 0 14px}
@media(min-width:1000px){
  .home-intro{columns:2;column-gap:46px}
  .home-intro h2{columns:1}
}

/* ---------- on this page ---------- */
.toc{border:1px solid var(--rule);border-radius:var(--r);background:var(--paper-2);
 padding:14px 18px;margin:22px 0 26px;max-width:62ch}
.toc b{display:block;font:650 12.5px var(--ff);letter-spacing:.06em;text-transform:uppercase;
 color:var(--ink-3);margin:0 0 7px}
.toc ol{margin:0;padding-left:20px;columns:2;column-gap:28px}
.toc li{margin:3px 0;font-size:14px;break-inside:avoid}
@media(max-width:620px){.toc ol{columns:1}}
.refs{margin:0 0 12px;padding-left:22px;font-size:14.5px}
.refs li{margin:7px 0;line-height:1.5}

.lead-in{max-width:none;margin:4px 0 30px;padding:18px 20px;border:1px solid var(--rule);
 border-left:3px solid var(--signal);border-radius:0 var(--r) var(--r) 0;background:var(--paper-2)}
.lead-in p{margin:0 0 10px;max-width:78ch}
.lead-in p:last-child{margin:0}

/* ---------- the reading, below the shopping ---------- */
.about{margin-top:38px;padding-top:4px;border-top:1px solid var(--rule)}
.about-h{margin-top:22px!important}

/* ---------- family + listing grids ---------- */
.fam-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(258px,1fr));gap:12px;margin:0 0 26px}
.fam-card{display:block;border:1px solid var(--rule);border-radius:var(--r);padding:16px 17px;
  text-decoration:none;background:var(--paper);transition:border-color .15s,transform .15s}
.fam-card:hover{border-color:var(--signal-ink);transform:translateY(-1px)}
.fam-card strong{display:block;font:700 16px var(--ff);color:var(--ink);margin:0 0 4px}
.fam-card span{display:block;font-size:13.5px;color:var(--ink-3);line-height:1.5}
.fam-card em{display:block;font:600 12px var(--fm);color:var(--signal-ink);font-style:normal;margin-top:8px}

.rows{border:1px solid var(--rule);border-radius:var(--r);overflow:hidden}
.row{display:grid;grid-template-columns:62px minmax(0,1fr) auto;gap:14px;align-items:center;
  padding:11px 15px;border-bottom:1px solid var(--rule);text-decoration:none;background:var(--paper)}
.row:last-child{border-bottom:0}
.row:hover{background:var(--signal-wash)}
.row img{width:62px;height:62px;object-fit:contain}
.row b{display:block;font:700 15.5px var(--ff);color:var(--ink)}
.row span{display:block;font-size:13px;color:var(--ink-3);margin-top:1px}
.row .num{font:700 15.5px var(--fm);color:var(--ink);font-variant-numeric:tabular-nums}

/* ---------- notices ---------- */
.ruo{border:1px solid var(--rule-2);border-left:3px solid var(--signal-ink);
  background:var(--paper-2);border-radius:0 var(--r) var(--r) 0;
  padding:13px 16px;margin:24px 0;font-size:14px;color:var(--ink-2);max-width:72ch}
.ruo strong{color:var(--ink)}

/* ---------- footer ---------- */
/* Brand navy, to close the page and bookend the announcement bar at the top. Light-on-dark
   values are set explicitly - the site's --ink-2 and --signal-ink are tuned for dark type on
   white and are unreadable on navy. */
.ftr{background:var(--ink);color:#c3d0e8;padding:44px 0 30px;margin-top:60px}
.ftr-cols{display:grid;grid-template-columns:repeat(auto-fit,minmax(176px,1fr));gap:30px}
.ftr h4{font:650 12px var(--ff);letter-spacing:.09em;text-transform:uppercase;
 color:#7e93bd;margin:0 0 11px}
.ftr ul{list-style:none;margin:0;padding:0}
.ftr li{margin:0 0 7px}
.ftr a{color:#dbe4f4;text-decoration:none;font-size:14.5px}
.ftr a:hover{color:#ffffff;text-decoration:underline}
.ftr-end{border-top:1px solid #1c3160;margin-top:32px;padding-top:18px;
 font-size:12.5px;color:#7e93bd;display:flex;justify-content:space-between;gap:14px;flex-wrap:wrap}

/* ---------- buy box, basket, checkout ---------- */
.buy{display:flex;align-items:center;gap:10px;margin:0 0 8px;flex-wrap:wrap}
.buy label{font:600 14px var(--ff);color:var(--ink-3)}
.qty{width:74px;border:1px solid var(--rule-2);border-radius:8px;padding:8px 10px;
 font:600 15px var(--fm);color:var(--ink);background:var(--paper);text-align:center}
/* No flex on .pick itself. It is used inside the product page's ROW-direction buy bar AND
   inside a card's COLUMN-direction buy block; a flex-basis set here applied down the column
   and made the card dropdown 180px TALL, crushing the image. Row behaviour belongs to the row
   container. (And no backticks in this comment - the whole stylesheet is a template literal.) */
.pick{border:1px solid var(--rule-2);border-radius:8px;padding:8px 11px;
 font:600 15px var(--ff);color:var(--ink);background:var(--paper);max-width:280px}
.buy .pick{flex:1 1 180px}
.pick:focus{border-color:var(--signal-ink);outline:none;box-shadow:0 0 0 3px var(--signal-wash)}
.btn.is-added{background:var(--ok);border-color:var(--ok)}
.linkish{background:none;border:0;padding:0;color:var(--signal-ink);
 font:500 14px var(--ff);cursor:pointer;text-decoration:underline;text-underline-offset:2px}
.linkish:hover{color:var(--signal-deep)}
.bk-item a{display:flex;align-items:center;gap:11px;text-decoration:none}
.bk-item img{width:46px;height:46px;object-fit:contain;background:var(--paper-2);
 border:1px solid var(--rule);border-radius:7px;padding:3px;flex:0 0 auto}
.bk-item span{font:600 15px var(--ff);color:var(--ink)}
.bk-item a:hover span{color:var(--signal-ink)}
.basket-table td:last-child,.basket-table th:last-child{text-align:right;width:1%}
.totals{max-width:330px;margin-left:auto}
.totals td{text-align:right}
.co-grid{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,330px);gap:34px;align-items:start}
/* ---- the payment method chooser on /checkout/ ----
   One method renders as a confirmed line (.pay-only) rather than a question: the customer
   must always be told how they are paying, and a lone radio asking "how would you like to
   pay?" with one answer reads as a fault. */
.pay-pick{display:grid;gap:8px;margin:0 0 6px}
.pay-o{display:flex;gap:11px;align-items:flex-start;padding:12px 13px;cursor:pointer;
  border:1px solid var(--rule);border-radius:var(--r);background:var(--paper)}
.pay-o:hover{border-color:var(--ink-3)}
.pay-o input{margin:2px 0 0;flex:0 0 auto}
.pay-o span{display:block}
.pay-o b{display:block;font-size:15px}
.pay-o small{display:block;color:var(--ink-2);font-size:13px;margin-top:2px;line-height:1.45}
.pay-o:has(input:checked){border-color:var(--signal);box-shadow:inset 0 0 0 1px var(--signal);background:var(--signal-wash)}
.pay-only{cursor:default}
.pay-only input{position:absolute;opacity:0;pointer-events:none}
/* ---- pay before ordering: the details, and the confirmation upload ----
   The upload is the one thing standing between the customer and Place order, so it is sized
   as a step rather than as a footnote. */
.bank{width:100%;border-collapse:collapse;margin:0 0 8px;font-size:14px}
.bank caption{text-align:left;font-weight:700;padding:0 0 6px;font-size:15px}
/* NO nowrap HERE. The fixed labels are short ("Account number", "BIC / SWIFT"), but a crypto
   network name is typed by the owner and can be any length -- "USDT (TRC-20) — Tron network"
   would then push the table wider than the phone and give the whole page a sideways scrollbar.
   That exact rule cost 57 pages a horizontal scroll once already. */
.bank th{text-align:left;font-weight:600;color:var(--ink-2);padding:6px 10px 6px 0;
  vertical-align:top;min-width:7.5em}
.bank td{padding:6px 0;word-break:break-all}
.bank code{font:13px/1.5 var(--fm);background:var(--paper-2);padding:2px 6px;border-radius:5px}
/* The label is the literal word "Copy", so it cannot wrap whatever happens -- but the audit
   cannot know that from the selector, and a rule that needs a human to vouch for it is the
   rule that gets copied somewhere it does not hold. Width instead of nowrap. */
.bank .copy{margin-left:7px;font-size:12px;padding:3px 9px;border:1px solid var(--rule);
  border-radius:6px;background:var(--paper);cursor:pointer}
.bank .copy:hover{border-color:var(--signal)}
.bank-note{font-size:13px;color:var(--ink-2);margin:0 0 4px}
.payfirst-p{margin-bottom:6px}
.proof{border-top:1px solid var(--rule);margin-top:14px;padding-top:14px}
.proof-h{font-size:17px;font-weight:800;margin:0 0 5px}
.proof-h .req{color:var(--stop,#b3261e)}
.proof-lead{font-size:15px;font-weight:600;margin:0 0 10px}
.proof input[type=file]{font-size:14px;width:100%}
.proof-msg{font-size:13px;margin-top:9px;font-weight:600}
.co-sum{position:sticky;top:96px;border:1px solid var(--rule);border-radius:var(--r);
 background:var(--paper-2);padding:18px}
.co-sum h2{font-size:17px;margin:0 0 10px}
.co-sum .sizes{margin:0;background:var(--paper)}
.co-sum td{text-align:right}
@media(max-width:860px){.co-grid{grid-template-columns:1fr;gap:22px}.co-sum{position:static}}
.form-grid{display:grid;grid-template-columns:1fr 1fr;gap:12px;margin:0 0 6px}
.form-grid .fg-2{grid-column:1/-1}
.form-grid label,#coForm>label{display:flex;flex-direction:column;gap:4px}
.form-grid span,#coForm>label span{font:600 13.5px var(--ff);color:var(--ink-2)}
.form-grid input,#coForm textarea{border:1px solid var(--rule-2);border-radius:8px;
 padding:9px 11px;font:inherit;font-size:15px;color:var(--ink);background:var(--paper);width:100%}
#coForm textarea{resize:vertical;font-family:var(--ff)}
.form-grid input:focus,#coForm textarea:focus{border-color:var(--signal-ink);outline:none;
 box-shadow:0 0 0 3px var(--signal-wash)}
@media(max-width:560px){.form-grid{grid-template-columns:1fr}}
.bar-note,.bar-stop{border-radius:8px;padding:9px 13px;font:600 13.5px var(--ff);margin:0 0 10px}
.bar-note{border:1px solid var(--rule-2);background:var(--paper-2);color:var(--ink-2)}
.bar-stop{border:1px solid var(--stop);background:#a3222c0d;color:var(--stop)}
.co-err{border:1px solid var(--stop);background:#a3222c0d;color:var(--stop);
 border-radius:8px;padding:10px 13px;font:600 14px var(--ff);margin:0 0 12px}
/* One search box at a time: the header has it above 860px, the menu below. */
.srch-rail{display:none}
.srch-page{max-width:520px;margin:0 0 20px}
.srch-page input{border-right:0}
.rail.is-open .rail-in{flex-wrap:wrap;overflow:visible}

/* ---------------------------------------------------------------- the Compounds panel
 * The bar is one row of six. Everything that used to make it a second row lives in here, in
 * columns, so the whole catalogue is one hover away instead of seven. */
.rail-item.has-mega{position:static}
/* "Compounds" is a button, not a link, because it opens a panel instead of going
   somewhere. Everything the bar does to .rail a has to be repeated for it, or it
   sits in the row at the browser default size. */
button.rail-top{flex:0 0 auto;padding:11px 14px;font:600 14.5px var(--ff);
 color:var(--ink-2);background:none;border:0;border-bottom:2px solid transparent;
 white-space:nowrap;cursor:pointer;line-height:inherit}
button.rail-top:hover{color:var(--signal-ink);border-bottom-color:var(--rule-2)}
button.rail-top[aria-current]{color:var(--ink);border-bottom-color:var(--signal)}
button.rail-top:focus-visible{outline:2px solid var(--signal);outline-offset:-2px}
.mega{position:absolute;left:0;right:0;top:100%;background:var(--paper);
 border-top:1px solid var(--rule);box-shadow:0 18px 40px #0613481a;
 opacity:0;visibility:hidden;transform:translateY(-6px);
 transition:opacity .13s ease,transform .13s ease,visibility .13s;z-index:40}
.has-mega:hover .mega,.has-mega:focus-within .mega,.has-mega.is-open .mega{
 opacity:1;visibility:visible;transform:none}
.mega-in{max-width:var(--maxw);margin:0 auto;padding:22px var(--gut) 26px;
 display:grid;grid-template-columns:repeat(4,1fr);gap:20px 28px}
.mega-col{display:flex;flex-direction:column;gap:2px;min-width:0}
.mega-col a{font:500 13.5px var(--ff);color:var(--ink-2);text-decoration:none;
 padding:4px 0;border-radius:4px}
.mega-col a:hover{color:var(--signal-ink);text-decoration:underline}
.mega-h{font:750 13px var(--ff)!important;color:var(--ink)!important;
 text-transform:uppercase;letter-spacing:.055em;padding-bottom:7px!important;
 margin-bottom:5px;border-bottom:1px solid var(--rule)}
.mega-end{background:var(--paper-2);border-radius:var(--r);padding:12px 14px;margin:-12px 0 0}
@media(max-width:980px){.mega-in{grid-template-columns:repeat(2,1fr)}}


/* ---------------------------------------------------------------- reconstitution calculator
 * Appears twice: standing alone on /peptide-calculator/, and inside the prose column on every
 * product page that sells a vial. It has to read as a tool in both, so it gets a tinted panel
 * rather than the plain prose background, and the four outputs are a self-sizing grid that
 * collapses to two columns on a phone instead of four unreadable ones. */
.calc{border:1px solid var(--rule-2);border-radius:var(--r);background:var(--paper-2);
 padding:16px;margin:0 0 22px}
.calc-in{display:grid;grid-template-columns:repeat(3,1fr);gap:12px;margin:0 0 14px}
.calc-in label{display:flex;flex-direction:column;gap:5px}
.calc-in span{font:650 12.5px var(--ff);color:var(--ink-2);letter-spacing:.01em}
.calc-in input,.calc-in select{border:1px solid var(--rule-2);border-radius:8px;padding:9px 11px;
 font:700 16px var(--fm);color:var(--ink);background:var(--paper);width:100%;
 font-variant-numeric:tabular-nums}
.calc-in input:focus,.calc-in select:focus{border-color:var(--signal-ink);outline:none;
 box-shadow:0 0 0 3px var(--signal-wash)}
.calc-out{display:grid;grid-template-columns:repeat(4,1fr);gap:10px}
.calc-fig{background:var(--paper);border:1px solid var(--rule);border-radius:8px;padding:11px 12px}
.calc-fig b{display:block;font:700 19px var(--fm);color:var(--signal-deep);
 font-variant-numeric:tabular-nums;line-height:1.2}
.calc-fig span{display:block;margin-top:3px;font:600 11.5px var(--ff);color:var(--ink-3)}
.calc-note{margin:12px 0 0;font:500 12.5px var(--ff);color:var(--ink-3)}
@media(max-width:720px){
 .calc-in{grid-template-columns:1fr 1fr}
 .calc-in label:first-child{grid-column:1/-1}
 .calc-out{grid-template-columns:1fr 1fr}
}

/* a plain two-column link list, used for the compound index on the calculator page */
.col-list{list-style:none;padding:0;margin:0 0 20px;columns:2;column-gap:28px}
.col-list li{break-inside:avoid;padding:6px 0;border-bottom:1px solid var(--rule)}
.col-list .fine{margin-left:6px}
@media(max-width:620px){.col-list{columns:1}}

/* numbered steps that need a little more air than a default list gives them */
.bul{padding-left:20px;margin:0 0 18px}
.bul li{margin:0 0 9px}

@media(prefers-reduced-motion:reduce){*{transition:none!important;animation:none!important}}