/*
 * Aethyrdancer design tokens — derived from the artwork, not chosen alongside it.
 *
 * NOT ENQUEUED YET. This file is a proposal: nothing on the site changes until it is
 * added to aethyrdancer_enqueue_styles() in functions.php. Adopt, edit, or delete.
 *
 * Generated from `python scripts/extract_palette.py --dir data/images` over the full
 * 15-piece favourites set on 2026-08-12. Re-run that script when the sample changes.
 *
 * WHAT THE ART ACTUALLY SAID
 *
 * The corpus does not share a hue. Across 15 pieces the accents span the entire hue
 * wheel, and averaging them collapses to near-neutral grey — the combined palette came
 * back at chroma 0.007–0.036, greyer than any single piece. That collapse is the
 * finding, not a failure: **a single fixed brand accent drawn from this corpus is
 * arithmetically impossible.** What the corpus does agree on is two things:
 *
 *   1. A near-black, violet-tinted ground. Every piece has one; several bottom out at
 *      effectively pure black (#000004, #020102, #040a15).
 *   2. A violet-cast neutral ramp — which is exactly what the averaging produced, and
 *      is therefore the right source for text and borders.
 *
 * So ground and text are fixed; the accent is a *variable* the collection sets. That
 * is also what makes the polychrome work safe: the chrome never commits to a hue a
 * rainbow piece could clash with.
 *
 * Chroma across the set ranges roughly 5x — the "meld" pieces peak near 0.04 while the
 * sacred-geometry and ChaoStar pieces reach 0.19. An accent tuned for one end is
 * invisible or overbearing at the other. Hence per-collection accents rather than one.
 *
 * RULE OF THUMB: the chrome must always be lower-chroma than the art. The art is the
 * picture; the site is the frame. If they compete at the same saturation, both lose.
 *
 * NAMING: custom properties keep the short `--ad-` prefix, but every CSS *class* uses
 * the full `aethyrdancer-` prefix. That asymmetry is deliberate. Ad blockers apply
 * generic cosmetic filters to class and id names beginning `ad-`, which silently hid
 * the entire product grid with no console error. Custom property names are invisible to
 * those filters, so they are safe — but never name a class `ad-anything`.
 */

:root {
	/*
	 * NATIVE CONTROLS FOLLOW THE PAGE, NOT THE OS.
	 *
	 * The dark ground below is a background-color, and a browser never inspects that when
	 * it paints its own widgets. Without this declaration every native <select> popup,
	 * date picker and scrollbar came from the UA's LIGHT defaults — so the sort control's
	 * open list rendered as near-white rows, and any option fill tuned for this page
	 * landed white-on-white. One line fixes every dropdown on the site, checkout's country
	 * and state selects included, which the theme does not style at all.
	 */
	color-scheme: dark;

	/* ---------------------------------------------------------------
	 * Ground ramp — violet-tinted near-black. The constant across all
	 * three pieces. Never pure #000: the art's blacks are all tinted.
	 * --------------------------------------------------------------- */
	--ad-ground-000: #030308; /* deepest — full-bleed hero, lookbook */
	--ad-ground-100: #0e0c16; /* page background */
	--ad-ground-200: #1a1626; /* raised surface: cards, panels */
	--ad-ground-300: #2a2437; /* hover surface, wells — the corpus ground cluster */
	--ad-ground-400: #3f3850; /* borders, dividers, disabled */

	/* ---------------------------------------------------------------
	 * Text — the violet-cast neutral ramp the 15-piece average produced.
	 * All verified against --ad-ground-100; do not swap these by eye.
	 * --------------------------------------------------------------- */
	--ad-text-strong: #efecf4; /* headings          16.60:1  AAA */
	--ad-text: #d5d0de;        /* body copy         12.84:1  AAA */
	--ad-text-muted: #8a859e;  /* captions, meta     5.48:1  AA  */

	/* ---------------------------------------------------------------
	 * Accent — SWAPPABLE. These defaults come from the violet piece
	 * ("Prismatic Organic Infinite Razor"). A collection page can
	 * override the three values and everything downstream follows.
	 * --------------------------------------------------------------- */
	--ad-accent: #8886de;
	--ad-accent-strong: #6362be;
	--ad-accent-soft: #c1a8e6;

	/* Semantic aliases — components reference these, never a raw hex. */
	--ad-link: var(--ad-accent-soft);
	--ad-link-hover: var(--ad-text-strong);
	--ad-focus: var(--ad-accent-soft);
	--ad-surface: var(--ad-ground-200);
	--ad-border: var(--ad-ground-400);

	/*
	 * THE VIOLET GLOW, ONE DEFINITION.
	 *
	 * Derived in text-fx.css from the `ui` and `meta` lettering variants (#683ffd at
	 * stdDeviation 1 / 0.3 and 2.5 / 0.75, through that file's CSS-radius = 2-sigma
	 * mapping). It lives here because more than the dropdowns wear it now — every dark
	 * surface in assets/css/surfaces.css reads from this. Tight layer first, so it
	 * paints nearest the glyph, matching the SVG paint order.
	 *
	 * NOT AVAILABLE EVERYWHERE, and that is a fact about text-shadow rather than a
	 * choice: it never paints inside a native <select> popup on any platform. Prices are
	 * held back from it deliberately — see the archive-price note in text-fx.css.
	 */
	--ad-glow:
		0 0 2px rgb(104 63 253 / 30%),
		0 0 5px rgb(104 63 253 / 75%);

	/*
	 * THE QUIET PAIR'S WHOLE PAINT STACK, FOR TEXT THAT HAS TO WRAP (2026-09-17).
	 *
	 * `--ad-glow` alone does not look like the `meta` lettering, and on running text it is
	 * close to invisible. The SVG gets its look from four layers, not one: a black drop
	 * shadow offset (6.5, 8.5) with blur stdDeviation 1, the two violet glows, and a white
	 * fill at 72%. That translucent fill is what lets the violet show through the letters.
	 * Under an opaque fill the glow hides behind the glyphs and leaves only a 5px halo on
	 * a near-black ground. Measured on production: the computed text-shadow was correct,
	 * and the text still looked plain white.
	 *
	 * So the treatment carries its fill with it. Use both tokens together, or it is not the
	 * treatment. Paint order matches the SVG: the first shadow listed paints on top, so the
	 * glows sit over the drop shadow, and the text sits over all of them.
	 *
	 * `--ad-glow` is left as it was on purpose. Fields, notices and the cart tables wear it
	 * behind opaque text, and a 6.5px drop shadow inside a form control would be wrong.
	 */
	--ad-quiet-fill: rgb(255 255 255 / 72%);
	--ad-quiet-fx:
		var(--ad-glow),
		6.5px 7px 2px rgb(0 0 0 / 100%);

	/*
	 * THE SAME TREATMENT AT TWO OTHER TYPE SIZES (2026-09-17).
	 *
	 * The base displacement started as the `meta` and `title` variants' own 6.5/8.5, authored
	 * against 16-20px lettering. The downward value came back to 7px on 2026-09-18 (operator):
	 * 8.5 is measured inside an SVG viewBox against a glyph the renderer also strokes and
	 * glows, and in flat CSS on running text it sat further from the letters than it looks
	 * there. Across is unchanged. It does not survive being moved to another size: on the 12.8px
	 * size-guide headers an 8.5px drop lands most of a line below the glyph it belongs to
	 * and reads as a second row of smudge, and on a 32px archive title the same offset is
	 * too tight to register at all. So the displacement tracks the type and the glow does
	 * not, because a glow has no direction to get wrong.
	 *
	 * Roughly 0.6x across for 12-14px and 1.4x for 28-32px, rounded to whole pixels.
	 *
	 * THE SMALL TIER IS SQUARE AT 4/4, not scaled from 8.5 the way the across value is
	 * scaled from 6.5. Downward displacement is the axis that costs something here: the
	 * size-guide rows are 12.8px on a 1.6 line-height, so even 5px of drop reached into the
	 * gap above the next row and read as belonging to it. Across, a shadow has the cell's
	 * padding to fall into. Reduced from 5px to 4px by the operator on 2026-09-18.
	 *
	 * Use `-sm` and `-lg` with the type size, not with how important the text is.
	 */
	--ad-quiet-fx-sm:
		var(--ad-glow),
		4px 4px 2px rgb(0 0 0 / 100%);
	--ad-quiet-fx-lg:
		var(--ad-glow),
		9px 11px 3px rgb(0 0 0 / 100%);

	/* ---------------------------------------------------------------
	 * Type scale — 1.25 (major third). Conservative on purpose: the
	 * art carries the drama, the type should not compete.
	 * --------------------------------------------------------------- */
	--ad-text-xs: 0.8rem;
	--ad-text-sm: 0.9rem;
	--ad-text-base: 1rem;
	--ad-text-lg: 1.25rem;
	--ad-text-xl: 1.563rem;
	--ad-text-2xl: 1.953rem;
	--ad-text-3xl: 2.441rem;

	/* Spacing — 4px base, geometric-ish. */
	--ad-space-1: 0.25rem;
	--ad-space-2: 0.5rem;
	--ad-space-3: 0.75rem;
	--ad-space-4: 1rem;
	--ad-space-6: 1.5rem;
	--ad-space-8: 2rem;
	--ad-space-12: 3rem;
	--ad-space-16: 4rem;

	--ad-radius: 4px;
	--ad-radius-lg: 10px;
}

/* -------------------------------------------------------------------
 * Collection accents. Put one of these classes on <body> (or a section)
 * and the accent triplet re-points. Derived from the sampled pieces.
 * ------------------------------------------------------------------- */

/*
 * Violet / periwinkle. Three pieces cluster here — Prismatic Infinite Razor,
 * Infinite Razor Recursion, Purple_Gold_Alien_Intestine. The largest family, and
 * the reason it is also the :root default.
 */
.aethyrdancer-collection-aethyr {
	--ad-accent: #8886de;        /*  6.01:1  AA body     */
	--ad-accent-strong: #6362be; /*  3.71:1  large / UI  */
	--ad-accent-soft: #c1a8e6;   /*  9.25:1  AAA         */
	--ad-card-tint: #5b4798;
	--ad-card-tint-deep: #33284a;
	--ad-card-glow: #8886de;
}

/*
 * Muted rose / terracotta. Busy Organic Body Horror and both Hyper Organic Melds.
 * Note the low chroma — these pieces peak near 0.04, so this accent is deliberately
 * the most restrained of the set. Anything louder would overpower the artwork.
 */
.aethyrdancer-collection-meld {
	--ad-accent: #997676;        /*  4.81:1  AA body     */
	--ad-accent-strong: #7f6061; /*  3.46:1  large / UI  */
	--ad-accent-soft: #ccb6af;   /* 10.05:1  AAA         */
	--ad-card-tint: #6b4a52;
	--ad-card-tint-deep: #3a2e33;
	--ad-card-glow: #c9928c;
}

/* Blue / cyan. Purple Teal Gradient Dragon Bone — the only strongly blue piece. */
.aethyrdancer-collection-abyss {
	--ad-accent: #689eb4;        /*  6.59:1  AA body     */
	--ad-accent-strong: #507a97; /*  4.22:1  large / UI  */
	--ad-accent-soft: #9dd1d4;   /* 11.55:1  AAA         */
	--ad-card-tint: #2f6c85;
	--ad-card-tint-deep: #1e3a44;
	--ad-card-glow: #689eb4;
}

/* Brass / gold over slate. The bio-mechanical piece. */
.aethyrdancer-collection-brass {
	--ad-accent: #a78c5f;        /*  6.06:1  AA body     */
	--ad-accent-strong: #806e4e; /*  3.93:1  large / UI  */
	--ad-accent-soft: #dcc07d;   /* 10.97:1  AAA         */
	--ad-card-tint: #6b5a35;
	--ad-card-tint-deep: #3a3226;
	--ad-card-glow: #a78c5f;
}

/*
 * Polychrome — the two sacred-geometry rainbow pieces and ChaoStar_03.
 *
 * These carry six or more high-chroma hues each. The correct chrome for them is NOT
 * a sixth accent, it is no accent: go fully neutral and let the art be the only
 * colour on the page. These values are the corpus average, i.e. the greys the whole
 * set agrees on. This is a deliberate design position, not a placeholder.
 */
.aethyrdancer-collection-spectrum {
	--ad-accent: #8a859e;        /*  5.48:1  AA body     */
	--ad-accent-strong: #646165; /*  3.18:1  large / UI  */
	--ad-accent-soft: #bbb8ae;   /*  9.77:1  AAA         */
	--ad-card-tint: #413a56;
	--ad-card-tint-deep: #221c2e;
	--ad-card-glow: #b9b2c9;
}


/* -------------------------------------------------------------------
 * Collection accents, derived 2026-08-17 from each collection's own
 * exemplar artwork with scripts/extract_palette.py — the same method that
 * produced the five families above.
 *
 * Three collections resolve to a family already derived from those exact
 * pieces, so they alias rather than duplicate: Purple Teal Gradient Dragon
 * Bone *is* the abyss source, Busy Organic Body Horror *is* the meld source,
 * and Colors Out of Space is polychrome, which by the argument on `spectrum`
 * gets neutral chrome rather than a sixth colour.
 *
 * Feywrought was a fourth until 2026-08-17, aliasing `brass` off the
 * bio-mechanical piece's gold. Re-measuring against all three of its exemplars
 * moved it to a desaturated blue and broke the alias — `brass` itself is now
 * used by nothing, and is kept only because the five families are the argument
 * the rest of this file rests on.
 *
 * Three are new. Their values come straight from the cluster output, except
 * where a step failed its contrast band — those are lightened toward white
 * along the same hue and noted inline.
 *
 * All ten collections are now derived. See docs/collections.md.
 * ------------------------------------------------------------------- */

/* Pelagic Depths — blue/cyan. Same source art as `abyss`. */
.aethyrdancer-collection-pelagic-depths {
	--ad-accent: #689eb4;        /*  6.59:1  AA body     */
	--ad-accent-strong: #507a97; /*  4.22:1  large / UI  */
	--ad-accent-soft: #9dd1d4;   /* 11.55:1  AAA         */
	--ad-card-tint: #2f6c85;
	--ad-card-tint-deep: #1e3a44;
	--ad-card-glow: #689eb4;
}

/* In Praise of Plague — muted rose/terracotta. Same source art as `meld`. */
.aethyrdancer-collection-in-praise-of-plague {
	--ad-accent: #997676;        /*  4.81:1  AA body     */
	--ad-accent-strong: #7f6061; /*  3.46:1  large / UI  */
	--ad-accent-soft: #ccb6af;   /* 10.05:1  AAA         */
	--ad-card-tint: #6b4a52;
	--ad-card-tint-deep: #3a2e33;
	--ad-card-glow: #c9928c;
}

/*
 * Feywrought — desaturated blue. RECALIBRATED 2026-08-17, away from gold.
 *
 * The first pass took the accent from the bio-mechanical piece's gold clusters and
 * called it `brass`. That was one image out of three. Re-measured across all
 * three exemplars, the gold is the outlier: Feywrought_01 is almost achromatic
 * (chroma 0.001-0.005, warm greys rising to a cyan highlight at hue 197) and
 * Feywrought_02 is magenta-tinted greys at chroma 0.010-0.030. A gold chrome sat
 * on top of two nearly colourless pieces and fought the second one outright.
 *
 * What the three actually share is a cool, very low-chroma thread — the blue
 * ground cluster in the bio-mechanical piece, 17.3% coverage at hue 248, and
 * Feywrought_01's cyan highlight. This is that blue, at the hue the source
 * measures rather than a hue chosen to look blue.
 *
 * KEEPING IT OFF `abyss`. Pelagic Depths sits at hue 225.6, chroma 0.066 — also a
 * blue, and near enough that hue alone would not separate them. This is 22
 * degrees away AND at chroma 0.038, a little over half. The separation is
 * saturation as much as hue, which is also what "desaturated" is supposed to
 * mean. Compared on the real garments before choosing: it makes the Goldwrought
 * jacket's brass read as brass by complement, where the gold ground merged with
 * it.
 */
.aethyrdancer-collection-feywrought {
	--ad-accent: #687c90;        /*  4.50:1  AA body     */
	--ad-accent-strong: #4d6173; /*  3.02:1  large / UI  */
	--ad-accent-soft: #899eb2;   /*  7.02:1  AAA         */
	--ad-card-tint: #3a5b7b;
	--ad-card-tint-deep: #1c3042;
	--ad-card-glow: #899eb2;
}

/*
 * Colors Out of Space — polychrome. Eight clusters spanning violet, magenta,
 * blue, red and yellow-green at chroma up to 0.19. The correct chrome for a
 * piece carrying that many high-chroma hues is no colour at all; see the note
 * on `spectrum`.
 */
.aethyrdancer-collection-colors-out-of-space {
	--ad-accent: #8a859e;        /*  5.48:1  AA body     */
	--ad-accent-strong: #646165; /*  3.18:1  large / UI  */
	--ad-accent-soft: #bbb8ae;   /*  9.77:1  AAA         */
	--ad-card-tint: #413a56;
	--ad-card-tint-deep: #221c2e;
	--ad-card-glow: #b9b2c9;
}

/*
 * Alien Contact — teal, and almost nothing else. Every one of the eight
 * clusters lands within four degrees of hue 158, which makes this the most
 * monochrome family in the corpus. Accent-strong is lightened from the derived
 * #3e664c, which measured 2.96:1 and missed its band.
 */
.aethyrdancer-collection-alien-contact {
	--ad-accent: #5d8a68;        /*  4.90:1  AA body     */
	--ad-accent-strong: #40684e; /*  3.04:1  large / UI  */
	--ad-accent-soft: #83bc94;   /*  8.85:1  AAA         */
	--ad-card-tint: #284b37;
	--ad-card-tint-deep: #14291d;
	--ad-card-glow: #5d8a68;
}

/*
 * Otherdimensional Visions — magenta ground with green luminance. The accent
 * is the green rather than the rose: the greens carry 18% coverage against the
 * rose's 5%, and the ground is already magenta, so green is what actually
 * reads as light against it.
 */
.aethyrdancer-collection-otherdimensional-visions {
	--ad-accent: #8c997f;        /*  6.44:1  AA body     */
	--ad-accent-strong: #586357; /*  3.08:1  large / UI  */
	--ad-accent-soft: #c6ddbe;   /* 13.38:1  AAA         */
	--ad-card-tint: #592145;
	--ad-card-tint-deep: #1e1720;
	--ad-card-glow: #a24261;
}

/*
 * Infernal Design — red at very low chroma, peaking near 0.048. Restrained for
 * the same reason `meld` is, and close to it by measurement rather than by
 * choice. Accent and accent-strong are both lightened from the derived
 * #8a6c6e (4.11:1) and #6b5152 (2.70:1), which missed their bands.
 */
.aethyrdancer-collection-infernal-design {
	--ad-accent: #907375;        /*  4.53:1  AA body     */
	--ad-accent-strong: #725a5a; /*  3.06:1  large / UI  */
	--ad-accent-soft: #c59da0;   /*  8.04:1  AAA         */
	--ad-card-tint: #503e41;
	--ad-card-tint-deep: #1f1414;
	--ad-card-glow: #c59da0;
}


/*
 * Druid's Weaving — gold over green and teal. Since Feywrought was recalibrated
 * to a desaturated blue this is the only warm accent left in the catalogue, so
 * nothing needs to keep the two apart any more. The teal that runs
 * under it becomes the card tint rather than a fourth accent.
 *
 * Accent and accent-strong are lightened from the derived #936034 (3.66:1) and
 * #693b1f (2.07:1), which missed their bands. Accent-soft is untouched.
 */
.aethyrdancer-collection-druids-weaving {
	--ad-accent: #9e7149;        /*  4.53:1  AA body     */
	--ad-accent-strong: #7e563e; /*  3.05:1  large / UI  */
	--ad-accent-soft: #b89a5f;   /*  7.23:1  AAA         */
	--ad-card-tint: #2f6d62;
	--ad-card-tint-deep: #1f3d35;
	--ad-card-glow: #b89a5f;
}

/*
 * Hypnoprism — polychrome. ChaoStar_03 is one of the pieces `spectrum` was
 * derived from in the first place, and the cluster output confirms it: eight
 * hues across rose, violet, blue, green, red and cyan at chroma up to 0.157.
 * Neutral chrome, for the same reason as Colors Out of Space.
 */
.aethyrdancer-collection-hypnoprism {
	--ad-accent: #8a859e;        /*  5.48:1  AA body     */
	--ad-accent-strong: #646165; /*  3.18:1  large / UI  */
	--ad-accent-soft: #bbb8ae;   /*  9.77:1  AAA         */
	--ad-card-tint: #413a56;
	--ad-card-tint-deep: #221c2e;
	--ad-card-glow: #b9b2c9;
}

/*
 * Fractal Organic — violet. Prismatic Organic Infinite Razor is an `aethyr`
 * source piece, and the clustering returns #8886de, #6362be and #c1a8e6
 * verbatim: the aethyr triplet, rediscovered from the artwork.
 */
.aethyrdancer-collection-fractal-organic {
	--ad-accent: #8886de;        /*  6.01:1  AA body     */
	--ad-accent-strong: #6362be; /*  3.71:1  large / UI  */
	--ad-accent-soft: #c1a8e6;   /*  9.25:1  AAA         */
	--ad-card-tint: #5b4798;
	--ad-card-tint-deep: #33284a;
	--ad-card-glow: #8886de;
}

/* -------------------------------------------------------------------
 * Astra bridge.
 *
 * Astra emits a large inline stylesheet of high-specificity WooCommerce
 * selectors that all resolve through --ast-global-color-*. Re-pointing
 * those variables makes Astra's own CSS follow this palette instead of
 * being fought selector by selector.
 *
 * Slot semantics VERIFIED on Astra 4.13.9 by reading the defaults it
 * emits, not guessed. Astra's own aliases confirm 4/5/6 are all
 * backgrounds:
 *   --ast-global-color-primary:              var(--ast-global-color-4)
 *   --ast-global-color-secondary:            var(--ast-global-color-5)
 *   --ast-global-color-alternate-background: var(--ast-global-color-6)
 *
 * Astra defaults, for reference:
 *   0 #046bd2  1 #045cb4  2 #1e293b  3 #334155  4 #FFFFFF
 *   5 #F0F5FA  6 #111111  7 #D1D5DB  8 #111111
 *
 * Note slot 6 is an alternate *background* (Astra ships it dark), not a
 * border — slot 7 is the light grey that acts as a border in practice.
 * ------------------------------------------------------------------- */
:root {
	--ast-global-color-0: var(--ad-accent);        /* primary: links, buttons */
	--ast-global-color-1: var(--ad-accent-strong); /* primary hover */
	--ast-global-color-2: var(--ad-text-strong);   /* headings */
	--ast-global-color-3: var(--ad-text);          /* body text */
	--ast-global-color-4: var(--ad-ground-100);    /* page background */
	--ast-global-color-5: var(--ad-ground-200);    /* secondary background */
	--ast-global-color-6: var(--ad-ground-000);    /* alternate background */
	--ast-global-color-7: var(--ad-ground-400);    /* borders */
	--ast-global-color-8: var(--ad-ground-300);

	/*
	 * FOUR MORE OF ASTRA'S, AND THEY ARE THE REASON THE FORMS WERE WHITE.
	 *
	 * Each was traced to its consumer in Astra 4.13.9 rather than assumed; each has
	 * exactly one, and every one of them shipped white or near-white:
	 *
	 *   --ast-comment-inputs-background   #FFF     every input/select/textarea, site-wide
	 *   --ast-global-dark-bg-style        #fff     WooCommerce's fields, and the header search
	 *   --ast-wc-container-head-bg-color  #fbfbfb  the cart and order tables' <thead>
	 *
	 * That first one is the whole story: Astra sets it on a bare element selector, so it
	 * reached the cart quantity steppers, every checkout field, the account forms and the
	 * shipping calculator at once. Re-pointing it fixes all of them with no selector.
	 *
	 * --ast-border-color is different — Astra REFERENCES it in a dozen stylesheets and
	 * never declares a value anywhere in the theme. It only gets one when a border colour
	 * is set in the customizer, so on this install every `border-color: var(--ast-border-color)`
	 * was invalid at computed-value time and fell back to `currentColor`, painting table
	 * and field borders in the text colour. Giving it a value is what makes those borders
	 * read as edges instead of as lines.
	 *
	 * Astra also ships an `.astra-dark-mode-enable` body class that covers much of this.
	 * Deliberately not used: it is an undocumented parent-theme class, and the parent
	 * theme is a soft decision (see CLAUDE.md). Adding the class would make the forms go
	 * white again, silently, on the day the theme is swapped.
	 */
	--ast-comment-inputs-background: var(--ad-surface);
	--ast-global-dark-bg-style: var(--ad-surface);
	--ast-wc-container-head-bg-color: var(--ad-ground-300);
	--ast-border-color: var(--ad-border);

	/*
	 * And the rest of Astra's light grounds, found by enumerating every --ast-* property
	 * on the computed root and keeping the ones whose relative luminance was above 0.35 —
	 * rather than by finding them one page at a time. `--ast-global-dark-lfs` is the one
	 * that was actually showing: it is the "Cart totals" heading, #fbfbfb behind #efecf4
	 * text, a contrast ratio of 1.13. The others have no surface on the site today and are
	 * re-pointed so they cannot become one quietly.
	 *
	 * Astra's own `--ast-global-color-2` and `-3` also read as light here and are left
	 * alone on purpose: those are the text ramp, already re-pointed above, and they are
	 * SUPPOSED to be light.
	 *
	 * --ast-lifter-hover-bg is deliberately not in this list — it belongs to LifterLMS,
	 * which is not installed and is not going to be.
	 */
	--ast-global-dark-lfs: var(--ad-ground-300);
	--ast-title-layout-bg: var(--ad-ground-200);
	--ast-widget-bg-color: var(--ad-ground-200);
	--ast-code-block-background: var(--ad-ground-000);
	--ast-search-border-color: var(--ad-border);
}

/* -------------------------------------------------------------------
 * Minimal application layer.
 *
 * Re-pointing Astra's variables covers most surfaces, but the page
 * background itself is not expressed through them on every container
 * type, so it is set explicitly here. Keep this section small — it is
 * the seam where tokens stop and theming begins.
 * ------------------------------------------------------------------- */

/*
 * Ground, and its texture.
 *
 * THE PAGE AND THE MASTHEAD ARE THE SAME WALL.
 *
 * This tile comes from the same generator the masthead's crest does — lit brick from
 * build_brick_wall.py with the corpus line work laid over it — so the wall the header
 * crumbles along and the wall the page stands on are one surface. They were different
 * before: a flat photographic tile below, a lit procedural one above, which put a seam
 * across the site at exactly the place the eye is already looking.
 *
 * THE TEXTURE IS A BACKGROUND LAYER ON <body>, NOT A PSEUDO-ELEMENT.
 *
 * The obvious construction — a fixed `body::before` at `z-index: -1` — painted nothing.
 * Astra sets the page background on body through a selector that outranks both `body` and
 * `html body`, and which does not surface when the cascade is enumerated from
 * `document.styleSheets`; a negative-z layer then sits behind that opaque fill and is
 * never seen. Putting the texture *in* body's own background stack means nothing can
 * paint over it, because there is nothing between a background layer and its own colour.
 *
 * The stack, topmost first: a flat scrim of the page ground, then the wall. The scrim is
 * what makes the strength tunable — at `--ad-grain-opacity: 0.9` it is 10% ground laid
 * back over the texture. Without it the only way to dial it would be to re-export.
 *
 * The tile is a dark brick-and-graffiti crop from the operator's own corpus, already
 * carrying a constant 47% alpha, so the token multiplies that rather than starting from
 * opaque. It is 256px drawn at 512: upscaling costs nothing on a texture and halves how
 * often the eye catches the pattern repeating, which is far more visible on structured
 * brick than any edge seam.
 *
 * THIS IS THE PAGE'S OWN WALL, AND THE MASTHEAD FOLLOWS IT — NOT THE OTHER WAY ROUND.
 *
 * For a while it was the other way round: unifying the two walls replaced this tile with
 * the masthead's generated masonry, which made them match by changing the one of the two
 * that was already right. The crest is now painted from *this* tile — see
 * scripts/build_masthead.py — so the surface the page stands on is the surface the header
 * crumbles along, and the corpus texture is what both of them are made of.
 *
 * The URL arrives as a custom property from inc/site-header.php carrying a `filemtime`,
 * with the literal here only as a fallback. Nothing versions a `url()` inside a
 * stylesheet, so without the query string a returning visitor keeps whichever version
 * they cached first, indefinitely.
 *
 * The wrappers below must stay transparent or they cover it again.
 */
:root {
	--ad-grain-opacity: 0.65;
	--ad-grain-size: 512px;
}

body {
	background-color: var(--ad-ground-100);
	background-image:
		linear-gradient(
			rgb(14 12 22 / calc(1 - var(--ad-grain-opacity))),
			rgb(14 12 22 / calc(1 - var(--ad-grain-opacity)))
		),
		var(--ad-ground-tile, url("../images/grain.webp"));
	background-repeat: repeat, repeat;
	background-size: auto, var(--ad-grain-size);
	color: var(--ad-text);
}

.site,
.site-content,
#content {
	background-color: transparent;
}

/* -------------------------------------------------------------------
 * Retrofit the two components that already exist but have no styling,
 * plus the spin viewer, which currently hardcodes two neutral greys.
 * ------------------------------------------------------------------- */

.aethyrdancer-sizing-notice {
	background: var(--ad-surface);
	border-left: 3px solid var(--ad-accent);
	border-radius: var(--ad-radius);
	color: var(--ad-text);
	font-size: var(--ad-text-sm);
	padding: var(--ad-space-3) var(--ad-space-4);
}

/* The notice is a <div> wrapping a <p> since it gained an optional heading. */
.aethyrdancer-sizing-notice > p {
	margin: 0;
}

/*
 * The loud variant, for a product whose sizing advice CONTRADICTS the catalogue default
 * rather than merely extending it. Emphasis is structural: a raised ground, a full rule
 * instead of a left one, and a separated heading. Deliberately NOT a colour change --
 * the accent is per-collection and re-tinting a warning would give it ten different
 * meanings, while a red from outside the ramp would be the only unmeasured hue on the
 * site. See aethyrdancer_sizing_notice_overrides() in the core plugin.
 */
.aethyrdancer-sizing-notice--critical {
	background: var(--ad-ground-300);
	border: 2px solid var(--ad-accent);
	border-left-width: 8px;
	padding: var(--ad-space-4);
}

.aethyrdancer-sizing-notice__lead {
	border-bottom: 1px solid var(--ad-ground-400);
	color: var(--ad-text-strong);
	display: block;
	margin-bottom: var(--ad-space-3);
	padding-bottom: var(--ad-space-3);
}

.aethyrdancer-size-guide {
	background: var(--ad-surface);
	border: 1px solid var(--ad-ground-400);
	border-radius: var(--ad-radius);
	color: var(--ad-text);
	margin: var(--ad-space-3) 0 var(--ad-space-4);
	overflow: hidden;
}

.aethyrdancer-size-guide > summary {
	color: var(--ad-text-strong);
	cursor: pointer;
	font-weight: 700;
	padding: var(--ad-space-3) var(--ad-space-4);
}

.aethyrdancer-size-guide[open] > summary {
	border-bottom: 1px solid var(--ad-ground-400);
}

.aethyrdancer-size-guide__scroll {
	overflow-x: auto;
}

.aethyrdancer-size-guide table {
	border-collapse: collapse;
	font-size: var(--ad-text-xs);
	margin: 0;
	min-width: 100%;
	width: max-content;
}

.aethyrdancer-size-guide caption {
	color: var(--ad-text-muted);
	padding: var(--ad-space-3) var(--ad-space-4);
	text-align: left;
}

.aethyrdancer-size-guide :is(th, td) {
	border-bottom: 1px solid var(--ad-ground-400);
	padding: var(--ad-space-2) var(--ad-space-3);
	text-align: left;
	white-space: nowrap;
}

.aethyrdancer-size-guide thead th,
.aethyrdancer-size-guide tbody th {
	color: var(--ad-text-strong);
}

.aethyrdancer-size-guide__note {
	color: var(--ad-text-muted);
	font-size: var(--ad-text-xs);
	margin: 0;
	padding: var(--ad-space-3) var(--ad-space-4);
}

.aethyrdancer-ai-disclosure {
	color: var(--ad-text-muted);
	font-size: var(--ad-text-xs);
}

.aethyrdancer-spin__stage {
	background-color: var(--ad-ground-200);
}

.aethyrdancer-spin__hint {
	color: var(--ad-text-muted);
	font-size: var(--ad-text-sm);
}
