/*
Theme Name: Caliber Sciences
Author: Caliber Sciences
Description: Purpose-built WordPress block (FSE) theme for Caliber Sciences, an injectable-peptide reference storefront. Rebrand v2 (2026-08-01): monochrome clinical register, not a boutique apothecary. Paper-white ground, near-black ink, hairline structure, a single steel-blue accent used only where it carries meaning (links, focus, the top evidence tier, low-stock signal), geometric Archivo sans for words, IBM Plex Mono for every number. See the token table below for the full system.
Requires at least: 6.6
Tested up to: 7.0
Requires PHP: 8.1
Version: 1.2.0
License: Unlicensed - private, unpublished theme
Text Domain: caliber-sciences

----------------------------------------------------------------------------
DESIGN TOKENS - source of truth is theme.json (settings.color.palette,
settings.typography). theme.json is strict JSON and cannot carry comments,
so the one-line usage rule for each token lives here. Hex/rgba values below
MUST always match theme.json exactly - if you change a token, change it in
both files and re-run storefront/tests/check-contrast.sh before committing.

None of these slugs reuse WordPress core's default preset slugs (small,
medium, large, x-large, huge for font sizes; the numeric 10-80 scale for
spacing; black, white, vivid-* for colors) - core silently wins a merge on
any of those names, so every slug here is deliberately distinct.

Color palette (slug -> usage rule):
  base          #FAFAF8  Page background. Paper, not bone - the warm cream
                          register of the previous storefront pass is gone;
                          this is a cold, clinical white-adjacent ground.
  surface       #FFFFFF  Card, table, and panel backgrounds - pure white,
                          one step brighter than base so surfaces read as
                          slightly raised without any shadow or gradient.
  ink           #16181A  Primary text, headings, default icon/border color,
                          and the fill for the footer band. Near-black,
                          neutral (no warm cast). 14.7:1 on base.
  gray-muted    #565B60  Secondary/meta text only (captions, table headers,
                          source markers, category tag lines). 7.0:1 on
                          base - AA and AAA both clear with real margin.
  hairline      rgba(22,24,26,.14)  Every rule and border in the system,
                          always 1px. Borders only, never text - exempt
                          from the contrast gate for the same reason a low-
                          opacity divider always is.
  accent        #2F5F8F  THE ONLY color in the system besides ink/gray. Used
                          exclusively for: links, focus-visible outlines,
                          the top evidence tier badge, and the low-stock
                          batch signal. 5.6:1 on base. If an element is not
                          one of those four things, it is not blue - this is
                          a hard rationing rule, not a style preference.
  accent-strong #1F4265  Link hover/active state only.
  accent-tint   #EAF0F6  Fill for the top-tier badge and selected/hover
                          surfaces. Never used as a text color.

REMOVED: the previous pass's two warm-toned tokens (a readable deep tone
used for headings/links, and a bright accessory tone used for chip/banner
fills) and every rule that filled/bordered/colored text with them. Former
roles map forward as: the deep tone's heading-color role -> ink; the
bright tone's chip-fill role -> gone (chips are retired, see the
category-tags section below); any purely decorative warm-toned border or
fill -> hairline, or accent only where the element is actually interactive
(a link, a focus state, a top-tier/low-stock signal). There is no
substitute "second accent" color in this system - accent is rationed, not
relocated.

Typography (theme.json slugs):
  display  Archivo, weight 650 for headings. Same physical font as `body`
           (see below) - the two slugs share one variable file and exist
           so templates can keep addressing "display" vs "body" as
           distinct roles even though, post-rebrand, both resolve to the
           same typeface. The previous pass's serif display face and its
           @font-face are gone entirely: no serif ships in this theme any
           more (anti-slop rule 0, caliber-rebrand-v2-design.md).
  body     Archivo 400/500/650/700 against the existing self-hosted
           archivo-variable.woff2 (no new font asset - the file's wght
           axis already spans the weights this theme actually uses, so a
           discrete @font-face entry per weight against the same source
           costs nothing beyond the declaration). 400 is body copy; 500 is
           the primary button label and the "SCIENCES" half of the wordmark;
           650 is every heading; 700 is the "CALIBER" half of the wordmark.
           No other Archivo weight is declared because none is used.
  mono     IBM Plex Mono 400/500/600, self-hosted as three static woff2
           files (theme/assets/fonts/ibm-plex-mono-{400,500,600}.woff2,
           agent-C-owned asset; the @font-face rules for these three files
           live below, in this stylesheet, not in theme.json - a static
           per-weight font family is simplest declared as plain CSS rather
           than through theme.json's fontFace mechanism, which this theme
           otherwise reserves for the single Archivo variable file). ALL
           data is mono: prices, doses, strengths, vial counts, lot
           numbers, SKUs, dates, evidence-tier labels, nav/eyebrow labels.
           Archivo (the `body`/`display` slugs) never renders a number.

Font-size slugs (theme.json settings.typography.fontSizes) - all fixed
(no fluid clamp) except `display`, which is a hand-authored clamp():
  micro       0.6875rem  - eyebrow/label text, nav links, table headers.
  caption     0.8125rem  - secondary/meta text, dosing-table data cells.
  base        1rem       - body copy, button label size (theme default).
  lede        1.0625rem  - intro/lead paragraphs (h4 default, .pdp-summary).
  heading-sm  1.375rem   - h3 default, product-card titles.
  heading-lg  1.75rem    - h2 default.
  display     clamp(2.1rem, 1.7rem + 2vw, 3rem)  - h1/hero default.

Spacing slugs (theme.json settings.spacing.spacingSizes) - unchanged by
the rebrand, same non-colliding-slug reasoning as font sizes:
  hairline  0.5rem   tight       1rem     base   1.5rem
  component clamp(2rem,...,2.5rem)        section-sm  clamp(3rem,...,4rem)
  section   clamp(4rem,...,6rem)          section-lg  clamp(5rem,...,8rem)

Custom tokens (settings.custom, --wp--custom--*):
  lineWidth          1px    - every hairline rule/border in the system.
  tracking.micro     0.12em - letter-spacing for eyebrow/micro/nav text.
  tracking.wide      0.06em - letter-spacing for uppercase captions.
  radius.sm          2px    - buttons, form controls, the evidence badge.
  radius.md          4px    - cards, panels, tables, product tiles.
  radius.pill        4px    - kept as a slug so any stray template still
                              requesting "pill" degrades to a rectangle
                              instead of a stadium shape; nothing in this
                              build requests a NEW pill radius (anti-slop
                              rule 0: nothing rounder than 4px anywhere).

Root padding (styles.spacing.padding, theme.json) - clamp(1.25rem, 5vw,
4rem) left/right, 0 top/bottom. Works with settings.
useRootPaddingAwareAlignments (already true) to give every alignwide/
default-width block a horizontal gutter at narrow viewports while
alignfull sections keep bleeding to the true viewport edge for their own
background/color-block treatment.

Asset path convention: static theme assets referenced from block template
HTML (parts/*.html, templates/*.html - no PHP available there) use
root-relative paths, e.g. /wp-content/themes/solu/assets/img/... . This
assumes a domain-root WordPress install (true here); revisit if the site
ever moves to a subdirectory install.
----------------------------------------------------------------------------
*/

/* -------------------------------------------------------------------- */
/* IBM Plex Mono - self-hosted static weights (theme/assets/fonts/, an   */
/* agent-C-owned asset shipped in parallel with this stylesheet; these   */
/* faces are declared here regardless of whether the files have landed   */
/* yet - a 404 on the woff2 just falls back to the ui-monospace stack in */
/* the `mono` font-family declaration, it does not break the page). SIL  */
/* OFL 1.1, copyright IBM - see theme/assets/fonts/LICENSE-fonts.md      */
/* (agent-C-owned). font-display: swap avoids a flash of invisible mono  */
/* text on first paint.                                                  */
/* -------------------------------------------------------------------- */

@font-face {
  font-family: 'IBM Plex Mono';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('assets/fonts/ibm-plex-mono-400.woff2') format('woff2');
}

@font-face {
  font-family: 'IBM Plex Mono';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('assets/fonts/ibm-plex-mono-500.woff2') format('woff2');
}

@font-face {
  font-family: 'IBM Plex Mono';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url('assets/fonts/ibm-plex-mono-600.woff2') format('woff2');
}

/* -------------------------------------------------------------------- */
/* Base reset - the minimum not already handled by theme.json/WP core.  */
/* -------------------------------------------------------------------- */

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

img,
svg {
  max-width: 100%;
  height: auto;
  display: block;
}

/* Corner radius is small and restrained now (2px controls/badges, 4px
   cards/panels/tables) - the previous pass's "rounded-but-confident"
   moderate radius (10px/16px/999px pill) is gone along with the warm
   apothecary register it belonged to. Nothing in this theme is rounder
   than 4px (anti-slop rule 0). */
.wp-block-button__link,
.wp-block-search__button,
input,
select,
textarea {
  border-radius: var(--wp--custom--radius--sm);
}

/* -------------------------------------------------------------------- */
/* Motion - CSS-only hover transitions, nothing else. 120ms max (anti-   */
/* slop rule 0). Respect prefers-reduced-motion throughout (Lighthouse/  */
/* accessibility budget).                                                */
/* -------------------------------------------------------------------- */

a,
.wp-block-button__link,
.rule-top,
.rule-bottom,
.caliber-card,
.caliber-brand,
.caliber-nav a {
  transition: color 0.12s ease, border-color 0.12s ease, background-color 0.12s ease;
}

@media (prefers-reduced-motion: reduce) {
  * {
    transition-duration: 0.001ms !important;
  }
}

/* -------------------------------------------------------------------- */
/* Link styling - plain underline (a real text-decoration, not a border */
/* hack), accent by default, accent-strong on hover/active (theme.json  */
/* styles.elements.link carries the color/textDecoration; underline-     */
/* offset has no theme.json property, so it is set here). Focus-visible  */
/* everywhere: 2px accent outline, offset 2px (WCAG 2.4.7), never a      */
/* color-only state change.                                              */
/* -------------------------------------------------------------------- */

a {
  text-underline-offset: 3px;
}

a:hover,
a:focus-visible {
  text-decoration-thickness: 2px;
}

a:focus-visible,
button:focus-visible,
.wp-block-button__link:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible {
  outline: 2px solid var(--wp--preset--color--accent);
  outline-offset: 2px;
}

/* -------------------------------------------------------------------- */
/* Secondary button (5.9) - WP core's built-in "Outline" button style    */
/* variation, not a custom class: 1px hairline border, ink text, hover   */
/* solidifies the border to full ink. The default (primary) button fill  */
/* is entirely theme.json-driven (styles.elements.button).               */
/* -------------------------------------------------------------------- */

.wp-block-button.is-style-outline .wp-block-button__link {
  background-color: transparent;
  color: var(--wp--preset--color--ink);
  border: 1px solid var(--wp--preset--color--hairline);
}

.wp-block-button.is-style-outline .wp-block-button__link:hover {
  border-color: var(--wp--preset--color--ink);
}

/* -------------------------------------------------------------------- */
/* Divider rule utilities - lighter-weight structural lines than a      */
/* whole-page grid; used sparingly to separate nav/footer zones and, in */
/* this rebrand, to replace every card/box border the previous pass     */
/* used for the front-page explainer columns and similar spots.         */
/* -------------------------------------------------------------------- */

.rule-top {
  border-top: var(--wp--custom--line-width) solid var(--wp--preset--color--hairline);
}

.rule-bottom {
  border-bottom: var(--wp--custom--line-width) solid var(--wp--preset--color--hairline);
}

/* -------------------------------------------------------------------- */
/* Eyebrow - uppercase tracked micro-label, now mono (data/label voice)  */
/* instead of Archivo, gray-muted by default. `.is-accent` is for the    */
/* front-page hero eyebrow (5.10: "eyebrow, mono micro uppercase         */
/* accent") - accent is rationed to links/focus/top-tier/low-stock       */
/* elsewhere in this system, and a hero eyebrow reads as a wayfinding    */
/* label in the same family as a current-nav-link, so it earns the      */
/* exception. `.is-on-dark` is for eyebrows placed on the footer's ink   */
/* ground (the footer's "Reference"/"Legal" column labels) - gray-muted  */
/* fails contrast on ink, so this variant uses the same paper-on-ink     */
/* text color the rest of the footer uses (5.2).                        */
/* -------------------------------------------------------------------- */

.eyebrow {
  font-family: var(--wp--preset--font-family--mono);
  font-size: var(--wp--preset--font-size--micro);
  font-weight: 500;
  letter-spacing: var(--wp--custom--tracking--micro);
  text-transform: uppercase;
  color: var(--wp--preset--color--gray-muted);
}

.eyebrow.is-on-dark {
  color: rgba(250, 250, 248, 0.72);
}

.eyebrow.is-accent {
  color: var(--wp--preset--color--accent);
}

/* -------------------------------------------------------------------- */
/* Card / panel - the general-purpose surface-tinted container: info    */
/* panels, the empty-state block. Flat 1px hairline border, 4px radius,  */
/* no shadow - the previous pass's bold 2px ink border and 16px radius   */
/* both die here (this rule is explicitly named in the rebrand brief).   */
/* Product tiles use the more specific .caliber-card component below,    */
/* not this generic class.                                               */
/* -------------------------------------------------------------------- */

.card {
  background-color: var(--wp--preset--color--surface);
  border: 1px solid var(--wp--preset--color--hairline);
  border-radius: var(--wp--custom--radius--md);
}

/* Unused by any current template (kept for a future dark/ink-filled
   card variant, e.g. a featured or "sold out" tile) - ink fill, base
   text, a paper-on-ink hairline (rgba(250,250,248,0.16), the same value
   the footer uses for its own rule lines on ink) so the frame stays
   visible against its own fill without reaching for the rationed accent
   or a color that no longer exists in this palette. */
.card.is-on-ink {
  background-color: var(--wp--preset--color--ink);
  border-color: rgba(250, 250, 248, 0.16);
  color: var(--wp--preset--color--base);
}

/* -------------------------------------------------------------------- */
/* Screen-reader-only utility (skip-link partner, form labels, etc).    */
/* -------------------------------------------------------------------- */

.u-visually-hidden {
  border: 0;
  clip: rect(0, 0, 0, 0);
  height: 1px;
  margin: -1px;
  overflow: hidden;
  padding: 0;
  position: absolute;
  width: 1px;
  white-space: nowrap;
}

/* -------------------------------------------------------------------- */
/* Brand lockup (section 1) - the inline reticle-mark SVG                */
/* (theme/assets/img/icon-mark.svg, fill="currentColor") paired with the */
/* live-text wordmark: "CALIBER" (Archivo 700) + "LABS" (Archivo 500),   */
/* both uppercase, letter-spacing 0.08em, a 0.45em gap between the two    */
/* words and a 0.55em gap between the mark and the wordmark. Two fixed   */
/* margins (not a single flex `gap`) because those two gaps are          */
/* deliberately different sizes - a single `gap` shorthand on the flex   */
/* container would make them equal, which the brief does not ask for.    */
/* Renders at 0.95rem in the header (ink); the footer variant is paper   */
/* on ink (section 5.2) via the `footer`/`.has-ink-background-color`      */
/* context selectors below, since the SVG mark already recolors for free */
/* through currentColor and needs no separate rule of its own.           */
/*                                                                        */
/* Supersedes the previous pass's `.wordmark`/`.wordmark-mark` classes -  */
/* this is the shared class contract with agents B (templates) and C     */
/* (render markup); do not reintroduce the old class names.               */
/* -------------------------------------------------------------------- */

.caliber-brand {
  display: inline-flex;
  align-items: center;
  font-size: 0.95rem;
  line-height: 1;
  color: var(--wp--preset--color--ink);
  text-decoration: none;
}

.caliber-brand:hover,
.caliber-brand:focus-visible {
  color: var(--wp--preset--color--accent-strong);
}

.caliber-brand-mark {
  width: 1.6em;
  height: 1.6em;
  flex-shrink: 0;
  margin-right: 0.55em;
}

.caliber-brand b,
.caliber-brand strong {
  font-family: var(--wp--preset--font-family--body);
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.caliber-brand span:not(.caliber-brand-mark):not(.u-visually-hidden) {
  display: inline-block;
  font-family: var(--wp--preset--font-family--body);
  font-weight: 500;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  margin-left: 0.45em;
}

footer .caliber-brand,
.has-ink-background-color .caliber-brand {
  color: var(--wp--preset--color--base);
}

footer .caliber-brand:hover,
footer .caliber-brand:focus-visible,
.has-ink-background-color .caliber-brand:hover,
.has-ink-background-color .caliber-brand:focus-visible {
  color: rgba(250, 250, 248, 0.72);
}

/* -------------------------------------------------------------------- */
/* Primary navigation (5.1/5.2) - mono, micro, uppercase, tracked,       */
/* gray-muted by default; current page and hover switch to ink with a    */
/* 2px accent underline offset 4px (a box-shadow, not text-decoration,   */
/* so the offset is exact and independent of the underline the link      */
/* element style would otherwise draw). On the footer's ink ground the   */
/* same class instead follows the footer's own link convention (5.2):    */
/* rgba(250,250,248,0.72) text, underlined, paper on hover - the box-     */
/* shadow current-page indicator does not apply there, since the footer  */
/* nav is a plain link list, not a wayfinding bar.                       */
/* -------------------------------------------------------------------- */

.caliber-nav {
  display: flex;
  flex-wrap: wrap;
  gap: 1.25rem;
}

.caliber-nav a {
  font-family: var(--wp--preset--font-family--mono);
  font-size: var(--wp--preset--font-size--micro);
  font-weight: 500;
  letter-spacing: var(--wp--custom--tracking--micro);
  text-transform: uppercase;
  color: var(--wp--preset--color--gray-muted);
  text-decoration: none;
  padding-bottom: 4px;
  box-shadow: 0 2px 0 0 transparent;
}

.caliber-nav a:hover,
.caliber-nav a:focus-visible,
.caliber-nav a.current-menu-item,
.caliber-nav a[aria-current="page"] {
  color: var(--wp--preset--color--ink);
  box-shadow: 0 2px 0 0 var(--wp--preset--color--accent);
}

footer .caliber-nav a,
.has-ink-background-color .caliber-nav a {
  color: rgba(250, 250, 248, 0.72);
  text-decoration: underline;
  text-underline-offset: 3px;
  padding-bottom: 0;
}

footer .caliber-nav a:hover,
footer .caliber-nav a:focus-visible,
.has-ink-background-color .caliber-nav a:hover,
.has-ink-background-color .caliber-nav a:focus-visible {
  color: var(--wp--preset--color--base);
  box-shadow: none;
}

/* -------------------------------------------------------------------- */
/* Product card (5.3) - surface white, 1px hairline border, 4px radius,  */
/* tight padding. Hover: border-color accent (the title itself stays     */
/* ink - only the frame signals interactivity). No image region, no      */
/* inner boxes: the card is a title, a category-tag line, and a price    */
/* line, full stop.                                                      */
/*                                                                        */
/* Stack: .caliber-card-top (the peptide-class term, mono/micro/gray-    */
/* muted, and a 14px reticle mark at 25% ink opacity, right-aligned) ->   */
/* the h3 title (inherits the sitewide heading style: Archivo 650, ink)   */
/* -> .caliber-tags -> .caliber-price, pushed to the card's bottom edge   */
/* by margin-top:auto since the card itself is a flex column.            */
/* -------------------------------------------------------------------- */

.caliber-card {
  display: flex;
  flex-direction: column;
  gap: 0.55rem;
  background-color: var(--wp--preset--color--surface);
  border: 1px solid var(--wp--preset--color--hairline);
  border-radius: var(--wp--custom--radius--md);
  padding: var(--wp--preset--spacing--tight);
}

.caliber-card:hover,
.caliber-card:focus-within {
  border-color: var(--wp--preset--color--accent);
}

.caliber-card h3 {
  margin: 0;
}

.caliber-card h3 a {
  color: inherit;
  text-decoration: none;
}

/* nowrap + a growing first child keeps the mark on the SAME row as the
   peptide-class term. Without it a long term ("Immune, Mitochondrial, and
   Metabolic Compounds") pushed the 14px mark onto its own line, where it
   read as a stray dot floating under the label rather than as a corner
   register mark. The term wraps internally instead. */
.caliber-card-top {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  flex-wrap: nowrap;
  gap: 0.5rem;
  font-family: var(--wp--preset--font-family--mono);
  font-size: var(--wp--preset--font-size--micro);
  font-weight: 500;
  letter-spacing: var(--wp--custom--tracking--micro);
  text-transform: uppercase;
  color: var(--wp--preset--color--gray-muted);
}

.caliber-card-mark {
  width: 14px;
  height: 14px;
  flex-shrink: 0;
  color: var(--wp--preset--color--ink);
  opacity: 0.25;
}

/* -------------------------------------------------------------------- */
/* Category tags (5.4) - a single line of interpunct-separated mono      */
/* text, never a box or a pill. Micro size on cards (the default);       */
/* .caliber-detail scopes the PDP context up to caption size per 5.4.     */
/* The previous pass's pill-shaped category-chip system this replaces is  */
/* deleted below.                                                         */
/* Any `<a>` inside this line (the taxonomy-archive chip-row use per      */
/* section 6) simply inherits the sitewide accent link color - no extra  */
/* rule needed for that case.                                             */
/* -------------------------------------------------------------------- */

.caliber-tags {
  display: block;
  font-family: var(--wp--preset--font-family--mono);
  font-size: var(--wp--preset--font-size--micro);
  font-weight: 400;
  letter-spacing: 0.04em;
  line-height: 1.5;
  color: var(--wp--preset--color--gray-muted);
  margin: 0;
  overflow-wrap: anywhere;
}

.caliber-detail .caliber-tags {
  font-size: var(--wp--preset--font-size--caption);
}

/* -------------------------------------------------------------------- */
/* Price line (5.5) - mono, no wrapper box, no label. The amount segment */
/* (a `b`/`strong` child) is weight 600 ink; the unit segment (a `small`  */
/* child, e.g. "/ 10 mg vial") is weight 400 gray-muted and never wraps.  */
/* Multiple strengths are separate .caliber-price-line elements inside   */
/* one .caliber-price wrapper, stacked 0.35em apart via the adjacent-     */
/* sibling margin below rather than a flex `gap`, so it holds regardless  */
/* of whether the renderer emits `<p>`, `<div>`, or `<li>` per line.      */
/* .caliber-price itself carries the card's bottom hairline rule and the */
/* margin-top:auto that pins it to the card's bottom edge (5.3); outside  */
/* a flex-column context - e.g. a standalone PDP price block - margin-    */
/* top:auto is simply a no-op, which is the correct, harmless fallback.   */
/* -------------------------------------------------------------------- */

/* The separating rule belongs to the CARD context only. The same renderer
   output also appears standalone on the PDP, inside a section that already
   draws its own .rule-top - unscoped, the two stacked into a pair of empty
   hairlines above the price with nothing between them. */
.caliber-card .caliber-price {
  margin-top: auto;
  padding-top: 0.7rem;
  border-top: 1px solid var(--wp--preset--color--hairline);
}

.caliber-price-line {
  display: block;
  font-family: var(--wp--preset--font-family--mono);
  font-size: var(--wp--preset--font-size--base);
  color: var(--wp--preset--color--ink);
}

.caliber-price-line + .caliber-price-line {
  margin-top: 0.35em;
}

.caliber-price-line b,
.caliber-price-line strong {
  font-weight: 600;
}

.caliber-price-line small {
  font-weight: 400;
  font-size: var(--wp--preset--font-size--caption);
  color: var(--wp--preset--color--gray-muted);
  white-space: nowrap;
  margin-left: 0.35em;
}

/* -------------------------------------------------------------------- */
/* Evidence tier badge (5.6) - the ONE outlined badge in the system now. */
/* This replaces the previous five-tier weight-ramp system entirely      */
/* (is-approved/is-trialed/is-early-human/is-animal-only/is-anecdotal),  */
/* which depended on the two retired warm-toned tokens for three of its  */
/* of its five states. The new system is a plain binary: the top tier    */
/* (regulatory_label) gets the one rationed use of accent as a fill/     */
/* border/text color; every other tier renders identically - hairline    */
/* border, gray-muted text, no fill - because the brief no longer asks   */
/* this badge to carry a five-step visual hierarchy, only to mark "is     */
/* this the strongest evidence tier, yes or no." Split-tier rendering     */
/* (two badges side by side for a compound with two tiers) is a rendering */
/* concern owned by mu-plugins/reference-render.php, not this stylesheet  */
/* - multiple adjacent .caliber-tier elements simply flow inline.         */
/* -------------------------------------------------------------------- */

.caliber-tier {
  display: inline-flex;
  align-items: center;
  font-family: var(--wp--preset--font-family--mono);
  font-size: var(--wp--preset--font-size--micro);
  font-weight: 500;
  letter-spacing: var(--wp--custom--tracking--micro);
  text-transform: uppercase;
  border: 1px solid var(--wp--preset--color--hairline);
  border-radius: var(--wp--custom--radius--sm);
  padding: 0.3em 0.7em;
  color: var(--wp--preset--color--gray-muted);
  background-color: transparent;
}

.caliber-tier.is-top {
  border-color: var(--wp--preset--color--accent);
  color: var(--wp--preset--color--accent);
  background-color: var(--wp--preset--color--accent-tint);
}

/* -------------------------------------------------------------------- */
/* Dosing gap - a deliberate "no citable figure" research finding        */
/* (dosing/pharmacokinetics/post-reconstitution-stability entries whose   */
/* source_type requires a gap_statement instead of a citation). Renders   */
/* as a quiet, permanent-looking callout: surface background, a 1px      */
/* hairline border, gray-muted text. A dosing gap is a completed,        */
/* correct finding that the literature has no number, not unfinished     */
/* editorial work, so its treatment is deliberately calm rather than      */
/* loud (mu-plugins/reference-render.php always precedes the gap text     */
/* with a literal bold "No citable figure." lead-in, so the distinction   */
/* is carried by visible text as well as by this container). No token in  */
/* this rule changed name in the rebrand, only their values, via the      */
/* preset vars below - nothing here needed editing.                      */
/* -------------------------------------------------------------------- */

.dosing-gap {
  display: block;
  background-color: var(--wp--preset--color--surface);
  border: 1px solid var(--wp--preset--color--hairline);
  border-radius: var(--wp--custom--radius--sm);
  color: var(--wp--preset--color--gray-muted);
  padding: 0.85em 1.1em;
  margin: 0.75em 0;
  font-size: var(--wp--preset--font-size--caption);
  line-height: 1.55;
}

.dosing-gap strong {
  color: var(--wp--preset--color--ink);
}

/* -------------------------------------------------------------------- */
/* Reconstitution dose calculator (single-product.html, mu-plugins/     */
/* reference-render.php, theme/assets/js/reconstitution-calculator.js). */
/* Layout and form-control styling only - the calculator's own logic    */
/* lives entirely in the JS file; this stylesheet has no state to       */
/* express beyond the one warning variant below. Focus-visible styling  */
/* for these inputs/select is already covered by the sitewide           */
/* input:focus-visible / select:focus-visible rule near the top of this */
/* file - nothing new is needed for that.                               */
/* -------------------------------------------------------------------- */

.reconstitution-calculator__form {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(9rem, 1fr));
  gap: 0.85rem;
  margin: 0.75rem 0;
}

.reconstitution-calculator__field {
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
}

.reconstitution-calculator__field label {
  font-family: var(--wp--preset--font-family--body);
  font-size: var(--wp--preset--font-size--caption);
  font-weight: 600;
  color: var(--wp--preset--color--ink);
}

.reconstitution-calculator__field input,
.reconstitution-calculator__field select {
  border: 1px solid var(--wp--preset--color--hairline);
  border-radius: var(--wp--custom--radius--sm);
  padding: 0.5em 0.65em;
  font-family: var(--wp--preset--font-family--body);
  font-size: var(--wp--preset--font-size--base);
  background-color: var(--wp--preset--color--base);
  color: var(--wp--preset--color--ink);
}

.reconstitution-calculator__result {
  margin-top: 0.75rem;
  padding-top: 0.75rem;
  border-top: 1px solid var(--wp--preset--color--hairline);
}

.reconstitution-calculator__result dl {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 0.3rem 0.75rem;
  margin: 0;
}

.reconstitution-calculator__result dt {
  font-weight: 600;
  color: var(--wp--preset--color--gray-muted);
}

.reconstitution-calculator__result dd {
  margin: 0;
  color: var(--wp--preset--color--ink);
}

/* The over-1-mL "exceeds syringe capacity" case - the single most
   practically useful finding in the source research corpus. The
   previous pass gave this the theme's loudest treatment (a bright warm-
   toned fill, ink border) alongside the legal-draft banner; that token
   is retired now, and accent is reserved for links/focus/top-
   tier/low-stock, none of which this is. A solid 1px ink border (heavier
   than the standard hairline, since this is a live arithmetic result the
   reader just produced, not passive chrome) on a surface fill keeps the
   warning legible without misusing a color the rebrand rations. */
.reconstitution-calculator__warning {
  display: block;
  margin-top: 0.75rem;
  background-color: var(--wp--preset--color--surface);
  border: 1px solid var(--wp--preset--color--ink);
  border-radius: var(--wp--custom--radius--sm);
  color: var(--wp--preset--color--ink);
  padding: 0.75em 1em;
  font-weight: 600;
}

/* -------------------------------------------------------------------- */
/* Dosing table (5.7, restructured 2026-08-01) - Ro-style Timeframe /     */
/* Dosage / Frequency / Note columns, all four genuinely data (a week     */
/* range, a dose, a schedule word, a footnote marker) - the previous       */
/* regimen-name-as-prose-label first column is gone, so every column is   */
/* now mono per this stylesheet's own sitewide rule ("ALL data is mono").  */
/* Surface ground; 1px hairline rules above the header (the table's own   */
/* border), below the header row, between body rows, and below the last  */
/* row (the table's own bottom border - the last row's cells carry no     */
/* border-bottom of their own, so that edge is not doubled). NO vertical  */
/* rules, NO zebra striping. Left-aligned throughout - columns are        */
/* ragged and honest (5.7), never right-aligned to a false grid.          */
/*                                                                        */
/* This is the fix for the owner-reported "the table keeps growing huge"  */
/* bug: agent E moves any long prose (gap statements, caveats) out of the */
/* cells entirely into .caliber-dosing-footnotes below the table, so no   */
/* cell ever holds more than a short mono token that can balloon a row's  */
/* height by word-wrapping. A cell that still needs to point at a         */
/* footnote carries a .caliber-dosing-note superscript marker instead of  */
/* the prose itself. The .dosing-gap component (still used standalone in  */
/* other detail tables, e.g. the pharmacokinetics table) is untouched -   */
/* it simply no longer needs to appear inside this specific table.        */
/*                                                                        */
/* .dosing-table-wrap is kept from the previous pass: a horizontal-scroll */
/* safety net so this table never forces the whole page to overflow       */
/* horizontally at a narrow viewport (WCAG 1.4.10) - the under-600px      */
/* behavior this fix is required to preserve. It now wraps a              */
/* .caliber-dosing-table specifically.                                    */
/* -------------------------------------------------------------------- */

.dosing-table-wrap {
  overflow-x: auto;
}

/* The 34rem floor keeps four columns legible on a tablet, but it is
   DISABLED below 600px, where the table stops being a table entirely (see
   the stacked reflow near the foot of this file). Left on, it forced a
   phone to sideways-scroll a schedule: Timeframe and Dosage were visible,
   Frequency was clipped mid-word, and Note was off-screen with no visual
   hint that two more columns existed. Page-level overflow still measured 0
   because this wrapper absorbed it, which is exactly what made it easy to
   miss in automated checks. */
@media (min-width: 601px) {
  .dosing-table-wrap table {
    min-width: 34rem;
  }
}

.dosing-table-wrap .dosing-gap {
  margin: 0;
}

.caliber-dosing-table {
  width: 100%;
  table-layout: fixed;
  border-collapse: collapse;
  background-color: var(--wp--preset--color--surface);
  border: 1px solid var(--wp--preset--color--hairline);
  border-radius: var(--wp--custom--radius--md);
}

.caliber-dosing-table thead th {
  font-family: var(--wp--preset--font-family--mono);
  font-size: var(--wp--preset--font-size--micro);
  font-weight: 500;
  letter-spacing: var(--wp--custom--tracking--micro);
  text-transform: uppercase;
  color: var(--wp--preset--color--gray-muted);
  text-align: left;
  padding: 0.6rem 0.8rem;
  border-bottom: 1px solid var(--wp--preset--color--hairline);
}

/* Tight, near-even fixed proportions across all four columns - narrowest
   share to Note, which holds only a short superscript-footnote marker
   (see .caliber-dosing-note below), never a sentence. Applied to both th
   and td by position so the width holds regardless of whether agent E's
   markup keeps a <th scope="row"> for the first column (Timeframe) or
   renders it as a plain <td> - either way this table no longer has a
   prose-label column, so there is no longer a reason for column 1 to use
   a different tag's typography than the rest. */
.caliber-dosing-table th:nth-child(1),
.caliber-dosing-table td:nth-child(1) { width: 27%; }
.caliber-dosing-table th:nth-child(2),
.caliber-dosing-table td:nth-child(2) { width: 27%; }
.caliber-dosing-table th:nth-child(3),
.caliber-dosing-table td:nth-child(3) { width: 26%; }
.caliber-dosing-table th:nth-child(4),
.caliber-dosing-table td:nth-child(4) { width: 20%; }

.caliber-dosing-table td,
.caliber-dosing-table tbody th[scope="row"] {
  padding: 0.6rem 0.8rem;
  border-bottom: 1px solid var(--wp--preset--color--hairline);
  vertical-align: top;
  text-align: left;
  font-family: var(--wp--preset--font-family--mono);
  font-size: var(--wp--preset--font-size--caption);
  font-weight: 400;
  letter-spacing: normal;
  text-transform: none;
  color: var(--wp--preset--color--ink);
  line-height: 1.4;
}

.caliber-dosing-table tr:last-child td,
.caliber-dosing-table tbody tr:last-child th[scope="row"] {
  border-bottom: none;
}

/* Note column (last): mono micro gray-muted, same quiet weight the old
   "source" column used - still just a marker, never a full sentence.
   overflow-wrap guards a long unbroken label under table-layout: fixed. */
.caliber-dosing-table td:last-child,
.caliber-dosing-table th:last-child {
  font-size: var(--wp--preset--font-size--micro);
  color: var(--wp--preset--color--gray-muted);
  overflow-wrap: anywhere;
}

.caliber-dosing-table td .dosing-gap {
  font-family: var(--wp--preset--font-family--body);
  font-size: var(--wp--preset--font-size--caption);
}

/* Superscript reference marker inside a cell (e.g. "12 weeks¹"), pointing
   at the matching numbered entry in .caliber-dosing-footnotes below the
   table. Small and quiet on purpose - a footnote pointer, not a second
   data value competing with the cell's own figure. */
.caliber-dosing-note {
  font-family: var(--wp--preset--font-family--mono);
  font-size: 0.7em;
  font-weight: 500;
  color: var(--wp--preset--color--gray-muted);
  vertical-align: super;
  line-height: 1;
  margin-left: 0.15em;
}

/* Footnote list below the table: small, mono, gray-muted, numbered by
   CSS counter (agent E emits a plain <ol class="caliber-dosing-footnotes">
   with one <li> per note - no manual "1." text needed in the markup).
   This is where the prose a cell used to hold now lives, which is the
   actual fix for the table's old height-growth problem: the sentence
   still exists, it just no longer lives inside a fixed-width cell. */
/* -------------------------------------------------------------------- */
/* Dosing schedule on phones. Below 600px the four-column table stops     */
/* being a table and becomes one stacked block per timeframe: the         */
/* timeframe is the block's heading and the other three fields sit under  */
/* it as label/value lines. A schedule read top-to-bottom survives this   */
/* far better than a grid does - the alternative was sideways scrolling   */
/* to reach Frequency and Note, which is not a thing anyone does on a     */
/* product page.                                                          */
/*                                                                        */
/* The labels come from nth-of-type rather than data-label attributes so  */
/* the renderer emits plain semantic <td>s and this stays a pure          */
/* presentation concern. Cell order is fixed by the markup contract       */
/* (timeframe th, then dosage, frequency, note), so the mapping is        */
/* stable; if a column is ever added, update these three rules with it.   */
/* thead is moved off-screen rather than display:none so screen readers   */
/* keep the header association.                                           */
/* -------------------------------------------------------------------- */

@media (max-width: 600px) {
  /* display:block on the TABLE, not just the rows. Blocking the rows alone
     left the element display:table, so the (visually hidden) thead cells
     still drove the column model and squeezed each stacked cell to its old
     percentage: measured 86px, 83px and 64px inside a 350px row, which is
     what broke "Starting" across two lines as "Star" / "ting". Collapsing
     table, thead, tbody, tr and cells to blocks removes the column model
     entirely so each value gets the card's full width. */
  .caliber-dosing-table,
  .caliber-dosing-table tbody {
    display: block;
    table-layout: auto;
    border: none;
  }

  .caliber-dosing-table caption {
    display: block;
  }

  .caliber-dosing-table thead {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }

  .caliber-dosing-table tbody tr {
    display: block;
    border: 1px solid var(--wp--preset--color--hairline);
    border-radius: var(--wp--custom--radius--md);
    padding: 0.75rem 0.9rem;
    margin-bottom: 0.6rem;
  }

  .caliber-dosing-table tbody th[scope="row"],
  .caliber-dosing-table tbody td {
    display: block;
    border: none;
    padding: 0;
  }

  /* The per-column percentage widths above are restated here rather than
     overridden by a shorter selector, because they would otherwise win on
     specificity: `.caliber-dosing-table td:nth-child(1)` scores (0,2,1)
     against `.caliber-dosing-table tbody td` at (0,1,2), so the class count
     decides it. That is why the cells kept their desktop widths (86px, 83px
     and 64px inside a 350px row) even after display:block took effect from
     the very same rule block - display had no competitor, width did.
     Matching the selectors exactly and relying on source order is clearer
     here than escalating to !important. */
  .caliber-dosing-table th:nth-child(1),
  .caliber-dosing-table td:nth-child(1),
  .caliber-dosing-table th:nth-child(2),
  .caliber-dosing-table td:nth-child(2),
  .caliber-dosing-table th:nth-child(3),
  .caliber-dosing-table td:nth-child(3),
  .caliber-dosing-table th:nth-child(4),
  .caliber-dosing-table td:nth-child(4) {
    width: 100%;
    max-width: 100%;
  }

  .caliber-dosing-table tbody th[scope="row"] {
    font-size: var(--wp--preset--font-size--base);
    margin-bottom: 0.35rem;
  }

  .caliber-dosing-table tbody td {
    padding-top: 0.2rem;
    /* Cancels the desktop last-column rule that allows breaking inside a
       word. That exists so a long uppercase source label cannot overrun a
       narrow fixed column; here there is no fixed column, and leaving it on
       hyphenated "Starting" into "Star"/"ting". */
    overflow-wrap: normal;
  }

  .caliber-dosing-table tbody td:empty {
    display: none;
  }

  .caliber-dosing-table tbody td::before {
    font-family: var(--wp--preset--font-family--mono);
    font-size: var(--wp--preset--font-size--micro);
    font-weight: 500;
    letter-spacing: var(--wp--custom--tracking--micro);
    text-transform: uppercase;
    color: var(--wp--preset--color--gray-muted);
    margin-right: 0.5em;
  }

  .caliber-dosing-table tbody td:nth-of-type(1)::before { content: "Dosage"; }
  .caliber-dosing-table tbody td:nth-of-type(2)::before { content: "Frequency"; }
  .caliber-dosing-table tbody td:nth-of-type(3)::before { content: "Note"; }
}

/* The protocol caption. A <caption> centers itself by default, which left
   it as the one centered line on an otherwise entirely left-aligned page
   (anti-slop rule 0: no centered body text). It names the protocol and its
   source, so it reads as a label above the schedule, not as a title. */
.caliber-dosing-caption {
  caption-side: top;
  text-align: left;
  font-family: var(--wp--preset--font-family--body);
  font-size: var(--wp--preset--font-size--caption);
  font-weight: 500;
  color: var(--wp--preset--color--ink);
  padding: 0 0 0.5rem;
}

.caliber-dosing-footnotes {
  list-style: none;
  counter-reset: dosing-footnote;
  margin: 0.75rem 0 0;
  padding: 0.75rem 0 0;
  border-top: 1px solid var(--wp--preset--color--hairline);
  font-family: var(--wp--preset--font-family--mono);
  font-size: var(--wp--preset--font-size--micro);
  color: var(--wp--preset--color--gray-muted);
  line-height: 1.6;
}

.caliber-dosing-footnotes li {
  counter-increment: dosing-footnote;
  padding-left: 1.4em;
  text-indent: -1.4em;
}

.caliber-dosing-footnotes li::before {
  content: counter(dosing-footnote) ". ";
  font-weight: 600;
  color: var(--wp--preset--color--gray-muted);
}

.caliber-dosing-footnotes li + li {
  margin-top: 0.35em;
}

/* -------------------------------------------------------------------- */
/* Generic detail table (identity, pharmacokinetics, reconstitution) -   */
/* the remaining PDP data tables that are not the dosing table           */
/* (.caliber-dosing-table, mixed column typography) or the batch list     */
/* (.caliber-batches, a non-tabular row list). Same hairline-rule         */
/* language as the dosing table but with a single, uniform mono/caption   */
/* data-cell treatment throughout, since these tables do not mix a body-  */
/* prose column with data columns the way dosing does.                   */
/* -------------------------------------------------------------------- */

.caliber-detail {
  width: 100%;
  border-collapse: collapse;
  background-color: var(--wp--preset--color--surface);
  border: 1px solid var(--wp--preset--color--hairline);
  border-radius: var(--wp--custom--radius--md);
}

.caliber-detail th {
  font-family: var(--wp--preset--font-family--mono);
  font-size: var(--wp--preset--font-size--micro);
  font-weight: 500;
  letter-spacing: var(--wp--custom--tracking--micro);
  text-transform: uppercase;
  color: var(--wp--preset--color--gray-muted);
  text-align: left;
  padding: 0.6rem 0.85rem;
  border-bottom: 1px solid var(--wp--preset--color--hairline);
}

.caliber-detail td {
  padding: 0.6rem 0.85rem;
  border-bottom: 1px solid var(--wp--preset--color--hairline);
  vertical-align: top;
  text-align: left;
  font-family: var(--wp--preset--font-family--mono);
  font-size: var(--wp--preset--font-size--caption);
  color: var(--wp--preset--color--ink);
}

.caliber-detail tr:last-child td {
  border-bottom: none;
}

/* -------------------------------------------------------------------- */
/* Batch list (5.8) - per lot: the lot number (mono caption, ink) left,  */
/* the vial count (mono caption) right, hairline separators between      */
/* rows. Fewer than 5 vials (.is-low): the count renders in accent (the  */
/* low-stock signal is one of the four rationed uses of that color) and  */
/* any nested "- low" suffix drops to micro size. Depleted lots are       */
/* hidden upstream (mu-plugins/lot-inventory.php); this stylesheet has    */
/* no visibility logic of its own.                                       */
/*                                                                        */
/* Owner-reported spacing bug (2026-08-01): the panel itself carried no   */
/* padding, so the "Availability" eyebrow and the "N vials on hand." lead */
/* line - both plain <p> elements mu-plugins/reference-render.php emits   */
/* directly inside .caliber-batches, ahead of the per-lot rows - sat      */
/* flush against the panel's own 1px border (measured live: 0px left      */
/* padding). Padding now lives on the panel itself, matching the card     */
/* padding used elsewhere in the system (spacing--tight, same token       */
/* .caliber-card uses); .caliber-batch-row's own horizontal padding is    */
/* removed below so the rows' text aligns with the eyebrow/lead line      */
/* above them instead of being indented further, and its hairline         */
/* separators are now inset by the panel's own padding rather than        */
/* bleeding to the true edge.                                             */
/* -------------------------------------------------------------------- */

.caliber-batches {
  background-color: var(--wp--preset--color--surface);
  border: 1px solid var(--wp--preset--color--hairline);
  border-radius: var(--wp--custom--radius--md);
  padding: var(--wp--preset--spacing--tight);
}

.caliber-batch-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.65rem 0;
  border-bottom: 1px solid var(--wp--preset--color--hairline);
  font-family: var(--wp--preset--font-family--mono);
  font-size: var(--wp--preset--font-size--caption);
  color: var(--wp--preset--color--ink);
}

.caliber-batch-row:last-child {
  border-bottom: none;
}

.caliber-batch-row.is-low > *:last-child {
  color: var(--wp--preset--color--accent);
}

.caliber-batch-row.is-low small {
  font-size: var(--wp--preset--font-size--micro);
}

/* -------------------------------------------------------------------- */
/* "Full research" accordion (5.11, single-product.html). Plain <details>/ */
/* <summary> elements, not a custom class - there is nothing here for a   */
/* class to hook that the semantic elements do not already provide. 1px   */
/* hairline border, 4px radius, surface ground; the default disclosure    */
/* triangle is suppressed in favor of a mono +/- indicator; an open       */
/* accordion gets a hairline rule under its summary. Inner legacy research */
/* sections inherit the rest of this file's tokens without further        */
/* rework this pass (5.11).                                                */
/* -------------------------------------------------------------------- */

details {
  background-color: var(--wp--preset--color--surface);
  border: 1px solid var(--wp--preset--color--hairline);
  border-radius: var(--wp--custom--radius--md);
}

summary {
  list-style: none;
  cursor: pointer;
  padding: 0.8rem 1rem;
  font-family: var(--wp--preset--font-family--mono);
  font-size: var(--wp--preset--font-size--caption);
  font-weight: 500;
  letter-spacing: var(--wp--custom--tracking--micro);
  text-transform: uppercase;
  color: var(--wp--preset--color--ink);
}

summary::-webkit-details-marker {
  display: none;
}

summary::after {
  content: "+";
  float: right;
  font-weight: 600;
}

details[open] summary {
  border-bottom: 1px solid var(--wp--preset--color--hairline);
}

details[open] summary::after {
  content: "\2212";
}

details > *:not(summary) {
  padding: 0.9rem 1rem;
  color: var(--wp--preset--color--gray-muted);
}

/* -------------------------------------------------------------------- */
/* Legal draft banner (page-legal.html's version-marker region) - a     */
/* loud, boxed notice that the four /legal/* pages are working drafts   */
/* pending counsel review, never finished or binding. A solid 1px ink   */
/* border on a surface fill (heavier than the standard hairline card,   */
/* since this must not be mistaken for ordinary page chrome) replaces   */
/* the previous pass's bright warm-toned fill - accent is rationed in    */
/* system and this banner is neither a link, a focus state, a top tier,  */
/* nor a low-stock signal.                                               */
/* -------------------------------------------------------------------- */

.legal-draft-banner {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.4em 0.75em;
  background-color: var(--wp--preset--color--surface);
  border: 1px solid var(--wp--preset--color--ink);
  border-radius: var(--wp--custom--radius--sm);
  padding: 0.9em 1.1em;
}

.legal-draft-banner__label {
  font-family: var(--wp--preset--font-family--mono);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: var(--wp--custom--tracking--wide);
  color: var(--wp--preset--color--ink);
  white-space: nowrap;
}

.legal-draft-banner__text {
  color: var(--wp--preset--color--ink);
}

/* [OPERATOR: ...] placeholder chip inside seeded legal-page body copy -
   must read as unmistakably unfinished. A dashed ink border with no
   fill signals "still open" on its own (the dash pattern itself is the
   cue, not a loud fill color the way the retired bright warm-toned
   version relied on); box-decoration-break keeps the border intact if a long
   placeholder wraps across two lines. */
.legal-operator-todo {
  display: inline;
  background-color: transparent;
  color: var(--wp--preset--color--ink);
  font-weight: 700;
  border: 1px dashed var(--wp--preset--color--ink);
  border-radius: var(--wp--custom--radius--sm);
  padding: 0.05em 0.45em;
  box-decoration-break: clone;
  -webkit-box-decoration-break: clone;
}

/* -------------------------------------------------------------------- */
/* Landing-page trust row (/go/*) - manufacturer + ingredient disclosure */
/* signals. Deliberately NOT testimonial cards: no name, no quote, no    */
/* avatar - a plain fact stated plainly, styled like a compact card.     */
/* -------------------------------------------------------------------- */

.trust-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
  gap: 0.75rem;
}

.trust-item {
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
  background-color: var(--wp--preset--color--surface);
  border: 2px solid var(--wp--preset--color--ink);
  border-radius: var(--wp--custom--radius--md);
  padding: 1.1rem 1.2rem;
}

/* -------------------------------------------------------------------- */
/* Landing-page sticky mobile CTA (/go/*) - a thumb-reachable "Shop"     */
/* affordance for cold TikTok traffic on a small viewport, where the     */
/* header CTA has scrolled out of view. Hidden at the tablet breakpoint  */
/* and up, where the header's own "Shop now" button is already visible   */
/* without scrolling back up. env()-padded for iOS home-indicator safe   */
/* area; a plain fallback (0px) covers browsers without env() support.  */
/* -------------------------------------------------------------------- */

.landing-sticky-cta {
  display: flex;
  position: sticky;
  bottom: 0;
  z-index: 20;
  background-color: var(--wp--preset--color--base);
  border-top: 2px solid var(--wp--preset--color--ink);
  padding: 0.6rem 1rem calc(0.6rem + env(safe-area-inset-bottom, 0px));
}

.landing-sticky-cta .wp-block-button {
  flex: 1;
}

.landing-sticky-cta .wp-block-button__link {
  display: block;
  text-align: center;
}

@media (min-width: 782px) {
  .landing-sticky-cta {
    display: none;
  }
}

/* -------------------------------------------------------------------- */
/* PDP summary paragraph (single-product.html PDP restructure) - the new */
/* short plain-prose statement that now leads the page in place of the   */
/* evidence tier. No new color/type decision: inherits this theme's       */
/* default body-copy color, just given a touch more line-height and a     */
/* slightly larger size than dense reference prose, since it is meant to  */
/* be read at a glance, not studied like the collapsed research below.    */
/* -------------------------------------------------------------------- */

.pdp-summary {
  font-size: var(--wp--preset--font-size--lede);
  line-height: 1.55;
}

/* -------------------------------------------------------------------- */
/* Header at phone width. Below WordPress's own navigation breakpoint    */
/* (782px) the nav collapses to its hamburger dialog, and the header CTA */
/* button then had to share one row with the wordmark and that toggle:   */
/* it compressed to 126px and broke "Browse the reference" across three  */
/* lines, a 102px-tall black slab that dominated the whole header. The   */
/* button is dropped there rather than shrunk, because the collapsed nav */
/* already carries the same destination as its first item - nothing      */
/* becomes unreachable. It returns unchanged at 782px and up.            */
/* -------------------------------------------------------------------- */

@media (max-width: 781px) {
  .site-header .header-cta,
  .site-header .wp-block-buttons {
    display: none !important;
  }
}

/* The toggle is WordPress's own 24px hamburger SVG; it inherits button
   color, which left it mid-gray against paper. Ink matches the wordmark
   beside it. */
.wp-block-navigation__responsive-container-open,
.wp-block-navigation__responsive-container-close {
  color: var(--wp--preset--color--ink);
}

/* -------------------------------------------------------------------- */
/* Card grid columns (section 4) - 1 column below 600px, 2 columns       */
/* 600-899px, 3 columns at 900px+. Implemented against                   */
/* ul.wc-block-product-template__responsive: WooCommerce's product-      */
/* template block renders this UL as a CSS GRID, not a flex/list layout,  */
/* so li-level width/flex rules do nothing here - measured directly       */
/* 2026-08-01 (the UL's own grid-template-columns is what resolves the    */
/* actual column count at every breakpoint; an earlier draft of the       */
/* interim mobile fix this replaces failed exactly that way by targeting  */
/* the LI instead). !important is required because the block's own        */
/* "columns" attribute writes an inline/attribute-driven                  */
/* grid-template-columns declaration of equal or greater specificity;     */
/* without it this rule loses that tie. Superseded here is the interim    */
/* mobile-stabilization block from 2026-08-01, which only guaranteed the  */
/* one-column-below-600px case (a response to a pill-shaped category-chip */
/* overflow that no longer exists, since that chip is retired) - that     */
/* guarantee is preserved below, now alongside the 2-column and 3-column   */
/* steps the full responsive pass adds.                                   */
/* -------------------------------------------------------------------- */

ul.wc-block-product-template__responsive {
  grid-template-columns: repeat(3, 1fr) !important;
}

@media (max-width: 899px) {
  ul.wc-block-product-template__responsive {
    grid-template-columns: repeat(2, 1fr) !important;
  }
}

@media (max-width: 599px) {
  ul.wc-block-product-template__responsive {
    grid-template-columns: 1fr !important;
  }
}

/* -------------------------------------------------------------------- */
/* "Pull a vial" - the owner's inventory action on a batch row. Rendered */
/* only for a signed-in owner (see render_pull_control() in             */
/* mu-plugins/reference-render.php); a visitor never sees it. Sized      */
/* down from the primary button because it repeats once per batch and    */
/* should not compete with the compound's own content.                   */
/* -------------------------------------------------------------------- */

.caliber-batch-row .caliber-pull-button {
  flex: none;
  margin-left: auto;
  background-color: var(--wp--preset--color--ink);
  color: var(--wp--preset--color--base);
  font-family: var(--wp--preset--font-family--body);
  font-size: var(--wp--preset--font-size--micro);
  font-weight: 500;
  line-height: 1;
  padding: 0.5em 0.9em;
  border-radius: var(--wp--custom--radius--sm);
  text-decoration: none;
  white-space: nowrap;
  transition: background-color 0.12s ease;
}

.caliber-batch-row .caliber-pull-button:hover,
.caliber-batch-row .caliber-pull-button:focus-visible {
  background-color: #000;
  color: var(--wp--preset--color--base);
}

.caliber-batch-row {
  gap: 0.75rem;
}

/* -------------------------------------------------------------------- */
/* Header row. The wordmark sits left, everything else right, on ONE     */
/* line. Three separate things were letting it break apart:              */
/*   - the row inherited layout:constrained and collapsed to the 700px   */
/*     content width (fixed in parts/header.html with align:wide),       */
/*   - core/navigation's container defaults to flex-wrap:wrap, so the    */
/*     four links wrapped and left CONTACT stranded on its own row,      */
/*   - the CTA label broke across two lines, which set the header's      */
/*     height and left the account/cart icons floating mid-band.         */
/* -------------------------------------------------------------------- */

.site-header .caliber-nav .wp-block-navigation__container {
  flex-wrap: nowrap;
}

.site-header .header-cta .wp-block-button__link {
  white-space: nowrap;
}

/* Breathing room between the three right-hand groups (links, the two
   WooCommerce icon blocks, the CTA) so they read as distinct clusters
   rather than one run-on strip. */
.site-header .wp-block-group.alignwide > .wp-block-group {
  gap: 1.25rem;
}

.site-header .wp-block-navigation,
.site-header .wc-block-customer-account,
.site-header .wc-block-mini-cart {
  flex: none;
}

/* -------------------------------------------------------------------- */
/* Compound-class filter (.caliber-filter, emitted by                     */
/* mu-plugins/reference-render.php's [caliber_class_filter]).             */
/*                                                                        */
/* This row used to be interpunct-separated links, identical in treatment */
/* to the category-tag lines on the cards below it, so it read as a       */
/* sentence rather than a control - the owner's words: "it is not obvious */
/* that this is a nav/filter". It is now a labelled row of discrete       */
/* bordered targets with a visible current state, which is the affordance */
/* a segmented filter needs. Still plain links: clicking one navigates to */
/* that class archive, no JS and no dropdown, as specified.               */
/*                                                                        */
/* Stays inside the system: hairline borders, 2px radius, mono micro      */
/* uppercase, ink fill for the active item. Accent is NOT used - a filter */
/* chip is not a link, a focus ring, a top tier, or a low-stock signal.   */
/* -------------------------------------------------------------------- */

.caliber-filter {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.5rem 0.75rem;
}

.caliber-filter-label {
  font-family: var(--wp--preset--font-family--mono);
  font-size: var(--wp--preset--font-size--micro);
  font-weight: 500;
  letter-spacing: var(--wp--custom--tracking--micro);
  text-transform: uppercase;
  color: var(--wp--preset--color--gray-muted);
  flex: none;
}

.caliber-filter-items {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
}

.caliber-filter-item {
  display: inline-block;
  border: 1px solid var(--wp--preset--color--hairline);
  border-radius: var(--wp--custom--radius--sm);
  padding: 0.35em 0.7em;
  font-family: var(--wp--preset--font-family--mono);
  font-size: var(--wp--preset--font-size--micro);
  line-height: 1.35;
  color: var(--wp--preset--color--gray-muted);
  text-decoration: none;
  background-color: var(--wp--preset--color--surface);
  transition: border-color 0.12s ease, color 0.12s ease, background-color 0.12s ease;
}

.caliber-filter-item:hover,
.caliber-filter-item:focus-visible {
  border-color: var(--wp--preset--color--ink);
  color: var(--wp--preset--color--ink);
  text-decoration: none;
}

.caliber-filter-item.is-current {
  background-color: var(--wp--preset--color--ink);
  border-color: var(--wp--preset--color--ink);
  color: var(--wp--preset--color--base);
}

@media (max-width: 600px) {
  .caliber-filter {
    flex-direction: column;
    align-items: flex-start;
  }
}
