/* ==========================================================================
   HERBARIUM · shared styles for every page
   Layout concept: the site is a herbarium cabinet. Each page is one folio.
   The analyser presses every plant in a recipe onto a mount-board sheet as a
   drawn specimen with a typed collector's label; the decoder annotates a pack
   with typed slips; the blog sign-up is a small sheet of its own; method and
   CV are quiet catalogue apparatus.
   Palette: cool archival mount board (grey-green, never cream), iron-gall
   blue-black ink, pressed-plant olive greens, faded cyanotype (Prussian) blue
   for links, stamps and focus. Dark = specimen cabinet: green-black interior,
   slate sheets, bone ink, specimens glowing like a cyanotype negative.
   Colour, as on a hand-coloured botanical plate: each specimen carries its own
   softened washes (a tomato red, a carrot orange, oats gold; site.js), laid a
   touch off the line work. The rest of the site borrows plate colours so its
   parts stay distinct: a leaf green for the plate analyser, an ochre for the
   label decoder, a madder plum for the blog, one colour per fibre type, and a
   colour per grade.
   Type: EB Garamond for all reading text, controls and navigation (small caps
   for labels on buttons and nav), true italics for binomials. Courier Prime
   only for small typed specimen tags, never for running text.
   The EB Garamond file Google Fonts serves has no small-cap or old-style
   figure tables: browsers synthesise the small caps (scaled capitals), so
   every small-cap label is set at weight 500 to keep its stems as dark as
   the lower case beside it, and its figures are lining and tabular. The
   figure settings below still apply to the Georgia fallback, which has
   old-style figures by default.
   ========================================================================== */
/* Georgia scaled to EB Garamond's width, so text barely moves when the web font arrives */
@font-face{font-family:"EB Garamond fallback";src:local("Georgia");size-adjust:86.2%}
:root{
  /* paper */
  --page:#E6EBE3;          /* folio board, cool grey-green */
  --sheet:#F7F9F4;         /* archival mount sheet */
  --sheet-2:#EEF2EA;       /* recessed panels on a sheet */
  --sheet-edge:#CDD5C7;
  --rule:#B9C3B3;
  --rule-soft:#D7DED1;
  --field-edge:#7A8475;    /* input outlines, 3:1 on sheet and page */
  /* ink */
  --ink:#1B2230;           /* iron-gall blue-black */
  --ink-2:#434D5D;
  --ink-3:#59626F;
  /* specimens */
  --plant-ink:#3B5A2E;
  --plant-wash:#C5D4AE;
  --dry-ink:#6B5333;
  --fruit-wash:#DCCDB0;
  --tape:#E4E2D2;
  --thread:#6E7F5C;
  /* accents */
  --cyan:#1E4E7C;          /* faded cyanotype / Prussian blue */
  --cyan-ink:#173F66;
  --cyan-wash:#DAE5EE;
  --madder:#8D2B3A;        /* caution only, always paired with a shape and a word */
  --madder-wash:#F2E0E1;
  --focus:#1E4E7C;
  /* plate colours, borrowed from the specimens so each part of the site keeps its own: the plate analyser a leaf green,
     the label decoder an ochre, the blog a madder plum. Text-safe (4.5:1) on the board and on sheets */
  --tone-an:#406637;
  --tone-de:#84591A;
  --tone-bl:#7F3A5D;
  /* one related colour per fibre type (and for polyphenols and live cultures), text-safe like the plate colours */
  --ft-inulin:#5F5291; --ft-pectin:#97374F; --ft-gos:#9F5013; --ft-rs:#80610D; --ft-ax:#5F6A29;
  --ft-bg:#2E6E58; --ft-ins:#546577; --ft-poly:#783F77; --ft-live:#266B76;
  /* grade letters, from a leaf green for A to a madder for E */
  --g-a:#2C6A31; --g-b:#5E6B1E; --g-c:#855E02; --g-d:#9B4E1A; --g-e:#963538;
  /* solid buttons: iron-gall ink on mount board */
  --btn:#1B2230;
  --btn-ink:#F7F9F4;
  --btn-hover:#434D5D;
  --shadow:0 1px 0 rgba(27,34,48,.05), 0 18px 40px -28px rgba(27,34,48,.45);
  --pill-shadow:0 6px 18px -10px rgba(27,34,48,.45);
  /* type */
  --font-text:"EB Garamond", "EB Garamond fallback", Garamond, "Iowan Old Style", "Palatino Linotype", Palatino, "Book Antiqua", Georgia, serif;
  --font-tag:"Courier Prime", "Courier New", Courier, ui-monospace, "SFMono-Regular", Menlo, monospace;
  /* typed tags: three sizes (nothing smaller than --tag-xs, about 10.5px) and two trackings */
  --tag-xs:.66rem;
  --tag-s:.7rem;
  --tag-m:.76rem;
  --track-caps:.12em;      /* upper-case tags */
  --track-mixed:.03em;     /* mixed-case tags, figures and names */
  /* scale */
  --s1:4px; --s2:8px; --s3:12px; --s4:16px; --s5:24px; --s6:32px; --s7:48px; --s8:72px; --s9:112px;
  --measure:64ch;
  --wrap:1360px;
  --head-h:65px;           /* sticky masthead height; site.js keeps it measured */
  color-scheme:light;
}
@media (prefers-color-scheme: dark){
  :root:not([data-theme="light"]){
    --page:#0D110F; --sheet:#151B18; --sheet-2:#1B2320; --sheet-edge:#28322C;
    --rule:#3A463F; --rule-soft:#252E29; --field-edge:#6A7568;
    --ink:#E4E8DF; --ink-2:#B7BFB4; --ink-3:#9AA398;
    --plant-ink:#B2CB96; --plant-wash:#2D3D2A; --dry-ink:#D3C096; --fruit-wash:#433A2E;
    --tape:#56625A; --thread:#93A97E;
    --cyan:#93BFE4; --cyan-ink:#B9D5EE; --cyan-wash:#192937;
    --madder:#F0A3AD; --madder-wash:#3A1F25; --focus:#93BFE4;
    --tone-an:#ABD1A3; --tone-de:#EFC189; --tone-bl:#E8B2CA;
    --ft-inulin:#BEB6EB; --ft-pectin:#ECA9B4; --ft-gos:#EFB694; --ft-rs:#E1C487; --ft-ax:#C2CF94;
    --ft-bg:#9BD2BC; --ft-ins:#B0C0D1; --ft-poly:#D9ADD6; --ft-live:#93CCD6;
    --g-a:#9BD69C; --g-b:#C5D38F; --g-c:#EDC889; --g-d:#F4B390; --g-e:#F2A7A4;
    --btn:#B6C3AC; --btn-ink:#0F1411; --btn-hover:#A2B198;
    --shadow:0 1px 0 rgba(0,0,0,.5), 0 22px 48px -26px rgba(0,0,0,.9);
    --pill-shadow:0 6px 18px -10px rgba(0,0,0,.8);
    color-scheme:dark;
  }
  /* specimens on a dark sheet take each plant's second set of washes */
  :root:not([data-theme="light"]) .sp{--c-lf:var(--lf-d,var(--plant-wash));--c-fr:var(--fr-d,var(--fruit-wash));--c-rt:var(--rt-d,var(--fruit-wash));--c-hd:var(--hd-d,var(--c-lf));--c-pt:var(--pt-d,var(--c-lf));--c-sk:var(--sk-d,var(--c-lf));--c-st:var(--st-d,var(--plant-ink));--c-rl:var(--rl-d,var(--dry-ink));--c-dt:var(--dt-d,var(--dry-ink));--c-gd:var(--gd-d,var(--plant-ink))}
}
:root[data-theme="dark"]{
  --page:#0D110F; --sheet:#151B18; --sheet-2:#1B2320; --sheet-edge:#28322C;
  --rule:#3A463F; --rule-soft:#252E29; --field-edge:#6A7568;
  --ink:#E4E8DF; --ink-2:#B7BFB4; --ink-3:#9AA398;
  --plant-ink:#B2CB96; --plant-wash:#2D3D2A; --dry-ink:#D3C096; --fruit-wash:#433A2E;
  --tape:#56625A; --thread:#93A97E;
  --cyan:#93BFE4; --cyan-ink:#B9D5EE; --cyan-wash:#192937;
  --madder:#F0A3AD; --madder-wash:#3A1F25; --focus:#93BFE4;
  --tone-an:#ABD1A3; --tone-de:#EFC189; --tone-bl:#E8B2CA;
  --ft-inulin:#BEB6EB; --ft-pectin:#ECA9B4; --ft-gos:#EFB694; --ft-rs:#E1C487; --ft-ax:#C2CF94;
  --ft-bg:#9BD2BC; --ft-ins:#B0C0D1; --ft-poly:#D9ADD6; --ft-live:#93CCD6;
  --g-a:#9BD69C; --g-b:#C5D38F; --g-c:#EDC889; --g-d:#F4B390; --g-e:#F2A7A4;
  --btn:#B6C3AC; --btn-ink:#0F1411; --btn-hover:#A2B198;
  --shadow:0 1px 0 rgba(0,0,0,.5), 0 22px 48px -26px rgba(0,0,0,.9);
  --pill-shadow:0 6px 18px -10px rgba(0,0,0,.8);
  color-scheme:dark;
}
:root[data-theme="dark"] .sp{--c-lf:var(--lf-d,var(--plant-wash));--c-fr:var(--fr-d,var(--fruit-wash));--c-rt:var(--rt-d,var(--fruit-wash));--c-hd:var(--hd-d,var(--c-lf));--c-pt:var(--pt-d,var(--c-lf));--c-sk:var(--sk-d,var(--c-lf));--c-st:var(--st-d,var(--plant-ink));--c-rl:var(--rl-d,var(--dry-ink));--c-dt:var(--dt-d,var(--dry-ink));--c-gd:var(--gd-d,var(--plant-ink))}

/* where each colour goes: the page's own plate colour (body[data-plate], the sign-up sheet), each drawer label's, and
   each nav link's; fibre types by key (data-ft on names, data-in on the key's rows and threads); sub-score bars by part;
   grade letters by grade */
[data-plate="analyser"]{--plate:var(--tone-an)}
[data-plate="decoder"]{--plate:var(--tone-de)}
.subscribe{--plate:var(--tone-bl)}
.entry[href$="analyser.html"]{--plate:var(--tone-an)}
.entry[href$="decoder.html"]{--plate:var(--tone-de)}
.entry[href="#subscribe"]{--plate:var(--tone-bl)}
.nav a[href$="analyser.html"]{--tone:var(--tone-an)}
.nav a[href$="decoder.html"]{--tone:var(--tone-de)}
.nav a.ext{--tone:var(--tone-bl)}
[data-ft="inulin"],[data-in="inulin"]{--ftc:var(--ft-inulin)}
[data-ft="pectin"],[data-in="pectin"]{--ftc:var(--ft-pectin)}
[data-ft="gos"],[data-in="gos"]{--ftc:var(--ft-gos)}
[data-ft="resistant_starch"],[data-in="resistant_starch"]{--ftc:var(--ft-rs)}
[data-ft="arabinoxylan"],[data-in="arabinoxylan"]{--ftc:var(--ft-ax)}
[data-ft="beta_glucan"],[data-in="beta_glucan"]{--ftc:var(--ft-bg)}
[data-ft="insoluble"],[data-in="insoluble"]{--ftc:var(--ft-ins)}
[data-in="polyphenols"]{--ftc:var(--ft-poly)}
[data-in="live"]{--ftc:var(--ft-live)}
[data-ft]{color:var(--ftc,inherit)}
[data-part="fibre"]{--bar:var(--ft-rs)}
[data-part="diversity"]{--bar:var(--tone-an)}
[data-part="fibreVariety"]{--bar:var(--ft-inulin)}
[data-part="polyphenols"]{--bar:var(--ft-poly)}
[data-part="fermented"]{--bar:var(--ft-live)}
[data-g="A"]{color:var(--g-a)}
[data-g="B"]{color:var(--g-b)}
[data-g="C"]{color:var(--g-c)}
[data-g="D"]{color:var(--g-d)}
[data-g="E"]{color:var(--g-e)}

/* ---------- base ---------- */
*,*::before,*::after{box-sizing:border-box}
html{-webkit-text-size-adjust:100%;text-size-adjust:100%;scroll-behavior:smooth;scroll-padding-top:calc(var(--head-h) + 23px);background:var(--page)}
body{margin:0;background:var(--page);color:var(--ink);font-family:var(--font-text);font-size:clamp(1.0625rem,1rem + .25vw,1.21875rem);line-height:1.55;font-variant-numeric:oldstyle-nums proportional-nums;-webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility;min-height:100vh;min-height:100svh;display:flex;flex-direction:column}
main{flex:1 0 auto}
main:focus{outline:none}
[hidden]{display:none!important}
img,svg{display:block;max-width:100%}
a{color:var(--cyan);text-decoration-thickness:1px;text-underline-offset:.18em}
a:hover{color:var(--cyan-ink);text-decoration-thickness:2px}
:focus-visible{outline:2px solid var(--focus);outline-offset:3px}
::selection{background:var(--cyan-wash);color:var(--ink)}
h1,h2,h3,h4{font-weight:500;line-height:1.1;margin:0;letter-spacing:-.005em;text-wrap:balance}
p{margin:0 0 var(--s4)}
p,li,dd{text-wrap:pretty}
p:last-child{margin-bottom:0}
ul,ol{margin:0;padding:0}
i,em,.bin{font-style:italic}
button,input,textarea,select{font:inherit;color:inherit}
.visually-hidden{position:absolute!important;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}
/* keeps a short phrase whole, such as "E-number" or "packaged-food", so it never breaks at its hyphen */
.nw{white-space:nowrap}
.skip{position:absolute;left:var(--s4);top:-60px;z-index:50;background:var(--ink);color:var(--sheet);padding:var(--s2) var(--s4);font-size:1rem}
.skip:focus{top:var(--s3);color:var(--sheet)}
.wrap{width:100%;max-width:calc(var(--wrap) + 96px);margin:0 auto;padding-left:max(16px,env(safe-area-inset-left,0px));padding-right:max(16px,env(safe-area-inset-right,0px))}
@media (min-width:720px){.wrap{padding-left:max(32px,env(safe-area-inset-left,0px));padding-right:max(32px,env(safe-area-inset-right,0px))}}
@media (min-width:1200px){.wrap{padding-left:max(48px,env(safe-area-inset-left,0px));padding-right:max(48px,env(safe-area-inset-right,0px))}}

/* typed label voice (small tags only) */
.kicker{font-family:var(--font-tag);font-variant-numeric:lining-nums tabular-nums;font-size:var(--tag-m);text-transform:uppercase;letter-spacing:var(--track-caps);color:var(--plate,var(--ink-2));margin:0 0 var(--s3);display:block}
.lede{font-size:1.12em;color:var(--ink-2);max-width:var(--measure)}
.muted{color:var(--ink-3)}
.small{font-size:.92rem}

/* ---------- header ---------- */
.masthead{position:sticky;top:0;z-index:20;background:var(--page);border-bottom:1px solid var(--rule)}
.masthead .wrap{display:flex;align-items:center;gap:var(--s2) var(--s5);min-height:64px;flex-wrap:wrap;padding-top:var(--s2);padding-bottom:var(--s2)}
/* top:-1px is an optical nudge, not a slip: it puts the name's lower-case letters on the same top line as the small capitals of the nav and the theme button */
.wordmark{display:flex;align-items:baseline;gap:var(--s3);text-decoration:none;color:var(--ink);min-width:0;margin-right:auto;position:relative;top:-1px}
.wordmark:hover{color:var(--ink)}
.wordmark b{font-weight:500;font-size:1.32rem;letter-spacing:-.005em;white-space:nowrap}
.wordmark [data-site="domain"]{font-style:italic;font-size:1rem;color:var(--ink-3);white-space:nowrap}
.nav{display:flex;gap:var(--s5);align-items:center;min-width:0}
.nav a{font-size:1.06rem;font-variant-caps:all-small-caps;font-weight:500;letter-spacing:.09em;color:var(--ink-2);text-decoration:none;padding:var(--s2) 0;border-bottom:1px solid transparent;white-space:nowrap;display:inline-flex;align-items:center;gap:3px}
.ext-mark{width:.62em;height:.62em;flex:0 0 auto;opacity:.8}
.nav a:hover{color:var(--ink);border-bottom-color:var(--tone,var(--ink-3))}
.nav a[aria-current="page"]{color:var(--ink);border-bottom:2px solid var(--tone,var(--cyan));padding-bottom:calc(var(--s2) - 1px)}
.theme-btn{display:inline-flex;align-items:center;gap:var(--s2);background:none;border:1px solid var(--field-edge);border-radius:2px;padding:4px 13px 5px 9px;font-size:1rem;font-variant-caps:all-small-caps;font-weight:500;letter-spacing:.07em;color:var(--ink-2);cursor:pointer;min-height:36px}
.theme-btn:hover{border-color:var(--ink-2);color:var(--ink)}
.theme-btn svg{width:16px;height:16px}
/* the icon follows the setting, as the word does: a half-filled disc for Auto, a sun for Light, a crescent for Dark */
.theme-btn .ti-light,.theme-btn .ti-dark,:root[data-theme="light"] .theme-btn .ti-auto,:root[data-theme="dark"] .theme-btn .ti-auto{display:none}
:root[data-theme="light"] .theme-btn .ti-light,:root[data-theme="dark"] .theme-btn .ti-dark{display:inline}
/* all three labels share one cell, so the pill keeps its width; the head script's data-theme picks the visible one before first paint */
.theme-btn [data-theme-label]{display:inline-grid;justify-items:center;position:relative;top:1px}
.theme-btn [data-theme-label]>span{grid-area:1/1}
.tl-light,.tl-dark,:root[data-theme="light"] .tl-auto,:root[data-theme="dark"] .tl-auto{visibility:hidden}
:root[data-theme="light"] .tl-light,:root[data-theme="dark"] .tl-dark{visibility:visible}
@media (max-width:1159px){.wordmark [data-site="domain"]{display:none}}
@media (max-width:999px){
  .nav{order:3;width:100%;gap:var(--s5);padding-bottom:2px}
}
/* between 720 and 999 the nav wraps under the wordmark, so the sticky header is taller */
@media (min-width:720px) and (max-width:999px){:root{--head-h:106px}}
@media (max-width:719px){
  .masthead{position:static}
  html{scroll-padding-top:16px}
  .masthead .wrap{gap:0 var(--s4);padding-top:var(--s2);padding-bottom:0;min-height:0}
  .wordmark{min-height:44px;align-items:center}
  /* wraps rather than overflows if the links ever outgrow the row (fallback fonts, larger text) */
  .nav{justify-content:space-between;flex-wrap:wrap;gap:0 var(--s2)}
  .nav a{font-size:1.02rem;letter-spacing:.06em;padding:10px 0}
  .nav a[aria-current="page"]{padding-bottom:9px}
  .nav .long{position:absolute!important;width:1px;height:1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap}
}
@media (max-width:359px){.nav a{font-size:.95rem;letter-spacing:.03em}}
/* landscape phones: a sticky header would cover a quarter of the screen */
@media (max-height:520px){
  .masthead{position:static}
  html{scroll-padding-top:16px}
}

/* ---------- page heads and section scaffolding ---------- */
.page-head{padding-top:clamp(28px,4vw,60px);padding-bottom:clamp(20px,3vw,40px)}
.page-head h1{font-size:clamp(2.2rem,1.2rem + 2.8vw,3.6rem);line-height:1.04;letter-spacing:-.012em;max-width:24ch}
.page-head .lede{margin-top:var(--s4);margin-bottom:0}
.sec{padding-top:clamp(48px,7vw,104px)}
.sec-head{display:flex;flex-wrap:wrap;align-items:baseline;gap:var(--s2) var(--s5);margin-bottom:var(--s5);padding-bottom:var(--s3);border-bottom:1px solid var(--rule)}
.sec-head h2{font-size:clamp(1.55rem,1.2rem + 1.1vw,2.1rem)}
.sec-head p{margin:0;color:var(--ink-2);max-width:62ch;flex:1 1 320px;min-width:0}

/* ---------- buttons, chips, fields ---------- */
.btn{display:inline-flex;align-items:center;justify-content:center;gap:var(--s2);border:1px solid var(--btn);background:var(--btn);color:var(--btn-ink);font-size:1.1rem;font-weight:500;font-variant-caps:all-small-caps;letter-spacing:.08em;padding:8px 20px 10px;border-radius:2px;cursor:pointer;text-decoration:none;min-height:44px;text-align:center;line-height:1.2}
/* a solid button takes its page's plate colour on hover */
.btn:hover{background:var(--plate,var(--btn-hover));border-color:var(--plate,var(--btn-hover));color:var(--btn-ink);text-decoration:none}
.btn.ghost{background:transparent;border-color:var(--ink);color:var(--ink)}
.btn.ghost:hover{background:var(--sheet-2);border-color:var(--ink);color:var(--ink)}
.btn[disabled]{opacity:.55;cursor:not-allowed}
.linkish{background:none;border:0;padding:4px 0;font-size:1rem;color:var(--cyan);text-decoration:underline;text-decoration-thickness:1px;text-underline-offset:.2em;cursor:pointer;text-align:left}
.linkish:hover{color:var(--cyan-ink)}
.chips{display:flex;flex-wrap:wrap;gap:6px}
.chip{position:relative;border:1px solid var(--rule);background:var(--sheet);color:var(--ink);font-size:.98rem;padding:5px 12px 6px;border-radius:2px;cursor:pointer;text-align:left;line-height:1.25;min-height:40px}
.chip:hover{border-color:var(--ink-2);color:var(--ink)}
.chip[disabled]{opacity:.55;cursor:not-allowed}
.chip[disabled]:hover{border-color:var(--rule)}
.chip[aria-pressed="true"]{border-color:var(--cyan);background:var(--cyan-wash);color:var(--cyan-ink);box-shadow:inset 0 0 0 1px var(--cyan)}
.chip .k{color:var(--ink-3);margin-right:7px;font-variant-caps:all-small-caps;font-weight:500;letter-spacing:.08em}
.chip[aria-pressed="true"] .k{color:var(--cyan-ink)}
.chip .c{color:var(--ink-3);margin-left:6px;font-variant-numeric:lining-nums}
.field{display:grid;gap:6px;min-width:0}
.field label,.field .label{font-family:var(--font-tag);font-size:var(--tag-s);text-transform:uppercase;letter-spacing:var(--track-caps);color:var(--ink-2)}
.field .hint{font-size:.88rem;color:var(--ink-3)}
/* a field's own error message replaces its hint (aria-describedby already points at it) */
.hint.is-err{color:var(--madder)}
/* ruled like a notebook: one rule per 1.647em line (28px at the default text size). The height is a whole
   number of lines (border, top padding, ten lines), so no line is cut in half by the bottom edge */
textarea.notebook{width:100%;min-height:calc(2px + .235em + 10 * 1.647em);resize:vertical;border:1px solid var(--field-edge);border-radius:2px;background-color:var(--sheet);padding:.235em 14px;font-family:var(--font-text);font-size:1.0625rem;line-height:1.647em;background-image:repeating-linear-gradient(to bottom,transparent 0,transparent calc(1.647em - 1px),var(--rule-soft) calc(1.647em - 1px),var(--rule-soft) 1.647em);background-attachment:local;background-position:0 .235em;color:var(--ink)}
textarea.notebook:focus-visible{outline-offset:1px}
input.num{border:1px solid var(--field-edge);background:var(--sheet);border-radius:2px;padding:8px 12px;font-size:1.0625rem;font-variant-numeric:lining-nums;min-height:44px;width:7em;color:var(--ink)}
input.num[aria-invalid="true"]{border-color:var(--madder);box-shadow:inset 0 0 0 1px var(--madder)}
::placeholder{color:var(--ink-3);opacity:1}
.form-row{display:flex;flex-wrap:wrap;gap:var(--s4);align-items:end}
.status{font-size:.98rem;font-style:italic;color:var(--ink-2);min-height:1.5em;margin:0;line-height:1.4;overflow-wrap:break-word;overflow-wrap:anywhere}
.status b{color:var(--ink);font-weight:500;font-style:normal}

/* tool layout: notebook on the left, output on the right */
.tool-grid{display:grid;gap:var(--s6);grid-template-columns:1fr}
@media (min-width:1080px){.tool-grid{grid-template-columns:minmax(300px,370px) minmax(0,1fr);gap:var(--s7);align-items:start}}
.notes-panel{display:grid;gap:var(--s5);min-width:0;align-content:start}
/* the notebook stays in view beside a long sheet, but only when all of it fits on screen (site.js sets .fits) */
@media (min-width:1080px){.tool-grid>.notes-panel.fits{position:sticky;top:calc(var(--head-h) + 23px)}}

/* ---------- the herbarium sheet (signature) ---------- */
/* each sheet lays out its foot by its own width, which differs between pages and between the stacked and side-by-side tools */
.sheet{position:relative;margin:0;background:var(--sheet);border:1px solid var(--sheet-edge);box-shadow:var(--shadow);padding:clamp(16px,2.6vw,36px);min-width:0;container:sheet/inline-size}
.sheet-top{display:flex;justify-content:space-between;align-items:flex-start;gap:var(--s4);flex-wrap:wrap;margin-bottom:clamp(16px,2.4vw,28px)}
.sheet-inst{font-family:var(--font-tag);font-size:var(--tag-s);letter-spacing:var(--track-caps);text-transform:uppercase;color:var(--ink-2);line-height:1.6;min-width:0;flex:1 1 260px;max-width:max-content}
.sheet-inst strong{display:block;margin-top:4px;font-family:var(--font-text);font-size:1.25rem;line-height:1.22;letter-spacing:0;text-transform:none;font-weight:500;color:var(--ink);text-wrap:balance;overflow-wrap:break-word;overflow-wrap:anywhere}
.barcode{display:flex;flex-direction:column;align-items:flex-end;gap:2px;flex:0 0 auto}
.barcode svg{height:28px;width:auto;color:var(--ink)}
.barcode span{font-family:var(--font-tag);font-size:var(--tag-xs);color:var(--ink-3);letter-spacing:var(--track-mixed)}
/* as on a real sheet, the barcode keeps to the top right, also when it wraps under a long title. A short title asks only
   for its own width (max-width above), so the barcode wraps under it only when the title needs the room */
.sheet-top>.barcode{margin-left:auto}
.stamp{position:relative;margin:4px 0 0 auto;transform:rotate(-6deg);border:2px solid var(--cyan);color:var(--cyan);font-family:var(--font-tag);font-weight:700;font-size:var(--tag-s);letter-spacing:var(--track-caps);text-transform:uppercase;padding:6px 10px 5px;border-radius:3px;opacity:.9;pointer-events:none;text-align:center;line-height:1.35;background:color-mix(in srgb,var(--sheet) 70%,transparent)}
.stamp small{display:block;font-weight:400;letter-spacing:var(--track-mixed);font-size:.95em;text-transform:none}
/* labels in one row stretch to the tallest, so their bottom edges line up */
.specimens{list-style:none;display:grid;grid-template-columns:repeat(auto-fill,minmax(132px,1fr));gap:clamp(14px,2vw,26px) clamp(10px,1.6vw,22px);align-items:stretch;min-height:120px}
@media (max-width:480px){.specimens{grid-template-columns:repeat(2,minmax(0,1fr))}}
.specimen{display:grid;grid-template-rows:auto 1fr;gap:6px;min-width:0}
.specimen .plate{position:relative;aspect-ratio:5/7;transition:opacity .25s ease}
.specimen .plate svg{width:100%;height:100%}
/* tracing a fibre: other drawings fade, their labels stay fully legible */
.specimens.filtering .specimen:not(.hit) .plate{opacity:.25}
.specimens.filtering .specimen:not(.hit) .tag-label{border-style:dashed}
.specimens.filtering .specimen.hit .tag-label{border-color:var(--cyan);box-shadow:inset 0 0 0 1px var(--cyan)}
.tag-label{border:1px solid var(--rule);background:var(--sheet);padding:6px 8px 7px;font-size:.82rem;line-height:1.28;min-width:0}
.tag-label .no{font-family:var(--font-tag);font-size:var(--tag-xs);color:var(--ink-3);letter-spacing:var(--track-mixed);display:flex;flex-wrap:wrap;justify-content:space-between;gap:0 6px}
.tag-label .no span{white-space:nowrap}
.tag-label .cn{display:block;font-weight:500;font-size:.98rem;margin-top:2px;overflow-wrap:break-word;overflow-wrap:anywhere}
.tag-label .bn{display:block;font-style:italic;color:var(--ink-2);overflow-wrap:break-word;overflow-wrap:anywhere}
.tag-label .bn .infra,.tag-label .bn .hx{font-style:normal}
/* a family is a name, so it takes the names' tracking: even "Amaryllidaceae" then fits the narrowest tag whole */
.tag-label .fam{display:block;font-family:var(--font-tag);font-size:var(--tag-xs);letter-spacing:var(--track-mixed);text-transform:uppercase;color:var(--ink-3);margin-top:3px;overflow-wrap:break-word;overflow-wrap:anywhere}
/* each fibre type in its own colour (data-ft); the separating dots stay quiet */
.tag-label .ft{display:block;font-family:var(--font-tag);font-size:var(--tag-xs);color:var(--ink-3);margin-top:4px;letter-spacing:var(--track-mixed);overflow-wrap:break-word;overflow-wrap:anywhere}
/* a sentence, so it is set as text; centred in the space the specimens would take */
.sheet-empty{display:grid;align-content:center;font-size:.94rem;font-style:italic;color:var(--ink-3);border:1px dashed var(--rule);padding:var(--s5);text-align:center;grid-column:1/-1}
/* scale bar beside the collector's label once the sheet leaves the bar room for its figures; both start on one top line,
   and the button sits under the label so the label stays short */
.sheet-foot{display:grid;gap:var(--s4) var(--s5);margin-top:clamp(20px,3vw,36px);grid-template-columns:minmax(0,1fr)}
.sheet-act{margin:0}
.sheet-act .btn{width:100%;text-wrap:balance}
@container sheet (min-width:640px){
  .sheet-foot{grid-template-columns:minmax(0,1fr) minmax(260px,340px);align-items:start}
  .sheet-act{grid-column:2}
}
@supports not (container-type:inline-size){@media (min-width:860px) and (max-width:1079px),(min-width:1200px){
  .sheet-foot{grid-template-columns:minmax(0,1fr) minmax(260px,340px);align-items:start}
  .sheet-act{grid-column:2}
}}
.scalebar{min-width:0}
.scalebar .cap{font-family:var(--font-tag);font-size:var(--tag-s);color:var(--ink-2);letter-spacing:var(--track-caps);text-transform:uppercase;margin-bottom:6px;text-wrap:balance}
.scalebar .read{font-size:.95rem;color:var(--ink-2);margin-top:6px}
.scalebar .read b{font-weight:600;color:var(--ink)}
.sb{position:relative;padding-top:22px;container:scale/inline-size}
.sb-track{display:flex;height:8px;border:1px solid var(--ink)}
.sb-track i{display:block;height:100%}
.sb-track i:nth-child(odd){background:var(--ink)}
.sb-track i:nth-child(even){background:var(--sheet)}
.sb-fill{height:7px;margin-top:3px;background:var(--rule-soft);position:relative}
.sb-fill i{position:absolute;inset:0 auto 0 0;background:var(--plant-ink)}
.sb-ticks{position:relative;height:16px;margin-top:3px}
.sb-ticks span{position:absolute;top:0;transform:translateX(-50%);font-family:var(--font-tag);font-size:var(--tag-xs);letter-spacing:var(--track-mixed);color:var(--ink-3);white-space:nowrap}
/* end figures sit inside the track, so the bar can run the full width */
.sb-ticks span:first-child{transform:none}
.sb-ticks span:last-child{transform:translateX(-100%)}
/* a bar too short for its figures labels every other division (.mn hidden), then only its two ends (.mj hidden too);
   the breakpoints grow with the figures' width (w3 "100", w5 "1,000", w6 "10,000", w7 "100,000") */
@container scale (max-width:299px){.sb-ticks .mn{visibility:hidden}}
@container scale (max-width:399px){.sb-ticks.w3 .mn{visibility:hidden}}
@container scale (max-width:599px){.sb-ticks.w5 .mn{visibility:hidden}}
@container scale (max-width:299px){.sb-ticks.w5 .mj{visibility:hidden}}
@container scale (max-width:699px){.sb-ticks.w6 .mn{visibility:hidden}}
@container scale (max-width:359px){.sb-ticks.w6 .mj{visibility:hidden}}
@container scale (max-width:799px){.sb-ticks.w7 .mn{visibility:hidden}}
@container scale (max-width:399px){.sb-ticks.w7 .mj{visibility:hidden}}
.sb-pin{position:absolute;top:0;height:42px;border-left:2px solid var(--cyan)}
.sb-pin span{position:absolute;top:0;left:5px;white-space:nowrap;font-family:var(--font-tag);font-size:var(--tag-xs);font-weight:700;color:var(--cyan);letter-spacing:var(--track-mixed)}
.sb-pin.flip span{left:auto;right:5px}
.collector{border:1px solid var(--ink);padding:12px 14px;background:var(--sheet);font-size:.92rem;line-height:1.4;min-width:0}
.collector .ch{font-family:var(--font-tag);font-size:var(--tag-s);letter-spacing:var(--track-caps);text-transform:uppercase;font-weight:700;border-bottom:1px solid var(--ink);padding-bottom:6px;margin-bottom:8px;text-align:center;line-height:1.3}
.collector dl{margin:0;display:grid;grid-template-columns:auto 1fr;gap:3px 10px;align-items:baseline}
.collector dt{font-family:var(--font-tag);font-size:var(--tag-s);color:var(--ink-3);letter-spacing:var(--track-mixed)}
.collector dd{margin:0;min-width:0;overflow-wrap:break-word;overflow-wrap:anywhere}

/* specimen drawing classes. The line work keeps the theme's inks; each plant's washes (and a few inks: red stalks, violet
   streaks, florets) come from site.js as custom properties on its <svg>: --lf, --fr and so on for a light sheet, --lf-d
   and so on for a dark one (the dark-theme blocks above pick those). Without them, the plain sage and buff washes */
.sp{--c-lf:var(--lf,var(--plant-wash));--c-fr:var(--fr,var(--fruit-wash));--c-rt:var(--rt,var(--fruit-wash));--c-hd:var(--hd,var(--c-lf));--c-pt:var(--pt,var(--c-lf));--c-sk:var(--sk,var(--c-lf));--c-st:var(--st,var(--plant-ink));--c-rl:var(--rl,var(--dry-ink));--c-dt:var(--dt,var(--dry-ink));--c-gd:var(--gd,var(--plant-ink))}
.sp .st{fill:none;stroke:var(--c-st);stroke-width:1.15;stroke-linecap:round;stroke-linejoin:round}
.sp .st2{fill:none;stroke:var(--c-st);stroke-width:.7;stroke-linecap:round}
.sp .lf{fill:var(--c-lf);fill-opacity:.85;stroke:var(--plant-ink);stroke-width:.9;stroke-linejoin:round}
.sp .hd{fill:var(--c-hd)}
.sp .pt{fill:var(--c-pt)}
.sp .sk{fill:var(--c-sk)}
.sp .vn{fill:none;stroke:var(--plant-ink);stroke-width:.45;stroke-linecap:round;opacity:.75}
.sp .rt{fill:var(--c-rt);fill-opacity:.9;stroke:var(--dry-ink);stroke-width:.9;stroke-linejoin:round}
.sp .rl{fill:none;stroke:var(--c-rl);stroke-width:.55;stroke-linecap:round}
.sp .fr{fill:var(--c-fr);fill-opacity:.9;stroke:var(--dry-ink);stroke-width:.9}
.sp .dt{fill:var(--c-dt)}
.sp .gd{fill:var(--c-gd)}
.sp .tp{fill:var(--tape);stroke:var(--rule);stroke-width:.4;opacity:.92}
.sp .pk{fill:var(--sheet-2);stroke:var(--field-edge);stroke-width:.7}
/* the first, paler pass of each wash, laid a touch off the line work as a colourist's brush leaves it: fills only */
.sp .wash{opacity:.5}
.sp .wash :is(.st,.st2,.vn,.rl,.dt,.gd,.tp,.pk){display:none}
.sp .wash :is(.lf,.fr,.rt){stroke:none;fill-opacity:1}
.sp.ghost .wash{display:none}

/* ---------- result blocks (analyser and decoder) ---------- */
.results{margin-top:clamp(32px,4.5vw,56px);display:grid;gap:clamp(32px,4vw,52px)}
.results[aria-busy="true"]{opacity:.6}
.row{display:grid;gap:clamp(24px,3vw,44px);grid-template-columns:1fr}
@media (min-width:900px){
  .row.r-det{grid-template-columns:minmax(0,5fr) minmax(0,7fr)}
  .row.r-recs{grid-template-columns:minmax(0,7fr) minmax(0,5fr)}
  .row.r-two{grid-template-columns:repeat(2,minmax(0,1fr))}
}
.block{min-width:0}
.stack{display:grid;gap:clamp(24px,3vw,36px);align-content:start;min-width:0}
.block-h{font-family:var(--font-tag);font-size:var(--tag-m);letter-spacing:var(--track-caps);text-transform:uppercase;color:var(--ink-2);font-weight:700;padding-bottom:8px;border-bottom:1px solid var(--rule);margin-bottom:var(--s4);line-height:1.3}
.det{display:grid;grid-template-columns:auto 1fr;gap:var(--s4) var(--s5);align-items:start}
.grade{font-size:clamp(4.2rem,3rem + 4vw,6.6rem);line-height:.82;font-weight:500;letter-spacing:-.02em;min-width:1ch;font-variant-numeric:lining-nums}
.det .verdict{font-size:1.3rem;line-height:1.2;font-weight:500;margin-bottom:6px}
.det .summary{color:var(--ink-2)}
.det .overall{font-size:.96rem;color:var(--ink-2);margin-top:var(--s3);font-variant-numeric:lining-nums}
.scores{list-style:none;display:grid;gap:12px}
.score{display:grid;grid-template-columns:minmax(0,10.5em) minmax(0,1fr) 3.6em;gap:var(--s3);align-items:center}
.score .nm{font-size:.98rem;min-width:0}
.score .val{font-size:1rem;text-align:right;font-variant-numeric:lining-nums tabular-nums}
.ruler{position:relative;height:14px;border-bottom:1px solid var(--ink-3);background-image:repeating-linear-gradient(to right,var(--rule) 0,var(--rule) 1px,transparent 1px,transparent 10%),linear-gradient(var(--rule),var(--rule));background-size:100% 6px,1px 6px;background-repeat:no-repeat;background-position:0 100%,100% 100%}
.ruler i{position:absolute;left:0;bottom:3px;height:6px;background:var(--bar,var(--plant-ink));border-radius:0 1px 1px 0}
.ruler.neg i{background:var(--madder)}
.score .why{grid-column:1/-1;font-size:.86rem;color:var(--ink-3);margin-top:-6px}
@media (max-width:520px){.score{grid-template-columns:minmax(0,1fr) 3.6em}.score .ruler{grid-column:1/-1;grid-row:2}}

/* annotation lists */
.alist{list-style:none;display:grid;gap:10px}
.alist li{display:grid;grid-template-columns:18px minmax(0,1fr);gap:var(--s2);align-items:start;font-size:.98rem}
.alist li>span{min-width:0;overflow-wrap:break-word;overflow-wrap:anywhere}
.alist .ico{width:18px;height:18px;margin-top:.22em}
.alist .sub{display:block;font-size:.86rem;color:var(--ink-3)}
.ico-ok{stroke:var(--plant-ink);fill:none;stroke-width:1.6}
.ico-warn{stroke:var(--madder);fill:none;stroke-width:1.6}
.ico-info{stroke:var(--cyan);fill:none;stroke-width:1.6}
.sev{font-family:var(--font-tag);font-size:var(--tag-xs);letter-spacing:var(--track-caps);text-transform:uppercase;margin-right:6px}
.sev.warn{color:var(--madder)}
.sev.info{color:var(--cyan)}
.sev.good{color:var(--plant-ink)}
.sev.none{color:var(--ink-3)}
.empty-note{font-size:.94rem;color:var(--ink-3);font-style:italic}

/* recommendations */
.recs{list-style:none;counter-reset:rec;display:grid;gap:var(--s4)}
.recs li{counter-increment:rec;display:grid;grid-template-columns:2.2em minmax(0,1fr);gap:var(--s3);padding-bottom:var(--s4);border-bottom:1px solid var(--rule-soft)}
.recs li:last-child{border-bottom:0;padding-bottom:0}
.recs li::before{content:counter(rec);font-family:var(--font-tag);font-size:var(--tag-m);color:var(--ink-3);border:1px solid var(--rule);width:2em;height:2em;display:grid;place-items:center;border-radius:50%}
.recs .t{font-weight:500;font-size:1.08rem;display:block;line-height:1.25}
.recs .d{display:block;color:var(--ink-2);font-size:.96rem;margin-top:2px}
.impact{display:flex;flex-wrap:wrap;gap:6px;margin-top:8px}
.impact span{font-family:var(--font-tag);font-size:var(--tag-s);border:1px solid var(--plant-ink);color:var(--plant-ink);padding:2px 7px;border-radius:2px;letter-spacing:var(--track-mixed)}
.more-btn{margin-top:var(--s4)}

/* citations and references */
.cites{white-space:nowrap}
.cite,.cite-sep{font-size:.7em;vertical-align:super;line-height:0;font-variant-numeric:lining-nums;font-style:normal}
.cite{text-decoration:underline;text-decoration-thickness:1px;text-underline-offset:.12em;padding:0 1px}
.cite-sep{color:var(--ink-3)}
.cite:hover{text-decoration-thickness:2px}
.refs{list-style:none;counter-reset:ref;display:grid;gap:10px;font-size:.9rem;line-height:1.4}
.refs li{counter-increment:ref;display:grid;grid-template-columns:2em minmax(0,1fr);gap:var(--s2)}
.refs li::before{content:counter(ref) ".";color:var(--ink-3);font-variant-numeric:lining-nums tabular-nums;text-align:right;padding-right:.25em}
.refs .st{font-style:italic;color:var(--ink-3)}
.refs a{overflow-wrap:break-word;overflow-wrap:anywhere}
.refs.two-col{display:block;columns:1;column-gap:var(--s7)}
.refs.two-col li{break-inside:avoid;margin-bottom:10px;display:grid}
@media (min-width:900px){.refs.two-col{columns:2}}
.unmatched{list-style:none;display:flex;flex-wrap:wrap;gap:6px}
.unmatched li{font-size:.94rem;border:1px dashed var(--field-edge);padding:2px 9px 3px;color:var(--ink-2);background:var(--sheet);max-width:100%;overflow-wrap:break-word;overflow-wrap:anywhere}
.disclaimer{font-size:.9rem;color:var(--ink-3);border-top:1px solid var(--rule);padding-top:var(--s3);max-width:90ch;margin:0}
/* straight after the drawers, their bottom rule already closes the section: the note sits under it as a footnote */
.drawers + .disclaimer{border-top:0;padding-top:0}
.err{border:1px solid var(--madder);background:var(--madder-wash);color:var(--ink);padding:var(--s4);font-size:.98rem}
/* the notice a tool page shows when scripts are off, or its food data did not load, keeps the tool's own gap above the form */
noscript .err,.engine-missing .err{margin-bottom:var(--s6)}

/* progressive disclosure: catalogue drawers */
.drawers{display:grid;border-top:1px solid var(--rule)}
.more{border-bottom:1px solid var(--rule);min-width:0}
/* a long title wraps within its own column; Show and Hide stay on the first line, at the right */
.more>summary{cursor:pointer;list-style:none;display:flex;justify-content:space-between;align-items:baseline;gap:var(--s4);padding:12px 0;font-family:var(--font-tag);font-size:var(--tag-m);letter-spacing:var(--track-caps);text-transform:uppercase;color:var(--ink-2);font-weight:700}
.more>summary::-webkit-details-marker{display:none}
.more>summary>span:first-child{flex:1 1 auto;min-width:0;text-wrap:balance}
.more>summary .k{flex:0 0 auto;color:var(--cyan);letter-spacing:var(--track-mixed);font-weight:400;text-transform:none;white-space:nowrap}
/* the signs are decoration: summaries already expose open and closed */
.more>summary .k::after{content:" +";content:" +" / ""}
.more[open]>summary .k::after{content:" \2212";content:" \2212" / ""}
.more>summary:hover{color:var(--ink)}
.more-body{padding:var(--s2) 0 var(--s5);min-width:0}

/* evidence dots */
.ev{display:inline-flex;align-items:baseline;gap:6px;font-family:var(--font-tag);font-size:var(--tag-s);letter-spacing:var(--track-mixed);color:var(--ink-2);white-space:nowrap}
.ev .dots{display:inline-flex;gap:2px;align-self:center}
.ev .dots b{width:7px;height:7px;border-radius:50%;border:1px solid var(--ink-2);display:block}
.ev .dots b.f{background:var(--ink-2)}

/* wide tables */
.table-wrap{position:relative;overflow-x:auto;border-top:1px solid var(--ink);min-width:0;max-width:100%}
table.data{width:100%;border-collapse:collapse;font-size:.92rem;min-width:620px}
table.data th{font-family:var(--font-tag);font-size:var(--tag-xs);letter-spacing:var(--track-caps);text-transform:uppercase;color:var(--ink-2);text-align:left;font-weight:700;padding:10px 12px 8px 0;border-bottom:1px solid var(--rule);vertical-align:bottom}
table.data td{padding:10px 12px 10px 0;border-bottom:1px solid var(--rule-soft);vertical-align:top}
/* the last column runs to the rule's right end, in line with the page margin */
table.data tr>:last-child{padding-right:0}
table.data td.mono{font-size:.92rem;font-variant-numeric:lining-nums}
table.data td.num{text-align:right;white-space:nowrap;font-variant-numeric:lining-nums tabular-nums}
table.data th.num{text-align:right}
/* a text column after a figure column starts a full gutter away, so "Fibre, g" and "Fibre types" never read as one label */
table.data :is(th,td).num + :is(th,td):not(.num){padding-left:var(--s5)}
table.data td .sm{display:block;font-size:.86rem;color:var(--ink-3)}
.scroll-hint{display:none;font-size:.9rem;font-style:italic;color:var(--ink-3);margin:0 0 var(--s2)}
/* tables are 620px wide at least; with 16px gutters they fit from 652px */
@media (max-width:651px){.scroll-hint{display:block}}

/* ---------- drawer labels: the way into each part of the site (home and not-found pages) ---------- */
.entries{list-style:none;display:grid;gap:10px}
/* about 8px clear of the inner keyline on every side; a fixed arrow column keeps the arrows on one axis */
.entry{position:relative;display:grid;grid-template-columns:44px minmax(0,1fr) 20px;gap:var(--s4);align-items:center;text-decoration:none;color:var(--ink);background:var(--sheet);border:1px solid var(--sheet-edge);padding:13px 18px 13px 14px;min-height:84px}
.entry::before{content:"";position:absolute;inset:4px;border:1px solid var(--rule-soft);pointer-events:none}
/* a drawer label that leads to a tool or the blog carries that part's plate colour: a tab inside its keyline, its typed
   tag and its arrow */
.entry:is([href$="analyser.html"],[href$="decoder.html"],[href="#subscribe"])::before{border-left:3px solid var(--plate)}
.entry:hover{border-color:var(--plate,var(--cyan));color:var(--ink)}
.entry:hover .entry-t{text-decoration:underline;text-decoration-thickness:1px;text-underline-offset:.16em}
.entry-fig{display:block;width:44px;height:62px}
.entry-fig svg{width:44px;height:62px}
.entry-txt{min-width:0;display:grid;gap:1px}
.entry-no{font-family:var(--font-tag);font-size:var(--tag-xs);letter-spacing:var(--track-caps);text-transform:uppercase;color:var(--plate,var(--ink-3))}
.entry-t{font-size:1.3rem;font-weight:500;line-height:1.15}
.entry-d{font-size:.92rem;color:var(--ink-2);line-height:1.38}
.entry-go{color:var(--plate,var(--cyan));font-size:1.2rem;justify-self:center}

/* ---------- the blog, by email (home #subscribe): a small sheet with one taped specimen ---------- */
.subscribe{position:relative;display:grid;gap:var(--s5);grid-template-columns:minmax(0,1fr);background:var(--sheet);border:1px solid var(--sheet-edge);box-shadow:var(--shadow);padding:clamp(20px,2.8vw,40px)}
.subscribe::before{content:"";position:absolute;inset:4px;border:1px solid var(--rule-soft);border-left:3px solid var(--plate);pointer-events:none}
/* columns start together, so the form never jumps when a status line appears */
@media (min-width:900px){.subscribe{grid-template-columns:84px minmax(0,6fr) minmax(0,5fr);gap:clamp(24px,3.2vw,52px);align-items:start}}
.sub-fig{display:none}
@media (min-width:900px){.sub-fig{display:block;width:84px;height:118px;align-self:center}.sub-fig svg{width:84px;height:118px}}
.sub-copy{min-width:0;position:relative}
.sub-copy h2{font-size:clamp(1.55rem,1.2rem + 1.1vw,2.1rem);margin:0 0 var(--s3)}
.sub-copy p{color:var(--ink-2);max-width:54ch;margin:0}
.sub-form{display:grid;gap:var(--s2);min-width:0;position:relative}
.sub-form label{font-family:var(--font-tag);font-size:var(--tag-s);text-transform:uppercase;letter-spacing:var(--track-caps);color:var(--ink-2)}
.sub-row{display:flex;flex-wrap:wrap;gap:var(--s2)}
.sub-row input{flex:1 1 160px;min-width:0;min-height:44px;border:1px solid var(--field-edge);border-radius:2px;background:var(--page);padding:8px 12px;font-size:1.0625rem;color:var(--ink)}
.sub-row .btn{flex:0 0 auto}
@media (max-width:359px){.sub-row .btn{flex:1 1 100%}}
.sub-form[data-subscribe-state="invalid"] input{border-color:var(--madder);box-shadow:inset 0 0 0 1px var(--madder)}
.sub-status{font-size:.96rem;font-style:italic;color:var(--ink-2);min-height:1.45em;margin:0;line-height:1.4}
.sub-form[data-subscribe-state="invalid"] .sub-status{color:var(--madder)}
.sub-past{font-size:.98rem;margin:var(--s1) 0 0}
.sub-past a{display:inline-flex;align-items:center;gap:4px}

/* ---------- footer ---------- */
.foot{margin-top:clamp(72px,10vw,140px);border-top:1px solid var(--ink);padding:var(--s6) 0 calc(var(--s8) + env(safe-area-inset-bottom,0px))}
.foot-grid{display:grid;gap:var(--s5);grid-template-columns:1fr}
/* two columns only once the footer nav fits on one line beside the text; first lines share a baseline */
@media (min-width:1180px){.foot-grid{grid-template-columns:minmax(0,1fr) auto;align-items:baseline}}
.foot p{font-size:.94rem;color:var(--ink-2);max-width:80ch}
.foot .by{font-size:.9rem;color:var(--ink-3)}
.foot .sub-line{color:var(--ink)}
.foot nav{display:flex;flex-wrap:wrap;gap:var(--s2) var(--s5);justify-content:flex-start}
@media (min-width:1180px){.foot nav{justify-content:flex-end}}
.foot nav a{font-size:1.04rem;font-variant-caps:all-small-caps;font-weight:500;letter-spacing:.08em;padding:6px 0;display:inline-flex;align-items:center;gap:3px}

/* placeholder links (SITE values still '#') render as plain text until they are filled in */
a[data-site-href]:not([href]){color:var(--ink-2);text-decoration:none;cursor:default}

/* phones: one scrolling row of samples, shorter notebook (seven whole lines); padding leaves room for the focus ring.
   A chip never grows wider than the row, so its border and focus ring stay in view: a longer name wraps inside it */
@media (max-width:719px){
  .chips.scroll{position:relative;flex-wrap:nowrap;align-items:center;overflow-x:auto;padding:6px 6px 10px;margin:-6px -6px 0;scroll-padding-inline:16px;scrollbar-width:thin}
  .chips.scroll .chip{flex:0 0 auto;max-width:100%;text-wrap:balance}
  textarea.notebook{min-height:calc(2px + .235em + 7 * 1.647em)}
}
/* Windows high contrast: keep pressed states and filled evidence dots visible */
@media (forced-colors:active){
  .chip[aria-pressed="true"],.fbtn[aria-pressed="true"]{outline:2px solid Highlight;outline-offset:-4px}
  .ev .dots b.f{forced-color-adjust:none;background:CanvasText}
}
@media (prefers-reduced-motion:reduce){
  html{scroll-behavior:auto}
  *,*::before,*::after{transition-duration:0s!important;animation-duration:0s!important;animation-iteration-count:1!important}
}
@media print{.masthead{display:none}}
