/* =====
   DINKOMART — what every page but the home page shares: crumbs, the page
   head, the form field, the product card, the toast.
   ===== */

/* =====
   STUDIO PIECES (2026-10-14) — what every page but the home page may use:
   the logo's three colours in turn, a section's slate, an arrow sitting
   in a notch (main.css .cut / .cutbox), a line read as it passes.
   ===== */
.tone-0 { --tone: var(--brand);  --tone-soft: var(--brand-soft);  --tone-ink: var(--brand-ink);  --tone-on: var(--on-brand); }
.tone-1 { --tone: var(--accent); --tone-soft: var(--accent-soft); --tone-ink: var(--accent-ink); --tone-on: var(--on-accent); }
.tone-2 { --tone: var(--farm);   --tone-soft: var(--farm-soft);   --tone-ink: var(--farm-ink);   --tone-on: var(--bg); }

/* A section's slate: its number in the gold, then its name. */
.kick {
  display: inline-flex; align-items: center; gap: 10px; margin-bottom: var(--s-4);
  font: 600 var(--fs-label)/1 var(--font-mono); text-transform: uppercase; letter-spacing: .14em; color: var(--fg-subtle);
}
.kick b {
  display: inline-grid; place-items: center; min-width: 30px; height: 22px; padding: 0 7px; border-radius: 7px;
  background: var(--accent); color: var(--on-accent); font-weight: 700; letter-spacing: .04em;
}

/* An arrow in a notch: a card sets --cut: var(--cut-go) (a 54px notch for
   this 48px disc) and holds it as a grid child, or as a .cutbox's child. */
/* A number chip (48x30) in a top-left notch: a step, a point of a list. */
:root { --cut-n-tl: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='68' height='50'%3E%3Cg transform='matrix(-1 0 0 1 68 0)'%3E%3Cpath d='M0 50H68A14 14 0 0 0 54 36H35A21 21 0 0 1 14 15V14A14 14 0 0 0 0 0Z'/%3E%3C/g%3E%3C/svg%3E"); }
:root { --cut-go: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='70' height='70'%3E%3Cpath d='M0 0H70A16 16 0 0 1 54 16H46A30 30 0 0 0 16 46V54A16 16 0 0 1 0 70Z'/%3E%3C/svg%3E"); --cut-go-tr: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='70' height='70'%3E%3Cpath d='M0 70H70A16 16 0 0 0 54 54H46A30 30 0 0 1 16 24V16A16 16 0 0 0 0 0Z'/%3E%3C/svg%3E"); }
.cut-go {
  grid-area: 1 / 1; justify-self: end; align-self: end; position: relative; z-index: 2;
  width: 48px; height: 48px; display: grid; place-items: center; border-radius: 50%;
  background: var(--fg); color: var(--bg); rotate: -45deg;
  transition: rotate .5s var(--ease-out), background-color .3s var(--ease), color .3s var(--ease);
}
.cut-go .ico { width: 18px; height: 18px; }

/* A line read as it passes (functions.php read_words()): its words, each
   with its place (--wi of --n), on the line's own view timeline — which
   the pictures set into a line ride (about.css). The words themselves
   stand in full ink: they used to light one by one as the reading reached
   them, and the owner read text greyed until scrolled as fading and blur
   ("i dont like the fading texts … on scroll why it blurs", 2026-10-26). */
.read { view-timeline: --read block; }

/* A band of cards on a ground a step under the page, so a white card and
   its cut both read; back to paper at its foot, clear of the footer. */
.ground { background: linear-gradient(var(--surface-sunk) calc(100% - 7rem), var(--bg)); }

/* A RAIL of cards (the product page's "what else", a short shelf's "more"):
   a whole number of cards, never one sliced (the owner, three times), a
   set at a time (main.js railButtons; arrows only when it overflows). */
.rail {
  --n: 5; --gap: clamp(14px, 2vw, 22px);
  display: grid; grid-auto-flow: column; gap: var(--gap);
  grid-auto-columns: calc((100% - (var(--n) - 1) * var(--gap)) / var(--n));
  overflow-x: auto; scroll-snap-type: x mandatory; scroll-padding-inline: 4px; scrollbar-width: none;
  /* Room for a card's lift and shadow: a sideways scroller clips the other axis too. */
  padding: 10px 4px 26px; margin: -10px -4px -26px;
}
.rail::-webkit-scrollbar { display: none; }
.rail > .pcard { scroll-snap-align: start; }
.rail[data-scroller][data-edge] { -webkit-mask-image: none; mask-image: none; }   /* whole cards: no fade (shop.css fades the pills) */
@media (max-width: 1240px) { .rail { --n: 4; } }
@media (max-width: 980px)  { .rail { --n: 3; } }
@media (max-width: 700px)  { .rail { --n: 2; } }
.railbtn {
  width: var(--tap); height: var(--tap); display: grid; place-items: center;
  border: 0; border-radius: 50%; background: var(--surface); color: var(--fg);
  box-shadow: 0 6px 16px -10px rgba(17, 21, 18, .3);
  transition: background var(--dur) var(--ease), opacity var(--dur) var(--ease), scale var(--dur-press) var(--ease-out);
}
.railbtn:hover { background: var(--surface-2); }
.railbtn:active { scale: .92; }
.railbtn:disabled { opacity: .35; cursor: default; }

/* ----- breadcrumbs */
.crumbs {
  display: flex; flex-wrap: wrap; align-items: center; gap: 4px 10px;
  font: 500 var(--fs-label)/1.4 var(--font-mono);
  text-transform: uppercase; letter-spacing: var(--track-label); color: var(--fg-subtle);
}
.crumbs a { display: inline-flex; align-items: center; min-height: 32px; color: inherit; text-decoration: none; }
.crumbs a:hover { color: var(--fg); text-decoration: underline; text-underline-offset: 3px; }
.crumbs [aria-current] { color: var(--fg); }

/* ===== THE PAGE HEAD
   A stage (main.css): crumbs, kicker, the title rising word by word, a
   line, its numbers; the shop deals a fan of three (shop.css). */
.shead {
  --stage-top: clamp(1.5rem, 2.8vw, 2.75rem);
  position: relative; overflow: hidden; overflow: clip; isolation: isolate;
  padding-block: var(--stage-top) clamp(1.5rem, 2.6vw, 2.5rem);
}
/* A light leak in the range's colour. Still as the page scrolls, and so
   are the head's words: their drift-and-fade read as "blurred on scroll"
   (owner, 2026-10-17; D48, as D39 had it for the heroes). */
.shead::before {
  content: ''; position: absolute; z-index: -1; top: -40%; right: -8%; width: 62%; height: 150%;
  background: radial-gradient(closest-side, var(--lit, rgba(31, 154, 80, .26)), transparent);
  pointer-events: none;
}
.shead__grid {
  display: grid; align-items: center; gap: var(--s-6);
  grid-template-columns: minmax(0, 1fr) minmax(0, 300px);
}
.shead--bare .shead__grid { grid-template-columns: minmax(0, 1fr); }
.shead__copy { display: grid; justify-items: start; gap: var(--s-3); min-width: 0; }
.shead__kicker {
  display: inline-flex; align-items: center; gap: 12px;
  font: 600 var(--fs-label)/1 var(--font-mono);
  text-transform: uppercase; letter-spacing: .12em; color: var(--fg-muted);
}
/* A point of the range's light. */
.shead__kicker::before {
  content: ''; width: 7px; height: 7px; border-radius: 50%; background: var(--brand);
  box-shadow: 0 0 0 4px var(--lit, rgba(31, 154, 80, .26)), 0 0 18px 2px var(--lit, rgba(31, 154, 80, .26));
}
.shead__logo {
  width: 72px; height: 72px; object-fit: contain; padding: 8px;
  background: #fff; border-radius: 20px; box-shadow: 0 0 0 1px var(--border), var(--shadow-md);
}
.shead__title {
  margin-top: 2px;
  font-size: clamp(2.4rem, 1.3rem + 3vw, 4.4rem);
  font-weight: 800; line-height: .96; letter-spacing: -.045em;
  overflow-wrap: anywhere;
  view-transition-name: shead-title;
}
.shead__sub { font: 500 .82rem/1.5 var(--font-mono); letter-spacing: .02em; color: var(--fg-subtle); }
.shead__lede { max-width: 52ch; font-size: clamp(1.05rem, 1rem + .3vw, 1.22rem); line-height: 1.55; color: var(--fg-muted); }
.shead__stats { display: flex; flex-wrap: wrap; gap: var(--s-5); margin-top: var(--s-2); }
.shead__stats > div { display: grid; gap: 6px; padding-right: var(--s-5); border-right: 1px solid var(--border); }
.shead__stats > div:last-child { border-right: 0; padding-right: 0; }
.shead__stats dt {
  font: 600 var(--fs-label)/1 var(--font-mono);
  text-transform: uppercase; letter-spacing: var(--track-label); color: var(--fg-subtle);
}
.shead__stats dd { font: 600 1.3rem/1 var(--font-mono); font-variant-numeric: tabular-nums; color: var(--fg); }
.shead .crumbs { color: var(--fg-subtle); }
.shead--farm .shead__logo { border-color: transparent; }

/* ----- forms
   One field, every form: checkout, contact, farmers, a price request. A
   label above, the input, a hint, an error tied to it by aria-describedby.
   48px inputs, 16px text so a phone does not zoom on focus. */
.field { display: grid; gap: 7px; min-width: 0; }
.field label, .field legend { padding: 0; font-weight: 600; font-size: .9rem; color: var(--fg); }
.field__opt {
  margin-left: 4px; font: 500 var(--fs-label)/1 var(--font-mono);
  text-transform: uppercase; letter-spacing: var(--track-label); color: var(--fg-subtle);
}
.field input:not([type='radio'], [type='checkbox']), .field textarea, .field select {
  width: 100%; min-height: 50px; padding: 12px 16px;
  background: var(--surface); color: var(--fg);
  border: 1px solid var(--border-strong); border-radius: 14px;
  font-size: 1rem; line-height: 1.4;
  transition: border-color var(--dur) var(--ease), box-shadow var(--dur) var(--ease), background var(--dur) var(--ease);
}
.field textarea { resize: vertical; min-height: 104px; }
.field input:not([type='radio'], [type='checkbox']):hover, .field textarea:hover { border-color: var(--fg-subtle); }
.field input:focus, .field textarea:focus, .field select:focus {
  outline: none; border-color: var(--brand);
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--brand) 16%, transparent);
}
.field__hint { font-size: .84rem; color: var(--fg-subtle); }
.field__err { display: flex; gap: 6px; font-size: .86rem; font-weight: 600; color: var(--err); }
.field--bad input, .field--bad textarea { border-color: var(--err); }
.field--bad input:focus, .field--bad textarea:focus { box-shadow: 0 0 0 4px color-mix(in srgb, var(--err) 16%, transparent); }

/* The honeypot: present to a script that fills every input, absent for
   people and for screen readers. */
.hp { position: absolute !important; left: -10000px; width: 1px; height: 1px; overflow: hidden; }

/* Long text: the partners' own sections, the owner's pages. */
.prose { max-width: 68ch; color: var(--fg-muted); font-size: 1rem; line-height: 1.7; }
.prose > * + * { margin-top: var(--s-4); }
.prose strong { color: var(--fg); font-weight: 650; }


/* =====
   THE PRODUCT CARD — one card, every grid (includes/pcard.php; D43).
   ONE OBJECT on the shop's ground (owner, 2026-10-15: "too much big …
   not so modern"): a white card, its photograph in a square well inset
   from its edge, the brand with its range's dot, the name in two lines'
   room, the packs, and on the foot line the price beside the CUT — the
   card's corner bitten away (main.css .cut) for Add, which sits in the
   notch on the ground and becomes the − 1 + stepper there. ONE link, the
   name, stretched over all. The ground is its own element (.pcard__bg):
   the mask cuts the ground, never the button; its wrapper (.pcard__shot)
   casts the shadow round the cut.
   ===== */
.pcard {
  /* A 102x48 notch for the 96x42 button and a 6px gap, 14px fillets;
     its inner corner the button's round end plus the gap. */
  --cut: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='116' height='62'%3E%3Cpath d='M0 0H116A14 14 0 0 1 102 14H41A27 27 0 0 0 14 41V48A14 14 0 0 1 0 62Z'/%3E%3C/svg%3E");
  --cut-w: 116px; --cut-h: 62px;
  --btn-w: 96px; --btn-h: 42px;
  --in: 7px;            /* the well, in from the card's edge */
  --pad: 15px;          /* the words, in from it */
  --r: 22px;
  position: relative; isolation: isolate; container: pcard / inline-size;
  display: grid; grid-template-columns: minmax(0, 1fr); grid-template-rows: auto auto auto auto auto 1fr;
  transition: translate .5s var(--ease-out), scale var(--dur-press) var(--ease-out);
}
/* The body and the form lay their pieces straight into the card's grid,
   so Add can share the foot line with the price without measuring it.
   The ground spans every row of the one column, so each piece names its
   own cell: placed by row alone, it would start a second column. */
.pcard__body, .pcard__buy { display: contents; }

/* The ground and its shadow; a deeper one faded in on a hover. BOTH ON
   THE SHOT, outside its box only, so the notch stays clean: a blurred
   pool under the card showed grey through the notch round Add (owner,
   2026-10-17: "on hover looks shit"; D50). Opacity only, and the shadows
   are painted once (D46): as a drop-shadow it was filtered again on every
   frame a card rose or arrived. */
.pcard__shot {
  grid-area: 1 / 1 / -1 / -1; z-index: -1; position: relative; display: grid; border-radius: var(--r);
  box-shadow: 0 1px 1px rgba(17, 21, 18, .05), 0 8px 18px rgba(17, 21, 18, .06);
}
.pcard__shot::after {
  content: ''; position: absolute; inset: 0; border-radius: inherit; pointer-events: none;
  box-shadow: 0 2px 4px rgba(17, 21, 18, .05), 0 24px 42px -16px rgba(17, 21, 18, .34);
  opacity: 0; transition: opacity .45s var(--ease-out);
}
.pcard__bg { border-radius: inherit; background: var(--card, var(--surface)); }
[data-theme='dark'] .pcard { --card: #181C19; }
[data-theme='dark'] .pcard__bg { box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .045); }
[data-theme='dark'] .pcard__shot::after { box-shadow: 0 24px 42px -16px rgba(0, 0, 0, .75); }

.pcard:has(.pcard__link:active) { scale: .98; }
.pcard:has(.pcard__link:focus-visible) .pcard__shot { outline: 2px solid var(--focus-ring); outline-offset: 3px; }
@media (hover: hover) and (pointer: fine) {
  .pcard:hover { translate: 0 -4px; }
  .pcard:hover .pcard__shot::after { opacity: 1; }
  .pcard:hover .pcard__img { scale: 1.05; }
  /* The second photograph answers "what else is there": it takes the
     well and THE FIRST GIVES WAY. Packshots are multiplied into the
     light, so one laid over another let both show — two bottles in one
     well (owner's screenshot, 2026-10-17). */
  .pcard:hover .pcard__img--alt { opacity: 1; }
  /* Only where there IS a second photograph: a card whose photographs are
     its options' (data-v, D82) has no --alt, and hiding its first left the
     well empty on hover (owner's screenshot, HTP sprayer, 2026-11-06; D88). */
  .pcard:hover .pcard__img:first-of-type:not(:only-of-type):not([data-v]) { opacity: 0; }
  .pcard:hover .pcard__name { color: var(--brand-ink); }
}
.pcard, .pcard :is(button, a, label) { -webkit-tap-highlight-color: transparent; }

/* THE WELL: a square inset in the card. A packshot on white stands in a
   soft studio light — its white melts into it (multiply), so a bottle on
   a white sweep reads as photographed here, not as a white box; a
   photograph fills the well; another shape stands on its own edge
   colours (pic_fit). */
:root { --well: radial-gradient(125% 100% at 50% 14%, #FFFFFF 0 26%, #EEECE6 100%); }
[data-theme='dark'] { --well: radial-gradient(125% 100% at 50% 14%, #F1F0EC 0 26%, #D9D6CE 100%); }
.pcard__media {
  grid-area: 1 / 1; position: relative; overflow: hidden; isolation: isolate;
  margin: var(--in) var(--in) 0; aspect-ratio: 1; border-radius: calc(var(--r) - var(--in) + 2px);
  background: var(--well);
}
.pcard__img {
  position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover;
  transition: scale .7s var(--ease-out), opacity var(--dur-slow) var(--ease);
}
.pcard__img--alt { opacity: 0; }
/* Its sweep is never quite white (#F5F5F5 to #FEFEFE, measured): lifted
   5% it is, and only the pack is left on the light. Its second photograph
   (the hover) stands the same way, whatever it was flagged. */
.pcard__media .is-pack,
.pcard__media:has(> .is-pack) .pcard__img--alt { padding: 10%; object-fit: contain; background: none; filter: brightness(1.05); mix-blend-mode: multiply; }

/* Per photograph (pic_fit): a pack stands on a plate of its own edge
   colour; another shape on its own top-to-bottom colours, its edges
   feathered in, so the cloth it was shot on carries on. */
.is-pack { object-fit: contain; padding: 9%; background: var(--plate); }
.is-fit, .is-plate { background: linear-gradient(var(--plate-a, var(--surface-sunk)), var(--plate-b, var(--surface-sunk))); }
.is-fit { object-fit: contain; }
.pcard__img.is-wide:not(.pcard__img--alt) {
  inset: 50% 0 auto; height: auto; translate: 0 -50%; background: none;
  -webkit-mask-image: linear-gradient(transparent, #000 14%, #000 86%, transparent);
  mask-image: linear-gradient(transparent, #000 14%, #000 86%, transparent);
}
.pcard__img.is-tall:not(.pcard__img--alt) {
  inset: 0 auto 0 50%; width: auto; translate: -50% 0; background: none;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 14%, #000 86%, transparent);
  mask-image: linear-gradient(90deg, transparent, #000 14%, #000 86%, transparent);
}

.pcard__flags {
  position: absolute; top: 9px; left: 9px; right: 9px; z-index: 2;
  display: flex; flex-wrap: wrap; gap: 6px; pointer-events: none;
}
.pcard__flag {
  padding: 5px 9px; border-radius: var(--r-full);
  font: 600 var(--fs-label)/1.1 var(--font-mono); text-transform: uppercase; letter-spacing: var(--track-label);
  background: rgba(255, 255, 255, .88); color: #111512; box-shadow: 0 1px 2px rgba(17, 21, 18, .12);
  -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px);
}
.pcard__flag--out { background: #111512; color: #fff; }
/* DM's Choice (D82, D84; catalogue.php dm_choice_badge()): a ribbon, as
   Amazon's Choice is a label — deep forest, "DM's" in white and "Choice"
   in the logo's gold, a swallowtail notch at its end, a lit top edge. On a
   card it runs in from the photograph's left edge. */
.dmc {
  --notch: 9px;
  display: inline-flex; align-items: center; gap: 6px; padding: 6px calc(var(--notch) + 9px) 6px 9px;
  border-radius: 5px 0 0 5px;
  clip-path: polygon(0 0, 100% 0, calc(100% - var(--notch)) 50%, 100% 100%, 0 100%);
  background: linear-gradient(180deg, #1B4D31 0%, #0E3420 55%, #0A2717 100%); color: #fff;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .18), inset 0 -2px 0 rgba(0, 0, 0, .28),
              inset 3px 0 0 var(--harvest-400);
  font: 700 .78rem/1 var(--font-display); letter-spacing: -.005em; white-space: nowrap;
}
.dmc__mark { width: 22px; height: 11px; object-fit: contain; }
.dmc__txt b { font-weight: 800; color: var(--harvest-400); }
.pcard__flags .dmc { order: -1; margin: 5px 0 0 -9px; padding-left: 12px; border-radius: 0; }

/* A government scheme's subsidy (D84): a fact about buying, said under the
   name in the brand's green with a shield — not printed over the photograph. */
.pcard__perk {
  grid-area: 4 / 1; justify-self: start; position: relative; z-index: 2;
  display: inline-flex; align-items: center; gap: 6px; margin: 8px var(--pad) 0; padding: 4px 10px 4px 6px;
  border-radius: var(--r-full); background: var(--brand-soft); color: var(--brand-ink);
  font: 650 .78rem/1.1 var(--font-body);
}
.pcard__perk .ico { width: 15px; height: 15px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }

/* THE WORDS: the maker, with the dot of the range it is in; the name in
   two lines' room, so a row's feet line up. */
.pcard__brand {
  grid-area: 2 / 1; display: flex; align-items: center; gap: 7px; min-width: 0; margin: 14px var(--pad) 0;
  font: 600 var(--fs-label)/1.3 var(--font-mono); text-transform: uppercase; letter-spacing: var(--track-label);
  color: var(--fg-subtle); white-space: nowrap; overflow: hidden;
}
.pcard__brand::before { content: ''; flex: none; width: 6px; height: 6px; border-radius: 50%; background: var(--tint-b, var(--brand)); }
.pcard__name {
  grid-area: 3 / 1; margin: 6px var(--pad) 0; min-height: 2.5em;
  font: 650 1.02rem/1.25 var(--font-display); letter-spacing: -.012em;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
  transition: color var(--dur) var(--ease);
}
.pcard__link { color: inherit; text-decoration: none; }
.pcard__link:hover { color: inherit; }
.pcard__link:focus-visible { outline: none; }
/* The stretched link: the whole card is the target. */
.pcard__link::after { content: ''; position: absolute; inset: 0; z-index: 1; border-radius: var(--r); }

/* The pack switch: radio buttons, so the card sells the family pack with
   no script — one quiet segmented pill. A chip's ::before reaches 44px. */
.vchips {
  display: inline-flex; flex-wrap: wrap; gap: 2px; min-width: 0; margin: 0; padding: 3px; border: 0;
  border-radius: 16px; background: color-mix(in srgb, var(--fg) 6%, transparent);
}
.pcard .vchips { grid-area: 5 / 1; position: relative; z-index: 2; justify-self: start; margin: 11px var(--pad) 0; }
.vchip { position: relative; display: inline-flex; }
.vchip::before { content: ''; position: absolute; inset: -9px -1px; }
.vchip input { position: absolute; inset: 0; z-index: 1; margin: 0; opacity: 0; cursor: pointer; }
.vchip span {
  display: inline-flex; align-items: center; min-height: 26px; padding: 0 10px; border-radius: var(--r-full);
  font: 600 .72rem/1 var(--font-mono); color: var(--fg-subtle); white-space: nowrap;
  transition: color var(--dur) var(--ease), background var(--dur) var(--ease), box-shadow var(--dur) var(--ease), scale var(--dur-press) var(--ease-out);
}
.vchip input:checked + span { background: var(--surface); color: var(--fg); box-shadow: 0 1px 2px rgba(17, 21, 18, .12), 0 3px 10px -4px rgba(17, 21, 18, .2); }
[data-theme='dark'] .vchip input:checked + span { background: #2A302C; }
.vchip input:focus-visible + span { outline: 2px solid var(--focus-ring); outline-offset: 1px; }
.vchip input:active + span { scale: .95; }
/* The price follows the chosen pack, picked out by position; without :has
   every price shows. */
.pcard__buy:not(:has(.vchip:nth-of-type(2) input:checked)) .price[data-v='2'],
.pcard__buy:not(:has(.vchip:nth-of-type(3) input:checked)) .price[data-v='3'],
.pcard__buy:not(:has(.vchip:nth-of-type(4) input:checked)) .price[data-v='4'],
.pcard__buy:has(.vchip:nth-of-type(n+2) input:checked) .price[data-v='1'] { display: none; }
/* ... and the option's own photograph, where options have their own (D82). */
.pcard:not(:has(.vchip:nth-of-type(2) input:checked)) .pcard__img[data-v='2'],
.pcard:not(:has(.vchip:nth-of-type(3) input:checked)) .pcard__img[data-v='3'],
.pcard:not(:has(.vchip:nth-of-type(4) input:checked)) .pcard__img[data-v='4'],
.pcard:has(.vchip:nth-of-type(n+2) input:checked) .pcard__img[data-v='1'] { display: none; }

/* THE FOOT LINE: the price, on the notch's line, beside the way to buy. */
.pcard__price {
  grid-area: 6 / 1; align-self: end; position: relative; z-index: 2;
  display: flex; align-items: center; flex-wrap: wrap; gap: 2px 7px; min-width: 0; min-height: var(--btn-h);
  margin: 10px calc(var(--cut-w) - var(--in)) 0 var(--pad);
}
.pcard.is-still .pcard__price { margin: 10px var(--pad) 12px; min-height: 0; }
.price { font-weight: 600; font-size: 1.1rem; color: var(--fg); }
.pcard .price { font: 800 1.22rem/1 var(--font-display); letter-spacing: -.025em; font-variant-numeric: tabular-nums; }
.pcard__price s { font: 500 var(--fs-label) var(--font-mono); color: var(--fg-subtle); }
.pcard__pack {
  grid-area: 5 / 1; justify-self: start; align-self: end; max-width: calc(100% - 2 * var(--pad)); margin: 10px var(--pad) 0;
  overflow: hidden; text-overflow: ellipsis;
  padding: 4px 7px; border-radius: var(--r-full); background: color-mix(in srgb, var(--fg) 6%, transparent);
  font: 600 var(--fs-label)/1 var(--font-mono); color: var(--fg-subtle); white-space: nowrap;
}
.pcard__off {
  padding: 3px 7px; border-radius: var(--r-full); background: var(--accent-soft); color: var(--accent-ink);
  font: 600 var(--fs-label)/1.2 var(--font-mono); white-space: nowrap;
}
.pcard.is-out .pcard__img { filter: grayscale(.75); opacity: .7; }
/* Price on request is a STATE, not a zero. It is never formatted as money. */
.price--quote { font-size: var(--fs-label); text-transform: uppercase; letter-spacing: var(--track-label); color: var(--accent-ink); }
.pcard .price--quote { font: 600 var(--fs-label)/1.2 var(--font-mono); letter-spacing: var(--track-label); text-transform: uppercase; }

/* Add fills the notch: ink, the brand's green under a pointer, its plus
   turning; it ticks when it lands, busy meanwhile, so a double tap adds
   once. */
.addbtn {
  grid-area: 6 / 1; align-self: end; justify-self: end;
  position: relative; z-index: 3; display: inline-grid; justify-content: center; align-items: center; gap: 6px;
  width: var(--btn-w); height: var(--btn-h); padding: 0; border: 0; border-radius: var(--r-full);
  background: var(--fg); color: var(--bg);
  font-weight: 700; font-size: .88rem; text-decoration: none;
  transition: background-color var(--dur) var(--ease), color var(--dur) var(--ease), opacity var(--dur) var(--ease), scale var(--dur-press) var(--ease-out);
}
.addbtn::before { content: ''; position: absolute; inset: -3px; }
.addbtn:hover { color: var(--bg); }
.addbtn:active { scale: .94; }
.addbtn .ico { grid-area: 1 / 1; width: 17px; height: 17px; }
.addbtn__txt { grid-area: 1 / 2; }
.addbtn__plus, .addbtn__done { transition: opacity var(--dur) var(--ease), scale .35s var(--ease-out), rotate .35s var(--ease-out); }
.addbtn__done { opacity: 0; scale: .4; }
.is-done .addbtn__plus { opacity: 0; scale: .4; rotate: 90deg; }
.is-done .addbtn__done { opacity: 1; scale: 1; }
/* No price yet: Ask, in the gold. */
.addbtn--ask { background: var(--accent); color: var(--on-accent); }
.addbtn--ask:hover { color: var(--on-accent); }
.is-busy { cursor: progress; opacity: .72; }
@media (hover: hover) and (pointer: fine) {
  .addbtn:not(.addbtn--ask):hover { background-color: var(--brand); color: var(--on-brand); }
  .addbtn:not(.addbtn--ask):hover .addbtn__plus { rotate: 90deg; }
}

/* The stepper that takes Add's place once the pack is in the cart: the
   same size in the same notch, in the brand's green. */
.pstep {
  grid-area: 6 / 1; align-self: end; justify-self: end;
  position: relative; z-index: 3;
  display: grid; grid-template-columns: 34px minmax(0, 1fr) 34px; align-items: center;
  width: var(--btn-w); height: var(--btn-h); border-radius: var(--r-full); background: var(--brand); color: var(--on-brand);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .16);
  animation: pstepIn .35s var(--ease-out);
}
@keyframes pstepIn { from { opacity: 0; scale: .88; } }
.pstep button {
  position: relative; height: var(--btn-h); display: grid; place-items: center;
  border: 0; border-radius: var(--r-full); background: none; color: inherit;
  transition: background var(--dur) var(--ease), scale var(--dur-press) var(--ease-out);
}
.pstep button::before { content: ''; position: absolute; inset: -3px 0; }
.pstep button:hover { background: rgba(255, 255, 255, .14); }
.pstep button:active { scale: .86; }
.pstep .ico { width: 16px; height: 16px; }
.pstep output { font: 600 .92rem var(--font-mono); text-align: center; }
.pstep.is-busy { opacity: 1; }
.pstep.is-busy output { opacity: .5; }

/* A CARD AS ITS OWN SKELETON — its ground, its well and bars where the
   brand, name and price will be, breathing (an opacity pulse), while it
   waits: for the script on a slow line (until main.js deals it in), and
   while the shop fetches a filter (`is-loading`, shop.js). Its words stay
   in place, unseen, holding the layout. */
:is(html.js:not(.reveal-on) .pcard[data-reveal], .results.is-loading .pcard) { opacity: 1; animation: skelPulse 1.3s ease-in-out infinite; }
:is(html.js:not(.reveal-on) .pcard[data-reveal], .results.is-loading .pcard) > :not(.pcard__shot) { visibility: hidden; }
:is(html.js:not(.reveal-on) .pcard[data-reveal], .results.is-loading .pcard) .pcard__media { visibility: visible; background: var(--skel-bg); }
:is(html.js:not(.reveal-on) .pcard[data-reveal], .results.is-loading .pcard) .pcard__media > * { visibility: hidden; }
:is(html.js:not(.reveal-on) .pcard[data-reveal], .results.is-loading .pcard)::after {
  content: ''; grid-area: 2 / 1 / -1 / -1; margin: 15px var(--pad) 14px; pointer-events: none;
  background:
    linear-gradient(var(--skel-bg) 0 0) left 0 top 0 / 42% 10px no-repeat,
    linear-gradient(var(--skel-bg) 0 0) left 0 top 22px / 90% 14px no-repeat,
    linear-gradient(var(--skel-bg) 0 0) left 0 top 42px / 62% 14px no-repeat,
    linear-gradient(var(--skel-bg) 0 0) left 0 bottom 8px / 34% 22px no-repeat;
}
@keyframes skelPulse { 50% { opacity: .55; } }
@media (prefers-reduced-motion: reduce) { :is(html.js:not(.reveal-on) .pcard[data-reveal], .results.is-loading .pcard) { animation: none; } }

/* ----- the specimen tile
   No photograph: the range's tint and mark (DESIGN.md). */
.specimen {
  position: absolute; inset: 0; overflow: hidden; display: grid; place-items: center;
  background: radial-gradient(90% 70% at 50% 0%, var(--tint-a, var(--brand-soft)), transparent 70%), var(--surface-sunk);
}
.specimen::before {
  content: ''; position: absolute; inset: 0; opacity: .5;
  background-image: repeating-linear-gradient(-45deg, transparent 0 11px, color-mix(in srgb, var(--fg) 4%, transparent) 11px 12px);
}
.specimen__mark { position: relative; width: 44%; height: 44%; color: var(--tint-b, var(--brand)); opacity: .38; }


/* ----- into the cart (shop.js flyToCart): the photograph's copy that
   arcs from the card to the cart; transform and opacity only. */
.flyimg {
  position: fixed; z-index: 400; pointer-events: none; object-fit: cover;
  border-radius: 18px; background: #fff;
  box-shadow: 0 18px 40px -12px rgba(17, 21, 18, .45);
  transform-origin: 50% 50%; will-change: transform;
}

/* ----- toast */
.toast {
  position: fixed; z-index: 60; left: 50%; bottom: max(24px, env(safe-area-inset-bottom));
  width: min(440px, calc(100vw - 24px)); translate: -50% 0;
  display: grid; grid-template-columns: 56px minmax(0, 1fr) auto; align-items: center; gap: 12px;
  padding: 10px; border: 1px solid var(--border); border-radius: 22px;
  background: var(--surface); box-shadow: var(--shadow-lg);
  transition: opacity .32s var(--ease-out), translate .32s var(--ease-out);
}
@starting-style { .toast { opacity: 0; translate: -50% 18px; } }
/* Leaving is shorter than arriving (Emil Kowalski). */
.toast.is-leaving { opacity: 0; translate: -50% 10px; transition-duration: .18s; }
.toast__pic { width: 56px; height: 56px; border-radius: 14px; object-fit: contain; background: var(--plate); }
.toast__txt { display: grid; gap: 2px; min-width: 0; line-height: 1.3; }
.toast__txt small {
  display: inline-flex; align-items: center; gap: 6px;
  font: 600 var(--fs-label)/1.2 var(--font-mono); text-transform: uppercase; letter-spacing: var(--track-label); color: var(--ok);
}
.toast__txt b { overflow: hidden; white-space: nowrap; text-overflow: ellipsis; font-size: .92rem; }
.toast__txt span { overflow: hidden; white-space: nowrap; text-overflow: ellipsis; font-size: .82rem; color: var(--fg-subtle); }
.toast.is-error { grid-template-columns: minmax(0, 1fr) auto; padding-left: 18px; }
.toast.is-error .toast__txt small { color: var(--err); }


/* A tick, drawn once: the filters' checkboxes, the partners' ticked lists. */
:root {
  --tick: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4.5 12.5l5 5 10-11'/%3E%3C/svg%3E");
}

@media (max-width: 1080px) {
  .shead__grid { grid-template-columns: minmax(0, 1fr) minmax(0, 260px); }
}
@media (max-width: 760px) {
  .shead__grid { grid-template-columns: minmax(0, 1fr); }
  .shead__stats dd { font-size: 1.35rem; }
  .toast { top: calc(var(--top-h, 60px) + 10px); bottom: auto; }
  @starting-style { .toast { opacity: 0; translate: -50% -14px; } }
  .toast.is-leaving { translate: -50% -8px; }
}
/* Two up on a phone: tighter corners, a smaller notch for a smaller Add
   (80x36 in an 85x41 notch; its ::before still reaches 44px). */
@media (max-width: 599px) {
  .pcard {
    --cut: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='97' height='53'%3E%3Cpath d='M0 0H97A12 12 0 0 1 85 12H35A23 23 0 0 0 12 35V41A12 12 0 0 1 0 53Z'/%3E%3C/svg%3E");
    --cut-w: 97px; --cut-h: 53px; --btn-w: 80px; --btn-h: 36px;
    --in: 5px; --pad: 11px; --r: 18px;
  }
  .pcard__brand { margin-top: 11px; }
  .pcard__name { font-size: .94rem; }
  .pcard .price { font-size: 1.08rem; }
  .pcard__flags { top: 6px; left: 6px; right: 6px; }
  .pcard__flag { padding: 4px 7px; }
  .addbtn { font-size: .8rem; gap: 4px; }
  .addbtn .ico { width: 15px; height: 15px; }
  .pstep { grid-template-columns: 28px minmax(0, 1fr) 28px; }
}

/* A narrow card (two up on a phone, five across at 1024): the price beside
   Add had 18-70px and ran under it. There the price takes its own line,
   the card's width, just above the notch (D87). */
@container pcard (max-width: 205px) {
  .pcard__price { margin: 10px var(--pad) calc(var(--cut-h) - 2px); min-height: 0; }
}
