/*
 * Bulldogs Site Worker - consent banner styling.
 *
 * ===========================================================================
 * WHAT THIS IS NOW: A CARD, NOT A BAR
 * ===========================================================================
 * It used to be a full-width strip pinned across the bottom of the viewport.
 * That shape reads as a legal notice bolted onto the page - it spans furniture
 * it has nothing to do with, and the wider it gets the more it looks like
 * something to be got rid of rather than something to be read.
 *
 * So the banner is now a bounded card in the bottom-left corner, with a header
 * carrying the title and an explicit "Continue without accepting" escape route,
 * a sentence of plain purpose copy, one row per category with a switch, and the
 * actions at the foot. The layout and the affordances are taken from a
 * competitor banner (Usercentrics, via Termageddon) that the owner reviewed.
 *
 * 🚨 WHAT WAS DELIBERATELY *NOT* TAKEN FROM IT. That banner ships its Marketing
 * and Functional toggles PRE-ENABLED. That is the exact practice Planet49 (CJEU
 * C-673/17) held is not consent, and the ICO says the same of any pre-ticked or
 * pre-toggled control for a non-essential purpose. Every optional switch here
 * renders OFF, in the markup, for every visitor - see BannerRenderer invariant 2
 * and the tests that pin it. Nothing in this file may ever draw an unchecked
 * input as though it were on.
 *
 * ===========================================================================
 * WHY THIS FILE STOPPED INHERITING
 * ===========================================================================
 * It used to set `color: inherit` and `border: 1px solid currentColor` on the
 * buttons, on the theory that adopting the host theme was friendlier than
 * fighting it across ~29 sites. That is not what happened. On the pilot,
 * Elementor's kit prints
 *
 *     .elementor-kit-<n> button { color: #CC3366; ... }
 *
 * at a specificity our single-class rule could not beat, so "Accept all" and
 * "Reject all" rendered raspberry pink - a colour that appears nowhere else on
 * that site, and which on "Accept all" reads as a warning. On an arbitrary
 * client theme it lands somewhere else, unpredictably.
 *
 * So: two complete presets of our own, and one inherited property.
 *
 * ===========================================================================
 * THE EQUAL-PROMINENCE RULE (read before editing anything below)
 * ===========================================================================
 * 🚨 The ICO requires refusing consent to be as easy as giving it, and a filled
 * "Accept" against an outlined "Reject" is the dark pattern regulators
 * penalise. There is therefore NO selector anywhere in this file that can
 * address Accept or Reject individually. Both carry `.bsw-btn` and nothing
 * else, every declaration that reaches them lives in ONE shared rule, and
 * BannerStyleTest asserts that it always will - by name and by shape, including
 * the positional selectors (`nth-child`, `first-child`, …) that would single one
 * out just as effectively and much less obviously.
 *
 * "Save settings" IS quieter, on purpose, and that is not an exception being
 * smuggled in. It is a THIRD action - the thing you press after using the
 * switches - not the counterpart to consenting, and the balance the ICO rule
 * protects is the one between giving and refusing. It carries its own
 * `.bsw-secondary` class, deliberately named without `bsw-btn` in it so that the
 * "every .bsw-btn selector is the shared rule" test cannot be satisfied by a
 * `.bsw-btn-accept` sneaking in on a substring.
 *
 * Refusing, meanwhile, now has TWO routes of its own: the Reject button, and the
 * "Continue without accepting" control in the header, which records the same
 * persisted denial rather than merely dismissing the card.
 *
 * 🚨 ACCEPT SITS ON THE RIGHT, and that is DOM ORDER AND NOTHING ELSE. The
 * markup runs Reject, Accept, Save; the shared rule sizes all three identically
 * and `flex: 1 1 0` makes the two consent buttons exactly equal in width. If a
 * future change wants to move one of them, it moves in the markup - the moment
 * this file needs to know which is which, the rule above has already been
 * broken.
 *
 * "More information" is NOT a button in the visual sense: it decides nothing and
 * records nothing, so it is a text control sitting in the links row beside
 * Cookie policy and Privacy policy. It carries `.bsw-more`, named without
 * `bsw-btn` in it for exactly the reason `.bsw-secondary` is.
 *
 * "Drawing people to accepting" comes from the design being clear and well made
 * - real contrast, a readable sentence, generous targets - and never from
 * making Reject weaker. If a change needs Accept and Reject to differ, it is the
 * wrong change.
 *
 * ===========================================================================
 * THE SWITCHES ARE REAL CHECKBOXES
 * ===========================================================================
 * Every category control is an `<input type="checkbox">` with `appearance: none`
 * and a `::before` thumb. It is not a `<div role="switch">`, and the difference
 * is not stylistic: a div-based toggle looks identical, and silently loses
 * keyboard operation, the focus ring, and the semantics a screen reader
 * announces. Tab reaches it and Space flips it because it is a checkbox, not
 * because anything here made it so.
 *
 * `appearance: none` replaces the old `appearance: auto`. The reason that
 * property was forced in the first place has not gone away - a theme or form
 * plugin hiding the native input with `position: absolute; opacity: 0; clip:
 * rect(0 0 0 0)` would leave the consent toggles invisible but still tabbable -
 * so the whole reset list below is kept and extended. We now draw the control
 * ourselves instead of asking the UA to.
 *
 * ===========================================================================
 * HOW THESE RULES BEAT AN ARBITRARY HOST THEME
 * ===========================================================================
 * Three deliberate levers, in the order they do the work:
 *
 *   1. THE ID. The banner root already carries `id="bsw-banner"` (the client
 *      script and the reopen control's aria-controls both depend on it), so
 *      `#bsw-banner .bsw-btn` costs nothing and scores 1-1-0. That alone beats
 *      every class-and-element rule a theme or page builder emits, Elementor's
 *      `.elementor-kit-<n> button` (0-1-1) included.
 *   2. `!important`, on a NAMED LIST of properties, not on everything. The list
 *      is the set a theme actually reaches for on a `button`, an `a`, an `input`
 *      or a `p`: colour, background (including background-image, because theme
 *      buttons love a gradient), border, border-radius, padding, font-size,
 *      font-weight, line-height, letter-spacing, text-transform,
 *      text-decoration, box-shadow and opacity - plus the STRUCTURAL few whose
 *      loss is not cosmetic: position, inset, z-index, display and overflow. A
 *      rule as ordinary as `.some-builder-class div { display: none !important }`
 *      would otherwise take the banner off the page entirely while every
 *      server-side check went on reporting the site healthy.
 *
 *      That last one is why EVERY element this card is built from carries an
 *      explicit `display: … !important` under the id. The card has more `div`s
 *      in it than the old bar did - a header, a rows list, an actions row - and
 *      each of them is one `div { display: none }` away from disappearing.
 *
 *      What is left un-important is the tuning nothing fights us for on an
 *      unknown theme - flex-direction, flex-wrap, gap, align-items - because
 *      marking those too would only make this file harder to override on
 *      purpose later.
 *   3. COMPOUND SELECTORS on our own elements for anything that lives outside
 *      the banner, where there is no id to lean on - see the fixed withdrawal
 *      pill, which is addressed as
 *      `.bsw-reopen.bsw-reopen-fixed[data-bsw-action="reopen"]` (0-3-0).
 *
 * `all: revert` was considered and rejected. It would out-muscle everything in
 * one line, but it also discards the UA behaviour we depend on (the checkbox's
 * own keyboard handling, the button's focus behaviour) and it reverts
 * `font-family` away from the one property we deliberately inherit.
 *
 * WHAT A THEME CAN STILL BREAK, stated rather than discovered later:
 *   - A rule of its own carrying BOTH an id and `!important`. Nothing short of
 *     inline styles beats that, and inline styles on the buttons are themselves
 *     forbidden (BannerRendererTest asserts neither button carries one).
 *   - `transform`, `filter`, `perspective` or `contain` on an ANCESTOR of the
 *     banner - `<body>` or `<html>`. Any of those makes that ancestor the
 *     containing block for our `position: fixed`, and the banner stops being
 *     pinned to the viewport. It cannot be defended from here; it is a finding
 *     for the scanner, not a stylesheet problem.
 *   - `font-family`, which we inherit on purpose so the banner does not look
 *     pasted on. A theme with an unreadable display face gets an unreadable
 *     banner, and that is the trade we chose.
 *
 * ===========================================================================
 * MEASURED CONTRAST (sRGB, WCAG 2.1 relative luminance)
 * ===========================================================================
 * These are recomputed from the shipped hex values by BannerStyleTest, so the
 * table cannot drift away from the palette below it.
 *
 * LIGHT preset          text #111111 on #ffffff ............ 18.88:1  (AA: 4.5)
 *                       muted #595959 on #ffffff ........... 7.00:1  (AA: 4.5)
 *                       button #ffffff on #141414 .......... 18.42:1  (AA: 4.5)
 *                       button fill #141414 on #ffffff ..... 18.42:1  (AA: 3.0)
 *                       button hover #ffffff on #000000 .... 21.00:1
 *                       Save label #141414 on #ffffff ...... 18.42:1  (AA: 4.5)
 *                       Save border #595959 on #ffffff ..... 7.00:1  (AA: 3.0)
 *                       switch off #767676 on #ffffff ...... 4.54:1  (AA: 3.0)
 *                       switch on #141414 on #ffffff ....... 18.42:1  (AA: 3.0)
 *                       thumb off #ffffff on #767676 ....... 4.54:1  (AA: 3.0)
 *                       thumb on #ffffff on #141414 ........ 18.42:1  (AA: 3.0)
 *                       pill border #767676 on #ffffff ..... 4.54:1  (AA: 3.0)
 * DARK preset           text #f2f2f2 on #0e0e0e ............ 17.24:1
 *                       muted #a6a6a6 on #0e0e0e ........... 7.93:1
 *                       button #0e0e0e on #f2f2f2 .......... 17.24:1
 *                       button fill #f2f2f2 on #0e0e0e ..... 17.24:1
 *                       button hover #0e0e0e on #ffffff .... 19.30:1
 *                       Save label #f2f2f2 on #0e0e0e ...... 17.24:1
 *                       Save border #a6a6a6 on #0e0e0e ..... 7.93:1
 *                       switch off #767676 on #0e0e0e ...... 4.25:1
 *                       switch on #f2f2f2 on #0e0e0e ....... 17.24:1
 *                       thumb off #0e0e0e on #767676 ....... 4.25:1
 *                       thumb on #0e0e0e on #f2f2f2 ........ 17.24:1
 *                       pill border #767676 on #0e0e0e ..... 4.25:1
 *
 * The hairline borders and the shadows are decorative only - nothing is
 * identified by them - so they are deliberately below 3:1. The Essential row's
 * locked switch is decorative too: it is `aria-hidden`, and the fact it conveys
 * is stated in the row's own text, so it is not the only carrier of that state.
 */

/* ==========================================================================
 * The palettes.
 *
 * The LIGHT preset is defined on `.bsw-banner` and `.bsw-reopen` themselves
 * rather than on `.bsw-theme-light`, and that is not shorthand. A full-page
 * cache can serve HTML rendered by the previous version of this plugin for
 * hours after an upgrade - markup with `class="bsw-banner"` and no theme class
 * at all. Defining the default on the element means that page still gets a
 * complete palette instead of a banner with `var()` resolving to nothing.
 *
 * `.bsw-theme-dark` scores the same 0-1-0, so it wins purely by coming later.
 * Keep it last.
 *
 * 🚨 The two blocks must declare the SAME properties in the SAME order.
 * BannerStyleTest compares the key lists, because a property declared in one
 * preset and not the other resolves to nothing in the other - and `var(--gone)`
 * on `color` computes to the inherited value, i.e. straight back to the host
 * theme's colour, on one preset only.
 * ========================================================================== */
.bsw-banner,
.bsw-reopen {
	--bsw-bg:              #ffffff;
	--bsw-fg:              #111111;
	--bsw-muted:           #595959;
	--bsw-hairline:        #e2e2e2;
	--bsw-btn-bg:          #141414;
	--bsw-btn-fg:          #ffffff;
	--bsw-btn-bg-hover:    #000000;
	--bsw-ghost-fg:        #141414;
	--bsw-ghost-border:    #595959;
	--bsw-ghost-bg-hover:  #f2f2f2;
	--bsw-track-off:       #767676;
	--bsw-knob-off:        #ffffff;
	--bsw-track-on:        #141414;
	--bsw-knob-on:         #ffffff;
	--bsw-accent:          #141414;
	--bsw-pill-border:     #767676;
	--bsw-shadow:          0 1px 2px rgba( 0, 0, 0, .08 ), 0 12px 40px rgba( 0, 0, 0, .16 );
	--bsw-pill-shadow:     0 1px 2px rgba( 0, 0, 0, .10 ), 0 4px 14px rgba( 0, 0, 0, .12 );
}

.bsw-theme-dark {
	--bsw-bg:              #0e0e0e;
	--bsw-fg:              #f2f2f2;
	--bsw-muted:           #a6a6a6;
	--bsw-hairline:        #2a2a2a;
	--bsw-btn-bg:          #f2f2f2;
	--bsw-btn-fg:          #0e0e0e;
	--bsw-btn-bg-hover:    #ffffff;
	--bsw-ghost-fg:        #f2f2f2;
	--bsw-ghost-border:    #a6a6a6;
	--bsw-ghost-bg-hover:  #262626;
	--bsw-track-off:       #767676;
	--bsw-knob-off:        #0e0e0e;
	--bsw-track-on:        #f2f2f2;
	--bsw-knob-on:         #0e0e0e;
	--bsw-accent:          #f2f2f2;
	--bsw-pill-border:     #767676;
	--bsw-shadow:          0 1px 2px rgba( 0, 0, 0, .50 ), 0 12px 40px rgba( 0, 0, 0, .65 );
	--bsw-pill-shadow:     0 1px 2px rgba( 0, 0, 0, .40 ), 0 4px 14px rgba( 0, 0, 0, .50 );
}

/* ==========================================================================
 * The card.
 * ========================================================================== */

#bsw-banner.bsw-banner {
	/*
	 * STRUCTURAL, and therefore defended. A theme rule as ordinary as
	 * `.elementor-element div { display: none !important }` would otherwise hide
	 * the banner from every visitor while the plugin went on reporting itself
	 * healthy - the worst failure this file can produce, because the site looks
	 * compliant from the server side and is not.
	 *
	 * `display` in particular: see the [hidden] rule below for why marking it
	 * important here is safe, and why it is the attribute selector rather than
	 * `!important` that decides which of the two wins.
	 *
	 * Bottom-LEFT, matching the withdrawal pill it temporarily occludes, and
	 * `inset-inline-end: auto` so the card sizes to its own width rather than
	 * stretching. That `auto` is as load-bearing as the two insets that are set:
	 * leave it at the old `0` and the card is a full-width bar again with a
	 * rounded corner.
	 */
	position: fixed !important;
	inset-block-end: 1rem !important;
	inset-inline-start: 1rem !important;
	inset-inline-end: auto !important;
	z-index: 99999 !important;
	display: flex !important;
	overflow-y: auto !important;

	/*
	 * Two width declarations, deliberately, in the same shape as the padding
	 * pair below: the first is a browser without `min()` support falling back to
	 * a fixed card, the second clamps it inside a narrow viewport. Order matters
	 * - an unsupported second declaration is dropped and the first survives.
	 */
	width: 27.5rem !important;
	width: min( 27.5rem, calc( 100vw - 2rem ) ) !important;

	/*
	 * Un-important on purpose. Nothing competes for these on an unknown theme,
	 * and leaving them overridable is what lets a future per-site tweak adjust
	 * the layout without having to out-!important us.
	 */
	flex-direction: column;
	align-items: stretch;
	gap: .625rem;
	/*
	 * 🚨 THE PAIR THAT KEEPS AN EXPANDED CARD ON SCREEN, and it is a pair: this
	 * cap plus the `overflow-y: auto` above. Since the two-layer change the card
	 * GROWS when "More information" is pressed - four detail regions on a site
	 * offering every category is a lot of new height - and on a short viewport an
	 * uncapped card runs its actions off the bottom of the screen with no way to
	 * scroll to them. The banner would then be one a visitor cannot answer.
	 *
	 * `overscroll-behavior: contain` stops that inner scroll chaining to the page
	 * behind it once it reaches the end.
	 */
	max-height: min( 85vh, calc( 100vh - 2rem ) );
	overscroll-behavior: contain;

	box-sizing: border-box !important;
	margin: 0 !important;
	padding: 1rem !important;

	background: var( --bsw-bg ) !important;
	background-image: none !important;
	color: var( --bsw-fg ) !important;
	border: 1px solid var( --bsw-hairline ) !important;
	border-radius: .875rem !important;
	box-shadow: var( --bsw-shadow ) !important;
	opacity: 1 !important;
	visibility: visible !important;

	/* The one inherited property, and the only one. */
	font-family: inherit;

	font-size: .875rem !important;
	font-weight: 400 !important;
	font-style: normal !important;
	line-height: 1.5 !important;
	letter-spacing: normal !important;
	text-transform: none !important;
	text-align: start !important;
	text-shadow: none !important;
}

/*
 * 🚨 The two `display` rules have to beat the host theme AND each other, in that
 * order. Read this before touching either.
 *
 * Outwards: the banner ships hidden and the client script decides visibility.
 * The `hidden` attribute is only a UA `display: none`, so ANY theme rule that
 * sets a display on this element - or on a broad `div` selector - beats it and
 * shows the banner to every visitor, including the ones who already answered.
 * The reverse is just as bad: `div { display: none !important }` is an ordinary
 * enough page-builder rule, and it would hide the banner from everyone while the
 * server-side scan went on reporting the site healthy. So BOTH declarations are
 * `!important`.
 *
 * Between themselves: two `!important` author declarations are settled by
 * specificity, and `[hidden]` puts this rule at 1-2-0 against the root rule's
 * 1-1-0. Hidden therefore wins, which is the direction that must never break -
 * a banner that cannot be dismissed is worse than one that never appears.
 *
 * Do not "simplify" either selector. Dropping the id from this one puts it at
 * 0-2-0, below the root rule, and the banner becomes undismissable.
 */
#bsw-banner.bsw-banner[hidden] {
	display: none !important;
}

/* ==========================================================================
 * THE TWO LAYERS.
 *
 * Both are in the cached HTML and exactly one is visible at a time - opening
 * layer 2 hides layer 1. That mutual exclusion is what keeps the
 * equal-prominence rule intact with two sets of buttons on the page, so it is
 * not a presentation detail: see BannerRenderer::actions().
 *
 * 🚨 TWO `display` RULES PER LAYER, both `!important`, `[hidden]` winning on
 * specificity - the same pattern as the banner root above, for the same reason.
 * `hidden` is only the UA stylesheet's `display: none`, so it is the weakest
 * declaration on the page and loses in BOTH directions to a host theme's
 * `div { display: none !important }`. That shipped broken once already, on the
 * layer-2 detail regions this replaced.
 * ========================================================================== */

#bsw-banner .bsw-layer {
	display: flex !important;
	flex-direction: column;
	gap: .625rem;
	box-sizing: border-box !important;
	width: auto !important;
	float: none !important;
	margin: 0 !important;
	padding: 0 !important;
	background: none !important;
	border: 0 !important;
}

/*
 * 🚨 Carries the id AND the attribute (1-2-0) so it outranks the rule above
 * (1-1-0). Do not simplify the selector: without `#bsw-banner` it falls to
 * 0-2-0, below the visible rule, and layer 2 is open for every visitor on every
 * cached page.
 */
#bsw-banner .bsw-layer[hidden] {
	display: none !important;
}

/* ==========================================================================
 * LAYER 1: the top strip, the title, the intro.
 *
 * The strip holds ONLY the escape route, right-aligned, with a hairline under
 * it. It is deliberately not on the title's line - the title is the first thing
 * read, and a control sharing its baseline competes with it.
 * ========================================================================== */

#bsw-banner .bsw-top {
	display: flex !important;
	justify-content: flex-end;
	box-sizing: border-box !important;
	width: auto !important;
	margin: 0 !important;
	padding: 0 0 .5rem !important;
	background: none !important;
	border: 0 !important;
	border-block-end: 1px solid var( --bsw-hairline ) !important;
}

#bsw-banner .bsw-title {
	display: block !important;
	box-sizing: border-box !important;
	margin: 0 !important;
	padding: 0 !important;
	background: none !important;
	border: 0 !important;
	color: var( --bsw-fg ) !important;
	font-family: inherit;
	font-size: .9375rem !important;
	font-weight: 600 !important;
	font-style: normal !important;
	line-height: 1.3 !important;
	letter-spacing: normal !important;
	text-transform: none !important;
	text-decoration: none !important;
	opacity: 1 !important;
}

/*
 * "Continue without accepting →".
 *
 * A text control rather than a fourth filled button, because three filled
 * buttons and this one would be four competing targets - but it is FULL
 * contrast, underlined, and sits at the top-right where the eye lands first.
 * It is not a quiet way to refuse; it is a fast one. The button it is quieter
 * than is Save, not Reject, and Reject is right there at the same weight as
 * Accept.
 *
 * 24px is the WCAG 2.5.8 target minimum; 28px here leaves room in a header that
 * has to sit on one line beside the title on a narrow card.
 */
#bsw-banner .bsw-dismiss {
	display: inline-flex !important;
	align-items: center;
	box-sizing: border-box !important;
	width: auto !important;
	min-height: 1.75rem !important;
	margin: 0 !important;
	padding: 0 !important;
	background: none !important;
	background-image: none !important;
	border: 0 !important;
	border-radius: 0 !important;
	box-shadow: none !important;
	opacity: 1 !important;
	color: var( --bsw-fg ) !important;
	font-family: inherit;
	font-size: .75rem !important;
	font-weight: 500 !important;
	font-style: normal !important;
	line-height: 1.3 !important;
	letter-spacing: normal !important;
	text-transform: none !important;
	text-decoration: underline !important;
	text-underline-offset: .15em;
	text-shadow: none !important;
	white-space: nowrap !important;
	cursor: pointer !important;
	-webkit-appearance: none !important;
	appearance: none !important;
}

#bsw-banner .bsw-dismiss:hover,
#bsw-banner .bsw-dismiss:focus {
	color: var( --bsw-fg ) !important;
}

#bsw-banner .bsw-dismiss:focus-visible {
	outline: 2px solid var( --bsw-accent ) !important;
	outline-offset: 2px !important;
}

/*
 * Decorative. The accessible name is the text, not the glyph.
 *
 * Colour is stated rather than inherited, even though this span sits inside a
 * button that already sets it: `color: inherit` anywhere in this file except the
 * inline withdrawal control is the regression that painted Accept and Reject
 * raspberry pink, and BannerStyleTest fails the build if it reappears.
 */
#bsw-banner .bsw-arrow {
	display: inline !important;
	/*
	 * The gap is a margin, not the space character in the markup. WP Rocket's HTML
	 * minifier collapses inter-element whitespace, so on the live site the label
	 * rendered as "Continue without accepting→" with the two touching. A margin
	 * survives minification.
	 */
	margin-inline-start: .25rem !important;
	color: var( --bsw-fg ) !important;
	background: none !important;
	font-size: inherit !important;
	font-weight: inherit !important;
	opacity: 1 !important;
}

/* ==========================================================================
 * The purpose sentence, and the two policy links.
 * ========================================================================== */

#bsw-banner .bsw-text {
	display: block !important;
	box-sizing: border-box !important;
	max-width: 68ch !important;
	margin: 0 !important;
	padding: 0 !important;
	background: none !important;
	border: 0 !important;
	color: var( --bsw-fg ) !important;
	font-family: inherit;
	/*
	 * 🚨 THE LARGEST BLOCK ON THE CARD, so it is where tightening pays best -
	 * it was three lines at 14px/21.7px, i.e. 65 of the card's 327px. 13px on a
	 * 1.45 leading, with the copy cut to land in two lines at this width.
	 *
	 * 12px is the floor for body text in this design; do not take it lower to
	 * win a line. Cut words instead - and see BannerRenderer for the two things
	 * in this sentence that are doing compliance work and must survive any
	 * rewrite.
	 */
	font-size: .8125rem !important;
	font-weight: 400 !important;
	line-height: 1.45 !important;
	letter-spacing: normal !important;
	text-transform: none !important;
	text-align: start !important;
	opacity: 1 !important;
}

/*
 * Both policy links keep their underline. Colour alone is not an accessible
 * affordance, and they are the same colour as the surrounding text by design -
 * there is no brand colour in either preset to tint them with.
 *
 * ONE rule for both. The cookie policy is the primary of the two - it is the
 * document that discharges the PECR duty - but "primary" is about which one is
 * named first in the sentence, not about making the other harder to see.
 */
#bsw-banner .bsw-policy,
#bsw-banner .bsw-privacy {
	display: inline !important;
	/*
	 * A margin rather than a separator character, and it is not cosmetic: with
	 * only the markup's single space between them, "Cookie policy Privacy policy"
	 * reads as one four-word link at a glance, and on a narrow card the wrap lands
	 * between them and makes it worse. Measured on the pilot before this was
	 * added. It goes on both, so the pair cannot be spaced asymmetrically, and a
	 * trailing margin at the end of the sentence is invisible.
	 */
	margin-inline-end: .5rem !important;
	/*
	 * 🚨 WCAG 2.2 Target Size (Minimum), 2.5.8 AA: 24x24 CSS px. At 12px on a 1.5
	 * leading these links measured 18 high, which is under it - a pre-existing
	 * miss rather than a regression from the size pass, but a miss.
	 *
	 * Fixed with vertical padding on the HIT AREA, not by growing the type: the
	 * 12px is deliberate and the card is deliberately compact. 3px each side takes
	 * 18 to 24 exactly. Padding on an inline box extends the painted and
	 * hit-tested region without changing the line box, so the row does not get
	 * taller and the visual weight is unchanged - measured, not assumed.
	 *
	 * 2.5.8's "Inline" exception would arguably cover these, since they are text
	 * in a line of text. We are not taking it: the exception exists for links
	 * inside running prose, and these are three discrete controls on a line of
	 * their own, which is a different thing to a visitor's thumb.
	 */
	padding-block: .1875rem !important;
	color: var( --bsw-fg ) !important;
	background: none !important;
	text-decoration: underline !important;
	text-underline-offset: .15em;
	font-family: inherit;
	font-size: inherit !important;
	font-weight: 500 !important;
	letter-spacing: normal !important;
	text-transform: none !important;
	opacity: 1 !important;
}

#bsw-banner .bsw-policy:focus-visible,
#bsw-banner .bsw-privacy:focus-visible {
	outline: 2px solid var( --bsw-accent ) !important;
	outline-offset: 2px !important;
}

/* ==========================================================================
 * LAYER 1: the inline category run.
 *
 * 🚨 ONE LINE OF NAME-AND-SWITCH PAIRS, flowing left to right and wrapping only
 * when the card is too narrow. NOT stacked rows, and no dividers between them -
 * that layout is what this replaced.
 *
 * There is deliberately NO rule here for a description, a hint or any secondary
 * text inside a pair, because layer 1 carries none. Every word of explanation
 * lives in layer 2. If you find yourself adding `.bsw-cat-desc`, the change has
 * gone wrong - see BannerRenderer and the test that asserts a pair's text is
 * exactly a category name.
 * ========================================================================== */

#bsw-banner .bsw-cats {
	display: flex !important;
	flex-wrap: wrap;
	align-items: center;
	gap: .5rem 1rem;
	box-sizing: border-box !important;
	width: auto !important;
	margin: 0 !important;
	padding: 0 !important;
	list-style: none !important;
	background: none !important;
	border: 0 !important;
}

#bsw-banner .bsw-cat {
	display: inline-flex !important;
	align-items: center;
	gap: .375rem;
	box-sizing: border-box !important;
	width: auto !important;
	float: none !important;
	margin: 0 !important;
	padding: 0 !important;
	background: none !important;
	border: 0 !important;
	color: var( --bsw-fg ) !important;
	cursor: pointer !important;
	font-family: inherit;
	font-size: .75rem !important;
	font-weight: 400 !important;
	line-height: 1.4 !important;
	letter-spacing: normal !important;
	text-transform: none !important;
	opacity: 1 !important;
}

/*
 * The Essential pair is not a control, so it does not offer a control's cursor.
 * It is also the one pair with no input in it at all - see BannerRenderer: an
 * `essential` entry in the consent record would be a category the client script
 * grants and denies, and essential cookies are not consented to.
 */
#bsw-banner .bsw-cat-locked {
	cursor: default !important;
}

#bsw-banner .bsw-cat-name {
	display: inline !important;
	color: var( --bsw-fg ) !important;
	background: none !important;
	font-family: inherit;
	font-size: .75rem !important;
	font-weight: 500 !important;
	font-style: normal !important;
	line-height: 1.4 !important;
	letter-spacing: normal !important;
	text-transform: none !important;
	text-decoration: none !important;
	opacity: 1 !important;
}

/* ==========================================================================
 * The links row: Cookie policy, Privacy policy, More information.
 *
 * "More information" is styled as a third link and is a real <button>, because
 * it opens a panel rather than navigating and a link with no href is not
 * keyboard operable. Only the LOOK is a link's.
 * ========================================================================== */

#bsw-banner .bsw-links {
	display: flex !important;
	flex-wrap: wrap;
	align-items: baseline;
	/*
	 * The row gap clears the 3px of vertical padding each control now carries, so
	 * two wrapped lines of links cannot have touching hit areas - adjacent targets
	 * that share an edge are ambiguous to tap even when each is big enough.
	 */
	gap: .5rem .75rem;
	box-sizing: border-box !important;
	width: auto !important;
	margin: 0 !important;
	padding: 0 !important;
	background: none !important;
	border: 0 !important;
	color: var( --bsw-muted ) !important;
	font-family: inherit;
	font-size: .75rem !important;
	line-height: 1.5 !important;
	text-align: start !important;
}

#bsw-banner .bsw-more {
	display: inline !important;
	box-sizing: border-box !important;
	width: auto !important;
	min-width: 0 !important;
	height: auto !important;
	margin: 0 !important;
	/* The same 24px target as the two links beside it. See .bsw-policy. */
	padding: .1875rem 0 !important;

	color: var( --bsw-fg ) !important;
	background: none !important;
	background-image: none !important;
	border: 0 !important;
	border-radius: 0 !important;
	box-shadow: none !important;
	opacity: 1 !important;

	font-family: inherit;
	font-size: .75rem !important;
	font-weight: 600 !important;
	font-style: normal !important;
	line-height: 1.5 !important;
	letter-spacing: normal !important;
	text-transform: none !important;
	text-decoration: underline !important;
	text-underline-offset: .2em !important;
	text-align: start !important;

	cursor: pointer !important;
	-webkit-appearance: none !important;
	appearance: none !important;
}

#bsw-banner .bsw-more:hover,
#bsw-banner .bsw-more:focus {
	color: var( --bsw-fg ) !important;
	background: none !important;
	text-decoration: underline !important;
}

#bsw-banner .bsw-more:focus-visible {
	outline: 2px solid var( --bsw-accent ) !important;
	outline-offset: 2px !important;
}

/* ==========================================================================
 * LAYER 2: the panel.
 * ========================================================================== */

#bsw-banner .bsw-panel-head {
	display: flex !important;
	align-items: center;
	justify-content: space-between;
	gap: 1rem;
	box-sizing: border-box !important;
	width: auto !important;
	margin: 0 !important;
	padding: 0 0 .5rem !important;
	background: none !important;
	border: 0 !important;
	border-block-end: 1px solid var( --bsw-hairline ) !important;
}

#bsw-banner .bsw-panel-title {
	display: block !important;
	box-sizing: border-box !important;
	margin: 0 !important;
	padding: 0 !important;
	background: none !important;
	border: 0 !important;
	color: var( --bsw-fg ) !important;
	font-family: inherit;
	font-size: .9375rem !important;
	font-weight: 600 !important;
	font-style: normal !important;
	line-height: 1.3 !important;
	letter-spacing: normal !important;
	text-transform: none !important;
	text-decoration: none !important;
	opacity: 1 !important;
}

/*
 * The ✕. It returns to layer 1 and records NOTHING - it is not a refusal and
 * not a dismissal of the banner. 44px, because a control this small is exactly
 * the one people miss.
 */
#bsw-banner .bsw-close {
	display: inline-flex !important;
	align-items: center;
	justify-content: center;
	flex: 0 0 auto;
	box-sizing: border-box !important;
	width: 2.25rem !important;
	min-width: 2.25rem !important;
	height: 2.25rem !important;
	min-height: 2.25rem !important;
	margin: 0 !important;
	padding: 0 !important;

	color: var( --bsw-fg ) !important;
	background: none !important;
	background-image: none !important;
	border: 0 !important;
	border-radius: .375rem !important;
	box-shadow: none !important;
	opacity: 1 !important;

	font-family: inherit;
	font-size: 1.125rem !important;
	font-weight: 400 !important;
	line-height: 1 !important;
	letter-spacing: normal !important;
	text-transform: none !important;
	text-decoration: none !important;

	cursor: pointer !important;
	-webkit-appearance: none !important;
	appearance: none !important;
}

#bsw-banner .bsw-close:hover,
#bsw-banner .bsw-close:focus {
	color: var( --bsw-fg ) !important;
	background: var( --bsw-ghost-bg-hover ) !important;
}

#bsw-banner .bsw-close:focus-visible {
	outline: 2px solid var( --bsw-accent ) !important;
	outline-offset: 2px !important;
}

#bsw-banner .bsw-close-glyph {
	display: block !important;
	color: var( --bsw-fg ) !important;
	background: none !important;
	font-family: inherit;
	font-size: 1.125rem !important;
	line-height: 1 !important;
	opacity: 1 !important;
}

/* ==========================================================================
 * The tabs.
 *
 * 🚨 The active tab is reached by `[aria-selected="true"]`, NOT by position.
 * Every positional selector form is banned in this file (BannerStyleTest) so
 * that nobody can single out one of the consent buttons, and a rule with an
 * exception for tabs is a rule with a hole in it. The attribute is also the
 * honest hook: it is what the accessibility tree reads, so the look and the
 * announcement cannot drift apart.
 * ========================================================================== */

#bsw-banner .bsw-tabs {
	display: flex !important;
	flex-wrap: wrap;
	align-items: stretch;
	gap: 0 1rem;
	box-sizing: border-box !important;
	width: auto !important;
	margin: 0 !important;
	padding: 0 !important;
	background: none !important;
	border: 0 !important;
	border-block-end: 1px solid var( --bsw-hairline ) !important;
}

#bsw-banner .bsw-tab {
	display: inline-flex !important;
	align-items: center;
	box-sizing: border-box !important;
	width: auto !important;
	min-width: 0 !important;
	height: auto !important;
	min-height: 2.25rem !important;
	margin: 0 0 -1px !important;
	padding: 0 !important;

	color: var( --bsw-muted ) !important;
	background: none !important;
	background-image: none !important;
	border: 0 !important;
	border-block-end: 2px solid transparent !important;
	border-radius: 0 !important;
	box-shadow: none !important;
	opacity: 1 !important;

	font-family: inherit;
	font-size: .75rem !important;
	font-weight: 600 !important;
	font-style: normal !important;
	line-height: 1.3 !important;
	letter-spacing: normal !important;
	text-transform: none !important;
	text-decoration: none !important;

	cursor: pointer !important;
	-webkit-appearance: none !important;
	appearance: none !important;
}

#bsw-banner .bsw-tab[aria-selected="true"] {
	color: var( --bsw-fg ) !important;
	border-block-end-color: var( --bsw-accent ) !important;
}

#bsw-banner .bsw-tab:focus-visible {
	outline: 2px solid var( --bsw-accent ) !important;
	outline-offset: 2px !important;
}

#bsw-banner .bsw-tabpanel {
	display: flex !important;
	flex-direction: column;
	gap: .375rem;
	box-sizing: border-box !important;
	width: auto !important;
	margin: 0 !important;
	padding: 0 !important;
	background: none !important;
	border: 0 !important;
}

/* Same pair, same reason, one level down. See the layer rules above. */
#bsw-banner .bsw-tabpanel[hidden] {
	display: none !important;
}

/* ==========================================================================
 * The category cards.
 * ========================================================================== */

#bsw-banner .bsw-card {
	display: block !important;
	box-sizing: border-box !important;
	width: auto !important;
	float: none !important;
	margin: 0 !important;
	padding: .625rem !important;
	background: none !important;
	border: 1px solid var( --bsw-hairline ) !important;
	border-radius: .5rem !important;
}

#bsw-banner .bsw-card-head {
	display: flex !important;
	align-items: flex-start;
	justify-content: space-between;
	gap: .625rem;
	box-sizing: border-box !important;
	width: auto !important;
	margin: 0 !important;
	padding: 0 !important;
	background: none !important;
	border: 0 !important;
}

#bsw-banner .bsw-card-copy {
	display: flex !important;
	flex-direction: column;
	gap: .1875rem;
	min-width: 0;
	box-sizing: border-box !important;
	margin: 0 !important;
	padding: 0 !important;
	background: none !important;
	border: 0 !important;
}

#bsw-banner .bsw-card-name {
	display: block !important;
	color: var( --bsw-fg ) !important;
	background: none !important;
	font-family: inherit;
	font-size: .8125rem !important;
	font-weight: 600 !important;
	font-style: normal !important;
	line-height: 1.35 !important;
	letter-spacing: normal !important;
	text-transform: none !important;
	text-decoration: none !important;
	opacity: 1 !important;
}

/*
 * The description. This is the only place the banner says what each purpose
 * DOES, so it is not decoration and it does not get the "incidental text" pass -
 * `--bsw-muted` clears WCAG AA against the card and BannerStyleTest measures it.
 */
#bsw-banner .bsw-card-desc {
	display: block !important;
	color: var( --bsw-muted ) !important;
	background: none !important;
	font-family: inherit;
	font-size: .75rem !important;
	font-weight: 400 !important;
	font-style: normal !important;
	line-height: 1.5 !important;
	letter-spacing: normal !important;
	text-transform: none !important;
	text-decoration: none !important;
	opacity: 1 !important;
}

/*
 * The chevron. 🚨 The only TOGGLE left in the banner, and therefore the only
 * control exposed to WP Rocket's replayed first click - see the guard in
 * consent.js. Drawn as a rotated border rather than a glyph font so it cannot
 * arrive as a missing-character box.
 */
#bsw-banner .bsw-chevron {
	display: inline-flex !important;
	align-items: center;
	justify-content: center;
	flex: 0 0 auto;
	box-sizing: border-box !important;
	width: 2.25rem !important;
	min-width: 2.25rem !important;
	height: 1.5rem !important;
	min-height: 1.5rem !important;
	margin: 0 !important;
	padding: 0 !important;

	color: var( --bsw-fg ) !important;
	background: none !important;
	background-image: none !important;
	border: 0 !important;
	border-radius: .375rem !important;
	box-shadow: none !important;
	opacity: 1 !important;

	cursor: pointer !important;
	-webkit-appearance: none !important;
	appearance: none !important;
}

#bsw-banner .bsw-chevron:focus-visible {
	outline: 2px solid var( --bsw-accent ) !important;
	outline-offset: 2px !important;
}

#bsw-banner .bsw-chevron-glyph {
	display: block !important;
	box-sizing: border-box !important;
	width: .5rem !important;
	height: .5rem !important;
	margin: -.1875rem 0 0 !important;
	padding: 0 !important;
	background: none !important;
	border: 0 !important;
	border-inline-end: 2px solid var( --bsw-fg ) !important;
	border-block-end: 2px solid var( --bsw-fg ) !important;
	opacity: 1 !important;
	transform: rotate( 45deg ) !important;
}

#bsw-banner .bsw-card-services {
	display: flex !important;
	flex-wrap: wrap;
	gap: .375rem;
	box-sizing: border-box !important;
	width: auto !important;
	margin: .625rem 0 0 !important;
	padding: .625rem 0 0 !important;
	background: none !important;
	border: 0 !important;
	border-block-start: 1px solid var( --bsw-hairline ) !important;
}

/* Same pair again. Read the layer rules above before touching either half. */
#bsw-banner .bsw-card-services[hidden] {
	display: none !important;
}

#bsw-banner .bsw-service {
	display: inline-block !important;
	box-sizing: border-box !important;
	margin: 0 !important;
	padding: .125rem .5rem !important;
	color: var( --bsw-fg ) !important;
	background: none !important;
	border: 1px solid var( --bsw-hairline ) !important;
	border-radius: 999px !important;
	font-family: inherit;
	font-size: .6875rem !important;
	font-weight: 500 !important;
	line-height: 1.5 !important;
	letter-spacing: normal !important;
	text-transform: none !important;
	opacity: 1 !important;
}

/* ==========================================================================
 * The Services tab: the flat list.
 * ========================================================================== */

#bsw-banner .bsw-service-row {
	display: flex !important;
	align-items: baseline;
	justify-content: space-between;
	gap: 1rem;
	box-sizing: border-box !important;
	width: auto !important;
	margin: 0 !important;
	padding: .5rem 0 !important;
	background: none !important;
	border: 0 !important;
	border-block-end: 1px solid var( --bsw-hairline ) !important;
}

#bsw-banner .bsw-service-name {
	display: block !important;
	color: var( --bsw-fg ) !important;
	background: none !important;
	font-family: inherit;
	font-size: .8125rem !important;
	font-weight: 500 !important;
	line-height: 1.4 !important;
	letter-spacing: normal !important;
	text-transform: none !important;
	opacity: 1 !important;
}

#bsw-banner .bsw-service-cat {
	display: block !important;
	color: var( --bsw-muted ) !important;
	background: none !important;
	font-family: inherit;
	font-size: .6875rem !important;
	font-weight: 400 !important;
	line-height: 1.4 !important;
	letter-spacing: normal !important;
	text-transform: none !important;
	opacity: 1 !important;
}

/* ==========================================================================
 * The switches.
 *
 * 🚨 These are `<input type="checkbox">` elements, drawn. Read the note at the
 * top of this file before replacing any of it with a div.
 *
 * The reset list is the one that used to force `appearance: auto`, kept and
 * extended: a theme or form plugin hiding the native input with `position:
 * absolute; opacity: 0; clip: rect(0 0 0 0)` leaves the consent toggles
 * invisible while still tabbable, which is worse than the wrong colour - the
 * visitor cannot see what they are choosing. The harness has a fixture that
 * does exactly that, and an e2e test that measures the rendered box.
 * ========================================================================== */

#bsw-banner input[data-bsw-category-toggle] {
	-webkit-appearance: none !important;
	appearance: none !important;
	/*
	 * `display` belongs in this reset list and was missing from it. The rest of
	 * the list defends against a theme hiding native inputs with `opacity: 0`,
	 * `visibility: hidden` or `clip` - `input { display: none !important }` is
	 * the same move by the fourth route, and it takes the consent switches off
	 * the page entirely while leaving the rest of the card looking healthy.
	 * Found by the audit that followed the layer-2 display bug; the two are the
	 * same class of failure.
	 */
	display: inline-block !important;
	position: relative !important;
	clip: auto !important;
	clip-path: none !important;
	flex: 0 0 auto;
	box-sizing: border-box !important;
	/*
	 * 40x24. 🚨 24 IS THE FLOOR, not a starting point - WCAG 2.2 Target Size
	 * (Minimum), 2.5.8 AA, is 24x24 CSS px and the short axis is now exactly on
	 * it. Nothing here may get smaller; a test measures every interactive
	 * control against 24 so that a future tightening pass fails rather than
	 * quietly crossing it.
	 */
	width: 2.5rem !important;
	height: 1.5rem !important;
	min-width: 2.5rem !important;
	min-height: 1.5rem !important;
	margin: 0 !important;
	padding: 0 !important;
	background: var( --bsw-track-off ) !important;
	background-image: none !important;
	border: 1px solid var( --bsw-track-off ) !important;
	border-radius: 999px !important;
	box-shadow: none !important;
	opacity: 1 !important;
	visibility: visible !important;
	transform: none !important;
	vertical-align: middle !important;
	cursor: pointer !important;
	transition: background-color .15s ease, border-color .15s ease !important;
}

/*
 * The thumb. Its POSITION is what says on or off, not its colour - so the state
 * survives a visitor who cannot distinguish the two track greys, and it is the
 * same affordance every native switch uses.
 */
#bsw-banner input[data-bsw-category-toggle]::before {
	content: "" !important;
	position: absolute !important;
	inset-block-start: 50% !important;
	inset-inline-start: .1875rem !important;
	display: block !important;
	box-sizing: border-box !important;
	width: 1rem !important;
	height: 1rem !important;
	background: var( --bsw-knob-off ) !important;
	background-image: none !important;
	border-radius: 50% !important;
	box-shadow: none !important;
	opacity: 1 !important;
	/*
	 * `transform`, not an inset, because transform is the property that is
	 * reliably animatable and because the reduced-motion block below can then
	 * switch one transition off rather than two.
	 */
	transform: translateY( -50% ) !important;
	transition: transform .15s ease, background-color .15s ease !important;
}

#bsw-banner input[data-bsw-category-toggle]:checked {
	background: var( --bsw-track-on ) !important;
	border-color: var( --bsw-track-on ) !important;
}

#bsw-banner input[data-bsw-category-toggle]:checked::before {
	background: var( --bsw-knob-on ) !important;
	transform: translate( 1rem, -50% ) !important;
}

#bsw-banner input[data-bsw-category-toggle]:focus-visible {
	outline: 2px solid var( --bsw-accent ) !important;
	outline-offset: 2px !important;
}

/*
 * The Essential row's locked switch. Decorative: the element is `aria-hidden`,
 * and the row's own text says "Always active", so this is never the only place
 * the state is stated. It is drawn in the ON position and given no hover, no
 * focus ring and no pointer cursor, because it is not a control and must not
 * read as a disabled one either - a greyed-out switch invites a click that will
 * never work.
 *
 * 🚨 IT IS PAINTED IN THE **ON** COLOURS, and it reads `--bsw-track-on` /
 * `--bsw-knob-on` DIRECTLY rather than through locked-specific variables of its
 * own. That indirection is what caused the bug this comment now guards against.
 *
 * There used to be `--bsw-locked-track` and `--bsw-locked-knob`, and
 * `--bsw-locked-track` was set to `#767676` in both presets - byte-identical to
 * `--bsw-track-off`. So the one row that is PERMANENTLY ACTIVE was painted the
 * same colour as every row that is switched OFF, with nothing but the thumb's
 * position telling them apart, directly contradicting the "always active" the
 * row's own text states. Measured side by side on `/s/tags-and-sitekit`: a
 * checked switch went `rgb(20,20,20)`, the locked graphic stayed
 * `rgb(118,118,118)`.
 *
 * Pointing at the shared variables makes that drift structurally impossible
 * rather than merely tested: there is no second value left to fall out of step.
 * Do not reintroduce locked-specific colour variables to "allow tuning" - if the
 * locked graphic ever needs to differ from an on switch, the thing to change is
 * what it CONVEYS, and that argument belongs in the row's text.
 */
#bsw-banner .bsw-locked {
	position: relative !important;
	display: block !important;
	flex: 0 0 auto;
	box-sizing: border-box !important;
	/* Matches the real switches exactly - see the note on the input rule. */
	width: 2.5rem !important;
	height: 1.5rem !important;
	margin: 0 !important;
	padding: 0 !important;
	background: var( --bsw-track-on ) !important;
	background-image: none !important;
	border: 1px solid var( --bsw-track-on ) !important;
	border-radius: 999px !important;
	box-shadow: none !important;
	opacity: 1 !important;
}

#bsw-banner .bsw-locked::before {
	content: "" !important;
	position: absolute !important;
	inset-block-start: 50% !important;
	inset-inline-start: .1875rem !important;
	display: block !important;
	box-sizing: border-box !important;
	width: 1rem !important;
	height: 1rem !important;
	background: var( --bsw-knob-on ) !important;
	background-image: none !important;
	border-radius: 50% !important;
	box-shadow: none !important;
	opacity: 1 !important;
	transform: translate( 1rem, -50% ) !important;
}

/* ==========================================================================
 * The actions.
 * ========================================================================== */

#bsw-banner .bsw-actions {
	display: flex !important;
	flex-wrap: wrap;
	align-items: stretch;
	gap: .5rem;
	box-sizing: border-box !important;
	width: auto !important;
	margin: 0 !important;
	padding: 0 !important;
	background: none !important;
	border: 0 !important;
}

/* ==========================================================================
 * The two consent buttons.
 *
 * 🚨 ONE rule for both. Accept and Reject are identical in element, class,
 * container, size, weight, contrast, padding, border, radius, hover and focus.
 * Do not add a selector that reaches one of them - not by name, not by
 * position. See the note at the top of this file.
 *
 * `flex: 1 1 0` puts them on one line and makes them EXACTLY equal in width,
 * which `flex: 1 1 auto` does not: with an `auto` basis each button starts from
 * its own label width and only the leftover space is shared, so "Accept all"
 * and "Reject all" came out 217.5px and 212.5px on the pilot. Five pixels is
 * not a dark pattern, but the whole point of this pair is that there is nothing
 * to argue about, and a zero basis costs nothing.
 *
 * 🚨 ALL THREE ACTIONS SHARE ONE ROW: Save, Reject, Accept. `.bsw-secondary`
 * below carries the SAME `flex: 1 1 0` and the same min-width, so the three are
 * equal thirds of the row and - the part that matters - Reject and Accept are
 * exactly equal to each other with a third button sitting beside them. Save
 * used to carry `flex-basis: 100%`, which pushed it onto a line of its own;
 * that is what this replaced.
 *
 * The card is 33rem so the three fit without the labels wrapping. Do not narrow
 * it back without re-measuring: a label that wraps to two lines makes ONE
 * button taller than the others, and on Accept or Reject that is the
 * equal-prominence invariant broken by a layout accident. `white-space: nowrap`
 * makes that failure loud rather than silent, and an e2e test measures the
 * rendered heights and the shared row.
 * ========================================================================== */
#bsw-banner .bsw-btn {
	display: inline-flex !important;
	align-items: center;
	justify-content: center;
	flex: 1 1 0;
	box-sizing: border-box !important;
	width: auto !important;
	min-width: 7.5rem !important;
	height: auto !important;
	/*
	 * 36px. WCAG 2.2 Target Size (Minimum), 2.5.8 AA, asks for 24x24 CSS px -
	 * these are ~130 wide by 36 high, so comfortably clear of it with room for
	 * the label. 44px is the iOS HIG / WCAG 2.5.5 AAA figure, which this
	 * deliberately no longer meets: the owner asked for a smaller card and AAA
	 * is not the bar this design is held to. Do NOT go below 24.
	 */
	min-height: 2.25rem !important;
	margin: 0 !important;
	padding: .5rem .75rem !important;
	white-space: nowrap !important;

	color: var( --bsw-btn-fg ) !important;
	background: var( --bsw-btn-bg ) !important;
	background-image: none !important;
	border: 1px solid var( --bsw-btn-bg ) !important;
	border-radius: .375rem !important;
	box-shadow: none !important;
	opacity: 1 !important;
	filter: none !important;
	transform: none !important;

	font-family: inherit;
	font-size: .8125rem !important;
	font-weight: 600 !important;
	font-style: normal !important;
	line-height: 1.2 !important;
	letter-spacing: .01em !important;
	text-transform: none !important;
	text-decoration: none !important;
	text-shadow: none !important;
	text-align: center !important;

	cursor: pointer !important;
	-webkit-appearance: none !important;
	appearance: none !important;
	transition: background-color .15s ease, border-color .15s ease !important;
}

#bsw-banner .bsw-btn:hover,
#bsw-banner .bsw-btn:focus {
	color: var( --bsw-btn-fg ) !important;
	background: var( --bsw-btn-bg-hover ) !important;
	border-color: var( --bsw-btn-bg-hover ) !important;
}

#bsw-banner .bsw-btn:focus-visible {
	outline: 2px solid var( --bsw-accent ) !important;
	outline-offset: 2px !important;
}

/* ==========================================================================
 * "Save settings" - the de-emphasised third action.
 *
 * Outlined rather than filled, and FIRST in a row of three rather than on a
 * line of its own. Same element, same flex sizing, same height, same target
 * size, same font as the pair beside it - the ONLY differences are the fill and
 * the border, which is what "de-emphasised" is allowed to mean here. It is
 * still a 44px target with an AA-contrast label; a quiet button is not a hidden
 * one.
 *
 * 🚨 This class must never be put on Accept or Reject. BannerRendererTest
 * asserts their class attribute is exactly "bsw-btn" under every preset, which
 * is what makes that impossible to do by accident.
 * ========================================================================== */
#bsw-banner .bsw-secondary {
	display: inline-flex !important;
	align-items: center;
	justify-content: center;
	flex: 1 1 0;
	box-sizing: border-box !important;
	width: auto !important;
	min-width: 7.5rem !important;
	height: auto !important;
	/* Same 36px as the pair beside it - see the note on .bsw-btn. */
	min-height: 2.25rem !important;
	margin: 0 !important;
	padding: .5rem .75rem !important;
	white-space: nowrap !important;

	color: var( --bsw-ghost-fg ) !important;
	background: transparent !important;
	background-image: none !important;
	border: 1px solid var( --bsw-ghost-border ) !important;
	border-radius: .375rem !important;
	box-shadow: none !important;
	opacity: 1 !important;
	filter: none !important;
	transform: none !important;

	font-family: inherit;
	font-size: .8125rem !important;
	font-weight: 600 !important;
	font-style: normal !important;
	line-height: 1.2 !important;
	letter-spacing: .01em !important;
	text-transform: none !important;
	text-decoration: none !important;
	text-shadow: none !important;
	text-align: center !important;

	cursor: pointer !important;
	-webkit-appearance: none !important;
	appearance: none !important;
	transition: background-color .15s ease, border-color .15s ease !important;
}

#bsw-banner .bsw-secondary:hover,
#bsw-banner .bsw-secondary:focus {
	color: var( --bsw-ghost-fg ) !important;
	background: var( --bsw-ghost-bg-hover ) !important;
	border-color: var( --bsw-ghost-fg ) !important;
}

#bsw-banner .bsw-secondary:focus-visible {
	outline: 2px solid var( --bsw-accent ) !important;
	outline-offset: 2px !important;
}

/* ==========================================================================
 * The withdrawal control.
 * ========================================================================== */

/*
 * The INLINE variant, rendered by [bulldogs_cookie_settings]. The site has put
 * this inside its own furniture - a footer menu, a legal column - so it is a
 * text control that INHERITS colour and font on purpose.
 *
 * That is not the inheritance this file exists to stop. An underlined word in a
 * footer taking the footer's link colour is correct; it is a consent BUTTON
 * taking an unrelated colour that is the ICO problem. What is defended here is
 * only the set that would stop it reading as text at all: a theme that styles
 * every `button` as a padded block would otherwise drop a grey slab into a
 * footer menu.
 */
.bsw-reopen[data-bsw-action="reopen"] {
	display: inline;
	box-sizing: border-box !important;
	margin: 0 !important;
	padding: 0 !important;
	background: none !important;
	background-image: none !important;
	border: 0 !important;
	border-radius: 0 !important;
	box-shadow: none !important;
	opacity: 1 !important;
	color: inherit;
	font: inherit;
	text-decoration: underline !important;
	text-underline-offset: .15em;
	text-transform: none !important;
	letter-spacing: normal !important;
	cursor: pointer !important;
	-webkit-appearance: none !important;
	appearance: none !important;
}

.bsw-reopen[data-bsw-action="reopen"]:focus-visible {
	outline: 2px solid currentColor !important;
	outline-offset: 2px !important;
}

/*
 * The FIXED variant, printed by ConsentModule when nothing else on the page
 * offers a route back.
 *
 * Bottom-LEFT, not bottom-right: live-chat widgets, back-to-top buttons and
 * cookie-bot leftovers all colonise the bottom-right corner, and a control that
 * lands under one of those is the discoverability problem again with extra
 * steps.
 *
 * Selector is 0-3-0 because there is no id out here to lean on. It sits below
 * the banner's own z-index on purpose: with the banner open, the pill is simply
 * occluded by it. Hiding it instead would take the focus target away from
 * hideBanner()'s return path.
 */
.bsw-reopen.bsw-reopen-fixed[data-bsw-action="reopen"] {
	position: fixed !important;
	inset-block-end: 1rem !important;
	inset-inline-start: 1rem !important;
	inset-inline-end: auto !important;
	z-index: 99998 !important;

	display: inline-flex !important;
	align-items: center !important;
	box-sizing: border-box !important;
	width: auto !important;
	max-width: calc( 100vw - 2rem ) !important;
	min-height: 2.25rem !important;
	margin: 0 !important;
	padding: .4375rem .8125rem !important;

	background: var( --bsw-bg ) !important;
	background-image: none !important;
	color: var( --bsw-fg ) !important;
	border: 1px solid var( --bsw-pill-border ) !important;
	border-radius: 999px !important;
	box-shadow: var( --bsw-pill-shadow ) !important;
	opacity: 1 !important;

	font-family: inherit;
	font-size: .75rem !important;
	font-weight: 500 !important;
	font-style: normal !important;
	line-height: 1.2 !important;
	letter-spacing: .01em !important;
	text-transform: none !important;
	text-decoration: none !important;
	text-shadow: none !important;
	white-space: nowrap !important;
	transition: background-color .15s ease, border-color .15s ease !important;
}

.bsw-reopen.bsw-reopen-fixed[data-bsw-action="reopen"]:hover,
.bsw-reopen.bsw-reopen-fixed[data-bsw-action="reopen"]:focus {
	border-color: var( --bsw-fg ) !important;
}

.bsw-reopen.bsw-reopen-fixed[data-bsw-action="reopen"]:focus-visible {
	outline: 2px solid var( --bsw-accent ) !important;
	outline-offset: 2px !important;
}

/*
 * The pill is the only control here the client script ever hides - it does so
 * when the page already carries a working legacy Usercentrics link. 0-4-0, so it
 * beats the positioning rule above.
 */
.bsw-reopen.bsw-reopen-fixed[data-bsw-action="reopen"][hidden] {
	display: none !important;
}

/* ==========================================================================
 * Narrow viewports.
 *
 * The card goes near-full-width and every button goes full width TOGETHER -
 * there is no width rule here that can reach one of the two consent buttons on
 * its own.
 * ========================================================================== */
@media ( max-width: 30rem ) {
	#bsw-banner.bsw-banner {
		inset-inline: .5rem !important;
		inset-block-end: .5rem !important;
		width: auto !important;
		gap: .75rem;
		padding: 1rem !important;
		border-radius: .75rem !important;
		max-height: min( 85vh, calc( 100vh - 1rem ) );
	}

	#bsw-banner .bsw-btn,
	#bsw-banner .bsw-secondary {
		flex: 1 1 100%;
		width: 100% !important;
	}
}

@media ( prefers-reduced-motion: reduce ) {
	#bsw-banner .bsw-btn,
	#bsw-banner .bsw-secondary,
	#bsw-banner input[data-bsw-category-toggle],
	#bsw-banner input[data-bsw-category-toggle]::before,
	.bsw-reopen.bsw-reopen-fixed[data-bsw-action="reopen"] {
		transition: none !important;
	}
}

/* Neither belongs on paper, and the fixed pill would print on every page. */
@media print {
	#bsw-banner.bsw-banner,
	.bsw-reopen.bsw-reopen-fixed[data-bsw-action="reopen"] {
		display: none !important;
	}
}
