/* ============================================================
 * components.css — the plugin's component vocabulary.
 *
 * REBUILT 2026-09-09 on the Claude Design system (assets/design-system/
 * website: README, states.md, reflow.md). Built ONLY from the custom
 * properties in tokens.css — there is NO literal colour, size, spacing,
 * or font value in this file; bin/check-design-tokens.sh enforces it.
 *
 * Rules carried from the handoff:
 *   corner rule — rounded marks INTERACTIVE objects only (fields, form
 *   panels, selectors, thumbs, draw widgets; pill on buttons/chips);
 *   everything else is square: link cards, bands, tables, panels, quotes.
 *   hover rule — a clickable box that CONTAINS a button stays still and
 *   the button changes; a box with no button takes the hover itself.
 *   halo (violet stroke + glow) is for SMALL WIDGET cards only; image cards
 *   get the grey lift; dark cards the deep shadow. Never mixed.
 *   data is Barlow (ui), prose is serif. Barlow has no italic — never
 *   italicise it.
 * Every state is on states.md; precedence disabled > loading > error >
 * focus > hover > default.
 *
 * SPECIFICITY — every component selector is scoped `.cap-shell …` on purpose.
 * Elementor's global kit styles bare `button` (0,1,1) and the theme reset styles
 * [type=button]/[type=submit]; an unscoped `.cap-btn` (0,1,0) loses to both and
 * the buttons came out in the theme's gold, block-display and Jost. Scoping wins
 * at 0,2,0 without a single !important. Every root the plugin renders carries
 * `cap-shell`; markup outside one (the WooCommerce checkout consent row) is
 * covered by the explicit block at the foot of this file.
 * ============================================================ */

/* ─── shell / type foundation ─────────────────────────────── */
.cap-shell {
  background: var(--cap-color-bg);
  color: var(--cap-color-text);
  font-family: var(--cap-font-serif);
  font-size: var(--cap-type-base);
  line-height: var(--cap-leading-body);
  -webkit-font-smoothing: antialiased;
}
/* a shell NESTED in another (a shortcode placed inside a card — the money page's buy form) paints nothing: its cream showed as a second
   panel inside the white card (owner review 2026-09-24). Only the outermost shell carries the page ground. */
.cap-shell .cap-shell { background: transparent; }
/* on an ink page (Chrome::ink_body_class) every shell stands on the ink — the cream showed as full-height bars beside the 1440 column (owner 2026-09-25) */
body.cap-ink-page .cap-shell { background: var(--cap-color-text); }
.cap-shell *,
.cap-shell *::before,
.cap-shell *::after { box-sizing: border-box; }
/* ═══ ITALIC LEDES ON DESKTOP (CD 24 Sep, desktop only) ════════════════════════════════════════════════════
   Every italic serif lede, and every italic line inside a card or box, is 19 from 1024 up; tablet and phone keep their
   sizes, and line-height, colour and weight stay. NOT here (CD): the D4 caption + chapter-list footnote, the rune /
   tarot pairing footnote, form helper lines, and the hero ledes set larger (22+). Weighted (0,3,1) so it outranks each
   page's own lede rule. */
@media (min-width: 1024px) {
  :root body .cap-shell :is(.cap-lede--card, .cap-rpage__card-lede, .cap-tcard__card-lede, .cap-rpage__tarot-essence,
    .cap-tcard__runes-essence, .cap-also__sub, .cap-draw__tile-s, .cap-draw__calc-lede, .cap-conf__card-l,
    .cap-home-reading__lede, .cap-home-poster__lede, .cap-gyr__lede, .cap-purchase-panel__lede,
    .cap-below__lede, .cap-results__band-lede, .cap-rhub__lede, .cap-thub__lede, .cap-404__lede, .cap-chron__lede,
    .cap-learn__hero .cap-lede, .cap-play__hero .cap-lede) { font-size: var(--cap-type-lede-box); }
}
@media (min-width: 700px) and (max-width: 1279px) {   /* T9-1 / T9-2 and the 820 sheets: the "Also available in" card's line 15, the sheet's (owner 2026-10-01) */
  :root body .cap-shell .cap-below__also .cap-also__sub { font-size: var(--cap-type-label); }   /* (0,4,1): the :is() above counts as its most specific member (two classes) */
}

/* ═══ ONE EYEBROW ON DESKTOP AND TABLET (CD 24 Sep; tablet from 2026-10-01) ═══════════════════════════════════════════════════
   Every ✦ eyebrow — on the page or inside a box, card, band or rail widget — takes the D2 page style from 768 up:
   500 · 16 · .16em · uppercase · line-height normal; violet on cream / white, lilac on ink (the colours each variant already
   sets). No smaller in-box step. The unstarred variants CD names ("Plain" / "Star ground", "More styles are coming",
   "Your poster") match already or are listed here. NOT eyebrows: text links, "Key dates", date cells, row labels, the
   transit bar, list bullets; the muted "On this page" / "Help" labels are navigation, left as they are. */
@media (min-width: 700px) {   /* from 700 (owner 2026-10-01): tablet takes the desktop eyebrow */
  :root body .cap-shell :is(.cap-eyebrow--card:not(.cap-eyebrow--muted), .cap-home-feature__eyebrow, .cap-tcard__eyebrow.cap-eyebrow--star,
    .cap-rpage__eyebrow.cap-eyebrow--star, .cap-thub__eyebrow--sm, .cap-404__eyebrow, .cap-learn__eyebrow, .cap-below__eyebrow,
    .cap-results__band-eyebrow, .cap-conf__eyebrow) {
    font-family: var(--cap-font-ui); font-weight: 500; font-size: var(--cap-type-eyebrow); letter-spacing: var(--cap-track-eyebrow);
    text-transform: uppercase; line-height: normal;
  }
}

/* ═══ THE PRESS RULE (owner 2026-09-24) ══════════════════════════════════════════════════════════════════
   Every readable word is selectable: a card or label that acts as one control is a plain container marked
   `data-press` (+ `.cap-press`), its ONE real control inside (the title link, the icon button); cap-press.js forwards
   a click that was not a drag or a selection. The title link wears the card's own colour in every state. */
.cap-shell .cap-press { cursor: pointer; }
/* the real control is screen-reader-only, so its keyboard focus shows on the card / the question row */
.cap-shell .cap-press:has(> .cap-press__link:focus-visible),
.cap-shell .cap-faq__item:has(> .cap-faq__toggle:focus-visible) > .cap-faq__q { outline: var(--cap-ring, var(--cap-focus-ring)); outline-offset: var(--cap-focus-ring-offset); }
.cap-faq__item > .cap-faq__toggle.cap-sr { font-family: var(--cap-font-ui); }   /* the screen-reader copy of the question (cap-press.js) in our face — inside an Elementor text widget outside .cap-shell (the money page) it took the kit's Jost (2026-10-18) */
/* the FAQ converted at load (cap-press.js): a div item keeps [open]; its answer hides while closed */
.cap-shell .cap-faq__item:not([open]) > .cap-faq__body { display: none; }
.cap-shell .cap-press__link,
.cap-shell .cap-press__link:is(:link, :hover, :active, :focus),
.cap-shell .cap-press__link:visited { color: inherit; text-decoration: none; }
/* EVERY LINK CARD IS A REAL LINK UNDER THE POINTER (owner 2026-10-07, round 36 follow-up): a card's link covers the whole card,
   invisible (no text drawn, no outline of its own — the card's ring shows its keyboard focus), so a right-click or Control-click
   anywhere on the card offers "Open link in new tab", a Cmd/Ctrl- or middle-click opens one, and a press is the link's own.
   A link or button inside the card (the Play card's eyebrow) sits above the cover. cap-press.js adds the classes: the cover to
   a card's link, `rel` to a card / inner control that is not positioned, `above` to the inner controls. This replaces the press
   rule's selectable text ON LINK CARDS only (a drag on a card is now a link drag); FAQ rows and the minute tip are unchanged.
   BOTH RULINGS TOGETHER (owner 2026-10-09, option 1): on a computer (a fine pointer that hovers) the cover lets the mouse pass
   through, so a drag reaches the card's words — plain text, outside any link, which Safari selects; cap-press.js gives it the
   pointer (`is-ctx`) the moment a right-click or a Mac Control-click begins, so the browser's menu offers "Open Link in New Tab".
   On a touch screen the cover takes every tap, as before. tests/select/ (commit check 9c) fails if a card's words stop selecting,
   sit inside a link, or the right-click stops finding the link. */
.cap-shell .cap-press > .cap-press__link.cap-press__cover { position: absolute; inset: 0; width: auto; height: auto; margin: 0; padding: 0; clip: auto; overflow: hidden; z-index: 2; font-size: 0; line-height: 0; color: transparent; border-radius: inherit; }
.cap-shell .cap-press > .cap-press__link.cap-press__cover:focus-visible { outline: 0; }
.cap-shell .cap-press__rel { position: relative; }
.cap-shell .cap-press__above { z-index: 3; }
@media (hover: hover) and (pointer: fine) {
  .cap-shell .cap-press > .cap-press__link.cap-press__cover { pointer-events: none; }
  .cap-shell .cap-press.is-ctx > .cap-press__link.cap-press__cover { pointer-events: auto; }
}
/* An ACTION BUTTON's label is selectable too (owner 2026-09-24, "Reveal my chart"): a native <button> is left out of any
   text selection, even one dragged across it; `user-select: text` lets it in. It stays a real button — cap-press.js
   stops the click that ends a drag which selected the label, so selecting it never submits. */
.cap-shell button { -webkit-user-select: text; user-select: text; }   /* every button's text (the AM / PM toggles, the ⓘ, the steppers …), not only .cap-btn (owner sweep 2026-09-27) */

/* ═══ THE THEME FLOOR (owner 2026-09-24) ════════════════════════════════════════════════════════════════
   Hello's reset.css stays in place (owner ruling) but its COLOURS never reach the site: these are Hello's own four
   colour selectors, at Hello's own weight, printed after it (the tokens sheet depends on Hello's handles), with the
   site's colours instead of Hello's magenta and navy. WooCommerce and Elementor print after the engine, so their rules still win
   every tie; inside a shell the system base below wins. Proven by the kit-colour probe (every page, 1440 + 390,
   rest · hover · focus): nothing resolves to Hello's two colours or the retired kit colours, bare injected controls included. */
a { color: var(--cap-color-primary); }
@media (hover: hover) { a:active, a:hover { color: var(--cap-color-text); } }
[type=button], [type=submit], button { border-color: currentColor; color: inherit; }
[type=button]:focus, [type=submit]:focus, button:focus { background-color: transparent; color: inherit; }
@media (hover: hover) { [type=button]:hover, [type=submit]:hover, button:hover { background-color: transparent; color: inherit; } }

/* ═══ THE SYSTEM BASE (owner 2026-09-23, sweep 1) ═══════════════════════════════════════════════════════
   Hello's reset.css styles bare elements — button / a / input / details … — in every state (its heaviest,
   `[type=button]:hover`, is (0,2,0)). This floor resets them inside the system to inherit-and-nothing at the SAME
   weight — the `:where(.cap-shell)` scope counts 0 — so with the engine's sheets printed AFTER the theme (the tokens
   sheet DEPENDS on Hello's handles, capriastro-engine.php, 2026-09-24) every tie resolves by order in the system's
   favour. Component rules sit in this file below the floor, so they win their own ties with it.
   NOT covered here: the Elementor kit's `.elementor-kit-N button:focus` (0,2,1) — CLEARED at its source 2026-09-24
   (Site Settings → Theme Style → Buttons + Links; the smoke test fails if either is refilled). */
/* A VISITED LINK NEVER CHANGES COLOUR (owner 2026-10-03): `:visited` is written on its own, never inside `:is()` / `:where()` —
   a browser may refuse to match `:visited` there for privacy, and the link then falls to its own visited purple (the "Ask the
   cards" title turned ink on the dark tarot hub card on the owner's tablet). Every link colour on the site comes from a
   class or from this inherit, so a visited link reads exactly like an unvisited one. */
:where(.cap-shell) a:is(:link, :hover, :active, :focus),
:where(.cap-shell) a:visited { color: inherit; background: none; text-decoration: none; box-shadow: none; }
:where(.cap-shell) :is(button, [type="button"], [type="submit"]):is(:enabled, :hover, :focus, :active, :disabled) { background: none; color: inherit; border: 0; border-radius: 0; padding: 0; margin: 0; font: inherit; letter-spacing: inherit; text-transform: none; text-decoration: none; box-shadow: none; cursor: pointer; }
:where(.cap-shell) :is(input, select, textarea):is(:enabled, :focus) { font: inherit; letter-spacing: inherit; color: inherit; background: none; border: 0; border-radius: 0; padding: 0; margin: 0; box-shadow: none; }
:where(.cap-shell) :where(label, small) { display: inline; line-height: inherit; font-size: inherit; }
:where(.cap-shell) :where(ul, ol, li) { margin: 0; padding: 0; border: 0; background: none; font-size: inherit; outline: 0; }
:where(.cap-shell) :where(details, summary) { display: block; }
:where(.cap-shell) :where(h1, h2, h3, p) { margin: 0; }
:where(.cap-shell) :where(img) { border: 0; box-shadow: none; }
.cap-shell input::-webkit-inner-spin-button, .cap-shell input::-webkit-outer-spin-button { appearance: none; -webkit-appearance: none; margin: 0; }

.cap-shell .cap-page { max-width: var(--cap-page-max); margin: 0 auto; }
/* the page ground is the system's cream, not the Elementor kit's older #FBFAF7 (owner review 2026-09-24: two near-invisible bands either
   side of the held hero row were the kit's body colour showing past the 1440 row) — only on pages built on the system */
body:has(.cap-shell) { background-color: var(--cap-color-bg); }
body.cap-ink-page { background-color: var(--cap-color-text); }   /* the tarot pages: ink edge to edge (Chrome::ink_body_class) */
/* Source Serif at optical size 14 everywhere (owner 2026-09-25): CD's sheets render the serif at opsz 14; left to auto, the
   browser sizes it to the px size (18 → 3.7% narrower) and every paragraph re-wraps. Only the serif is a variable face, so the
   other families ignore it. */
body { font-variation-settings: var(--cap-opsz-read); }
/* THE PAGE HOLDS ITS WIDTH (owner review 2026-09-24): on a window wider than the 1440 page, nothing that lays out content fills the
   window. ONE rule for every block that is not already inside a .cap-page: centred on the 1440 frame, plus an inset for blocks
   that sit on the content column (--cap-hold-inset: the page gutter). Found by probing every applied page at 1920: the home hero
   row and the Draws / Chronicles row (Elementor rows carrying their own 80 padding — inset 0) and the footer's bottom row (a
   content-column block — inset = the gutter). A new block joins by being added to this list. The article hero left the list at
   0.51.343: it carries its own 1172 width (D6), centred inside an inset wrap. */
@media (min-width: 1280px) {
  body :is(.cap-home-herorow.e-con, .cap-home-dcrow.e-con, .cap-shell .cap-footer__base) {   /* body :is() = (0,2,1): above each block's own margin rule */
    --width: auto; width: auto; max-width: none; margin-left: max(var(--cap-hold-inset, 0px), calc((100% - var(--cap-page-max)) / 2 + var(--cap-hold-inset, 0px))); margin-right: max(var(--cap-hold-inset, 0px), calc((100% - var(--cap-page-max)) / 2 + var(--cap-hold-inset, 0px)));
  }
  .cap-shell .cap-footer__base { --cap-hold-inset: var(--cap-page-x); }
}
.cap-shell .cap-inset { padding-left: var(--cap-page-x); padding-right: var(--cap-page-x); }
@media (min-width: 700px) and (max-width: 1279px) {
  .cap-shell .cap-inset { padding-left: var(--cap-page-x-mid); padding-right: var(--cap-page-x-mid); }
}
.cap-shell .cap-measure { max-width: var(--cap-measure); }
.cap-shell .cap-measure--hero { max-width: var(--cap-measure-hero); margin-left: auto; margin-right: auto; }
.cap-shell .cap-sr { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0,0,0,0); white-space: nowrap; border: 0; }
/* the trap field's box OUTSIDE a .cap-shell (owner 2026-10-05): the checkout form and the contact form are not shells */
.cap-hp { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0,0,0,0); white-space: nowrap; border: 0; }
.cap-shell .cap-stack { display: flex; flex-direction: column; gap: var(--cap-space-md); }
.cap-shell .cap-stack--sm { gap: var(--cap-space-sm); }
.cap-shell .cap-stack--lg { gap: var(--cap-space-lg); }
.cap-shell .cap-cluster { display: flex; flex-wrap: wrap; align-items: center; gap: var(--cap-space-sm); }
.cap-shell .cap-between { display: flex; justify-content: space-between; align-items: baseline; gap: var(--cap-space-md); }
.cap-shell .cap-center { text-align: center; }
.cap-shell a { color: var(--cap-color-primary); text-decoration: none; transition: color var(--cap-ease); }
/* round 22 (owner): the bare link's hover weighs (0,1,1), so a component that keeps its own colour (a card, a card title, a
   tile — usually `color: inherit` at (0,2,0)) is never repainted by it — the tarot hub's question-draw title went ink on ink */
@media (hover: hover) { :where(.cap-shell) a:hover { color: var(--cap-color-text); } }
.cap-shell p { margin: 0; }
.cap-shell h1,
.cap-shell h2,
.cap-shell h3,
.cap-shell h4 { margin: 0; font-weight: inherit; }

/* Reset the host theme's button + link styling inside our shell, so a component starts from nothing (Elementor's kit paints every `button` gold, in Jost, with its own padding and radius). NOTE the arithmetic: `.cap-shell button` is (0,1,1) — an exact TIE with the kit's `.elementor-kit-1463 button`, decided by LOAD ORDER, not weight. This stylesheet is enqueued after the kit's inline block, so the reset wins; if that order ever changes, a BARE `<button>` in the shell reverts to kit gold. Every button COMPONENT is safe either way — `.cap-shell .cap-btn` below declares its own background at (0,2,0) and beats the kit outright (measured on the poster CTA: rgb(36,31,61), the ink pill). */
.cap-shell button,
.cap-shell input[type="submit"],
.cap-shell input[type="button"] {
  background: none; border: 0; margin: 0; padding: 0; border-radius: 0;
  font: inherit; color: inherit; text-align: inherit; text-transform: none;
  letter-spacing: inherit; line-height: inherit; width: auto; box-shadow: none;
  -webkit-appearance: none; appearance: none;
}
.cap-shell a { text-decoration: none; }
@media (hover: hover) { .cap-shell a:hover { text-decoration: none; } }
.cap-shell img { max-width: 100%; }

/* KEYBOARD FOCUS — CD states.md, 27 Sep 2026 (D15c · D4b); replaces the one-halo rule. No browser outline anywhere; three cases:
   · FIELDS (text, date, time, select, textarea, the birth cells): ink border + the faint halo, on click and tap too — their own
     rules (.cap-input:focus, .cap-parts:focus-within, the cells); the line below is the floor for a bare field.
   · EVERYTHING ELSE (buttons, pills, selectors, radios, checkboxes, link cards, text links): a 2px ring 2px OUTSIDE the element,
     :focus-visible only (Tab / arrows — never click or tap), so a selected option (1px ink) and a focused one never look alike.
   · ON INK the ring is lilac: --cap-ring swaps inside the ink grounds listed below; the carousel dots sit 3px out. */
.cap-shell :focus { outline: none; }
.cap-shell :is(input:not([type="checkbox"], [type="radio"], [type="button"], [type="submit"]), select, textarea):focus-visible { box-shadow: var(--cap-shadow-focus); border-color: var(--cap-color-field-focus); }
.cap-shell :is(a, button, summary, [tabindex], input[type="checkbox"], input[type="radio"], [type="button"], [type="submit"]):focus-visible { outline: var(--cap-ring, var(--cap-focus-ring)); outline-offset: var(--cap-focus-ring-offset); }
body.cap-ink-page .cap-shell, .cap-shell .cap-footer, .cap-shell .cap-header-wrap--ink, .cap-shell .cap-card--dark, .cap-shell .cap-post__chart,
.cap-shell .cap-gyr__notsure, .cap-shell .cap-gyr__samples, .cap-shell .cap-draw--tarot, .cap-shell .cap-draw__calc, .cap-shell .cap-dhub--tarot,
.cap-shell .cap-vref--tarot, .cap-shell .cap-thub, .cap-shell .cap-rhub__band, .cap-shell .cap-rpage__tarot, .cap-shell .cap-rpage__card--ink,
.cap-shell .cap-hx-oneline, .cap-shell .cap-play2__big--tarot, .cap-shell .cap-compare { --cap-ring: var(--cap-focus-ring-on-ink); }
/* ERROR ON INK (CD 2g-4, owner 2026-09-29): the same ink grounds + the calculator's results band give a field in error the
   pink edge and the rose halo (below, .cap-input[aria-invalid]); cream grounds never set these, so they keep carmine. */
body.cap-ink-page .cap-shell, .cap-shell .cap-footer, .cap-shell .cap-card--dark, .cap-shell .cap-post__chart,
.cap-shell .cap-gyr__notsure, .cap-shell .cap-gyr__samples, .cap-shell .cap-draw--tarot, .cap-shell .cap-draw__calc, .cap-shell .cap-dhub--tarot,
.cap-shell .cap-vref--tarot, .cap-shell .cap-thub, .cap-shell .cap-rhub__band, .cap-shell .cap-rpage__tarot, .cap-shell .cap-rpage__card--ink,
.cap-shell .cap-hx-oneline, .cap-shell .cap-play2__big--tarot, .cap-shell .cap-compare, .cap-shell .cap-results__band {
  --cap-field-error-edge: var(--cap-color-error-on-ink); --cap-field-error-halo: var(--cap-shadow-error-ink), inset 0 0 0 var(--cap-border-hairline) var(--cap-color-error-on-ink);   /* the 2-px edge of 2g-4 = the 1-px border + a 1-px inset in the same pink, so the field keeps its 48 */
}

/* ─── type roles ──────────────────────────────────────────── */
.cap-shell .cap-h1 { font-family: var(--cap-font-display); font-weight: 800; font-size: var(--cap-type-xl); line-height: var(--cap-leading-display); letter-spacing: var(--cap-track-display); color: var(--cap-color-text); }
.cap-shell .cap-h1--hero { font-size: var(--cap-type-h1-hero); letter-spacing: var(--cap-track-hero); }
@media (min-width: 700px) and (max-width: 1279px) {
  /* round 29 (owner 2026-10-05, measured on the 820 sheets): the page heading's lines 1.04 apart (T1 · T6a · T14 · T17 · T18 ·
     T19 · T21 · T22 · T23 — 52 on 1.04; it was 1.06, 1 px a line more); the 38 px article heading keeps its own 1.08 (T20) */
  .cap-shell .cap-h1 { line-height: var(--cap-leading-hero-mid); }
  .cap-shell .cap-post__title { letter-spacing: var(--cap-track-display-mid); }   /* T20: -0.022em at 38 */
}
.cap-shell .cap-h2 { font-family: var(--cap-font-display); font-weight: 800; font-size: var(--cap-type-h2); line-height: var(--cap-leading-display); letter-spacing: var(--cap-track-display); color: var(--cap-color-text); }
.cap-shell .cap-h2--article { font-family: var(--cap-font-display-sm); font-size: var(--cap-type-lg); letter-spacing: var(--cap-track-tight); }           /* role B */
.cap-shell .cap-h3-card { font-family: var(--cap-font-display-sm); font-weight: 800; font-size: var(--cap-type-h3-card); line-height: var(--cap-leading-tight); letter-spacing: var(--cap-track-tight); }
.cap-shell .cap-section { font-family: var(--cap-font-ui); font-weight: 500; font-size: var(--cap-type-section); letter-spacing: var(--cap-track-label); text-transform: uppercase; color: var(--cap-color-text); line-height: var(--cap-leading-tight); }   /* role A */
.cap-shell .cap-section--primary { color: var(--cap-color-primary); }
.cap-shell .cap-subchapter { font-family: var(--cap-font-ui); font-weight: 600; font-size: var(--cap-type-subchapter); letter-spacing: var(--cap-track-label); text-transform: uppercase; }   /* role B2 */
.cap-shell .cap-faq-q { font-family: var(--cap-font-ui); font-weight: 500; font-size: var(--cap-type-faq); letter-spacing: var(--cap-track-faq); line-height: var(--cap-leading-tight); }   /* role C — weight 500 on every FAQ, so a question reads stronger than its answer (owner 2026-09-29; was 400) */
.cap-shell .cap-card-title { font-family: var(--cap-font-ui); font-weight: 600; font-size: var(--cap-type-card-title); letter-spacing: var(--cap-track-label); text-transform: uppercase; }   /* role D */
.cap-shell .cap-feature { font-family: var(--cap-font-ui); font-weight: 600; font-size: var(--cap-type-feature); letter-spacing: var(--cap-track-feature); text-transform: uppercase; }   /* role E */
.cap-shell .cap-label { font-family: var(--cap-font-ui); font-weight: 600; font-size: var(--cap-type-label); letter-spacing: var(--cap-track-label); text-transform: uppercase; }   /* role F */
.cap-shell .cap-spec-label { font-family: var(--cap-font-ui); font-weight: 600; font-size: var(--cap-type-sm); letter-spacing: var(--cap-track-label); text-transform: uppercase; color: var(--cap-color-text); }   /* role G */
.cap-shell .cap-data { font-family: var(--cap-font-ui); font-weight: 400; font-size: var(--cap-type-data); letter-spacing: var(--cap-track-data); line-height: var(--cap-leading-data); color: var(--cap-color-text-body); }
.cap-shell .cap-data--lg { font-size: var(--cap-type-data-lg); }
.cap-shell .cap-data--medium { font-weight: 500; letter-spacing: var(--cap-track-faq); }
.cap-shell .cap-eyebrow { font-family: var(--cap-font-ui); font-weight: 500; font-size: var(--cap-type-eyebrow); letter-spacing: var(--cap-track-eyebrow); text-transform: uppercase; color: var(--cap-color-primary); line-height: var(--cap-leading-tight); }
.cap-shell .cap-eyebrow--card { font-size: var(--cap-type-eyebrow-card); }
.cap-shell .cap-eyebrow--muted { color: var(--cap-color-muted); letter-spacing: var(--cap-track-btn); }
.cap-shell .cap-eyebrow--faint { color: var(--cap-color-muted); letter-spacing: var(--cap-track-btn); }   /* the lilac is an on-ink colour only (states.md); on cream the quiet eyebrow is the muted grey */
.cap-shell .cap-eyebrow--quiet { color: var(--cap-color-heading-quiet); }   /* the "Questions" heading only (~2.7:1, approved recessive) */
.cap-shell .cap-caption { font-family: var(--cap-font-ui); font-weight: 500; font-size: var(--cap-type-caption); letter-spacing: var(--cap-track-caption); text-transform: uppercase; color: var(--cap-color-muted); }   /* the quiet line under a CTA / carousel / widget */
.cap-shell .cap-eyebrow--on-ink { color: var(--cap-color-primary-soft); }
/* the quiet eyebrow on a dark ground — --cap-color-muted is tuned for cream and dies on ink */
.cap-shell .cap-eyebrow--on-ink-muted { color: var(--cap-color-on-ink-muted); letter-spacing: var(--cap-track-btn); }
.cap-shell .cap-eyebrow--star::before { content: "✦\00a0\00a0"; }
.cap-shell .cap-eyebrow--stars::before { content: "✦\00a0\00a0"; }
.cap-shell .cap-eyebrow--stars::after { content: "\00a0\00a0✦"; }
.cap-shell .cap-lede { font-family: var(--cap-font-serif); font-style: italic; font-weight: 500; font-size: var(--cap-type-lede); line-height: var(--cap-leading-lede); color: var(--cap-color-text-secondary); }
.cap-shell .cap-lede--on-ink { color: var(--cap-color-on-ink-3); }
.cap-shell .cap-lede--card { font-size: var(--cap-type-small); font-weight: 400; }
.cap-shell .cap-body { font-family: var(--cap-font-serif); font-size: var(--cap-type-base); line-height: var(--cap-leading-body); color: var(--cap-color-text-body); }
.cap-shell .cap-small { font-family: var(--cap-font-serif); font-size: var(--cap-type-small); line-height: var(--cap-leading-small); color: var(--cap-color-text-secondary); }
.cap-shell .cap-meta { font-family: var(--cap-font-ui); font-weight: 500; font-size: var(--cap-type-meta); letter-spacing: var(--cap-track-meta); text-transform: uppercase; color: var(--cap-color-muted); }
.cap-shell .cap-price { font-family: var(--cap-font-display-sm); font-weight: 800; letter-spacing: var(--cap-track-tight); color: var(--cap-color-text); }
.cap-shell .cap-hint { display: block; font-family: var(--cap-font-ui); font-weight: 500; font-size: var(--cap-type-hint); letter-spacing: var(--cap-track-feature); text-transform: uppercase; color: var(--cap-color-muted); padding-left: var(--cap-space-field-x); line-height: var(--cap-leading-small); }   /* EVERY hint sits on the field's text inset — the straight edge, not the rounded corner (20 / 18, owner review 2026-09-24; D4 · D15 · 1l · 3a-1) */
.cap-shell .cap-hint a,
.cap-shell .cap-hint button { color: var(--cap-color-primary); border-bottom: var(--cap-border-hairline) solid var(--cap-color-primary); background: none; border-top: 0; border-left: 0; border-right: 0; padding: 0; font: inherit; letter-spacing: inherit; text-transform: inherit; cursor: pointer; }
.cap-shell .cap-hint--plain { text-transform: none; letter-spacing: var(--cap-track-ui); }
/* THE 44 px TAP TARGET on a text link inside a hint (owner 2026-09-26: "Find your birth time" under every birth-details
   card): drawn unchanged — the hit area reaches --cap-tap-min tall through a pseudo-element, never padding, which would
   drop the underline. The reach is (44 − the line) / 2 above and below the line, ±20 where `lh` is unknown. */
.cap-shell .cap-tap-link { position: relative; }
@media (hover: hover) { .cap-shell a.cap-tap-link:hover { color: var(--cap-color-text); } }   /* round 23 rule 2: a violet link turns ink (it had no hover) */
.cap-shell .cap-tap-link::after { content: ""; position: absolute; left: 0; right: 0; top: calc((100% - var(--cap-tap-min)) / 2); bottom: max(calc((100% - var(--cap-tap-min)) / 2), calc(-1 * var(--cap-space-gap-7))); }   /* 100% = the link's own line box; the downward reach never passes 14, short of the button 20+ under it */

/* NO WORD ALONE ON A LAST LINE (owner rule 2026-10-01, every page and width): a headline balances its lines, a lede never
   ends on one word. Zero specificity (:where) so a page rule that sets its own wrapping still wins. Headlines = every H tag +
   the display-face titles that are not H tags; ledes = any class carrying "lede". */
:where(h1, h2, h3, h4, h5, h6, .cap-hx-title, .cap-rpage__card-title, .cap-tcard__card-title, .cap-post__rel-title,
  .cap-play2__soon-title, .cap-play2__big-title,
  /* the display-face lines that are not h-tags (owner 2026-10-01, the headline sweep) */
  .cap-post__chart-h, .cap-dhub__soon-title, .cap-home-poster__h, .cap-home-feature__title, .cap-h3-card, .cap-gyr__locked-title,
  .cap-hub__more-line, .cap-rhub__band-title, .cap-thub__band-title) { text-wrap: balance; }
:where([class*="lede"]) { text-wrap: pretty; }
:where(.cap-lede--card, .cap-tcard__lede, .cap-rpage__lede) { text-wrap: balance; }   /* short ledes in cards and the card / rune heroes: "pretty" cannot always lift the last word, balance can */

/* THE 44 × 44 TAP AREA on touch widths (owner rule 2026-09-28: "every tappable element has a hit area of at least 44 × 44,
   made without changing how it looks"). THE PATTERN (the 0.51.461 library-link band): an invisible ::after on the element
   itself, centred on it, max(its own size, 44) each way — nothing moves, the underline / border / focus ring stay the
   element's own, and anything already 44 or larger gets a band exactly its own size. Phone + tablet (touch) — every width below
   1280 (owner 2026-10-01; it was below 1024); desktop keeps mouse-sized targets. The tablet header's menu items and the home's section links + "Order it as a poster" joined 2026-10-01. The post share buttons + tag chips and the 404 sign tiles joined 2026-10-01 (tablet audit). The correspondence table's ruler / "See also" links and the archive post titles joined 2026-09-28, the footer's social ring 2026-09-29, the menu's "All 22 cards" / "All 25 runes" 2026-10-04 (round 26), the Play cards' hub eyebrows, the meanings pages' library link and the hubs' cross link 2026-09-30, the articles' "Astrology" hub link 2026-10-20.
   Measured by tests/tap-targets/run.mjs (hit-tested from each element's centre). EVERY LINK IN A LIST OR A ROW OF LINKS gets
   its 44 (owner 2026-10-01). Below 1280 the rows that could not get one are gone instead (owner 2026-10-02): the legal
   "On this page" list, the Learn planet strip, the poster-gallery and sample-page dots. NOT given a 44 band, by ruling:
   the tarot fan cards, a single link inside a running sentence, and the planet articles' link list (its row band, below).
   A new small control joins this list rather than growing its box. THE FOOTER LINK ROWS
   (owner 2026-10-01): each link is its own full-column-wide row — 44 tall on tablet, 40 on the phone (the approved exception
   to the 44 rule: the 1a sheet sets them 40 apart), 32 on desktop — rows that touch, never overlap. */
@media (max-width: 1279px) {
  .cap-shell :is(.cap-btn, .cap-header__logo, .cap-header__burger, .cap-trail__c, .cap-tcard__pn a, .cap-rpage__pn a,
    .cap-meta a, a.cap-meta, .cap-tcard__deck-all, .cap-rpage__deck-all, a.cap-link:not(.cap-link--action), .cap-draw__shuffle,
    .cap-tcard__runes-name, .cap-rpage__tarot-name, .cap-vref__name, .cap-arc-sort__chip, .cap-calc__minute-btn,
    .cap-purchase__tip, .cap-gyr__notsure-link, .cap-tcard__v a, .cap-footer__social a, .cap-vref__lib, .cap-dhub__cross-link, .cap-header__link, .cap-home__more, .cap-home-reading__poster, .cap-back, .cap-hx-months a, .cap-post__share-btn, .cap-post__tag, .cap-post__guide a, .cap-post__hub, .cap-404__sign, .cap-legal__links-row a, .cap-birth__ampm, .cap-post__measure li > strong:first-child > a, .cap-delivery__other, .cap-drawer__head-all, .cap-hx-bar__item) { position: relative; -webkit-tap-highlight-color: transparent; }
  .cap-shell :is(.cap-btn, .cap-header__logo, .cap-header__burger, .cap-trail__c, .cap-tcard__pn a, .cap-rpage__pn a,
    .cap-meta a, a.cap-meta, .cap-tcard__deck-all, .cap-rpage__deck-all, a.cap-link:not(.cap-link--action), .cap-draw__shuffle,
    .cap-tcard__runes-name, .cap-rpage__tarot-name, .cap-vref__name, .cap-arc-sort__chip, .cap-calc__minute-btn,
    .cap-purchase__tip, .cap-gyr__notsure-link, .cap-tcard__v a, .cap-footer__social a, .cap-vref__lib, .cap-dhub__cross-link, .cap-header__link, .cap-home__more, .cap-home-reading__poster, .cap-back, .cap-hx-months a, .cap-post__share-btn, .cap-post__tag, .cap-post__guide a, .cap-post__hub, .cap-404__sign, .cap-legal__links-row a, .cap-birth__ampm, .cap-post__measure li > strong:first-child > a, .cap-delivery__other, .cap-drawer__head-all, .cap-hx-bar__item)::after {
    content: ""; position: absolute; left: 50%; top: 50%; width: max(100%, var(--cap-tap-min)); height: max(100%, var(--cap-tap-min)); transform: translate(-50%, -50%);
  }
  /* round 20: the AM / PM switch (its cell routes taps to it too, but the band is what the tool and a finger first meet), and an
     article list's linked lead-in ("Aries: Shared money…" — the sign pages' links in the retrograde posts), one per list line */
  /* the two that the band cannot reach: a crumb that clips its own overflow (its ellipsis) clips its ::after too — it takes the
     height as padding cancelled by a negative margin instead (box 44 tall, the words and the row unmoved); the archive chips
     sit under the next Elementor section's paint — one layer up */
  .cap-shell .cap-trail__c--mid { padding-block: calc((var(--cap-tap-min) - 1lh) / 2); margin-block: calc((1lh - var(--cap-tap-min)) / 2); }
  .cap-shell .cap-arc-sort__chip { z-index: 1; }
  .cap-shell .cap-parts .cap-birth__ampm { z-index: 1; }   /* round 20: the cell's own layers covered the band's last 1–3 px */
  /* round 21: the delivery line's "Other countries →" (product page, cart, checkout) — on a phone it can wrap to a line of its own */
  .cap-shell .cap-header__item--menu .cap-header__link { z-index: 1; }   /* the Play item's hover bridge (its ::after, under the link) took the band's foot */
  /* NEIGHBOURING BANDS NEVER OVERLAP (owner rule 2026-09-29; the tap-target tool checks it): the money page's ⓘ sits right
     after "Find your birth time" — a centred band reached 6 px back over the link, so its band runs RIGHT from its left edge;
     the tarot "See also" cell ("Death · The World") wraps onto two lines at tablet widths — as a wrapping row whose row gap
     makes the wrapped lines 44 apart, the two bands meet without overlapping (one line: unchanged). */
  .cap-shell .cap-hint .cap-purchase__tip.cap-purchase__tip { z-index: 1; }   /* one layer up: at tablet width the line below painted over 5 px of its band */
  .cap-shell .cap-hint .cap-purchase__tip.cap-purchase__tip::after { left: 0; transform: translateY(-50%); }   /* doubled class: beats the tap list (its :is() carries a.cap-link:not(…)) */
  .cap-shell .cap-tcard__v:has(.cap-tcard__v-item) { display: flex; flex-wrap: wrap; align-items: baseline; column-gap: var(--cap-space-gap-2); row-gap: calc(var(--cap-tap-min) - 1lh); }
  .cap-shell .cap-tcard__v-item { white-space: nowrap; }   /* "Death ·" stays one piece: the wrap falls between the links */
  /* the 1o / 3e "Wrong address?" box (owner 2026-10-01): each "Nothing after…" line is a ROW — a hairline above it, running
     the box's inner width, the line centred in 44 under it; the first hairline 16 under what comes before (the Resend button,
     or the sentence once the reading is delivered), the rows stacked with no gap; one line after delivery = one row. Each
     link's band is its row's 44 — rows meet, bands never overlap. Words and type unchanged; desktop unchanged.
     The sentence's own "Write to us" (delivered) keeps its band reaching UP from 2 below its line, clear of the row. */
  .cap-shell .cap-oc__fix .cap-oc__fix-line { padding-block: calc((var(--cap-tap-min) - 1lh) / 2); border-top: var(--cap-border-hairline) solid var(--cap-color-line-strong); }
  .cap-shell .cap-oc__fix :not(.cap-oc__fix-line) + .cap-oc__fix-line { margin-top: calc(var(--cap-space-md) - var(--cap-space-gap-6)); }   /* the box's gap is 12: + 4 = 16 */
  .cap-shell .cap-oc__fix .cap-oc__fix-line + .cap-oc__fix-line { margin-top: calc(-1 * var(--cap-space-gap-6)); }
  .cap-shell .cap-oc__fix .cap-oc__fix-text .cap-mail,
  .cap-shell .cap-oc__fix .cap-oc__fix-line :is(.cap-oc__fix-link, .cap-mail) { position: relative; white-space: nowrap; -webkit-tap-highlight-color: transparent; }
  .cap-shell .cap-oc__fix .cap-oc__fix-text .cap-mail::after { content: ""; position: absolute; left: 50%; bottom: calc(-1 * var(--cap-space-gap-1)); width: max(100%, var(--cap-tap-min)); height: var(--cap-tap-min); transform: translateX(-50%); }
  .cap-shell .cap-oc__fix .cap-oc__fix-line :is(.cap-oc__fix-link, .cap-mail)::after { content: ""; position: absolute; left: 50%; top: 50%; width: max(100%, var(--cap-tap-min)); height: var(--cap-tap-min); transform: translate(-50%, -50%); }
  /* the tag / category archive post titles (owner 2026-09-28): the link fills its heading as a block — its only child, so
     the words wrap exactly as before — and a one- or two-line title takes the same band */
  body.archive .cap-shell .elementor-heading-title > a { display: block; position: relative; z-index: 1; -webkit-tap-highlight-color: transparent; }   /* one layer up: the widget below paints over the band otherwise */
  body.archive .cap-shell .elementor-heading-title > a::after { content: ""; position: absolute; left: 50%; top: 50%; width: max(100%, var(--cap-tap-min)); height: max(100%, var(--cap-tap-min)); transform: translate(-50%, -50%); }
  /* the planet articles' link lists (owner 2026-09-29; an APPROVED EXCEPTION to the 44 rule, owner 2026-10-02): the items
     sit 33 (phone) / 38 (tablet) apart, so the band is the item's own row — its line plus the list's gap (the pitch) — as
     wide as the words: each link owns its whole row and never covers the next */
  .cap-shell .cap-prose .wp-block-list > li > a:only-child { position: relative; -webkit-tap-highlight-color: transparent; }
  .cap-shell .cap-prose .wp-block-list > li > a:only-child::after { content: ""; position: absolute; left: 50%; top: 50%; width: max(100%, var(--cap-tap-min)); height: calc(1lh + var(--cap-space-sm)); transform: translate(-50%, -50%); }   /* one line + the list's gap = the item pitch */
}

/* the old heading class stays as an alias of the h1 role */
.cap-shell .cap-heading-1 { font-family: var(--cap-font-display); font-weight: 800; font-size: var(--cap-type-xl); line-height: var(--cap-leading-display); letter-spacing: var(--cap-track-display); color: var(--cap-color-text); margin: 0 0 var(--cap-space-md); }

/* ─── buttons (pill; four sizes; states.md §Buttons) ──────── */
.cap-shell .cap-btn {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--cap-space-sm);
  font-family: var(--cap-font-ui); font-weight: 600; font-size: var(--cap-type-btn-small);
  letter-spacing: var(--cap-track-btn); text-transform: uppercase; line-height: var(--cap-leading-btn-small);
  padding: var(--cap-btn-pad-small); border-radius: var(--cap-radius-pill);
  border: 0 solid transparent;   /* a filled button has no border: padding + line = its height (CD's sweep); the outlined variants take the hairline inside the same height */
  background: var(--cap-color-text); color: var(--cap-color-bg);
  cursor: pointer; text-decoration: none; white-space: nowrap;
  transition: background var(--cap-ease), color var(--cap-ease), border-color var(--cap-ease), box-shadow var(--cap-ease), transform var(--cap-ease-fast);
}
/* THE BUTTON STATES (round 23, owner-approved rule 1 + CD states.md §Buttons). Each variant is THREE rules, in this order:
     1. REST — no colour rule on :focus at all: a focused button changes nothing but its ring (owner 23 Sep). The 23 Sep
        "focus holds the resting look" rules existed to beat the Elementor kit's `button:focus`, which no longer exists on
        any page (measured 4 Oct, matched rules on the home and poster pages); the theme's own `button:focus` is neutralised
        by the engine's reset. Those rules outranked page-level colours and, on a touch screen (focus + a stuck :hover), let
        a tapped button change colour — so they are gone;
     2. HOVER — a mouse only, inside `@media (hover: hover)`;
     3. PRESS — `:active`, at every width (CD: "the hover values for the duration of the press"), + 1 px down; it ends when
        the finger lifts.
   A rule that changes a fill ALWAYS sets the label in the same rule (round 23 ruling 3: the outlined "Ask the Tarot" on ink
   was painted by a page rule and a component rule of different weight and lost its label after a click). A page never
   recolours a variant — it uses one. Hover colours are CD's: ink → violet · violet → ink · violet in a dark band → cream / ink
   · cream on ink → violet / white · outlined → filled. */
@media (max-width: 699px) { .cap-shell .cap-btn { color: var(--cap-color-on-ink); } }   /* every phone sheet draws the ink pill's text in the on-ink colour (28 Sep; the desktop sheets keep the cream bg colour); the variants below set their own */
@media (hover: hover) { .cap-shell .cap-btn:hover { background: var(--cap-color-primary); color: var(--cap-color-bg); } }
.cap-shell .cap-btn:active { background: var(--cap-color-primary); color: var(--cap-color-bg); transform: translateY(1px); }
.cap-shell .cap-btn--primary { background: var(--cap-color-primary); color: var(--cap-color-surface); }
@media (hover: hover) { .cap-shell .cap-btn--primary:hover { background: var(--cap-color-text); color: var(--cap-color-bg); } }
.cap-shell .cap-btn--primary:active { background: var(--cap-color-text); color: var(--cap-color-bg); }
/* the plain cream pill on ink — CD: a cream button goes violet with a white label */
.cap-shell .cap-btn--on-ink { background: var(--cap-color-on-ink); color: var(--cap-color-text); border-color: var(--cap-color-on-ink); }
@media (hover: hover) { .cap-shell .cap-btn--on-ink:hover { background: var(--cap-color-primary); border-color: var(--cap-color-primary); color: var(--cap-color-surface); } }
.cap-shell .cap-btn--on-ink:active { background: var(--cap-color-primary); border-color: var(--cap-color-primary); color: var(--cap-color-surface); }
.cap-shell .cap-btn--primary.cap-btn--on-ink { background: var(--cap-color-primary); border-color: var(--cap-color-primary); color: var(--cap-color-bg); }
@media (hover: hover) { .cap-shell .cap-btn--primary.cap-btn--on-ink:hover { background: var(--cap-color-bg); border-color: var(--cap-color-bg); color: var(--cap-color-text); } }
.cap-shell .cap-btn--primary.cap-btn--on-ink:active { background: var(--cap-color-bg); border-color: var(--cap-color-bg); color: var(--cap-color-text); }
.cap-shell .cap-btn--secondary { background: transparent; border-color: var(--cap-color-text); color: var(--cap-color-text); }
@media (hover: hover) { .cap-shell .cap-btn--secondary:hover { background: var(--cap-color-text); border-color: var(--cap-color-text); color: var(--cap-color-bg); } }
.cap-shell .cap-btn--secondary:active { background: var(--cap-color-text); border-color: var(--cap-color-text); color: var(--cap-color-bg); }
/* THE OUTLINED BUTTON ON INK (round 23 ruling 3): "Ask the Tarot / Ask the Runes" in the ink bands, the library bands' second
   button — a light hairline (the halo violet on phones), an on-ink label; hover / press: CD's dark-band inversion */
.cap-shell .cap-btn--secondary.cap-btn--on-ink { background: transparent; border-color: var(--cap-color-line-on-ink-3); color: var(--cap-color-on-ink); }
@media (hover: hover) { .cap-shell .cap-btn--secondary.cap-btn--on-ink:hover { background: var(--cap-color-on-ink); border-color: var(--cap-color-on-ink); color: var(--cap-color-text); } }
.cap-shell .cap-btn--secondary.cap-btn--on-ink:active { background: var(--cap-color-on-ink); border-color: var(--cap-color-on-ink); color: var(--cap-color-text); }
@media (max-width: 699px) { .cap-shell .cap-btn--secondary.cap-btn--on-ink { border-color: var(--cap-color-halo); } }   /* the phone sheets draw its hairline in the halo violet (2k, 2e, 2m, 2n) */
.cap-shell .cap-btn--violet { background: transparent; border-color: var(--cap-color-primary); color: var(--cap-color-primary); }
@media (hover: hover) { .cap-shell .cap-btn--violet:hover { background: var(--cap-color-primary); border-color: var(--cap-color-primary); color: var(--cap-color-bg); } }
.cap-shell .cap-btn--violet:active { background: var(--cap-color-primary); border-color: var(--cap-color-primary); color: var(--cap-color-bg); }
.cap-shell .cap-btn--error { background: var(--cap-color-error); color: var(--cap-color-bg); }
@media (hover: hover) { .cap-shell .cap-btn--error:hover { background: var(--cap-color-text); color: var(--cap-color-bg); } }
.cap-shell .cap-btn--error:active { background: var(--cap-color-text); color: var(--cap-color-bg); }
.cap-shell .cap-btn--ghost { background: transparent; border-color: var(--cap-color-line-strong); color: var(--cap-color-text); }
@media (hover: hover) { .cap-shell .cap-btn--ghost:hover { background: transparent; border-color: var(--cap-color-text); color: var(--cap-color-text); } }
.cap-shell .cap-btn--ghost:active { background: transparent; border-color: var(--cap-color-text); color: var(--cap-color-text); }
.cap-shell .cap-btn--ghost.is-active { background: var(--cap-color-text); border-color: var(--cap-color-text); color: var(--cap-color-bg); }
.cap-shell .cap-btn--ghost.cap-btn--on-ink { background: transparent; border-color: var(--cap-color-line-on-ink-3); color: var(--cap-color-on-ink); }
@media (hover: hover) { .cap-shell .cap-btn--ghost.cap-btn--on-ink:hover { background: transparent; border-color: var(--cap-color-line-on-ink-hover); color: var(--cap-color-on-ink); } }
.cap-shell .cap-btn--ghost.cap-btn--on-ink:active { background: transparent; border-color: var(--cap-color-line-on-ink-hover); color: var(--cap-color-on-ink); }
/* the header's "Free Birth Chart" pill is its own component and the sweep leaves it alone: 12.5 · 11px 22px · 38 (phone 11 · 10px 16px) */
.cap-shell .cap-header .cap-btn { font-size: var(--cap-type-btn); line-height: var(--cap-leading-ui); padding: var(--cap-btn-pad-m); border-width: var(--cap-border-hairline); }
.cap-shell .cap-btn--xs { padding: var(--cap-btn-pad-xs); font-size: var(--cap-type-chip-btn); letter-spacing: var(--cap-track-meta); }
/* small button (18 Sep): 40px tall on mobile at the 11px button size; the outlined variant absorbs its border */
.cap-shell .cap-btn--s, .cap-shell .cap-btn--m { padding: var(--cap-btn-pad-small); }
.cap-shell .cap-btn--secondary, .cap-shell .cap-btn--ghost, .cap-shell .cap-btn--violet { padding: var(--cap-btn-pad-small-outlined); border-width: var(--cap-border-hairline); }   /* the 1 px border is absorbed: still 40 */
.cap-shell .cap-btn--block:not(.cap-btn--l):not(.cap-btn--split) { padding: var(--cap-btn-pad-small-fill); }   /* a Small that fills its box: 13 all round on a phone */
/* page primary: desktop 14px hugging its label (no fixed width); mobile full-width takes the vertical value only */
/* LARGE — the page's primary action (CD's sweep, 23 Sep): 15 / 18 at every width, .16em desktop · .14em phone, 48 tall;
   the outlined variant absorbs its border; a full-width one takes 15 all round on a phone */
.cap-shell .cap-btn--l, .cap-shell .cap-btn--split { font-size: var(--cap-type-btn-large); line-height: var(--cap-leading-btn-large); letter-spacing: var(--cap-track-btn-large); padding: var(--cap-btn-pad-large); }
.cap-shell .cap-btn--l.cap-btn--block { padding: var(--cap-btn-pad-large-block); }
.cap-shell .cap-btn--l.cap-btn--secondary, .cap-shell .cap-btn--l.cap-btn--ghost, .cap-shell .cap-btn--l.cap-btn--violet { padding: var(--cap-btn-pad-large-outlined); }
.cap-shell .cap-btn--l.cap-btn--block.cap-btn--secondary, .cap-shell .cap-btn--l.cap-btn--block.cap-btn--ghost, .cap-shell .cap-btn--l.cap-btn--block.cap-btn--violet { padding: var(--cap-btn-pad-large-block-outlined); }
.cap-shell .cap-btn--block { display: flex; width: 100%; }
.cap-shell .cap-btn--split { display: flex; width: 100%; justify-content: space-between; }
.cap-shell .cap-btn--cta { box-shadow: var(--cap-shadow-cta); }
/* disabled (● 23 Sep): the SAME pill at opacity .45 — the grey-fill disabled is retired */
.cap-shell .cap-btn:disabled,
.cap-shell .cap-btn.is-disabled { opacity: var(--cap-opacity-disabled); cursor: not-allowed; transform: none; box-shadow: none; transition: none; }
@media (hover: hover) { .cap-shell .cap-btn:disabled:hover, .cap-shell .cap-btn.is-disabled:hover { background: inherit; color: inherit; } }
.cap-shell .cap-btn--primary:disabled,
.cap-shell .cap-btn--primary.is-disabled { background: var(--cap-color-primary); color: var(--cap-color-surface); }
@media (hover: hover) { .cap-shell .cap-btn--primary:disabled:hover { background: var(--cap-color-primary); color: var(--cap-color-surface); } }
.cap-shell .cap-btn.is-disabled:active { transform: none; }   /* a disabled link-button never presses (a <button disabled> never becomes :active) */
.cap-shell .cap-btn--primary.is-disabled:active { background: var(--cap-color-primary); color: var(--cap-color-surface); }
@media (max-width: 699px) {
}
.cap-shell .cap-btn.is-loading { background: var(--cap-color-text); color: var(--cap-color-bg); cursor: progress; }
/* LOADING IS NEVER THE DISABLED LOOK (round 23, rule 1): CapriUI.busy() also disables the button (no second submit), which
   put every loading button at .45 — "looks broken rather than busy" (the sweep). Loading = the ink pill at full strength,
   whatever the variant, in every state (CD: loading outranks hover). */
.cap-shell .cap-btn.is-loading:is(:disabled, .is-disabled, :hover, :active, :focus) { opacity: 1; background: var(--cap-color-text); border-color: var(--cap-color-text); color: var(--cap-color-bg); transform: none; }
.cap-shell .cap-btn.is-loading::before { content: ""; width: 11px; height: 11px; border-radius: var(--cap-radius-pill); border: var(--cap-border-selected) solid var(--cap-color-spinner-track); border-top-color: var(--cap-color-bg); animation: cap-spin 1s linear infinite; flex: none; }
@keyframes cap-spin { to { transform: rotate(360deg); } }
/* ON A TOUCH SCREEN A BUTTON'S PRESS IS AT ONCE, never by easing (owner 2026-10-07, round 37) — written for every element with a
   press look by bin/build-press.py into press.css (the "AT ONCE" block). */

/* text link (● 23 Sep): 600 · 12.5 / 11 · .14em · ink on a ONE-px violet underline (1.5 is the header's active-nav marker, a different component) */
.cap-shell .cap-link { background: none; border-top: 0; border-left: 0; border-right: 0; padding-top: 0; padding-left: 0; padding-right: 0; font-family: var(--cap-font-ui); font-weight: 600; font-size: var(--cap-type-textlink); letter-spacing: var(--cap-track-textlink); text-transform: uppercase; color: var(--cap-color-text); border-bottom: var(--cap-border-hairline) solid var(--cap-color-primary); padding-bottom: var(--cap-space-gap-1); line-height: var(--cap-leading-tight); text-decoration: none; display: inline-block; transition: color var(--cap-ease); }   /* owner 25 Sep: the /runes/one-rune/ "Browse all" spacing is the template sitewide — a 1.2 line and 2 below, the violet rule ~6 under the letters; never the inherited body line height */
@media (hover: hover) { .cap-shell .cap-link:hover { color: var(--cap-color-primary); } }
.cap-shell .cap-link--action { border: 0; padding: 0; color: var(--cap-color-primary); background: none; cursor: pointer; font-weight: 500; }
@media (hover: hover) { .cap-shell .cap-link--action:hover { color: var(--cap-color-text); } }

/* ─── fields (pill input; states.md §Fields) ──────────────── */
.cap-shell .cap-field { display: block; position: relative; }
.cap-shell .cap-field__label { display: block; margin: 0 0 var(--cap-space-xs); font-family: var(--cap-font-ui); font-weight: 500; font-size: var(--cap-type-hint); letter-spacing: var(--cap-track-feature); text-transform: uppercase; color: var(--cap-color-muted); padding-left: var(--cap-space-md); }
.cap-shell .cap-input {
  display: block; width: 100%;
  font-family: var(--cap-font-ui); font-weight: 400; font-size: var(--cap-type-input); letter-spacing: var(--cap-track-ui); line-height: var(--cap-leading-input);
  color: var(--cap-color-text); background: var(--cap-color-surface);
  border: var(--cap-border-hairline) solid var(--cap-color-field-empty); border-radius: var(--cap-radius-pill);
  padding: var(--cap-btn-pad-field); margin: 0; appearance: none; -webkit-appearance: none;
  transition: border-color var(--cap-ease), box-shadow var(--cap-ease), background var(--cap-ease);
}
/* the place-of-birth field is type="search" (26 Sep): Safari never offers its Contacts AutoFill (the person + chevron
   icon) on a search field, which autocomplete="off" cannot stop. The browser's own search look is removed so it draws
   exactly like any other .cap-input: no rounded inset, no magnifier, no native ✕ (the form's own ✕ is the clear control). */
.cap-shell input.cap-input[type="search"] { -webkit-appearance: none; appearance: none; }
.cap-shell input.cap-input[type="search"]::-webkit-search-decoration,
.cap-shell input.cap-input[type="search"]::-webkit-search-cancel-button,
.cap-shell input.cap-input[type="search"]::-webkit-search-results-button,
.cap-shell input.cap-input[type="search"]::-webkit-search-results-decoration { -webkit-appearance: none; appearance: none; display: none; }
.cap-shell .cap-input::placeholder { color: var(--cap-color-muted); opacity: 1; }
.cap-shell .cap-input:focus, .cap-shell .cap-input.is-suggested { border-color: var(--cap-color-field-focus); box-shadow: var(--cap-shadow-focus); }   /* .is-suggested: the focus look without the focus — the name on a touch screen, arriving from the calculator */
.cap-shell .cap-input.is-filled,
.cap-shell .cap-input:not(:placeholder-shown) { border-color: var(--cap-color-field-filled); }   /* filled = field-filled (CD field states 26 Sep, owner ruling: site-wide, replacing ink); focus stays ink */
.cap-shell .cap-input.is-error,
.cap-shell .cap-input[aria-invalid="true"] { border-color: var(--cap-field-error-edge, var(--cap-color-error)); box-shadow: var(--cap-field-error-halo, none); }
.cap-shell .cap-input[aria-invalid="true"]:focus-visible { border-color: var(--cap-field-error-edge, var(--cap-color-error)); box-shadow: var(--cap-field-error-halo, var(--cap-shadow-focus)); }   /* on ink the error halo stays while the field is focused (2g-4); on cream the focus halo, as before */
.cap-shell .cap-input:disabled { border-color: var(--cap-color-field-disabled-border); color: var(--cap-color-muted); background: var(--cap-color-field-disabled-bg); }   /* the lilac is never text on cream (states.md) */
.cap-shell .cap-input--select { padding-right: var(--cap-space-xl); background-image: none; }
.cap-shell .cap-select { position: relative; }
.cap-shell .cap-select::after { content: "▾"; position: absolute; right: var(--cap-space-md); top: 50%; transform: translateY(-50%); color: var(--cap-color-muted); pointer-events: none; font-family: var(--cap-font-ui); }
.cap-shell .cap-field-row { display: flex; gap: var(--cap-space-sm); }
.cap-shell .cap-field-row > * { flex: 1; min-width: 0; }
.cap-shell .cap-field-row > .cap-field--wide { flex: 1.2; }

/* the birth date + time (Capriastro_Calculator::birth_fields, CapriUI.birth): ONE native
   date input and ONE native time input, drawn as the same pill as a text field; the
   browser paints the locale format (07/26/1969 · 05:30 PM) and its own picker */
.cap-shell .cap-birth { flex-wrap: wrap; }
.cap-shell .cap-birth > .cap-birth__date { flex: 1 1 15rem; }     /* > : outranks the row's generic flex:1.2 (basis 0) */
.cap-shell .cap-birth > .cap-birth__time { flex: 1 1 10rem; }      /* on a phone the time wraps under the date at this width */
.cap-shell select.cap-input:not(.is-filled):not(:focus):not([aria-invalid="true"]),
.cap-shell .cap-input--native:not(.is-filled):not(:focus):not([aria-invalid="true"]) { border-color: var(--cap-color-field-empty); }   /* a select / a date / a time control never "shows a placeholder" — the empty state is the JS class; focus + error keep theirs */
.cap-shell .cap-input:is([type="date"], [type="time"]) { height: var(--cap-space-field-h); box-sizing: border-box; }   /* a native date / time control grows past its line box; every field is 48 (CD's sweep) */
.cap-shell .cap-input--native { min-height: var(--cap-space-field-h); height: var(--cap-space-field-h); box-sizing: border-box; text-align: left; }   /* iOS collapses an empty date control — pin the pill to a text field's height (the field pad is 14px = cell-y) */
.cap-shell .cap-input--native::-webkit-date-and-time-value { text-align: left; min-height: var(--cap-leading-input); }   /* iOS centres the value and gives an empty one no height */
.cap-shell .cap-input--native::-webkit-calendar-picker-indicator { opacity: 0.6; }

/* typo chip — field-attached feedback keeps its radius */
.cap-shell .cap-typo { display: flex; align-items: center; justify-content: space-between; gap: var(--cap-space-sm); margin-top: var(--cap-space-sm); padding: var(--cap-space-sm) var(--cap-space-md); border: var(--cap-border-hairline) solid var(--cap-color-error); border-radius: var(--cap-radius-md); background: var(--cap-color-error-fill); font-family: var(--cap-font-serif); font-style: italic; font-size: var(--cap-type-msg); color: var(--cap-color-text); }
.cap-shell .cap-typo strong { font-style: normal; font-weight: 600; }
/* round 34 (owner 2026-10-06): the notice never runs past its box — when the sentence and "Use this" don't fit side by side the
   button drops under the sentence (start-aligned); the sentence reads from the left even inside a centred band */
.cap-shell .cap-typo { flex-wrap: wrap; text-align: left; }
.cap-shell .cap-typo > span { flex: 1 1 auto; min-width: 0; overflow-wrap: anywhere; }
.cap-shell .cap-typo > .cap-btn { flex: none; }
.cap-shell .cap-typo .cap-btn { font-style: normal; }   /* "Use this" upright: the hint's italic serif sentence must not slant the Barlow button (Barlow has no italic face; owner 2026-10-08) */

/* THE PLACE LIST (D1b, 27 Sep): the <ul> is the slot, 8 under the field; the card holds the rows (five show, more scroll
   inside it); the keyboard hint sits 8 under the card, outside it. One line a row: the city left (Barlow 500, up to 60%,
   then an ellipsis), the region right (caption caps, it truncates first), the coordinates on the highlighted row only. */
.cap-shell :is(.cap-field, .cap-parts):has(.cap-places:not([hidden])) { position: relative; z-index: 40; }   /* round 22 D2: the cell holding an OPEN list goes over every lifted neighbour (the ⓘ's tap layer, a focused or errored cell) — its own z 30 only counts inside the cell */
.cap-shell .cap-places { position: absolute; z-index: 30; left: 0; right: 0; top: calc(100% + var(--cap-space-sm)); margin: 0; padding: 0; list-style: none; display: flex; flex-direction: column; gap: var(--cap-space-sm); }
.cap-shell .cap-places[hidden] { display: none; }
.cap-shell .cap-places__card { overflow: hidden; background: var(--cap-color-surface); border: var(--cap-border-hairline) solid var(--cap-color-field-empty); border-radius: var(--cap-radius-field-card); box-shadow: var(--cap-shadow-lift); }
.cap-shell .cap-places__rows { margin: 0; padding: 0; list-style: none; max-height: calc(5 * (var(--cap-type-card-value) * var(--cap-leading-tight) + 2 * var(--cap-space-gap-7) + var(--cap-border-hairline))); overflow-y: auto; }
.cap-shell .cap-places__row { display: flex; align-items: baseline; justify-content: space-between; gap: var(--cap-space-md); padding: var(--cap-space-gap-7) var(--cap-space-cell-x); cursor: pointer; }
.cap-shell .cap-places__row + .cap-places__row { border-top: var(--cap-border-hairline) solid var(--cap-color-field-empty); }
.cap-shell .cap-places__row[aria-selected="true"] { background: var(--cap-color-bg-deep); }   /* hover and the keyboard highlight are one colour (the mousemove moves the highlight) */
.cap-shell .cap-places__place { flex: 0 1 auto; max-width: 60%; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-family: var(--cap-font-ui); font-weight: 500; font-size: var(--cap-type-card-value); letter-spacing: var(--cap-track-faq); line-height: var(--cap-leading-tight); color: var(--cap-color-text); }
.cap-shell .cap-places__meta { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-family: var(--cap-font-ui); font-weight: 500; font-size: var(--cap-type-caption); letter-spacing: var(--cap-track-caption); text-transform: uppercase; line-height: var(--cap-leading-tight); color: var(--cap-color-caption); }
.cap-shell .cap-places__row[aria-selected="true"] .cap-places__meta { color: var(--cap-color-muted); }
.cap-shell .cap-places__coords { display: none; }
.cap-shell .cap-places__row[aria-selected="true"] .cap-places__coords { display: inline; }
@media (max-width: 699px) {   /* 2l place list (28 Sep): 52 rows, 12 / 16 pads, the place 17 / 20, the region at .12em, the sheet's drop shadow; no coordinates */
  .cap-shell .cap-places__card { box-shadow: var(--cap-mp-shadow-places); }
  .cap-shell .cap-places__row { align-items: center; min-height: var(--cap-mp-places-row-h); box-sizing: border-box; padding: var(--cap-space-block-2) var(--cap-space-md); }
  .cap-shell .cap-places__place { font-size: var(--cap-type-input); line-height: var(--cap-leading-input); }
  .cap-shell .cap-places__meta { letter-spacing: var(--cap-track-feature); line-height: normal; }
  .cap-shell .cap-places__row[aria-selected="true"] .cap-places__coords { display: none; }
}
.cap-shell .cap-places__empty { display: flex; flex-direction: column; gap: var(--cap-space-gap-3); padding: var(--cap-space-md) var(--cap-space-cell-x); line-height: normal; }   /* D1b: each line on its face's own line height (75 tall), not the cell's tight one */
.cap-shell .cap-places__empty-q { font-family: var(--cap-font-serif); font-style: italic; font-size: var(--cap-alert-text); color: var(--cap-color-caption); }
.cap-shell .cap-places__empty-hint,
.cap-shell .cap-places__keys { font-family: var(--cap-font-ui); font-weight: 500; font-size: var(--cap-type-caption); letter-spacing: var(--cap-track-caption); text-transform: uppercase; color: var(--cap-color-caption); }
@media (max-width: 699px) {   /* 2l no-match panel (28 Sep): 13 / 18 pads, the lines 4 apart, the question 14, the hint .12em */
  .cap-shell .cap-places__empty { gap: var(--cap-space-xs); padding: var(--cap-btn-pad-small); }   /* the no-match panel: 13 / 18 pads, the lines 4 apart */
  .cap-shell .cap-places__empty-q { font-size: var(--cap-type-card-value); }
  .cap-shell .cap-places__empty-hint { letter-spacing: var(--cap-track-feature); }
}
.cap-shell .cap-places__keys { cursor: default; padding-left: var(--cap-space-cell-x); }
@media (hover: none) { .cap-shell .cap-places__keys { display: none; } }   /* a keyboard hint means nothing on a touch screen */
.cap-shell .cap-error__link { color: var(--cap-color-primary); border-bottom: var(--cap-border-hairline) solid var(--cap-color-primary); }

/* ─── checkbox (states.md §Consent checkbox) ──────────────── */
.cap-shell .cap-check { display: flex; gap: var(--cap-space-sm); align-items: flex-start; cursor: pointer; font-family: var(--cap-font-serif); font-size: var(--cap-type-small); line-height: var(--cap-leading-small); color: var(--cap-color-text-body); }
.cap-shell .cap-check input { appearance: none; -webkit-appearance: none; flex: none; width: 20px; height: 20px; margin: 0; border-radius: var(--cap-radius-checkbox); border: var(--cap-border-selected) solid var(--cap-color-line-strong); background: var(--cap-color-surface); display: inline-grid; place-content: center; cursor: pointer; transition: background var(--cap-ease), border-color var(--cap-ease); }
.cap-shell .cap-check input:checked { background: var(--cap-color-text); border-color: var(--cap-color-text); }
.cap-shell .cap-check input:checked::after { content: "✔"; color: var(--cap-color-bg); font-size: var(--cap-type-btn); line-height: 1; }
.cap-shell .cap-check.is-blocked input { border-color: var(--cap-color-error); }
.cap-shell .cap-check.is-blocked { color: var(--cap-color-error); }

/* ─── messages (states.md §Messages) ──────────────────────── */
.cap-shell .cap-msg { display: flex; align-items: center; gap: var(--cap-space-sm); padding: var(--cap-space-sm) var(--cap-space-md); border-radius: var(--cap-radius-msg); background: var(--cap-color-bg-deep); font-family: var(--cap-font-serif); font-style: italic; font-size: var(--cap-type-msg); color: var(--cap-color-text); }
.cap-shell .cap-msg::before { content: "✦"; flex: none; width: 17px; height: 17px; border-radius: var(--cap-radius-pill); background: var(--cap-color-text); color: var(--cap-color-bg-deep); display: inline-grid; place-content: center; font-family: var(--cap-font-ui); font-style: normal; font-size: var(--cap-type-msg-mark); }   /* the mark's own size at every width — centred in the disc (owner 2026-10-07) */
.cap-shell .cap-msg--flat { border-radius: 0; }
.cap-shell .cap-msg--success { background: var(--cap-color-surface); border: var(--cap-border-hairline) solid var(--cap-color-line-strong); }
.cap-shell .cap-msg--success::before { content: "✔"; color: var(--cap-color-surface); }
.cap-shell .cap-msg--error { background: var(--cap-color-error-fill); border: var(--cap-border-hairline) solid var(--cap-color-error); }
.cap-shell .cap-msg--error::before { content: "!"; background: var(--cap-color-error); color: var(--cap-color-error-fill); font-weight: 700; }
.cap-shell .cap-error { font-family: var(--cap-font-serif); font-style: italic; font-size: var(--cap-type-msg); color: var(--cap-color-error); }
/* THE ALERT BOX (D1b, 27 Sep): a field error or a general one, in the helper line's slot — carmine edge, the error fill,
   16 corners, a round "!" mark beside the message (Source Serif italic, ink) */
.cap-shell .cap-alert { display: flex; align-items: flex-start; gap: var(--cap-space-gap-6); margin: 0; padding: var(--cap-space-gap-6); border: var(--cap-border-hairline) solid var(--cap-color-error); border-radius: var(--cap-radius-field-card); background: var(--cap-color-error-fill); font-size: var(--cap-alert-text); line-height: var(--cap-leading-lede); color: var(--cap-color-text); }
.cap-shell .cap-alert[hidden] { display: none; }
/* the message takes the room beside the mark and wraps inside the box — an unbroken string (an email address) breaks rather
   than push out (D1b / 2l, 29 Sep sheets: the text flex: 1, min-width: 0) */
.cap-shell .cap-alert { overflow-wrap: anywhere; }
.cap-shell .cap-alert > * { flex: 1; min-width: 0; }
.cap-shell .cap-alert a { white-space: nowrap; }   /* the link's words stay on one line — "Find your birth time" never breaks after "birth" (owner 2026-09-29) */
/* phone (29 Sep sheets 2j · 2l): the field-attached box — 6 in from the field on each side, 10 / 16 in, the mark 10 from the
   message; the mark 17 and the message 14 come from the alert tokens' phone values */
@media (max-width: 699px) { .cap-shell .cap-alert { gap: var(--cap-space-gap-5); padding: var(--cap-space-gap-5) var(--cap-space-gap-8); margin-left: var(--cap-space-gap-3); margin-right: var(--cap-space-gap-3); } }
/* the "!" mark lines up with the FIRST line of the message (CD 2g-4: a two-line message keeps its mark at the top) — its
   top offset centres it on one line box; a one-line alert looks exactly as before. The calculator's email field in error
   carries the same mark inside it, on the right (2g-4). */
.cap-shell .cap-alert::before { margin-top: calc((var(--cap-alert-text) * var(--cap-leading-lede) - var(--cap-alert-mark)) / 2); }
.cap-shell .cap-capture__field { position: relative; }
.cap-shell .cap-capture__field:has(.cap-capture__email[aria-invalid="true"])::after { position: absolute; right: var(--cap-space-gap-8); top: 50%; transform: translateY(-50%); pointer-events: none; }   /* 2g-4: 16 in from the edge (its 18 size: after the shared mark rule below) */
.cap-shell .cap-capture__field:has(.cap-capture__email[aria-invalid="true"]) .cap-capture__email { padding-right: calc(var(--cap-space-gap-8) + var(--cap-space-field-error-mark) + var(--cap-space-gap-5)); }
.cap-shell .cap-alert::before, .cap-shell .cap-capture__field:has(.cap-capture__email[aria-invalid="true"])::after { content: "!"; flex: none; width: var(--cap-alert-mark); height: var(--cap-alert-mark); border-radius: var(--cap-radius-pill); background: var(--cap-color-error); color: var(--cap-color-error-fill); display: flex; align-items: center; justify-content: center; font-family: var(--cap-font-ui); font-style: normal; font-weight: 700; font-size: var(--cap-type-alert-mark); line-height: 1; }
.cap-shell .cap-capture__field:has(.cap-capture__email[aria-invalid="true"])::after { width: var(--cap-space-field-error-mark); height: var(--cap-space-field-error-mark); }   /* the in-field mark is 18 (2g-4); the alert's stays --cap-alert-mark */

/* ─── badges / chips (states.md §Badges) ──────────────────── */
.cap-shell .cap-badge { display: inline-flex; align-items: center; justify-content: center; line-height: var(--cap-leading-ui); font-family: var(--cap-font-ui); font-weight: 600; font-size: var(--cap-type-badge); letter-spacing: var(--cap-track-meta); text-transform: uppercase; border-radius: var(--cap-radius-pill); padding: var(--cap-btn-pad-xs); border: var(--cap-border-hairline) solid transparent; white-space: nowrap; }
.cap-shell .cap-badge--price { border-color: var(--cap-color-primary); color: var(--cap-color-primary); padding: var(--cap-space-sm) var(--cap-space-md); font-size: var(--cap-type-eyebrow-card); }
.cap-shell .cap-badge--price.cap-badge--on-ink { border-color: var(--cap-color-primary-soft); color: var(--cap-color-primary-pale); }
.cap-shell .cap-badge--status { background: var(--cap-color-text); color: var(--cap-color-bg); }
.cap-shell .cap-badge--time { border-color: var(--cap-color-line-strong); color: var(--cap-color-muted); }
.cap-shell .cap-badge--ready { border-color: var(--cap-color-primary); color: var(--cap-color-primary); }
.cap-shell .cap-badge--tag { background: var(--cap-color-text); color: var(--cap-color-bg); }
/* corner badge (● 23 Sep): 600 · 12.5 / 9 · .14em, inner radius 12 / 10, other corners square; "New" = ink (default), "Sale" = violet; one per tile at most */
.cap-shell .cap-badge--corner { position: absolute; top: 0; right: 0; border-radius: 0 0 0 var(--cap-radius-badge-corner); background: var(--cap-color-text); color: var(--cap-color-bg); font-weight: 600; font-size: var(--cap-type-btn); letter-spacing: var(--cap-track-btn); padding: var(--cap-btn-pad-xs); }
.cap-shell .cap-badge--corner.cap-badge--sale { background: var(--cap-color-primary); color: var(--cap-color-surface); }
@media (max-width: 699px) { .cap-shell .cap-badge--corner { font-size: var(--cap-type-badge); } }
.cap-shell .cap-chip { display: inline-flex; align-items: center; justify-content: center; line-height: var(--cap-leading-ui); font-family: var(--cap-font-ui); font-weight: 600; font-size: var(--cap-type-eyebrow-card); letter-spacing: var(--cap-track-meta); text-transform: uppercase; border-radius: var(--cap-radius-pill); padding: var(--cap-btn-pad-s); border: var(--cap-border-hairline) solid var(--cap-color-line-strong); color: var(--cap-color-text); background: transparent; cursor: pointer; text-decoration: none; transition: border-color var(--cap-ease), background var(--cap-ease), color var(--cap-ease); }
@media (hover: hover) { .cap-shell .cap-chip:hover { border-color: var(--cap-color-text); color: var(--cap-color-text); } }
.cap-shell .cap-chip.is-active { background: var(--cap-color-text); border-color: var(--cap-color-text); color: var(--cap-color-bg); }
.cap-shell .cap-chip--on-ink { border-color: var(--cap-color-line-on-ink-3); color: var(--cap-color-on-ink-muted); }
@media (hover: hover) { .cap-shell .cap-chip--on-ink:hover { border-color: var(--cap-color-line-on-ink-hover); color: var(--cap-color-on-ink); } }
.cap-shell .cap-chip--on-ink.is-active { background: var(--cap-color-on-ink); border-color: var(--cap-color-on-ink); color: var(--cap-color-text); }
.cap-shell .cap-chip[aria-disabled="true"] { cursor: default; border-color: var(--cap-color-line-on-ink-3); color: var(--cap-color-on-ink-muted); }
@media (hover: hover) { .cap-shell .cap-chip--on-ink[aria-disabled="true"]:hover { cursor: default; border-color: var(--cap-color-line-on-ink-3); color: var(--cap-color-on-ink-muted); } }   /* D17 suit tabs: the four "soon" suits are inert (0.51.186) */

/* ─── cards / panels ──────────────────────────────────────── */
/* small widget card: rounded,
.cap-shell halo on hover */
.cap-shell .cap-card { position: relative; background: var(--cap-color-surface); color: var(--cap-color-text); border: var(--cap-border-hairline) solid var(--cap-color-line-strong); border-radius: var(--cap-radius-form); padding: var(--cap-space-card-pad); transition: box-shadow var(--cap-ease), border-color var(--cap-ease), transform var(--cap-ease-fast); }
@media (hover: hover) { .cap-shell .cap-card--hover:hover { box-shadow: var(--cap-shadow-halo); } }   /* hover = the violet glow, never a stroke (owner 2026-09-29; 0.51.398 had carried :hover onto the focus ring below) */
.cap-shell .cap-card--hover:has(:focus-visible):not(:focus-visible) { outline: var(--cap-ring, var(--cap-focus-ring)); outline-offset: var(--cap-focus-ring-offset); }   /* a card whose link sits inside it takes the ring (27 Sep focus rule) — keyboard only */
@media (hover: hover) { .cap-shell .cap-card--lift:hover { transform: translateY(var(--cap-lift)); } }
/* square link/feature card: grey lift */
.cap-shell .cap-card--flat { border-radius: 0; padding: 0; overflow: hidden; }
/* image / product card hover — round 23 rule 7: THE SHADOW ONLY (CD's value; owner 24 Sep "the shadow ONLY … no border change";
   CD's states.md adds the deep hairline — listed for the owner). A card's title never changes colour on any state. */
@media (hover: hover) { .cap-shell .cap-card--flat.cap-card--hover:hover { box-shadow: var(--cap-shadow-lift); } }
@media (hover: hover) { .cap-shell .cap-card--hub:hover { box-shadow: var(--cap-shadow-hub-card); } }
/* dark card: square, deep shadow only when it holds no button */
.cap-shell .cap-card--dark { background: var(--cap-color-text); color: var(--cap-color-on-ink); border: 0; border-radius: 0; padding: var(--cap-space-lg) var(--cap-space-lg); }
@media (hover: hover) { .cap-shell .cap-card--dark.cap-card--hover:hover { box-shadow: var(--cap-shadow-dark); border-color: transparent; } }
/* round 23 ruling 4 (owner): the ink link cards ("The full reading" on the birth chart, hub and sign pages) and the free-chart
   bands take the card hover — the violet glow round the card (on cream, rule 7) — and, as every card that holds a button
   (CD), their pill turns at the same time: violet in an ink card → cream / ink. Nothing else in the card changes colour. */
@media (hover: hover) {
  .cap-shell .cap-card--dark:is(a, .cap-press):hover, .cap-shell .cap-post__chart:is(a, .cap-press):hover { box-shadow: var(--cap-shadow-halo); }   /* a whole-card link is an <a>, or a .cap-press <div> once cap-press.js has turned it */
  .cap-shell .cap-card--dark:is(a, .cap-press):hover .cap-btn--primary.cap-btn--on-ink { background: var(--cap-color-bg); border-color: var(--cap-color-bg); color: var(--cap-color-text); }
}
.cap-shell .cap-card--dark .cap-h3-card,
.cap-shell .cap-card--dark .cap-h2 { color: var(--cap-color-on-ink); }
/* cream panel: square, deep cream */
.cap-shell .cap-panel { background: var(--cap-color-bg-deep); padding: var(--cap-space-panel-pad); }
.cap-shell .cap-panel--tight { padding: var(--cap-space-lg) var(--cap-space-card-pad); }
/* form panel: rounded, white */
.cap-shell .cap-form-panel { background: var(--cap-color-surface); border: var(--cap-border-hairline) solid var(--cap-color-line-strong); border-radius: var(--cap-radius-form); padding: var(--cap-space-panel-pad); display: flex; flex-direction: column; gap: var(--cap-space-sm); }
.cap-shell .cap-form-panel--compact { padding: var(--cap-space-card-pad); }
/* image well */
.cap-shell .cap-well { position: relative; background: var(--cap-color-bg-deep); display: flex; justify-content: center; padding: var(--cap-space-xl) 0; }
.cap-shell .cap-well--zoom { cursor: zoom-in; }
.cap-shell .cap-well__sheet { background: var(--cap-color-surface); box-shadow: var(--cap-shadow-well); overflow: hidden; border-radius: var(--cap-radius-sm); }
.cap-shell .cap-well__sheet img { display: block; width: 100%; height: 100%; object-fit: cover; }
.cap-shell .cap-well__zoom { position: absolute; right: var(--cap-space-md); bottom: var(--cap-space-md); width: 44px; height: 44px; border-radius: var(--cap-radius-pill); border: var(--cap-border-hairline) solid var(--cap-color-line-emphasis); background: var(--cap-color-scrim-soft); color: var(--cap-color-text); display: inline-grid; place-content: center; cursor: zoom-in; transition: background var(--cap-ease), color var(--cap-ease), border-color var(--cap-ease); }
@media (hover: hover) { .cap-shell .cap-well__zoom:hover { background: var(--cap-color-text); color: var(--cap-color-bg); border-color: var(--cap-color-text); } }
.cap-shell .cap-well__zoom svg { display: block; width: 18px; height: 18px; }
/* image slot (1:1 hero / gallery) */
.cap-shell .cap-media { position: relative; background: var(--cap-color-bg-deep); overflow: hidden; }
.cap-shell .cap-media--square { aspect-ratio: 1 / 1; }
.cap-shell .cap-media img { display: block; width: 100%; height: 100%; object-fit: cover; }
.cap-shell .cap-media__tag { position: absolute; left: var(--cap-space-md); bottom: var(--cap-space-md); }
.cap-shell .cap-thumb { width: 96px; height: 96px; flex: none; border-radius: var(--cap-radius-thumb); overflow: hidden; border: var(--cap-border-hairline) solid var(--cap-color-line-strong); background: var(--cap-color-bg-deep); cursor: pointer; padding: 0; transition: border-color var(--cap-ease); }
@media (hover: hover) { .cap-shell .cap-thumb:hover { border-color: var(--cap-color-line-deep); } }
.cap-shell .cap-thumb.is-selected { border-color: var(--cap-color-text); }   /* the active thumb (incl. "Your poster"): 1 px ink, never a heavier line (§9.ay, owner 2026-09-26) */
.cap-shell .cap-thumb img { display: block; width: 100%; height: 100%; object-fit: cover; }
.cap-shell .cap-thumb--sm { width: 72px; height: 72px; }

/* ─── selectors: option rows · segmented toggle · swatches ── */
.cap-shell .cap-options { background: var(--cap-color-surface); border: var(--cap-border-hairline) solid var(--cap-color-line-strong); border-radius: var(--cap-radius-md); overflow: hidden; }
.cap-shell .cap-option { display: flex; align-items: center; gap: var(--cap-space-md); padding: var(--cap-space-md) var(--cap-space-md); cursor: pointer; border-top: var(--cap-border-hairline) solid var(--cap-color-line); background: var(--cap-color-surface); transition: background var(--cap-ease); }
.cap-shell .cap-option:first-child { border-top: 0; }

.cap-shell .cap-option.is-selected { background: var(--cap-color-bg); }
@media (hover: hover) { .cap-shell .cap-option:hover { background: var(--cap-color-bg); } }
.cap-shell .cap-option input { position: absolute; opacity: 0; pointer-events: none; }
/* a hidden radio shows its keyboard focus on its row / cell (D15c): the ring outside, Tab and arrows only */
.cap-shell :is(.cap-option, .cap-orient__cell):has(> input:focus-visible) { outline: var(--cap-ring, var(--cap-focus-ring)); outline-offset: var(--cap-focus-ring-offset); position: relative; z-index: 1; }
.cap-shell .cap-option__dot { width: 16px; height: 16px; flex: none; border-radius: var(--cap-radius-pill); border: var(--cap-border-selected) solid var(--cap-color-line-strong); display: inline-grid; place-content: center; }
.cap-shell .cap-option__dot::after { content: ""; width: 8px; height: 8px; border-radius: var(--cap-radius-pill); background: transparent; }
.cap-shell .cap-option.is-selected .cap-option__dot { border-color: var(--cap-color-text); }
.cap-shell .cap-option.is-selected .cap-option__dot::after { background: var(--cap-color-text); }
.cap-shell .cap-option__name { font-family: var(--cap-font-ui); font-weight: 600; font-size: var(--cap-type-field); letter-spacing: var(--cap-track-ui); text-transform: uppercase; color: var(--cap-color-text); }
.cap-shell .cap-option__sub { font-family: var(--cap-font-ui); font-weight: 500; font-size: var(--cap-type-btn-sm); letter-spacing: var(--cap-track-label); text-transform: uppercase; color: var(--cap-color-muted); }
.cap-shell .cap-option__price { margin-left: auto; font-family: var(--cap-font-ui); font-weight: 600; font-size: var(--cap-type-field); color: var(--cap-color-text); }
.cap-shell .cap-toggle { display: flex; border: var(--cap-border-hairline) solid var(--cap-color-line-strong); border-radius: var(--cap-radius-pill); padding: var(--cap-space-xs); background: var(--cap-color-surface); }
.cap-shell .cap-toggle__opt { flex: 1; display: inline-flex; align-items: center; justify-content: center; gap: var(--cap-space-sm); padding: var(--cap-btn-pad-m); border-radius: var(--cap-radius-pill); font-family: var(--cap-font-ui); font-weight: 600; font-size: var(--cap-type-eyebrow-card); letter-spacing: var(--cap-track-meta); text-transform: uppercase; color: var(--cap-color-text); cursor: pointer; border: 0; background: transparent; line-height: var(--cap-leading-ui); transition: background var(--cap-ease), color var(--cap-ease); }
.cap-shell .cap-toggle__opt.is-active { background: var(--cap-color-text); color: var(--cap-color-bg); }
.cap-shell .cap-toggle__opt input { position: absolute; opacity: 0; pointer-events: none; }
.cap-shell .cap-toggle__icon { display: block; border: 1.2px solid currentColor; border-radius: 1px; }
.cap-shell .cap-toggle__icon--portrait { width: 8px; height: 11px; }
.cap-shell .cap-toggle__icon--landscape { width: 11px; height: 8px; }
.cap-shell .cap-swatches { display: grid; grid-template-columns: repeat(5, 1fr); gap: var(--cap-space-sm); }
.cap-shell .cap-swatch { border: var(--cap-border-hairline) solid var(--cap-color-line); border-radius: var(--cap-radius-selector); padding: var(--cap-space-sm) var(--cap-space-xs); display: flex; flex-direction: column; align-items: center; gap: var(--cap-space-sm); background: var(--cap-color-surface); cursor: pointer; transition: border-color var(--cap-ease); }
.cap-shell .cap-swatch.is-selected { border-color: var(--cap-color-text); }   /* 1 px ink (§9.ay) */
.cap-shell .cap-swatch.is-disabled { opacity: .45; cursor: not-allowed; }
.cap-shell .cap-swatch__chip { width: 28px; height: 28px; display: block; background: var(--cap-color-bg); border: var(--cap-border-hairline) dashed var(--cap-color-line-strong); }
.cap-shell .cap-swatch__chip--white { border: 4px solid var(--cap-color-surface); box-shadow: 0 0 0 1px var(--cap-color-line-strong); }
.cap-shell .cap-swatch__chip--black { border: 4px solid var(--cap-color-frame-black); }
.cap-shell .cap-swatch__chip--oak { border: 4px solid var(--cap-color-frame-oak); }
.cap-shell .cap-swatch__chip--walnut { border: 4px solid var(--cap-color-frame-walnut); }
.cap-shell .cap-swatch__name { font-family: var(--cap-font-ui); font-weight: 600; font-size: var(--cap-type-btn-sm); letter-spacing: var(--cap-track-ui); text-transform: uppercase; color: var(--cap-color-text); }
.cap-shell .cap-swatch__sub { font-family: var(--cap-font-ui); font-weight: 500; font-size: var(--cap-type-badge); letter-spacing: var(--cap-track-ui); text-transform: uppercase; color: var(--cap-color-muted); }

/* ─── list rows: spec rows · summary rows · FAQ ───────────── */
.cap-shell .cap-rows { border-top: var(--cap-border-hairline) solid var(--cap-color-line); }
.cap-shell .cap-row { display: grid; grid-template-columns: 160px minmax(0,1fr); gap: 0 var(--cap-space-md); align-items: baseline; padding: var(--cap-space-md) 0; border-bottom: var(--cap-border-hairline) solid var(--cap-color-line); }
.cap-shell .cap-row--stack { grid-template-columns: 1fr; gap: var(--cap-space-xs); }
.cap-shell .cap-summary { background: var(--cap-color-surface); border: var(--cap-border-hairline) solid var(--cap-color-line-strong); overflow: hidden; }
.cap-shell .cap-summary__row { display: flex; justify-content: space-between; align-items: center; gap: var(--cap-space-md); padding: var(--cap-space-md) var(--cap-space-md); border-bottom: var(--cap-border-hairline) solid var(--cap-color-line); }
.cap-shell .cap-summary__row:last-child { border-bottom: 0; }
.cap-shell .cap-summary__k { display: block; font-family: var(--cap-font-ui); font-weight: 600; font-size: var(--cap-type-btn); letter-spacing: var(--cap-track-label); text-transform: uppercase; color: var(--cap-color-muted); margin-bottom: var(--cap-space-xs); }
.cap-shell .cap-summary__v { font-family: var(--cap-font-ui); font-weight: 500; font-size: var(--cap-type-field); letter-spacing: var(--cap-track-faq); color: var(--cap-color-text); }
.cap-shell .cap-summary__total { font-family: var(--cap-font-display-sm); font-weight: 800; font-size: var(--cap-type-lg); letter-spacing: var(--cap-track-tight); }
.cap-shell .cap-faq { }
.cap-shell .cap-faq__head { border-top: var(--cap-border-emphasis) solid var(--cap-color-line-emphasis); padding-top: var(--cap-space-card-pad); margin-bottom: var(--cap-space-faq-gap); }
.cap-shell .cap-faq__list { border-top: var(--cap-border-hairline) solid var(--cap-color-line); }
.cap-shell .cap-faq__item { border-bottom: var(--cap-border-hairline) solid var(--cap-color-line); }
.cap-shell .cap-faq__q { display: flex; justify-content: space-between; align-items: center; gap: var(--cap-space-md); padding: var(--cap-space-row-pad) 0; cursor: pointer; list-style: none; transition: color var(--cap-ease); }
.cap-shell .cap-faq__q::-webkit-details-marker { display: none; }
/* no hover colour on a question (owner 2026-09-29, CD 1p / 2g / 3a / 3f): the question is ink closed AND open — only the
   toggle turns violet, open. A violet hover also stuck on a phone after a tap, so a question just closed stayed violet. */
.cap-shell .cap-faq__q::after { content: ""; flex: none; width: var(--cap-faq-toggle); height: var(--cap-faq-toggle); background: currentColor; color: var(--cap-color-caption); -webkit-mask: url("../img/faq-toggle-plus.svg") center / contain no-repeat; mask: url("../img/faq-toggle-plus.svg") center / contain no-repeat; }   /* CD's toggle (27 Sep, every FAQ): 10 × 10, 1.2 strokes, the text colour — grey closed */
.cap-shell .cap-faq__item[open] .cap-faq__q::after { color: var(--cap-color-primary); -webkit-mask-image: url("../img/faq-toggle-minus.svg"); mask-image: url("../img/faq-toggle-minus.svg"); }   /* open: the minus, violet */
.cap-shell .cap-faq__a { font-family: var(--cap-font-serif); font-size: var(--cap-type-faq-answer); line-height: var(--cap-leading-body); color: var(--cap-color-text-body); padding: 0 0 var(--cap-space-row-pad); }
.cap-shell .cap-faq__a a { color: var(--cap-color-primary); }
@media (hover: hover) { .cap-shell .cap-faq__a a[href]:hover { color: var(--cap-color-text); } }   /* round 23 rule 3: a link inside a sentence turns ink on hover, on every page (the answers had none) */   /* a link inside an answer ("Find your birth time →") is violet on every page (owner 2026-09-29) */
@media (max-width: 699px) {
  /* Patch 2026-09-09: mobile now MATCHES desktop — the 2px rule sits ABOVE the
     "✦ Questions" heading and the list opens on a 1px hairline (was inverted). */
  .cap-shell .cap-row { grid-template-columns: 110px minmax(0,1fr); gap: 0 var(--cap-space-sm); padding: var(--cap-space-sm) 0; }
}

/* ─── steps (how it works) ────────────────────────────────── */
.cap-shell .cap-steps { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--cap-space-md); }
.cap-shell .cap-step { display: flex; gap: var(--cap-space-md); align-items: flex-start; }
.cap-shell .cap-step + .cap-step { border-left: var(--cap-border-hairline) solid var(--cap-color-line); padding-left: var(--cap-space-md); }
.cap-shell .cap-step__n { width: 34px; height: 34px; flex: none; border-radius: var(--cap-radius-pill); background: var(--cap-color-text); color: var(--cap-color-bg); display: inline-grid; place-content: center; font-family: var(--cap-font-ui); font-weight: 600; font-size: var(--cap-type-sm); }
@media (max-width: 699px) {
  .cap-shell .cap-steps { grid-template-columns: 1fr; gap: var(--cap-space-sm); }
  .cap-shell .cap-step + .cap-step { border-left: 0; padding-left: 0; }
  .cap-shell .cap-step__n { width: 26px; height: 26px; }
}

/* ─── overlay (enlarged preview) ──────────────────────────── */
.cap-shell .cap-overlay { position: fixed; inset: 0; z-index: 10000; background: var(--cap-color-scrim); display: flex; align-items: center; justify-content: center; padding: var(--cap-space-md); }
.cap-shell .cap-astro { font-family: var(--cap-font-glyph); font-style: normal; font-weight: 400; letter-spacing: 0; line-height: 1; }   /* line-height 1: the glyph face never makes its line taller than its neighbours */   /* an article's ♀ / ♂ / ♈ … shown in Astronomicon (Capriastro_Editorial::astro_glyphs, round 28) */
.cap-shell .cap-astro--name { font-size: var(--cap-type-prose-glyph); -webkit-text-stroke: var(--cap-border-glyph-stroke) currentColor; }   /* a glyph before its name ("☉ The Sun"): one size step up and a thin outline in its own colour, so it carries the weight of the bold name beside it — Astronomicon has one weight, never a faux bold (owner 2026-10-08) */
.cap-shell .cap-sym { display: block; flex: none; }   /* a symbol-only button's drawn shape (round 27, Capriastro_Symbols): centred by the button's own grid / flex */
/* ONE ✕ SIZE (owner 2026-10-04, round 28): the menu's, the poster enlarge and the sample page — 0.7 em of the 18 data-lg size =
   12.6 px at every width (the form fields' thin ✕ keeps its round 24 drawing) */
.cap-shell :is(.cap-drawer__close, .cap-overlay__close, .cap-gyr__zoom-close) .cap-sym--close { font-size: var(--cap-type-data-lg); }
.cap-shell .cap-overlay__close { position: absolute; top: var(--cap-space-md); right: var(--cap-space-md); z-index: 1; width: 44px; height: 44px; display: inline-grid; place-content: center; padding: 0; margin: 0; text-align: center;   /* 16 inside the corner, the magnifier's size, the ✕ dead centre (owner 2026-09-26) */ border-radius: var(--cap-radius-pill); border: var(--cap-border-hairline) solid var(--cap-color-line-on-ink-3); background: transparent; color: var(--cap-color-on-ink); font-family: var(--cap-font-ui); font-weight: 500; font-size: var(--cap-type-lede); line-height: 1; cursor: pointer; transition: background var(--cap-ease), color var(--cap-ease), border-color var(--cap-ease); }
@media (hover: hover) { .cap-shell .cap-overlay__close:hover { background: var(--cap-color-on-ink); color: var(--cap-color-text); border-color: var(--cap-color-on-ink); } }
.cap-shell .cap-overlay__stage { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; overflow: hidden; padding: var(--cap-space-md); }
.cap-shell .cap-overlay__img { max-width: 100%; max-height: 100%; width: auto; height: auto; display: block; background: var(--cap-color-bg); box-shadow: var(--cap-shadow-modal); transform-origin: 0 0; touch-action: none; user-select: none; -webkit-user-select: none; cursor: grab; }
body.cap-noscroll { overflow: hidden; }

/* ─── loading & empty ─────────────────────────────────────── */
.cap-shell .cap-skeleton { background: var(--cap-color-bg-deep); border-radius: var(--cap-radius-skeleton); background-image: var(--cap-color-skeleton-shimmer); background-size: 400px 100%; animation: cap-shimmer 1.4s linear infinite; }
@keyframes cap-shimmer { from { background-position: 100% 0; } to { background-position: -100% 0; } }
.cap-shell .cap-empty { border: var(--cap-border-hairline) dashed var(--cap-color-line-strong); border-radius: var(--cap-radius-flat); padding: var(--cap-space-md); font-family: var(--cap-font-serif); font-style: italic; font-size: var(--cap-type-small); color: var(--cap-color-muted); text-align: center; }
.cap-shell .cap-pulse { animation: cap-pulse 1.6s ease-in-out infinite; }
@keyframes cap-pulse { 0%, 100% { opacity: .5; } 50% { opacity: 1; } }

/* ─── layout patterns (reflow.md) ─────────────────────────── */
.cap-shell .cap-split { display: grid; grid-template-columns: minmax(0,1fr) var(--cap-rail-purchase); gap: var(--cap-gutter-rail); align-items: start; }
.cap-shell .cap-split--rail { grid-template-columns: minmax(0, var(--cap-measure)) var(--cap-rail); }
.cap-shell .cap-sticky { position: sticky; top: var(--cap-space-lg); }
.cap-shell .cap-grid-2 { display: grid; grid-template-columns: repeat(2, 1fr); gap: var(--cap-gutter); }
.cap-shell .cap-grid-3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--cap-gutter); }
.cap-shell .cap-grid-4 { display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--cap-gutter); }
.cap-shell .cap-rule { border-top: var(--cap-border-hairline) solid var(--cap-color-line); }
.cap-shell .cap-rule--emphasis { border-top: var(--cap-border-emphasis) solid var(--cap-color-line-emphasis); }
@media (max-width: 1279px) {   /* two-column layouts collapse below 1280 (owner rule 2026-09-30, reflow.md) */
  .cap-shell .cap-split,
.cap-shell .cap-split--rail { grid-template-columns: 1fr; }
  .cap-shell .cap-sticky { position: static; }
}
@media (max-width: 1023px) {
  .cap-shell .cap-grid-4 { grid-template-columns: repeat(2, 1fr); }
  .cap-shell .cap-grid-3 { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 699px) {
  .cap-shell .cap-grid-3,
.cap-shell .cap-grid-4 { grid-template-columns: 1fr; }
  .cap-shell .cap-grid-2--keep { grid-template-columns: repeat(2, 1fr); gap: var(--cap-space-sm); }
  .cap-shell .cap-thumb { width: 72px; height: 72px; }
  .cap-shell .cap-well { padding: var(--cap-space-lg) 0; }
  .cap-shell .cap-card--dark { padding: var(--cap-space-card-pad); }
}

/* ─── table (kept from the first vocabulary; data is Barlow) ─ */
.cap-shell .cap-table { width: 100%; border-collapse: collapse; font-family: var(--cap-font-ui); font-weight: 400; font-size: var(--cap-type-data); letter-spacing: var(--cap-track-data); color: var(--cap-color-text-body); }
.cap-shell .cap-table th { font-weight: 600; font-size: var(--cap-type-sm); letter-spacing: var(--cap-track-label); text-transform: uppercase; color: var(--cap-color-text); text-align: left; }
.cap-shell .cap-table th,
.cap-shell .cap-table td { padding: var(--cap-space-sm) var(--cap-space-md); border-bottom: var(--cap-border-hairline) solid var(--cap-color-line); }


/* ─── the WooCommerce checkout consent row lives in checkout.css ──────────────
   It used to be defined here under an "outside the shell" heading while every one
   of its selectors was scoped `.cap-shell` — so it matched NOTHING, because the
   row is printed inside `#payment`, outside any shell we render. checkout.css
   styles it for real (prefixed `body.woocommerce-checkout`, which outranks the
   Elementor kit without `!important`); that file is the single definition. */

/* ─── `hidden` wins ───────────────────────────────────────────────────────────
   Scoping the components at 0,2,0 (see the header note) also made them outrank
   the `[hidden]` attribute rule, so the enlarge overlay and the mobile drawer
   painted over every page. Winning on SOURCE ORDER was not enough: a per-page
   stylesheet loads after this file, so a page rule at 0,2,0 took the tie back and
   re-showed hidden elements. The attribute is repeated deliberately — that is
   0,3,0, so `hidden` wins on WEIGHT, whichever stylesheet loads last. */
/* the consent line under an email-capture form — quiet, but never hidden */
.cap-shell .cap-join__consent { display: block; margin-top: var(--cap-space-sm); max-width: 46ch; }
.cap-shell .cap-join__consent a { color: inherit; border-bottom: var(--cap-border-hairline) solid var(--cap-color-line-strong); }

.cap-shell [hidden][hidden] { display: none; }

/* The near-dormant date/time fallback (owner 2026-09-22) — shown only where the
   browser has no native date/time input. The native field stays in the DOM as
   the value carrier (it still posts) but leaves the page. */
.cap-shell .cap-birth__carrier {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}
/* THE TYPED PARTS READ AS TWO FIELDS (owner 2026-09-23): the sheets draw two pills, "Birth date" and "Birth time".
   The group is the pill — the field border, radius and padding on `.cap-parts`; the parts inside are borderless,
   sized to their content, and the caret jumps along them. A focused part lights the whole pill (focus-within). */
.cap-shell .cap-parts { display: flex; align-items: center; gap: 0; min-width: 0; background: var(--cap-color-surface); border: var(--cap-border-hairline) solid var(--cap-color-field-empty); border-radius: var(--cap-radius-pill); padding: 0 var(--cap-space-gap-6) 0 var(--cap-space-field-x); transition: border-color var(--cap-ease-fast), box-shadow var(--cap-ease-fast); }
.cap-shell .cap-parts > .cap-birth__part:first-child { padding-left: 0; }   /* the pill's first part starts on the field text inset, like any field (and so do the hints under it) */
.cap-shell .cap-parts.is-filled { border-color: var(--cap-color-field-filled); }   /* filled = field-filled, like any field (CD field states 26 Sep) */
.cap-shell .cap-parts:focus-within { border-color: var(--cap-color-field-focus); box-shadow: var(--cap-shadow-focus); }   /* focus = ink + the violet ring, as .cap-input:focus */
.cap-shell .cap-parts .cap-birth__part { border: 0; border-radius: 0; background: transparent; box-shadow: none; min-width: 0; width: auto; flex: 0 0 auto; padding: var(--cap-space-field-y) var(--cap-space-gap-2); text-align: center; }
.cap-shell .cap-parts .cap-birth__part:focus, .cap-shell .cap-parts .cap-birth__part:focus-visible { outline: 0; box-shadow: none; border: 0; }
.cap-shell .cap-parts :is(.cap-birth__month, .cap-birth__day, .cap-birth__hour, .cap-birth__minute) { width: var(--cap-part-2); }
.cap-shell .cap-parts .cap-birth__year { width: var(--cap-part-4); }
/* "8:40  AM PM" (D4, owner 2026-09-24 — every form that asks for the time): the hour right-aligned against the colon, the
   minute left; AM and PM both always shown as TEXT, 6 apart and 10 after the time, the chosen one ink, the other the pale
   line grey, the unchosen one darkening to muted on hover. No chip, no fill. */
.cap-shell .cap-parts .cap-birth__hour { text-align: right; padding-right: 0; }
.cap-shell .cap-parts .cap-birth__minute { text-align: left; padding-left: 0; padding-right: 0; }   /* AM sits 10 after the minute, no more */
@supports (field-sizing: content) { .cap-shell .cap-parts .cap-birth__hour, .cap-shell .cap-parts .cap-birth__minute { width: auto; field-sizing: content; } }   /* "8:40" hugs the text inset where the browser can; the 2-digit token is the fallback */
.cap-shell .cap-parts .cap-birth__colon { font-family: var(--cap-font-ui); font-size: var(--cap-type-input); letter-spacing: var(--cap-track-ui); line-height: var(--cap-leading-input); color: var(--cap-color-text); flex: none; }
.cap-shell .cap-parts .cap-birth__hour:placeholder-shown ~ .cap-birth__colon { color: var(--cap-color-muted); }
.cap-shell .cap-parts :is(.cap-birth__month, .cap-birth__day) { padding-right: 0; }
/* "MM / DD / YYYY" and "hh : mm" (D1 / D1b, 26 Sep; the month a digit box since round 20) — the slashes carry their spaces
   (white-space: pre); they read muted until the date is complete, then ink: "07 / 16 / 1994" */
.cap-shell .cap-parts .cap-birth__slash { font-family: var(--cap-font-ui); font-size: var(--cap-type-input); letter-spacing: var(--cap-track-ui); line-height: var(--cap-leading-input); color: var(--cap-color-text); flex: none; white-space: pre; }
.cap-shell .cap-parts.is-blank :is(.cap-birth__slash, .cap-birth__colon) { white-space: pre; color: var(--cap-color-muted); }
@media (max-width: 699px) { .cap-shell :is(.cap-cells, .cap-fcard) .cap-parts .cap-birth__slash { word-spacing: -0.2em; padding: 0 var(--cap-space-gap-1); }
  .cap-shell :is(.cap-cells, .cap-fcard) .cap-parts .cap-birth__month + .cap-birth__slash { padding-right: 0; }
  .cap-shell :is(.cap-cells, .cap-fcard) .cap-parts .cap-birth__day + .cap-birth__slash { padding-left: 0; }
  .cap-shell :is(.cap-cells, .cap-fcard) .cap-parts .cap-birth__day { min-width: calc(var(--cap-birth-box) + 2 * var(--cap-space-gap-1)); } }   /* round 22 F2: in a phone's half-width cell (167) "mm / dd / yyyy" ran 11 past its column — the spaces round each slash give it back; round 22 (owner, even gaps): the month's new air is paid for by 2 px less round each slash, and the padding on the day's side of each slash moves INTO the (centred) day box, so its tap zone stays 44 wide and the four gaps stay equal */
.cap-shell .cap-parts :is(.cap-birth__day, .cap-birth__year) { padding-left: 0; }
.cap-shell .cap-parts .cap-birth__year { text-align: left; }
@supports (field-sizing: content) {   /* "07 / 16 / 1994" set as one line of text: each part hugs its digits */
  .cap-shell .cap-parts :is(.cap-birth__month, .cap-birth__day, .cap-birth__year) { width: auto; field-sizing: content; }
}
.cap-shell .cap-parts .cap-birth__ampm { display: inline-flex; align-items: center; gap: var(--cap-space-gap-3); flex: 0 0 auto; margin-left: var(--cap-space-gap-5); padding: 0; border: 0; border-radius: var(--cap-radius-sm); background: transparent; box-shadow: none; min-height: 0; cursor: pointer; font-family: var(--cap-font-ui); font-weight: 400; font-size: var(--cap-type-input); letter-spacing: var(--cap-track-ui); line-height: var(--cap-leading-input); text-transform: none; }
/* THE AM / PM SWITCH (round 20): one control, both words shown as TEXT — the chosen one ink, the other the pale line grey.
   No chip, no fill (D4, 24 Sep). Round 21 (owner): ONLY the chosen word is ever dark — the hover that darkened the other
   one is gone, since the pointer (or a touch screen's sticky hover) stays on the switch after a tap and both read lit. */
.cap-shell .cap-parts .cap-birth__ap-word { color: var(--cap-color-line-emphasis); transition: color var(--cap-ease-fast); }
.cap-shell .cap-parts .cap-birth__ap-word.is-on { color: var(--cap-color-text); }
@media (hover: hover) { .cap-shell .cap-parts .cap-birth__ampm:is(:hover, :focus, :active) { background: transparent; color: inherit; } }
/* round 22 (owner, Samsung tablet at 712 / 820: "after choosing PM both still look highlighted" — not reproducible in
   emulation): the two words' colours are pinned in EVERY state of the switch, and the chosen word carries the selected
   bar (the owner's rule, 29 Sep: the bar = selected) so the choice reads even where the two greys look alike */
@media (hover: hover) { .cap-shell .cap-parts .cap-birth__ampm:is(:hover, :focus, :active) .cap-birth__ap-word:not(.is-on) { color: var(--cap-color-line-emphasis); } }
.cap-shell .cap-parts .cap-birth__ampm .cap-birth__ap-word.is-on { color: var(--cap-color-text); text-decoration: underline; text-decoration-color: var(--cap-color-primary); text-decoration-thickness: var(--cap-border-hairline); text-underline-offset: var(--cap-space-gap-2); }
/* round 25 (owner, tablet): the switch never draws its own ring — the time cell's ink frame (focus-within) is the one marker,
   whether the switch was reached by Tab or by the minute's auto-advance */
.cap-shell .cap-field .cap-birth__ampm:focus-visible, .cap-shell .cap-parts .cap-birth__ampm:focus-visible { outline: 0; box-shadow: none; }
/* THE TAP AREAS (round 20): a tap anywhere in the cell goes to the nearest box (CapriUI.birth), so each box answers to the
   cell's full height and to the midpoint with its neighbour. On touch widths the small boxes are wide enough, and the
   switch far enough from the minute, that every one of those areas is at least 44 wide (measured at 388: the 168 cell). */
@media (max-width: 1279px) {
  .cap-shell .cap-parts .cap-birth__day { min-width: var(--cap-birth-box); }
  .cap-shell .cap-parts .cap-birth__year { padding-left: calc((var(--cap-birth-box) - 2ch) / 2); }   /* the year sits as far from its slash as the centred day does from its */
  /* round 21 (owner): the FIRST box of each cell starts on the label's left edge — the month and the hour hug their
     digits from there (field-sizing, or CapriUI.birth's sizer where a browser lacks it). The slashes carry 4 more px
     each side and the switch sits 24 after the minute box, so the month, day, minute and switch keep their 44-wide tap
     zones; the hour's zone is what a tight "8:40" leaves it (30–42 wide, measured — round 21 report). */
  .cap-shell .cap-parts .cap-birth__month { text-align: left; padding-right: calc((var(--cap-birth-box) - 2ch) / 2); }   /* round 22 (owner): the gap before the first slash matches the other three — the month carries the same air the centred day and the year carry; its tap zone only grows */
  .cap-shell .cap-parts .cap-birth__slash { padding: 0 var(--cap-space-gap-2); }
  .cap-shell .cap-parts .cap-birth__hour { text-align: left; }
  .cap-shell .cap-parts .cap-birth__minute { min-width: var(--cap-birth-box); }
  .cap-shell .cap-parts .cap-birth__ampm { margin-left: var(--cap-space-block-5); }
}
.cap-shell .cap-parts .cap-birth__part::placeholder { color: var(--cap-color-muted); }
/* THE MONTH'S NAME (round 22, owner): typed as a number, shown as JAN … DEC once the box is left — the cell's caps */
.cap-shell .cap-parts .cap-birth__month.is-word { text-transform: uppercase; }
/* THE FIRST BOX'S TAP AREA (round 22, owner): the month and the hour stay on the label's edge, and their boxes reach back
   over the cell's own padding to its edge — the digits do not move, the box is 44+ wide (padding cancelled by a margin) */
.cap-shell .cap-cells .cap-parts > .cap-birth__part:first-child { margin-left: calc(-1 * var(--cap-space-field-cell-x)); padding-left: var(--cap-space-field-cell-x); }
/* THE DATE AND TIME CELLS' ✕ (round 22, owner): clones of the form's place ✕ (CapriUI.birth) — in the calculator and poster
   cards it is .cap-cell__clear, placed on the cell like the place's; on the money page it is .cap-purchase__clear, placed on the
   value line's box (.cap-parts, made the positioning box here) */
.cap-shell .cap-parts:has(> .cap-purchase__clear) { position: relative; }
.cap-shell .cap-parts > .cap-purchase__clear { display: flex; }
.cap-shell .cap-parts > .cap-purchase__clear[hidden], .cap-shell .cap-birth__x[hidden] { display: none; }
/* every ✕ (date, time, place) sits at the right end of its cell's label row, at every width (owner 2026-10-09; CapriUI.birth
   moves it there): the icon on the label's line, its 44 band reaching UP from the label's foot, never down over the value */
.cap-shell .cap-field__label.has-x { display: flex; justify-content: space-between; align-items: center; }
.cap-shell .cap-field__label.has-x > :is(.cap-birth__x, .cap-cell__clear, .cap-purchase__clear):not([hidden]) { position: relative; inset: auto; transform: none; flex: none; display: flex; align-items: center; justify-content: center; width: var(--cap-cell-clear-icon); height: 1lh; margin: 0; padding: 0; z-index: 2; }
.cap-shell .cap-field__label.has-x > .cap-birth__x:not(.cap-purchase__clear) svg { width: var(--cap-cell-clear-icon); height: var(--cap-cell-clear-icon); flex: none; }   /* the money page's clone keeps its place ✕'s own 12 (round 22: the ✕ is the same size as the place's on every form) */
.cap-shell .cap-field__label.has-x > :is(.cap-birth__x, .cap-cell__clear, .cap-purchase__clear)::after { content: ""; position: absolute; left: 50%; bottom: calc(-1 * var(--cap-x-drop, 0px)); width: var(--cap-tap-min); height: var(--cap-tap-min); transform: translateX(-50%); }   /* --cap-x-drop: label foot → value top, measured by CapriUI.birth, so the band ends on the value */
/* the parts carry their own placeholders and the pill its own label-by-placeholder: the visible label above
   (BIRTH DATE / BIRTH TIME, 0.51.222 — an empty native control paints nothing on iOS) is for the native fields only */
.cap-shell .cap-birth__date:has(.cap-parts) > .cap-field__label, .cap-shell .cap-birth__time:has(.cap-parts) > .cap-field__label { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }

/* THE DELIVERY LINE'S LINK (round 21): "Other countries →" never breaks inside itself — on a narrow line the whole link moves
   down and the "·" before it is dropped (cap-sep.js) */
.cap-shell .cap-delivery__other { white-space: nowrap; }

/* ─── the breadcrumb trail (owner rule 2026-09-25) ───────────
   One row at every width; on a narrow screen the MIDDLE crumbs give way with an ellipsis, the first and the last never.
   Every trail carries `cap-trail` beside its page's own class (which keeps the type and colour). */
.cap-shell nav.cap-trail { display: flex; flex-wrap: nowrap; align-items: baseline; min-width: 0; white-space: nowrap; }
.cap-shell nav.cap-trail > * { flex: 0 0 auto; }
.cap-shell nav.cap-trail > .cap-trail__c--mid { flex: 0 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; }

/* ─── THE BIRTH-DETAILS CARD (CD's field-label rules §1, 26 Sep: the poster rail D15 / 3a, the calculator bar D1 / D5a) ───
   ONE white card (16 corners, 1 px line-strong), a labelled cell per field, 1 px dividers; the label is the input's
   <label> — the whole cell focuses it; label 600 · 13 · .1em caps quiet grey (11 · .14em on a phone); 18 padding (11 · 18);
   label → value 12 (8). A form sets its value size with --cap-cell-value (the poster 18 / 14, the calculator the input's 17). */
.cap-shell .cap-cells { --cap-cell-y: var(--cap-space-field-cell-y); --cap-cell-value: var(--cap-type-card-value); --cap-cell-value-h: calc(var(--cap-cell-value) * var(--cap-leading-tight)); background: var(--cap-color-surface); border: var(--cap-border-hairline) solid var(--cap-color-field-empty); border-radius: var(--cap-radius-field-card); }   /* CD's field-label rules §1 (26 Sep, owner ruling: the poster's cells follow them): 16 corners, 18 padding (11 · 18 on a phone), label → value 12 (8) */
/* PHONES UNDER 380 (round 24, owner: 360-wide phones): the date "MM / DD / YYYY" and the time + AM / PM ran 10–11 px past
   their half-width cells at 360 — the field inset (18) steps to 12 for every field cell under 380, so the labels, the values
   and the hint lines under the forms stay on one inset. Measured at 360: both rows fit, month / day / year zones ≥ 44. */
@media (max-width: 379px) { :root { --cap-space-field-cell-x: var(--cap-space-gap-6); } }
/* THE PHONE GUTTER (owner ruling 2026-10-05, round 31): 26 from 360 up (the sheets'), 20 below 360 — every page column, the header
   and the transit line (chrome.css) alike. One token: everything that sets the page inset reads --cap-page-x. */
@media (max-width: 359px) { :root { --cap-page-x: var(--cap-page-x-card); } }
.cap-shell .cap-cells .cap-field { position: relative; margin: 0; padding: var(--cap-cell-y) var(--cap-space-field-cell-x); display: flex; flex-direction: column; gap: var(--cap-space-field-label-gap); border-radius: 0; cursor: text; }   /* the cell IS the <label>: a tap anywhere in it focuses the field */
.cap-shell .cap-cells > .cap-field + .cap-field-row, .cap-shell .cap-cells > .cap-field-row + .cap-field { border-top: var(--cap-border-hairline) solid var(--cap-color-field-empty); }
.cap-shell .cap-cells .cap-field-row { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 0; margin: 0; }   /* CD 27 Sep: Birth date | Birth time split 1 : 1 on EVERY birth card at EVERY width (D4 · D15 · D1b · 1a · 1l · 3a-1 · 3b); the 7 : 6 / 1.2 : 1 split is retired. The D1 hero bar keeps its own fixed widths. */
.cap-shell .cap-cells .cap-field-row > .cap-field + .cap-field { border-left: var(--cap-border-hairline) solid var(--cap-color-field-empty); }
@media (min-width: 700px) and (max-width: 1279px) { .cap-shell .cap-cells .cap-field { gap: var(--cap-space-sm); } }   /* the tablet cards (T1 · T5 · T6a · T9, 1 Oct 2026): label → value 10 on the sheet's 15 / 18 line boxes = 8 on ours — the cell 79 tall */
.cap-shell .cap-cells > .cap-field:first-child { border-radius: var(--cap-radius-field-card) var(--cap-radius-field-card) 0 0; }
.cap-shell .cap-cells > .cap-field:last-child { border-radius: 0 0 var(--cap-radius-field-card) var(--cap-radius-field-card); }
.cap-shell .cap-cells > .cap-field-row:first-child > .cap-field:first-child { border-radius: var(--cap-radius-field-card) 0 0 0; }   /* a card that opens on the date | time row (the calculator): the focus edge follows the corners */
.cap-shell .cap-cells > .cap-field-row:first-child > .cap-field:last-child { border-radius: 0 var(--cap-radius-field-card) 0 0; }
/* A 320 PHONE (owner ruling 2026-10-05, round 31): below 360 the date and the time no longer fit side by side — each half-cell is
   133 wide and the date needs 140, the time 137 at their sizes — so the time sits UNDER the date, each the card's full width, a
   hairline between them. Nothing shrinks and every 44 tap area stays; 360 and up keep the 1 : 1 split (27 Sep). */
@media (max-width: 359px) {
  .cap-shell .cap-cells .cap-field-row { grid-template-columns: minmax(0, 1fr); }
  .cap-shell .cap-cells .cap-field-row > .cap-field + .cap-field { border-left: 0; border-top: var(--cap-border-hairline) solid var(--cap-color-field-empty); }
  .cap-shell .cap-cells > .cap-field-row:first-child > .cap-field:first-child { border-radius: var(--cap-radius-field-card) var(--cap-radius-field-card) 0 0; }
  .cap-shell .cap-cells > .cap-field-row:first-child > .cap-field:last-child { border-radius: 0; }
}
.cap-shell .cap-cells .cap-field:focus-within { outline: var(--cap-border-hairline) solid var(--cap-color-field-focus); outline-offset: calc(-1 * var(--cap-border-hairline)); z-index: 1; }   /* the focused cell's ink edge (D15-1): ONE px, drawn over the box's own line (owner 2026-09-26) */
.cap-shell .cap-cells .cap-field:has([aria-invalid="true"]) { outline: var(--cap-border-hairline) solid var(--cap-color-error); outline-offset: calc(-1 * var(--cap-border-hairline)); z-index: 1; }   /* error: the field and its label turn error red (CD field states); after the focus rule, so a focused cell in error stays carmine (D1b) */
.cap-shell .cap-cells .cap-field:has([aria-invalid="true"]) > .cap-field__label { color: var(--cap-color-error); }
.cap-shell .cap-cells .cap-field__label { margin: 0; padding: 0; font-family: var(--cap-font-ui); font-weight: 600; font-size: var(--cap-type-field-label); letter-spacing: var(--cap-track-field-label); text-transform: uppercase; color: var(--cap-color-heading-quiet); line-height: var(--cap-leading-tight); white-space: nowrap; }
.cap-shell .cap-cells .cap-field > .cap-input { width: 100%; height: auto; min-height: 0; padding: 0; border: 0; border-radius: 0; background: none; box-shadow: none; font-family: var(--cap-font-ui); font-weight: 400; font-size: var(--cap-cell-value); letter-spacing: var(--cap-track-data); line-height: var(--cap-leading-tight); color: var(--cap-color-text); }
.cap-shell .cap-cells .cap-field > .cap-input:focus { outline: 0; box-shadow: none; }
.cap-shell .cap-cells .cap-field > .cap-input--native { height: var(--cap-cell-value-h); }   /* the native date / time control (a phone) takes the value line's height, never its own */
/* the typed date and time parts sit in their cell as plain text — the cell is the field, so the parts' own pill goes */
.cap-shell .cap-cells .cap-parts, .cap-shell .cap-cells .cap-parts.is-filled, .cap-shell .cap-cells .cap-parts:focus-within { padding: 0; border: 0; border-radius: 0; background: none; box-shadow: none; }
.cap-shell .cap-cells .cap-parts .cap-birth__part { padding-top: var(--cap-space-gap-2); padding-bottom: var(--cap-space-gap-2); margin-top: calc(-1 * var(--cap-space-gap-2)); margin-bottom: calc(-1 * var(--cap-space-gap-2)); }   /* round 22 (owner: "yyyy" was cut at 1440): the line box is the type size, so the descenders get 4 above and below, cancelled by the margins — nothing moves */
.cap-shell .cap-cells .cap-parts :is(.cap-birth__part, .cap-birth__colon, .cap-birth__slash, .cap-birth__ap) { font-size: var(--cap-cell-value); line-height: var(--cap-leading-tight); }
.cap-shell .cap-cells :is(.cap-birth__date, .cap-birth__time):has(.cap-parts) > .cap-field__label { position: static; width: auto; height: auto; overflow: visible; clip-path: none; }   /* the cells show their labels */
.cap-shell .cap-cells .cap-field:has(> .cap-cell__clear) > .cap-input { padding-right: var(--cap-space-lg); }   /* the place: room for its ✕ */
/* the ✕ of a cell WITHOUT a visible label (it stays on the value line): its own 44 × 44 target, centred on the icon's spot (owner 2026-09-26); interactive content, so a tap on it never reaches the cell's label */
.cap-shell .cap-cell__clear { position: absolute; right: calc(var(--cap-space-field-cell-x) - (var(--cap-tap-min) - var(--cap-cell-clear-icon)) / 2); bottom: calc(var(--cap-cell-y) + (var(--cap-cell-value-h) - var(--cap-tap-min)) / 2); width: var(--cap-tap-min); height: var(--cap-tap-min); display: flex; align-items: center; justify-content: center; padding: 0; border: 0; background: none; color: var(--cap-color-caption); cursor: pointer; }
/* round 24 (owner, 4 Oct): ONE ✕ on every form — the money page's thin 1 px line in the caption grey; the cross 10.3 px from 700
   and 9 px on phones. One drawing everywhere (class-purchase / class-calculator / class-poster-preview / class-hx-front: span
   11.44 of 20, stroke 1.15); the date and time ✕ are clones of the form's place ✕, so they follow */
.cap-shell :is(.cap-cell__clear, .cap-purchase__clear) svg { width: var(--cap-cell-clear-icon); height: var(--cap-cell-clear-icon); flex: none; }   /* the size: 18 from 700 (a 10.3 px cross, a-money-filled-712), 15.75 on phones (a 9 px cross, a-poster-filled-388) — owner, round 24 */
@media (max-width: 699px) { .cap-shell :is(.cap-cell__clear, .cap-purchase__clear) svg path { stroke-width: 1.31; } }   /* the smaller drawing keeps the 1 px line on screen (1.15 of 20 at 18 px = 1.31 of 20 at 15.75 px) */
.cap-shell .cap-cell__clear[hidden] { display: none; }
@media (hover: hover) { .cap-shell .cap-cell__clear:hover { color: var(--cap-color-text); } }
.cap-shell .cap-cells .cap-places { top: calc(100% + var(--cap-border-hairline) + var(--cap-space-sm)); left: calc(-1 * var(--cap-border-hairline)); right: calc(-1 * var(--cap-border-hairline)); }   /* 8 under the card's own edge, its full width */
/* the phone cells (2j / 2l / 1l / 3b, 28 Sep): the label on a 13 line, the value on a 20 line at .06em, the empty hints
   (mm / dd / yyyy · hh : mm · the place's placeholder) in the caption grey — each cell 63, two rows 129 */
@media (max-width: 699px) {
  .cap-shell .cap-cells { --cap-cell-value-h: var(--cap-leading-input); }
  .cap-shell .cap-cells .cap-field__label { line-height: var(--cap-mp-leading-cell-label); }
  .cap-shell .cap-cells .cap-field > .cap-input,
  .cap-shell .cap-cells .cap-parts :is(.cap-birth__part, .cap-birth__colon, .cap-birth__slash, .cap-birth__ap) { line-height: var(--cap-leading-input); letter-spacing: var(--cap-track-ui); }
  .cap-shell :is(.cap-cells, .cap-fcard) .cap-input::placeholder,
  .cap-shell :is(.cap-cells, .cap-fcard) .cap-parts .cap-birth__part::placeholder,
  .cap-shell :is(.cap-cells, .cap-fcard) .cap-parts.is-blank :is(.cap-birth__slash, .cap-birth__colon) { color: var(--cap-color-caption); }   /* .cap-fcard = the money page's form card (1l), the same grey as the poster form (29 Sep) */
}

/* ─── the free-chart band on ink (D6 posts, D19 About): the natal-chart icon, "Free birth chart", an italic line, the
   caps link — one card, one set of rules (moved from page-post.css, 26 Sep) ─── */
.cap-shell .cap-post__chart { display: flex; align-items: center; gap: var(--cap-space-card-pad); padding: var(--cap-space-lg); background: var(--cap-color-text); color: var(--cap-color-on-ink); text-decoration: none; }
@media (hover: hover) { .cap-shell .cap-post__chart:hover { color: var(--cap-color-on-ink); } }
.cap-shell .cap-post__chart-icon { flex: none; width: calc(var(--cap-space-xl) + var(--cap-space-faq-gap)); color: var(--cap-color-primary-soft); }
.cap-shell .cap-post__chart-icon svg { display: block; width: 100%; height: auto; }
.cap-shell .cap-post__chart-copy { display: flex; flex-direction: column; gap: var(--cap-space-sm); }
.cap-shell .cap-post__chart-h { font-family: var(--cap-font-display-sm); font-weight: 800; font-size: var(--cap-type-lg); line-height: var(--cap-leading-tight); letter-spacing: var(--cap-track-tight); color: var(--cap-color-on-ink); }
.cap-shell .cap-post__chart-lede { font-family: var(--cap-font-serif); font-style: italic; font-size: var(--cap-type-lede-hero); line-height: var(--cap-leading-lede); color: var(--cap-color-on-ink-3); }
.cap-shell .cap-post__chart-link { font-family: var(--cap-font-ui); font-weight: 600; font-size: var(--cap-type-textlink); letter-spacing: var(--cap-track-textlink); text-transform: uppercase; color: var(--cap-color-primary-soft); }
@media (hover: hover) { .cap-shell .cap-post__chart:hover .cap-post__chart-link { color: var(--cap-color-on-ink); } }

/* ═══ PHONE, SITE-WIDE (owner ruling 27 Sep 2026, CD's phone sheets) ═══════════════════════════════════
   Page titles: the sheet's 28 on 1.12 at −.01em, in the 24pt cut (the site's own rule: display under 38px takes the
   24pt cut). Eyebrow stars (the two-star page eyebrow): a 10px ✦ each side, 8 from the words, no tracking on the star. */
@media (max-width: 699px) {
  .cap-shell .cap-h1 { font-family: var(--cap-font-display-sm); line-height: var(--cap-leading-hero); letter-spacing: var(--cap-track-hero); }
  .cap-shell .cap-eyebrow--stars::before { content: "✦"; font-size: var(--cap-type-caption); letter-spacing: 0; margin-right: var(--cap-space-gap-4); }
  .cap-shell .cap-eyebrow--stars::after { content: "✦"; font-size: var(--cap-type-caption); letter-spacing: 0; margin-left: var(--cap-space-gap-4); }
}

/* ─── WOOCOMMERCE'S OWN NOTICES outside the checkout (the 2j board's msg row, owner 2026-09-27) ───
   The cart (incl. the empty cart) and My Account print WooCommerce's notices above our markup, outside .cap-shell; the
   checkout + order-received pages carry theirs in checkout.css. Error = the ALERT BOX (carmine edge, the error fill, 16
   corners, the round "!" beside a Source Serif italic line); success = the white row with the ✔; info = the deep-cream row
   with the ✦. WooCommerce's absolutely placed icon-font ::before is reclaimed as the round mark. */
body:is(.woocommerce-cart, .woocommerce-account) :is(.woocommerce-error, .woocommerce-message, .woocommerce-info) {
  display: flex; align-items: center; flex-wrap: wrap; gap: var(--cap-space-gap-6); margin: 0 0 var(--cap-space-md); padding: var(--cap-space-gap-6);
  list-style: none; border: var(--cap-border-hairline) solid var(--cap-color-line-strong); outline: 0; box-shadow: none; border-radius: var(--cap-radius-msg);
  background: var(--cap-color-bg-deep); font-family: var(--cap-font-serif); font-style: italic; font-size: var(--cap-alert-text); line-height: var(--cap-leading-lede); color: var(--cap-color-text);
}
body:is(.woocommerce-cart, .woocommerce-account) .woocommerce-info { border-color: transparent; }
body:is(.woocommerce-cart, .woocommerce-account) .woocommerce-message { background: var(--cap-color-surface); }
body:is(.woocommerce-cart, .woocommerce-account) .woocommerce-error { background: var(--cap-color-error-fill); border-color: var(--cap-color-error); border-radius: var(--cap-radius-field-card); }
body:is(.woocommerce-cart, .woocommerce-account) :is(.woocommerce-error, .woocommerce-message, .woocommerce-info)::before {
  position: static; top: auto; left: auto; flex: none; width: var(--cap-alert-mark); height: var(--cap-alert-mark); border-radius: var(--cap-radius-pill);
  background: var(--cap-color-text); color: var(--cap-color-bg-deep); display: inline-grid; place-content: center;
  font-family: var(--cap-font-ui); font-style: normal; font-weight: 700; font-size: var(--cap-type-alert-mark); line-height: 1; content: "\2726";
}
body:is(.woocommerce-cart, .woocommerce-account) .woocommerce-message::before { content: "\2714"; color: var(--cap-color-surface); }
body:is(.woocommerce-cart, .woocommerce-account) .woocommerce-error::before { content: "!"; background: var(--cap-color-error); color: var(--cap-color-error-fill); }
body:is(.woocommerce-cart, .woocommerce-account) :is(.woocommerce-error, .woocommerce-message, .woocommerce-info) > * { margin: 0; }
body:is(.woocommerce-cart, .woocommerce-account) .woocommerce-error li { list-style: none; flex: 1; min-width: 0; }
body:is(.woocommerce-cart, .woocommerce-account) :is(.woocommerce-message, .woocommerce-info) a { color: var(--cap-color-primary); border-bottom: var(--cap-border-hairline) solid var(--cap-color-primary); text-decoration: none; font-style: normal; font-family: var(--cap-font-ui); letter-spacing: var(--cap-track-meta); text-transform: uppercase; font-size: var(--cap-type-hint); }
body:is(.woocommerce-cart, .woocommerce-account) :is(.woocommerce-message, .woocommerce-info) .button { order: 2; margin-left: auto; background: none; padding: 0; }

/* NO LINE STARTS OR ENDS ON A "·" (owner rule 2026-10-02): cap-sep.js wraps each " · " in .cap-sep and turns one that
   would open a line into the line break itself — the dot gone, the next word starting the line */
.cap-sep.is-break { display: block; height: 0; overflow: hidden; }

/* ═══ THE PAGE NUMBERS (owner 2026-10-03, round 20): the Chronicles hub (`.cap-pager`, Capriastro_Editorial) and the category /
   tag archives (Elementor's `.elementor-pagination` in the archive template) — one look: 32 pills, the current one filled, Prev /
   Next as quiet caps, a dead Prev / Next hidden. Moved here from page-archive.css so the hub carries the same rules. Below 1280
   each number takes a 44 tap band and the numbers sit 44 apart (gap 12) so no two bands overlap. ═══ */
.cap-shell .cap-arc__grid .elementor-pagination,
.cap-shell .cap-pager {
  margin-top: var(--cap-space-lg);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: var(--cap-space-sm);
}
.cap-shell .cap-arc__grid .elementor-pagination .page-numbers,
.cap-shell .cap-pager .page-numbers {
  width: 32px; height: 32px;
  display: inline-grid;
  place-content: center;
  border-radius: var(--cap-radius-pill);
  border: var(--cap-border-hairline) solid var(--cap-color-line-strong);
  background: transparent;
  color: var(--cap-color-text);
  font-family: var(--cap-font-ui);
  font-weight: 600;
  font-size: var(--cap-type-btn);
  line-height: var(--cap-leading-ui);
  transition: background var(--cap-ease), border-color var(--cap-ease), color var(--cap-ease);
}
@media (hover: hover) { .cap-shell .cap-arc__grid .elementor-pagination a.page-numbers:hover, .cap-shell .cap-pager a.page-numbers:hover {
  border-color: var(--cap-color-text);
  background: var(--cap-color-text);
  color: var(--cap-color-bg);
} }
.cap-shell .cap-arc__grid .elementor-pagination .page-numbers.current,
.cap-shell .cap-pager .page-numbers.current {
  background: var(--cap-color-text);
  border-color: var(--cap-color-text);
  color: var(--cap-color-bg);
}
.cap-shell .cap-arc__grid .elementor-pagination .page-numbers.prev,
.cap-shell .cap-pager .page-numbers.prev,
.cap-shell .cap-arc__grid .elementor-pagination .page-numbers.next,
.cap-shell .cap-pager .page-numbers.next {
  width: auto; height: auto;
  border: 0;
  padding: 0 var(--cap-space-xs);
  font-weight: 500;
  font-size: var(--cap-type-meta);
  letter-spacing: var(--cap-track-meta);
  text-transform: uppercase;
  color: var(--cap-color-muted);
}
@media (hover: hover) { .cap-shell .cap-arc__grid .elementor-pagination .page-numbers.prev:hover, .cap-shell .cap-pager .page-numbers.prev:hover, .cap-shell .cap-arc__grid .elementor-pagination .page-numbers.next:hover, .cap-shell .cap-pager .page-numbers.next:hover {
  background: transparent;
  color: var(--cap-color-text);
} }
/* on the first / last page Elementor still prints prev / next as a dead
   <span>; 2b shows only the live one. */
.cap-shell .cap-arc__grid .elementor-pagination span.page-numbers.prev,
.cap-shell .cap-pager span.page-numbers.prev,
.cap-shell .cap-arc__grid .elementor-pagination span.page-numbers.next,
.cap-shell .cap-pager span.page-numbers.next { display: none; }
@media (max-width: 1279px) {
  .cap-shell .cap-pager,
  .cap-shell .cap-arc__grid .elementor-pagination { gap: var(--cap-space-gap-6); }
  .cap-shell .cap-pager .page-numbers,
  .cap-shell .cap-arc__grid .elementor-pagination .page-numbers { position: relative; }
  .cap-shell .cap-pager .page-numbers::after,
  .cap-shell .cap-arc__grid .elementor-pagination .page-numbers::after { content: ""; position: absolute; left: 50%; top: 50%; width: max(100%, var(--cap-tap-min)); height: max(100%, var(--cap-tap-min)); transform: translate(-50%, -50%); }
}

/* THE NAME FIELDS' NOTE (owner 2026-10-05): "Latin letters only (A–Z, accents are fine)." under a name typed in letters the
   print fonts lack — a GENTLE WARNING, not a hint: the field errors' colour with the small round "!" in front, no box, the
   field's frame untouched. Same type on both forms = the money page's helper line under the name (size, weight 400, sentence
   case, no letter spacing). Inside a field cell it sits on the cell's text edge (the cell carries the inset). */
.cap-shell .cap-name-note { display: flex; align-items: flex-start; gap: var(--cap-space-gap-3); margin-top: var(--cap-space-xs); padding: 0; font-family: var(--cap-font-ui); font-style: normal; font-weight: 400; font-size: var(--cap-type-hint-long); line-height: var(--cap-leading-lede); letter-spacing: normal; text-transform: none; color: var(--cap-color-error); }
.cap-shell .cap-name-note[hidden] { display: none; }
.cap-shell .cap-name-note::before { content: "!"; flex: none; width: var(--cap-type-hint-long); height: var(--cap-type-hint-long); margin-top: calc(var(--cap-type-hint-long) * (var(--cap-leading-lede) - 1) / 2); border-radius: var(--cap-radius-pill); background: var(--cap-color-error); color: var(--cap-color-error-fill); display: flex; align-items: center; justify-content: center; font-family: var(--cap-font-ui); font-weight: 700; font-size: calc(var(--cap-type-hint-long) * .75); line-height: 1; }
