/**
 * css/components/contact-hubspot.css — style the HubSpot embedded form
 * (#427, Contact page only) through its own `--hsf-*` custom-property
 * contract wherever one exists, falling back to direct `hsfc-` class
 * selectors only where no property covers the need (dropdown typeface,
 * two-up First/Last row, button sizing/tracking — see each rule below).
 *
 * Scoped entirely under `.cg-hsform` (the embed's own container) rather
 * than `:root`, so nothing here can leak onto any other HubSpot embed this
 * site might ever carry.
 *
 * The scope class was `.cg-contact2__hsform` until #433, i.e. named after
 * the ONE page that carried the embed. It was renamed — not aliased — when
 * the sitewide contact popup took the same embed, because a rule set that
 * styles two unrelated surfaces should not be named after one of them, and
 * an alias would have left the misleading name in the codebase alongside
 * the honest one. Specificity is unchanged (one class either way), so the
 * measured specificity notes further down this file still hold verbatim.
 * Both surfaces sit on `--cg-ink`, which is why one skin serves both: this
 * file is a LIGHT-ON-DARK treatment and would need a variant, not just a
 * new scope class, to work on cream.
 *
 * The `--hsf-default-*` properties HubSpot itself injects
 * (`<style data-hsfc-id="BaseStyle">`) are read-only reference values, not
 * override points — every rule the injected stylesheet writes resolves as
 * `var(--hsf-<thing>, var(--hsf-default-<thing>))`, so setting the
 * NON-`default` name here is what wins. Verified against the live embed's
 * injected stylesheet (2026-08-20): 84 `--hsf-default-*` custom properties
 * (not the 201 the issue's own investigation reported — a different form
 * config than whichever one was inspected then; see the #427 PR).
 *
 * Tokens only — no raw hex, no @layer, no !important.
 */

/* ─── Layout shell HubSpot itself renders inside `.hs-form-html` ──────── */

.cg-hsform {
	--hsf-background__padding: 0;
	--hsf-background__border-style: none;
	--hsf-background__border-width: 0;
	--hsf-row__vertical-spacing: 28px;
	--hsf-row__horizontal-spacing: 24px;

	/* ─── Field text (input/textarea) — underline, not boxed (Figma) ──── */
	--hsf-field-input__background-color: transparent;
	--hsf-field-input__border-width: 0 0 1px 0;
	--hsf-field-input__border-style: solid;
	--hsf-field-input__border-color: var( --rule-on-dark );
	--hsf-field-input__border-radius: 0;
	--hsf-field-input__padding: 0 0 10px;
	--hsf-field-input__font-family: var( --font-body );
	--hsf-field-input__font-size: 16px;
	--hsf-field-input__color: var( --cg-white );
	--hsf-field-input__placeholder-color: var( --cg-white );

	--hsf-field-textarea__background-color: transparent;
	--hsf-field-textarea__border-width: 0 0 1px 0;
	--hsf-field-textarea__border-style: solid;
	--hsf-field-textarea__border-color: var( --rule-on-dark );
	--hsf-field-textarea__border-radius: 0;
	--hsf-field-textarea__padding: 10px 0;
	--hsf-field-textarea__font-family: var( --font-body );
	--hsf-field-textarea__font-size: 16px;
	--hsf-field-textarea__color: var( --cg-white );
	--hsf-field-textarea__placeholder-color: var( --cg-white );

	/*
	 * Checkbox (19×19, Figma). `padding` is what actually SIZES this
	 * control (the injected stylesheet builds the visible box from
	 * `border-width` + `padding`, no explicit width/height) — every
	 * `--hsf-field-checkbox__*` property below MUST be set explicitly,
	 * never left to fall through to the `--hsf-field-input__*` values
	 * above (the fallback chain tries `--hsf-field-checkbox__X`, THEN
	 * `--hsf-field-input__X`, THEN `--hsf-default-field-checkbox__X` —
	 * verified against the injected stylesheet, 2026-08-20). Leaving
	 * `--hsf-field-checkbox__padding` unset let it inherit the text
	 * input's asymmetric underline padding (`0 0 10px`) and collapsed the
	 * checkbox to a 2px sliver — caught rendering the real embed, not
	 * guessed. `width`/`height` below are a second, explicit safety net
	 * against the same collapse (belt-and-braces: correct padding math
	 * alone would already fix it, but a fixed box size can't drift if a
	 * future `--hsf-field-input__padding` change is made without
	 * remembering this fallback chain).
	 */
	--hsf-field-checkbox__background-color: transparent;
	--hsf-field-checkbox__border-color: var( --rule-on-dark );
	--hsf-field-checkbox__border-width: 1px;
	--hsf-field-checkbox__border-style: solid;
	--hsf-field-checkbox__padding: 0;
	--hsf-field-checkbox__color: var( --cg-cream );

	/* ─── Labels + description/footer copy (hidden text still needs to
	   inherit sane colour/family — it's in the a11y tree, not display:none;
	   see js/cg-contact-hubspot.js) ──────────────────────────────────── */
	--hsf-field-label__font-family: var( --font-sans );
	--hsf-field-label__color: var( --cg-cream );
	--hsf-field-description__font-family: var( --font-body );
	--hsf-field-description__color: var( --cg-grey );
	--hsf-field-footer__font-family: var( --font-body );
	--hsf-field-footer__font-size: 14px;
	--hsf-field-footer__color: var( --cg-grey );

	/* ─── Rich text HubSpot renders inside the form (e.g. the required-
	   fields line js/cg-contact-hubspot.js rewrites the text of) ──────── */
	--hsf-richtext__font-family: var( --font-body );
	--hsf-richtext__font-size: 14px;
	--hsf-richtext__color: var( --cg-grey );

	/* ─── Error/info alerts (validation states) ────────────────────────
	   Rust reads on ink, same "safe on any surface" reasoning
	   css/components/forms.css's own validation rules document. ─────── */
	--hsf-erroralert__font-family: var( --font-body );
	--hsf-erroralert__color: var( --accent );
	--hsf-infoalert__font-family: var( --font-body );
	--hsf-infoalert__color: var( --cg-cream );

	/*
	 * Submit button — outline-cream treatment, matches .cg-btn--cream
	 * (css/components/button.css) for the same "CTA on a dark band" job.
	 * `--hsf-button__width` is included even though `--btn-min-width` is
	 * also set via the `.hsfc-Button` class rule below — verified against
	 * the live embed (2026-08-20) that the class-rule `width` alone is NOT
	 * enough: the injected stylesheet's own `[data-hsfc-id=Renderer]
	 * .hsfc-Button{width:var(--hsf-button__width, auto)}` rule ties our
	 * class selector on specificity (0,2,0) each), and being injected
	 * into <head> LATER (at runtime, after every enqueued stylesheet) it
	 * wins that tie by source order — so `width` only actually applies
	 * through the variable, never through the competing class property.
	 * (No --hsf-button__height/--hsf-button__text-transform/
	 * -letter-spacing property exists, so those are still set via the
	 * hsfc- class rule below — direct selector only where no property
	 * covers it, per the issue's own instruction; they aren't ALSO set by
	 * the injected stylesheet's base rule, so there's no tie to lose.)
	 */
	--hsf-button__background-color: transparent;
	--hsf-button__background-image: none;
	--hsf-button__border-width: var( --btn-border );
	--hsf-button__border-style: solid;
	--hsf-button__border-color: var( --rule );
	--hsf-button__border-radius: 0;
	--hsf-button__color: var( --cg-cream );
	--hsf-button__font-family: var( --font-sans );
	--hsf-button__font-size: var( --btn-font-size );
	--hsf-button__font-weight: 700;
	--hsf-button__padding: var( --btn-padding );
	--hsf-button__box-shadow: none;
	--hsf-button__width: var( --btn-min-width );
	--hsf-button--hover__background-color: var( --cg-cream );
	--hsf-button--hover__color: var( --cg-ink );
	--hsf-button--hover__border-color: var( --cg-cream );
}

/* Field/dropdown/checkbox wrappers HubSpot renders as flex rows already
   respect --hsf-row__* above for the vertical rhythm; nothing else needed
   at that level. */

/* ─── Dropdown — Noe Text Regular, 28px, cream (Figma: "Select default
   option… 28px Noe Text Regular"). No --hsf-default-dropdown-input__* (or
   any dropdown-specific) property exists in the injected stylesheet — the
   84 vars cover input/textarea/checkbox/radio/button/richtext/heading only
   — so this is a direct hsfc- selector, scoped under our own container,
   never touching another embed. ───────────────────────────────────────── */
.cg-hsform .hsfc-DropdownInput {
	border: 0;
	border-bottom: var( --hairline ) solid var( --rule-on-dark );
	border-radius: 0;
	background: transparent;
	padding: 0 0 10px;
}

/*
 * Targets the ACTUAL text control (`.hsfc-TextInput--button`, the
 * readonly closed-state display), not just the `.hsfc-DropdownInput`
 * wrapper above. Font-family/size are inheritable, but the injected
 * stylesheet gives that inner control its OWN explicit declaration via
 * `--hsf-field-input__font-family`/`__font-size` (it's a `.hsfc-TextInput`
 * under the hood, styled exactly like every other text field) — an
 * explicit child rule always wins over an inherited value regardless of
 * specificity, so setting font on the wrapper alone silently did nothing
 * (caught rendering the real embed: it measured as Averta 16px, not Noe
 * 28px, until this rule targeted the control directly). Three selector
 * segments here vs. their two (`[data-hsfc-id=Renderer] .hsfc-TextInput`)
 * — 0,3,0 beats 0,2,0 outright, no source-order tie to worry about. */
.cg-hsform .hsfc-DropdownInput .hsfc-TextInput {
	font-family: var( --font-serif );
	font-weight: 400;
	font-size: clamp( 18px, 6vw, 28px );
	color: var( --cg-cream );
}

/* Explicit 19×19 box (Figma) — belt-and-braces alongside the
   `--hsf-field-checkbox__padding`/`__border-width` fix above; see that
   rule's comment for why padding math alone is fragile here. */
.cg-hsform .hsfc-CheckboxInput {
	box-sizing: border-box;
	width: 19px;
	height: 19px;
}

/* ─── First/Last two-up (Figma: "First and Last are a two-up split…
   sharing the y=622 rule as two 186-wide halves") — NO CUSTOM CSS NEEDED.
   Verified against the live embed (2026-08-20): HubSpot's own portal form
   already groups firstname/lastname onto ONE `.hsfc-Row`
   (`display:inline-flex`, HubSpot's own row-gap logic via
   `--hsf-row__horizontal-spacing` above), rendering them side by side
   natively — a single-field row is `display:grid` and spans the full form
   width instead. Forcing a width on the row here would fight that (the row
   IS the two-field container; sizing it to 50% would waste the other
   half), so this file only sets `--hsf-row__horizontal-spacing` (the gap
   between the two) and leaves HubSpot's own row layout alone. ─────────── */

/*
 * Button sizing/tracking the --hsf-button__* properties above don't cover.
 * `min-height`/`letter-spacing`/`text-transform` only — NOT `display`,
 * `width`, or `transition`: the injected stylesheet's base rule sets
 * `display:block` and its own `transition` directly (not via a `--hsf-*`
 * var) on the exact same `.hsfc-Button` at the same (0,2,0) specificity,
 * so those two are a genuine tie this rule loses on source order (see the
 * `--hsf-button__width` comment above) — `text-align:center` in that same
 * base rule already centers the button's text under `display:block`, so
 * losing `display:flex` here costs nothing visually, and losing the
 * `transition` property just means HubSpot's own timing (`.2s`, close
 * enough to this system's `--fade-out`) animates the hover colours
 * instead of this one — not worth fighting further.
 */
.cg-hsform .hsfc-Button {
	min-height: var( --btn-height );
	letter-spacing: 0.22em;
	text-transform: uppercase;
}

/* ─── Labels — visually hidden, not removed (js/cg-contact-hubspot.js adds
   the theme's EXISTING `.visually-hidden` utility, css/base.css, to every
   `.hsfc-FieldLabel`; nothing to style here, this comment documents why
   there's no `display:none`/`.screen-reader-text` rule in this file). ─── */

/* #427 review C2 — required fields need a VISIBLE marker.
   The labels are visually hidden (the design has no visible labels), so
   without this there is nothing on screen saying a field is required, while
   the intro line still reads "* indicates required fields". A blank required
   field then disables the submit button with no explanation — reproduced,
   and a lost lead on the agency's own contact page.
   The marker rides on the field itself via a data attribute set in JS. */
.cg-hsform [data-cg-required-marked]::placeholder {
	color: var( --cg-cream );
}

.cg-hsform [data-cg-required-marked] {
	border-bottom-color: var( --accent );
}

/* ─── Open dropdown panel ───────────────────────────────────────────────
   The options list rendered with NO background, so the four choices drew
   straight over the fields behind them (reported from a screenshot).

   Root cause is our own underline styling leaking through HubSpot's
   variable reuse — the same class of bug as the checkbox one:

     .hsfc-DropdownOptions__List__ListItem {
         background-color: var( --hsf-field-input__background-color, … );
     }

   We set `--hsf-field-input__background-color` to transparent so the text
   fields render as bare hairlines. HubSpot reuses that SAME variable for
   the dropdown options, which need an opaque surface — they are an overlay
   (`position:absolute; z-index:10000` in HubSpot's own base rule), not part
   of the field.

   Fixed with explicit backgrounds rather than by changing the variable,
   which would put a box back around every text field.

   Specificity note, measured not assumed: HubSpot's rule is
   `[data-hsfc-id="Renderer"] .hsfc-DropdownOptions` — an attribute selector
   plus a class, i.e. (0,2,0). Scoping ours under `.cg-hsform`
   alone is ALSO (0,2,0), so it tied and lost on source order (their sheet
   is injected into <head> after ours) — verified: the panel still computed
   `rgba(0,0,0,0)`. Including their own `[data-hsfc-id="Renderer"]` hook
   takes ours to (0,3,0), which wins on specificity. No `!important`. ─── */
.cg-hsform [data-hsfc-id="Renderer"] .hsfc-DropdownOptions {
	background-color: var( --cg-ink-85 );
	border-color: var( --rule-on-dark );
	box-shadow: 0 12px 32px rgba( 0, 0, 0, 0.45 );
}

.cg-hsform [data-hsfc-id="Renderer"] .hsfc-DropdownOptions__List__ListItem {
	background-color: transparent;
	padding: 12px 16px;
}

/* `filter: brightness(90%)` is HubSpot's own hover, and on a near-black
   surface it is close to invisible. An explicit lift reads on ink. */
.cg-hsform [data-hsfc-id="Renderer"] .hsfc-DropdownOptions__List__ListItem:hover,
.cg-hsform [data-hsfc-id="Renderer"] .hsfc-DropdownOptions__List__ListItem:focus,
.cg-hsform [data-hsfc-id="Renderer"] .hsfc-DropdownOptions__List__ListItem--selected {
	background-color: var( --cg-ink-70 );
	filter: none;
}

/* The type-to-filter box at the top of the panel sits on the same surface.
   It also has to opt OUT of the 28px Noe Text treatment: #427's spec puts
   that face on the dropdown's closed-state default option ("How can we help
   you?"), and the rule that delivers it reaches this input too, rendering
   the word "Search" as 28px serif. Body copy is what belongs here. */
.cg-hsform [data-hsfc-id="Renderer"] .hsfc-DropdownOptions__Search input {
	background-color: transparent;
	color: var( --cg-cream );
	font-family: var( --font-body );
	font-size: 16px;
}

/* Options are body copy for the same reason — only the closed-state default
   option carries the display face. */
.cg-hsform [data-hsfc-id="Renderer"] .hsfc-DropdownOptions__List__ListItem {
	font-family: var( --font-body );
	font-size: 16px;
}

/* ─── The dropdown's double hairline ────────────────────────────────────
   Every other field is a bare `.hsfc-TextInput` and draws ONE underline.
   The dropdown is the only field HubSpot wraps in an extra element, and
   `.hsfc-DropdownInput` takes its border from the same
   `--hsf-field-input__border-width` we set to give the fields their
   hairline — so the wrapper AND the control inside it each drew a rule.
   Measured: wrapper bottom y=470, control bottom y=459 — two lines 11px
   apart under "How can we help you?".

   The control keeps its underline (that is what every other field uses and
   what the design shows sitting directly under the text); the wrapper's is
   removed. Same (0,3,0) specificity approach as the panel rules above —
   HubSpot's own rule is (0,2,0) and their sheet loads later. ────────── */
.cg-hsform [data-hsfc-id="Renderer"] .hsfc-DropdownInput {
	border-bottom-width: 0;
}

/* ─── Panel reveal ──────────────────────────────────────────────────────
   HubSpot paints its own defaults (Helvetica, boxed inputs, purple button,
   visible labels, a duplicated intro heading) the moment the embed loads.
   js/cg-contact-hubspot.js corrects that on `hs-form-event:on-ready`, but
   the embed still takes ~1.3s to arrive — so the ink bar used to sit on the
   page visibly empty, then fill.

   Instead the whole panel wipes in top-to-bottom once its content is there,
   in the same language as the rest of the page: the 0.8s
   cubic-bezier(0.16, 1, 0.3, 1) and the 1px rust leading edge that
   css/components/motion.css uses for `.anim-mask` / `.anim-edge`.

   WHY A RETREATING COVER AND NOT `clip-path` ON THE PANEL:
   `.anim-mask` is a per-LINE text reveal and does not apply to a box. The
   obvious alternative — clipping the panel itself — would also clip the
   open dropdown, which is `position:absolute; z-index:10000` inside this
   panel and can extend past its bottom edge. A cover that retreats leaves
   the panel unclipped and its descendants free.

   The cover is painted in the PAGE background, so what the reader sees is
   the ink bar arriving, not a black box being uncovered.

   FAILS OPEN, in three places now: a <noscript> override in each template,
   a 2500ms timer in js/cg-contact-hubspot.js, and — because the popup only
   injects that script on first open, so a blocked script file would mean it
   never runs at all — a second timer in the popup's own always-present
   assets/js/gff-contact-popup.js. A blocked embed or a thrown error degrades
   to "panel arrives on a timer", never to a permanently masked form.

   SCOPE CLASS: `.cg-hsform-panel`, applied by BOTH surfaces (#433) — the
   Contact page's ink panel (pages/template-contact.php, alongside its own
   `.cg-contact2__formpanel` geometry class) and the sitewide contact popup
   (gff-contact-popup.php). It was `.cg-contact2__formpanel` while the
   Contact page was the only thing that had a HubSpot form to unmask.

   The cover is painted in `--cg-hsform-mask`. It defaults to `--surface`,
   which is right on the Contact page: the panel is ink on a cream page, so a
   retreating cream cover reads as the ink bar ARRIVING. The popup overrides
   it to ink, because that panel is a flyout sitting over arbitrary page
   content — a cream cover there would flash a cream block over the video.
   Ink-on-ink makes the panel look present from the first frame and wipes its
   CONTENTS in, with the rust edge carrying the movement. */
.cg-hsform-panel {
	position: relative;
}

.cg-hsform-panel.is-loading::after,
.cg-hsform-panel.is-ready::after {
	content: "";
	position: absolute;
	z-index: 6;
	inset: 0;
	background: var( --cg-hsform-mask, var( --surface ) );
	transform-origin: bottom;
	pointer-events: none;
}

.cg-hsform-panel.is-ready::after {
	transform: scaleY( 0 );
	transition: transform 0.8s cubic-bezier( 0.16, 1, 0.3, 1 );
}

/* The 1px leading edge, riding the bottom of the retreating cover so it
   sits exactly on the reveal boundary the whole way down — same role as
   `.anim-line .anim-edge`, same accent colour. */
.cg-hsform-panel.is-loading::before,
.cg-hsform-panel.is-ready::before {
	content: "";
	position: absolute;
	z-index: 7;
	right: 0;
	bottom: 0;
	left: 0;
	height: 1px;
	background: var( --accent );
	transform-origin: bottom;
	pointer-events: none;
}

.cg-hsform-panel.is-ready::before {
	opacity: 0;
	transition: transform 0.8s cubic-bezier( 0.16, 1, 0.3, 1 ), opacity 0.2s ease 0.7s;
	transform: translateY( 0 );
}

.cg-hsform-panel.is-loading::before {
	transform: translateY( 0 );
}

/* Reduced motion: no WIPE, but still a COVER.
 *
   This block used to switch off all four pseudo-elements, on the reasoning
   that "the reveal is decoration". Half of that is right — the 800ms wipe
   and the rust leading edge are decoration, and both go. The cover is not.
   It is the only thing standing between the reader and HubSpot's unstyled
   defaults, and removing it handed reduced-motion visitors the exact flash
   the mask exists to prevent: measured in the popup with
   `prefers-reduced-motion: reduce`, at 400ms after open the panel showed 17
   HubSpot field labels, none hidden, no required markers — the full raw
   form, for as long as the embed took to skin.

   Reduced motion means no animation, not no mask. So the cover stays,
   opaque and static, and simply stops existing the instant `is-ready`
   lands: `display: none` rather than the scaleY transition, which is a cut
   instead of a wipe. `::before` (the 1px travelling edge) has no static
   meaning at all and goes entirely.

   Specificity is a deliberate tie — two classes here, two classes in the
   base rules above — resolved by this block sitting later in the file. That
   is also why the no-JS `<noscript>` hatches in the two templates still
   win: they print at `wp_footer`, later in document order than this
   stylesheet, so with JS off the cover comes off under reduced motion too.
   No `!important` anywhere in the chain. */
@media ( prefers-reduced-motion: reduce ) {
	.cg-hsform-panel.is-ready::after,
	.cg-hsform-panel.is-loading::before,
	.cg-hsform-panel.is-ready::before {
		display: none;
	}
}

/* ─── Last-resort unmask, in CSS, because every other fail-open is JS ──────
 *
   Keeping the cover under reduced motion (the block above) closed the flash,
   and opened something worse: it made the cover fail CLOSED. Reproduced by
   aborting the request for js/cg-contact-hubspot.js on /contact-us/ with
   `prefers-reduced-motion: reduce` — an opaque cream void sat over a fully
   rendered 25-field form, permanently. `pointer-events: none` means the form
   underneath stays clickable and readable to a screen reader, so it is a
   silent, sighted-only failure: the worst kind to ship.

   Every other fail-open on this mask is JavaScript — this file's own timer,
   the popup's backstop, both `<noscript>` hatches — and all of them are
   downstream of the one thing that can go wrong here, which is the script
   that owns the reveal never running. A skin that 404s, is adblocked, or
   throws before its timer is scheduled takes the whole chain with it. The
   `<noscript>` hatches do not cover it either: they need JS DISABLED, not JS
   broken.

   So the final backstop is a CSS animation, which needs no script at all. A
   1ms animation after a 15s delay is a state change rather than a movement —
   which is why it is deliberately OUTSIDE the reduced-motion block above and
   must stay there. 15s sits past every JS ceiling (this file's CEILING of
   12000, the popup's 10000), so whenever JS is alive it has already resolved
   and this is never reached; in a broken load it is the only thing left. It applies while `is-loading` only, so the
   normal reveal cancels it by removing the class. ─────────────────────── */
/* Opacity alone, deliberately. The first version also animated `visibility`
   to `hidden` for tidiness and it did not work — measured on the pseudo-
   element after the fill had applied, opacity was 5.5e-13 and visibility was
   still `visible`, with or without an explicit `from`. Opacity is what
   actually clears the cover, `pointer-events: none` is already on the base
   rule, so the `visibility` declaration was decoration that read like a
   guarantee. Removed rather than left in to be believed. */
@keyframes cg-hsform-unmask {
	from {
		opacity: 1;
	}

	to {
		opacity: 0;
	}
}

/* PAGE-LOAD-RELATIVE, which is right for a panel that is on screen from
   first paint — i.e. the Contact page, the surface whose fail-closed defect
   this was written for. It is NOT right for the flyout, whose form does not
   begin loading until the panel opens; the plugin's own stylesheet restarts
   this clock on open at a higher specificity. See the long note in
   wp-content/plugins/gff-contact/assets/css/gff-contact-popup.css. */
.cg-hsform-panel.is-loading::after,
.cg-hsform-panel.is-loading::before {
	animation: cg-hsform-unmask 1ms linear 15s forwards;
}

/* ─── CD review r1 (2026-09-01) — the ink panels' red asterisks and their
       invisible links (#460) ────────────────────────────────────────────────

   > in flyout contact form/form on contact page, make red asterisk at top
   > white
   >
   > Links in contact flyout (link to partnership and careers page) need to be
   > styled. Currently can't see them on a black background. When selecting the
   > Partner option

   Both surfaces are the same embed on the same ink panel — the Contact page's
   `.cg-contact2__formpanel` and the flyout's `.contact-popup-form`, which both
   also carry `.cg-hsform-panel`. Scoped to that panel class rather than to
   `.cg-hsform` alone, and the reason is measured, not stylistic: HubSpot's own
   rules are `[data-hsfc-id="Renderer"] .hsfc-…`, i.e. (0,2,0), and its
   stylesheet is INJECTED INTO <head> AT RUNTIME — after every enqueued sheet —
   so a (0,2,0) selector of ours ties and loses on source order. This file
   already documents that trap twice (the dropdown-panel and button-width
   notes). `.cg-hsform-panel .cg-hsform .hsfc-…` is (0,3,0) and wins outright,
   with no `!important` (locked rule).

   TWO red asterisks are visible on these panels, and they are NOT the same
   element — measured on the rendered embed 2026-09-02:

     1. The intro line's "*", `rgb(192, 43, 10)`. An inline
        `style="color: #c02b0a; font-size: 13.008px"` authored in the portal's
        own rich-text module. An inline style cannot be beaten from a
        stylesheet without `!important`, so js/cg-contact-hubspot.js clears it
        and tags the span `data-cg-required-star` — the same move, in the same
        function, as the inline `text-align: center` it already clears on the
        paragraph around it. This rule is what then colours it.
     2. `.hsfc-FieldLabel__RequiredIndicator`, `rgb(229, 21, 32)`, HubSpot's
        per-label marker. Mostly invisible, because the labels are visually
        hidden — EXCEPT on checkbox captions, which js/cg-contact-hubspot.js
        deliberately keeps visible (`isCaptionLabel()`, #427 review C3). So the
        "Sign up to receive emails*" caption shows one, and that is the second
        red asterisk the CD is looking at.

   The CD separately asked for the email-signup asterisk to be REMOVED rather
   than recoloured. That is not done here and must not be: the field is
   required in HubSpot, and deleting its only visible marker is exactly the
   regression #427 review C2 documents (a blank required field disables submit
   with no error, no label and no asterisk). It is tracked as a HubSpot-side
   change in #461 — make the field optional, and the marker goes with it. */

.cg-hsform-panel .cg-hsform [data-cg-required-star],
.cg-hsform-panel .cg-hsform .hsfc-FieldLabel__RequiredIndicator {
	color: var( --cg-cream );
}

/* Links inside the portal's rich-text blocks. Measured before the fix: the
   "Please click here to go to our partner submission." link that the Partner
   option reveals computed to `rgb(14, 14, 12)` — `--cg-ink`, inherited from
   the theme's global `a { color: var(--base-link-color) }` — on an ink panel.
   Black on black, with `text-decoration: none`. Cream + underline is the same
   treatment #458 gives a link in body copy, which is what this is. */
.cg-hsform-panel .cg-hsform .hsfc-RichText a {
	color: var( --cg-cream );
	text-decoration: underline;
	text-decoration-thickness: from-font;
	text-underline-offset: 0.18em;
	transition: color var( --fade-out ) var( --fade-ease );
}

.cg-hsform-panel .cg-hsform .hsfc-RichText a:hover,
.cg-hsform-panel .cg-hsform .hsfc-RichText a:focus-visible {
	color: var( --accent );
}
