/**
 * BD Advocacy — global stylesheet: everything theme.json cannot hold, and nothing else (§15.4).
 *
 * Core inlines this file on every page (inc/assets.php registers it with a path), so its size is
 * paid per request; tools/lint/budgets.mjs holds it to 12 KB minified.
 *
 * Blocks 1 and 4 are GENERATED by tools/fonts/fetch.mjs — do not edit between the markers. Block 4
 * is byte-identical to the theme.json `styles.css` string on purpose (§15.1), so the Bengali
 * cascade also reaches a 7.0 site, which never parses that copy.
 *
 * Every colour is a token. The only literal colours are block 1's system font names and block 2's
 * icon masks, which are geometry, not palette.
 *
 * 1 fallback faces (gen) · 2 root · 3 focus · 4 Bengali (gen) · 5 7.0 fallbacks · 6 layout ·
 * 7 chrome (P3) · 8 motion · 9 forced colours · 10 print
 */

/* ---- 1. Fallback faces (generated) --------------------------------------------------------- */

/* BDA:FONT-FALLBACKS:START */
@font-face {
  font-family: "Fraunces Fallback";
  src: local("Georgia");
  size-adjust: 100%;
  ascent-override: 97.8%;
  descent-override: 25.5%;
  line-gap-override: 0%;
}

@font-face {
  font-family: "Fraunces Fallback";
  src: local("Times New Roman");
  size-adjust: 100%;
  ascent-override: 97.8%;
  descent-override: 25.5%;
  line-gap-override: 0%;
}

@font-face {
  font-family: "Inter Fallback";
  src: local("Arial");
  size-adjust: 100%;
  ascent-override: 96.875%;
  descent-override: 24.1211%;
  line-gap-override: 0%;
}

@font-face {
  font-family: "Inter Fallback";
  src: local("Helvetica");
  size-adjust: 100%;
  ascent-override: 96.875%;
  descent-override: 24.1211%;
  line-gap-override: 0%;
}

@font-face {
  font-family: "Noto Sans Bengali Fallback";
  src: local("Nirmala UI");
  size-adjust: 100%;
  ascent-override: 91.7%;
  descent-override: 40.8%;
  line-gap-override: 0%;
}

@font-face {
  font-family: "Noto Sans Bengali Fallback";
  src: local("Bangla Sangam MN");
  size-adjust: 100%;
  ascent-override: 91.7%;
  descent-override: 40.8%;
  line-gap-override: 0%;
}

@font-face {
  font-family: "Noto Sans Bengali Fallback";
  src: local("Kohinoor Bangla");
  size-adjust: 100%;
  ascent-override: 91.7%;
  descent-override: 40.8%;
  line-gap-override: 0%;
}

@font-face {
  font-family: "Noto Sans Bengali Fallback";
  src: local("Vrinda");
  size-adjust: 100%;
  ascent-override: 91.7%;
  descent-override: 40.8%;
  line-gap-override: 0%;
}

/* BDA:FONT-FALLBACKS:END */

/* ---- 2. Root and document defaults --------------------------------------------------------- */

/*
 * No dark palette in v1: `light only` — with the meta tag inc/assets.php prints — stops Android
 * Chrome's auto-dark inventing one out of parchment and gold. High contrast is the low-vision
 * alternative. The three masks are the CSS-only half of the icon set (§20.3); the PHP helper draws
 * the same glyphs inline everywhere else.
 */
:root {
	--bda-icon-check: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 6 9 17l-5-5'/%3E%3C/svg%3E");
	--bda-icon-arrow: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 12h15m-6-7 7 7-7 7'/%3E%3C/svg%3E");
	--bda-icon-chevron: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");

	color-scheme: light only;
}

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

/* Gutter: no sideways shift when a dialog locks scrolling. Scroll padding: an anchored heading
 * clears the sticky header, and on small screens the sticky call-to-action too. */
html {
	scroll-padding-top: calc(var(--wp--custom--size--header-h) + 8px);
	scrollbar-gutter: stable;
}

@media (max-width: 1023px) {

	/*
	 * The MEASURED height of the bar, with the design's nominal height as the fallback for a reader
	 * with no JavaScript (§1.12 A6, WCAG 2.4.11).
	 *
	 * `bda-ui.js` has published `--bda-sticky-h` from `bar.offsetHeight` since P3 and nothing read
	 * it; this read `size.stickyCtaH`, a fixed 64 px. The bar is 64 px only when both of its buttons
	 * fit on one line. At 360 px with a telephone number in the label it stands 104 px tall, so
	 * anything a keyboard reached in the last 40 px of the page scrolled to a position under the bar
	 * and stayed there. The measurement is the only number that is right at every width and in every
	 * language — Bengali labels are longer again.
	 */
	html {
		scroll-padding-bottom: calc(var(--bda-sticky-h, var(--wp--custom--size--sticky-cta-h)) + 16px + env(safe-area-inset-bottom));
	}
}

:where(body) {
	margin: 0;
	text-rendering: optimizelegibility;
	-webkit-font-smoothing: antialiased;
}

:where(img, svg, video, canvas) {
	max-width: 100%;
	height: auto;
}

/* The gutter lives on containers with global padding, not the site wrapper, so a full-width
 * section reaches the viewport edge without a negative margin (§15.4). */
.wp-site-blocks {
	padding: 0;
}

/*
 * No faux bold or italic on the theme's own components: the shipped faces carry the weights they
 * need. Scoped to `bda-*` rather than `body` on purpose (design-system §2.3) — the legacy canvas
 * shares the prefix and MUST keep its synthesised italics for G11, so legacy-bda-canvas.css hands
 * them back inside `.bda` (§31.6).
 */
[class*="bda-"] {
	font-synthesis: none;
}

/* ---- 3. Focus ------------------------------------------------------------------------------- */

/* One ring everywhere: a token-width outline plus a 4 px halo, legible on parchment, white, navy
 * and photography (§2.2.1). `:where()` keeps specificity at zero. */
:where(a, button, input, select, textarea, summary, [tabindex]):focus-visible {
	border-radius: var(--wp--custom--radius--sm);
	box-shadow: 0 0 0 4px var(--wp--custom--color--focus-halo);
	outline: var(--wp--custom--size--focus-width) solid var(--wp--custom--color--focus);
	outline-offset: 2px;
}

/* The ring inverts on dark grounds. The `:is()` grouping is load-bearing: as a plain comma list,
 * `.is-style-scheme-urgent .bda-callnum` would bind only to the second selector. */
:is(.is-on-dark, .is-style-scheme-navy),
.is-style-scheme-urgent .bda-callnum {
	--wp--custom--color--focus: var(--wp--preset--color--white);
	--wp--custom--color--focus-halo: var(--wp--preset--color--navy);
}

/* ---- 4. Bengali cascade (generated) -------------------------------------------------------- */

/* BDA:BN-RULES:START */
:lang(bn) {
	font-family: var(--wp--preset--font-family--bengali);
	font-synthesis: none;
	hyphens: manual;
	letter-spacing: 0;
	line-height: var(--wp--custom--type--leading-bn, 1.8);
	overflow-wrap: anywhere;
	text-transform: none;
	text-underline-offset: 0.18em;
}

:lang(bn) :is(h1, h2, h3, h4, h5, h6) {
	font-family: var(--wp--preset--font-family--bengali);
	font-weight: 700;
	letter-spacing: 0;
	line-height: var(--wp--custom--type--leading-bn-heading, 1.35);
	text-transform: none;
}

/* Emphasis in Bengali is weight, never a synthesised italic: Noto Sans Bengali has no italic. */
:lang(bn) :is(em, i, cite) {
	font-style: normal;
	font-weight: 700;
}

:lang(bn) :is(a, ins, u) {
	text-decoration-skip-ink: auto;
	text-decoration-thickness: 1px;
	text-underline-offset: 0.18em;
}

:lang(bn) ol {
	list-style-type: bengali;
}

/* The eyebrow loses its caps and tracking in Bengali (B4). */
:lang(bn) .is-style-eyebrow {
	color: var(--wp--preset--color--navy);
	font-size: var(--wp--preset--font-size--small);
	letter-spacing: 0;
	text-transform: none;
}

/* Justification is never used: it wrecks Bengali line breaking (B6). */
:lang(bn) :is(p, li, dd, dt, blockquote) {
	text-align: start;
}

/* English fragments inside Bengali pages keep the UI face (B9). */
:lang(bn) [lang='en'] {
	font-family: var(--wp--preset--font-family--ui);
}

/*
 * The one Bengali word in the English chrome ("বাংলা" on the language switch) uses the reader's
 * system Bengali stack, so the 108 KB webfont never loads on an English page (B9).
 */
.bda-lang {
	font-family: 'Nirmala UI', 'Bangla Sangam MN', 'Kohinoor Bangla', Vrinda, system-ui, sans-serif;
}

/* BDA:BN-RULES:END */

/* ---- 5. WordPress 7.0 fallbacks ------------------------------------------------------------ */

/*
 * Two 7.1-only features are progressive enhancement, restated here so a 7.0 site renders the same
 * (ADR §3, verify #11): `settings.viewport`/`@mobile` on `bda/section`, mirrored at 560 px; and
 * pseudo-selectors on block style variations, restated for `.is-style-*`.
 */
@media (max-width: 560px) {

	.wp-block-bda-section {
		--wp--style--block-gap: var(--wp--preset--spacing--50);
	}
}

.is-style-secondary > .wp-block-button__link:hover,
.is-style-secondary > .wp-block-button__link:active {
	background-color: var(--wp--preset--color--navy-100);
	border-color: var(--wp--preset--color--navy);
	color: var(--wp--preset--color--navy);
}

.is-style-ghost > .wp-block-button__link:hover {
	background-color: rgba(255, 255, 255, 0.1);
	border-color: var(--wp--preset--color--white);
	color: var(--wp--preset--color--white);
}

.is-style-urgent > .wp-block-button__link:hover,
.is-style-urgent > .wp-block-button__link:active,
.is-style-urgent-pill > .wp-block-button__link:hover {
	background-color: var(--wp--preset--color--urgent-700);
	border-color: var(--wp--preset--color--urgent-700);
	color: var(--wp--preset--color--white);
}

.is-style-call > .wp-block-button__link:hover {
	background-color: var(--wp--preset--color--urgent-050);
	border-color: var(--wp--preset--color--urgent-700);
	color: var(--wp--preset--color--urgent-700);
}

/* ---- 6. Layout primitives ------------------------------------------------------------------ */

/* The shapes the design is built from. Grids are auto-fit, not fixed columns, so the 768 px card
 * step needs no media query (§2.2.3). */
.bda-grid {
	display: grid;
	gap: var(--wp--custom--space--grid-gap);
	grid-template-columns: repeat(auto-fit, minmax(min(100%, 280px), 1fr));
}

.bda-grid--2 {
	grid-template-columns: repeat(auto-fit, minmax(min(100%, 320px), 1fr));
}

.bda-grid--4 {
	grid-template-columns: repeat(auto-fit, minmax(min(100%, 220px), 1fr));
}

.bda-prose:where(:not(.bda *)) {
	max-width: var(--wp--custom--space--prose);
}

.bda-prose:where(:not(.bda *)) p {
	max-width: var(--wp--custom--type--measure);
}

.bda-card {
	background: var(--wp--preset--color--white);
	border: var(--wp--custom--border--card);
	border-radius: var(--wp--custom--radius--lg);
	box-shadow: var(--wp--preset--shadow--sm);
	padding: var(--wp--custom--space--card-pad);
}

/* A card inside a white section reads as an outline, not as a raised surface (§19.4). */
.is-style-scheme-white .bda-card {
	border: var(--wp--custom--border--hairline);
	box-shadow: none;
}

.bda-card--hover:where(:hover, :focus-within) {
	border-color: var(--wp--preset--color--gold-200);
	box-shadow: var(--wp--preset--shadow--md);
	translate: 0 var(--wp--custom--motion--lift);
}

/* The whole card becomes the link target without nesting interactive elements. */
.bda-stretch::after {
	content: '';
	inset: 0;
	position: absolute;
}

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

/* ---- 7. Chrome components ------------------------------------------------------------------ */

/*
 * `hidden` means hidden, whatever a component declares.
 *
 * The user agent's `[hidden] { display: none }` has the lowest priority there is, so any author
 * rule that sets `display` on the same element silently defeats it. Several chrome components do
 * set one — the sticky bar is `flex`, the mega panel is `block` — and each is shipped hidden and
 * revealed by script. This is the one `!important` in the stylesheet, and it is here because the
 * attribute is a promise the markup makes to assistive technology, not a styling hint.
 */
[hidden] {
	display: none !important;
}

/* The skip link is the first focusable thing on the page and invisible until it is focused. */
.bda-skip .wp-block-button__link {
	background: var(--wp--preset--color--navy);
	border-radius: 0 0 var(--wp--custom--radius--sm) 0;
	color: var(--wp--preset--color--white);
	inset-block-start: 0;
	inset-inline-start: -9999px;
	position: absolute;
	z-index: var(--wp--custom--z--skip);
}

.bda-skip .wp-block-button__link:focus {
	inset-inline-start: 0;
}

.bda-util__inner,
.bda-header__inner,
.bda-foot-grid,
.bda-legal {
	margin-inline: auto;
	max-width: var(--wp--style--global--wide-size);
	padding-inline: var(--wp--custom--space--gutter);
}

.bda-util {
	font-size: var(--wp--preset--font-size--small);
}

.bda-util__inner {
	align-items: center;
	display: flex;
	gap: var(--wp--preset--spacing--40);
	justify-content: space-between;

	/*
	 * A fixed height, not a minimum.
	 *
	 * §18.2 specifies the utility bar at 36 px; letting its content decide made it 38.39 px, and a
	 * fractional bar puts <main> on a fractional row. That costs a rendered pixel in the G11
	 * comparison — the live site's <main> starts on a whole one — and it is the kind of thing that
	 * is much cheaper to fix here than to compensate for in a test.
	 */
	height: var(--wp--custom--size--util-h);
}

.bda-util__actions {
	align-items: center;
	display: flex;
	gap: var(--wp--preset--spacing--40);
}

/* Below the tablet step the left slot is dropped rather than wrapped (§18.2). */
@media (max-width: 767px) {

	.bda-util .bda-facts {
		display: none;
	}
}

/*
 * Below the small step the search trigger is the icon alone and the urgent pill drops its number
 * (§18.2). Both rules are in the two blocks' own stylesheets — `bda/dialog-trigger` and
 * `bda/contact-link` — because they are each about one control, and because `global.css` has a
 * 12 KB budget that is the theme's, not those blocks'.
 */

.bda-header {
	background: var(--wp--preset--color--white);
	border-block-end: var(--wp--custom--border--hairline);
	box-shadow: var(--wp--preset--shadow--header);
	position: sticky;
	inset-block-start: 0;
	z-index: var(--wp--custom--z--header);
}

.bda-header__inner {
	align-items: center;
	display: flex;
	gap: var(--wp--preset--spacing--40);
	justify-content: space-between;

	/* 80 px per §18.3, and a whole number for the same reason as the utility bar above. */
	height: var(--wp--custom--size--header-h);
}

/*
 * The lockup does not shrink. As a flex item beside the actions row it was being squeezed to 97 px
 * at 360 px — a wordmark at half its drawn width, which is the exact failure the 160 px floor
 * exists to prevent. The actions row gives way instead; below 344 px the emblem takes over.
 */
.bda-header__inner > .bda-logo,
.bda-header__row > .bda-logo {
	flex-shrink: 0;
}

.bda-actions {
	align-items: center;
	display: flex;
	gap: var(--wp--preset--spacing--30);
}

.bda-nav ul {
	align-items: center;
	display: flex;
	gap: 2px;
	list-style: none;
	margin: 0;
	padding: 0;
}

.bda-navitem {
	position: static;
}

.bda-navbtn {
	align-items: center;
	border-radius: var(--wp--custom--radius--pill);
	display: inline-flex;
	gap: 5px;
	font-size: var(--wp--preset--font-size--small);
	font-weight: 600;
	min-height: var(--wp--custom--size--target);
	padding: 8px 13px;
	text-decoration: none;
	white-space: nowrap;
}

.bda-navbtn:hover,
.bda-navitem.is-open .bda-navbtn,
.bda-navbtn[aria-current='page'] {
	background: var(--wp--preset--color--parchment);
	color: var(--wp--preset--color--navy);
}

.bda-navitem.is-open .bda-caret {
	rotate: 180deg;
}

/* The panel spans the header, which is why the nav item is `position: static`. */
.bda-mega {
	background: var(--wp--preset--color--white);
	border-block-end: var(--wp--custom--border--hairline);
	box-shadow: var(--wp--preset--shadow--lg);
	inset-block-start: 100%;
	inset-inline: 0;
	padding-block: var(--wp--preset--spacing--70) var(--wp--preset--spacing--60);
	position: absolute;
	z-index: var(--wp--custom--z--mega);
}

.bda-mega-inner {
	display: grid;
	gap: var(--wp--preset--spacing--60);
	grid-template-columns: 1fr var(--wp--custom--size--mega-aside);
	margin-inline: auto;
	max-width: var(--wp--style--global--wide-size);
	padding-inline: var(--wp--custom--space--gutter);
}

/* Under 1080 px the side panel becomes a row beneath the columns rather than a squeezed column. */
@media (max-width: 1079px) {

	.bda-mega-inner {
		grid-template-columns: 1fr;
	}
}

.bda-mega-side {
	background: var(--wp--preset--color--parchment);
	border-radius: var(--wp--custom--radius--lg);
	padding: var(--wp--custom--space--card-pad);
}

/* Below the burger threshold the desktop navigation is gone; the drawer carries it. */
@media (max-width: 1023px) {

	.bda-nav,
	.bda-header .bda-book {
		display: none;
	}
}

@media (width >= 1024px) {

	[data-bda-open='drawer'] {
		display: none;
	}
}

.bda-dialog--drawer {
	block-size: 100dvh;
	inline-size: min(420px, 92vw);
	margin-inline-start: auto;
	margin-block: 0;
	overflow-y: auto;
	padding: var(--wp--custom--space--gutter);
}

.bda-drawer__head {
	align-items: center;
	display: flex;
	justify-content: space-between;
	margin-block-end: var(--wp--preset--spacing--50);
}

.bda-drawer__nav a,
.bda-drawer__nav summary {
	display: block;
	font-weight: 600;
	min-height: var(--wp--custom--size--target);
	padding-block: 10px;
	text-decoration: none;
}

.bda-drawer__nav summary {
	cursor: pointer;
	list-style: none;
}

.bda-drawer__help {
	display: grid;
	gap: var(--wp--preset--spacing--30);
	margin-block: var(--wp--preset--spacing--50);
}

.bda-drawer__help > * {
	width: 100%;
}

.bda-dialog--search {
	inline-size: var(--wp--custom--size--search);
	margin: 12vh auto auto;
	padding: var(--wp--custom--space--panel-pad);
}

/* The close control sits above the field; the field still takes focus when the dialog opens. */
.bda-search__head {
	display: flex;
	justify-content: flex-end;
	margin-block-end: var(--wp--preset--spacing--30);
}

.bda-search__hint {
	color: var(--wp--preset--color--slate-400);
	font-size: var(--wp--preset--font-size--small);
	margin-block-start: var(--wp--preset--spacing--30);
}

/*
 * Brand block, then the four link columns. The columns are one block and one `navigation`
 * landmark (a page is allowed three: Primary, Breadcrumb, Footer), so the grid nests rather than
 * listing eight siblings.
 */
.bda-foot-grid {
	display: grid;
	gap: var(--wp--custom--space--grid-gap);
}

.bda-foot-brand {
	max-width: 46ch;
}

.bda-foot-grid > .bda-linklist {
	display: grid;
	gap: var(--wp--custom--space--grid-gap);
	grid-template-columns: repeat(auto-fit, minmax(min(100%, 160px), 1fr));
}

@media (width >= 768px) {

	.bda-foot-grid {
		grid-template-columns: minmax(0, 1fr) minmax(0, 2fr);
	}
}

.bda-legal {
	border-block-start: 1px solid var(--wp--custom--border--on-dark-soft);
	margin-block-start: var(--wp--preset--spacing--70);
	padding-block-start: var(--wp--preset--spacing--50);
}

/* Room for the sticky bar so it never covers the last line of the footer. */
.bda-footer {
	padding-block-end: calc(var(--wp--preset--spacing--70) + var(--bda-sticky-h, 0px));
}

/* ---- 8. Motion ------------------------------------------------------------------------------ */

.bda-card,
.wp-block-button__link {
	transition:
		background-color var(--wp--custom--motion--fast),
		color var(--wp--custom--motion--fast),
		border-color var(--wp--custom--motion--fast),
		box-shadow var(--wp--custom--motion--base),
		translate var(--wp--custom--motion--base);
	transition-timing-function: var(--wp--custom--motion--ease);
}

/* Reduced motion asks for motion to be removed, reduced or replaced — not for feedback to vanish.
 * Durations collapse to 1 ms, which keeps `transitionend` firing; the lift goes to zero (§5.1). */
@media (prefers-reduced-motion: reduce) {

	:root {
		--wp--custom--motion--base: 1ms;
		--wp--custom--motion--fast: 1ms;
		--wp--custom--motion--lift: 0px;
		--wp--custom--motion--nudge: 0px;
		--wp--custom--motion--slow: 1ms;
	}

	*,
	*::before,
	*::after {
		animation-duration: 0.01ms !important;
		animation-iteration-count: 1 !important;
		scroll-behavior: auto !important;
		transition-duration: 0.01ms !important;
	}
}

/* ---- 9. Forced colours ---------------------------------------------------------------------- */

/* Forced colours drops every background and border; boundaries are restated in system colours so
 * buttons, cards and fields keep their edges (§24.7). */
@media (forced-colors: active) {

	.wp-block-button__link,
	.bda-iconbtn,
	.bda-field:where(:not(.bda *)) input {
		border: 1px solid buttontext;
	}

	.bda-card {
		border: 1px solid canvastext;
	}

	:focus-visible {
		outline: 2px solid highlight;
	}
}

/* ---- 10. Print ------------------------------------------------------------------------------ */

/* A printed page is a reference document: chrome, calls to action, map and form go, and outbound
 * links print their address (§25.5). */

/*
 * The print-only footer, hidden on screen — declared BEFORE the print block, deliberately.
 *
 * It used to sit after it. Both rules are one class, so at equal specificity the later one wins, and
 * `display: none` won inside `@media print` too: the line identifying the chamber was styled for
 * paper and never reached it.
 */
.bda-print-foot {
	display: none;
}

@media print {

	.bda-util,
	.bda-header nav,
	.bda-drawer,
	.bda-search,
	.bda-stickycta,
	.bda-ctaband,
	.bda-map,
	.bda-notice,
	.bda-footer nav,
	form,
	.bda-aside:not(.bda-aside--keep):where(:not(.bda *)) {
		display: none !important;
	}

	body {
		background: white;
		color: black;
		font-size: 11pt;
	}

	p,
	li {
		orphans: 3;
		widows: 3;
	}

	.bda-card,
	.bda-step,
	details {
		break-inside: avoid;
	}

	/* An FAQ or a drawer group prints open, whatever state it was left in. */
	details > * {
		display: block;
	}

	.bda-prose:where(:not(.bda *)) a[href^="http"]:not([href^="tel"]):not([href^="mailto"])::after {
		content: " (" attr(href) ")";
		font-size: 0.8em;
	}

	.bda-print-foot {
		display: block;
	}
}

/*
 * The cover figure's shape.
 *
 * `core/post-featured-image`'s `aspectRatio` attribute is rendered as an inline style, and §30 P4
 * asserts that a service page carries none. The ratio is a design decision that belongs here anyway
 * — 15:7 is the crop the live covers were cut to.
 */
.bda-cover img {
	aspect-ratio: 15 / 7;
	object-fit: cover;
	width: 100%;
}

/*
 * Controls that need a script.
 *
 * `inc/assets.php` puts `bda-js` on <html> in the head; without it these are not drawn at all. The
 * `hidden` attribute cannot do this job — the Interactivity API resolves its directives server-side,
 * so a binding that clears `hidden` clears it for a reader who has no JavaScript either.
 */
:root:not(.bda-js) .bda-needs-js {
	display: none !important;
}
