/*
 * Phase 12 (section C): the accessibility toolbar's appearance, and every visual consequence of its settings.
 *
 * ================================================================================================================
 * WHY ALL OF IT IS HERE AND NONE OF IT IS IN THE SCRIPT.
 *
 * The response CSP is style-src 'self' with no nonce and no 'unsafe-inline', so the toolbar cannot inject a STYLE ELEMENT
 * or set a style attribute. The script's entire job is to set `data-a11y-*` attributes on <html>; everything
 * a visitor sees as a result is a rule in this file.
 *
 * That constraint produced a better design than a free hand would have. The styling is reviewable in one place, it
 * cannot be rewritten at runtime by anything that manages to run on the page, and the set of things the toolbar can
 * do to a layout is bounded by what is written here.
 *
 * ================================================================================================================
 * THIS FILE IS SHARED, BYTE FOR BYTE, between the storefront tree and the administration tree.
 *
 * AccessibilityAssetParityTest asserts the two copies are identical. It is deliberately free of design tokens for
 * that reason: it must not depend on `--brand` existing, because the administration does not define it and the
 * storefront's value differs per theme. So the toolbar's own chrome uses its own literal values, and the SETTINGS
 * (contrast, spacing, focus) act on generic element selectors that exist on every surface.
 *
 * ================================================================================================================
 * COLOUR IS NEVER THE ONLY SIGNAL. Every toggle carries a tick glyph when it is pressed, driven by [aria-pressed],
 * so "on" survives greyscale, a colour-blind reader, and the toolbar's own greyscale mode.
 * ================================================================================================================
 */

/* ---------------------------------------------------------------- the toolbar's own chrome */

.a11y-toolbar {
	position: fixed;

	/*
	 * BOTTOM INLINE-START, and that is a deliberate choice rather than an aesthetic one.
	 *
	 * Primary actions live at the inline-END of a bar in this product (the checkout's continue button, the cart's
	 * update control, the mobile navigation's menu). A floating control in that corner is the classic overlay defect:
	 * it sits on top of the one button the visitor came to press. Inline-start keeps it clear of all of them, in both
	 * directions, because `inset-inline-start` follows `dir` and needs no mirrored rule for Hebrew.
	 */
	inset-block-end: 1rem;
	inset-inline-start: 1rem;
	z-index: 900;
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: 0.5rem;
	font-family: system-ui, "Segoe UI", "Noto Sans Hebrew", Arial, sans-serif;
	font-size: 0.95rem;
	line-height: 1.5;
}

.a11y-toggle {
	display: inline-flex;
	align-items: center;
	gap: 0.4rem;

	/*
	 * At least 44x44 CSS px of target, which is the WCAG 2.2 AA minimum for a pointer target and the size a person
	 * with a tremor can actually hit. The padding rather than a fixed height keeps it correct when text is scaled.
	 */
	min-block-size: 2.75rem;
	min-inline-size: 2.75rem;
	padding-block: 0.55rem;
	padding-inline: 0.9rem;
	border: 2px solid #10253f;
	border-radius: 999px;
	background: #fff;
	color: #10253f;
	font: inherit;
	font-weight: 600;
	cursor: pointer;
	box-shadow: 0 2px 8px rgb(0 0 0 / 25%);
}

.a11y-toggle:hover {
	background: #10253f;
	color: #fff;
}

/*
 * `hidden` MUST WIN over the `display` below.
 *
 * The `hidden` attribute works through a user-agent rule whose specificity is the lowest that exists, so the
 * `display: flex` in the next rule defeats it outright: `panel.hidden = true` set the property and the panel stayed
 * on screen — open on every page load, over the checkout button on a phone, with Escape apparently doing nothing.
 * Three of the toolbar's own tests failed on it, which is what they are for.
 */
.a11y-panel[hidden] {
	display: none !important;
}

.a11y-panel {
	display: flex;
	flex-direction: column;
	gap: 0.35rem;
	inline-size: 16rem;

	/*
	 * The panel must never be taller than the viewport, because at 200% text it would otherwise push its own Reset
	 * button off the screen — and a settings panel whose Reset cannot be reached is worse than no panel.
	 */
	max-block-size: calc(100vh - 6rem);
	overflow-y: auto;
	padding: 0.75rem;
	border: 2px solid #10253f;
	border-radius: 10px;
	background: #fff;
	color: #10253f;
	box-shadow: 0 4px 16px rgb(0 0 0 / 30%);
}

.a11y-option {
	display: block;
	inline-size: 100%;
	min-block-size: 2.5rem;
	padding-block: 0.45rem;
	padding-inline: 0.6rem;
	border: 1px solid #8c9bad;
	border-radius: 6px;
	background: #f4f7fb;
	color: #10253f;
	font: inherit;
	text-align: start;
	cursor: pointer;
}

.a11y-option:hover {
	background: #e3ebf5;
}

/* THE STATE IS A GLYPH, not a colour. This is what survives greyscale and colour blindness. */
.a11y-option[aria-pressed="true"]::before {
	content: "✓ ";
	font-weight: 700;
}

.a11y-option[aria-pressed="true"] {
	border-color: #10253f;
	background: #d6e4f5;
	font-weight: 600;
}

.a11y-reset {
	margin-block-start: 0.35rem;
	border-color: #10253f;
	background: #fff;
	font-weight: 600;
}

.a11y-statement-link {
	display: block;
	margin-block-start: 0.5rem;
	padding-block: 0.35rem;
	color: #10253f;
	text-decoration: underline;
}

/* The live region: announced, never seen. */
.a11y-status {
	position: absolute;
	inline-size: 1px;
	block-size: 1px;
	margin: -1px;
	padding: 0;
	overflow: hidden;
	clip-path: inset(50%);
	white-space: nowrap;
}

/* ---------------------------------------------------------------- the settings themselves */

/*
 * TEXT SIZE. Steps on the ROOT font size, which works because the storefront's every font size is in `rem` and the
 * administration inherits Bootstrap's rem scale. Percentages rather than fixed pixels on purpose: a visitor who has
 * already raised their browser's default gets larger again from where THEY are, instead of being reset to our idea
 * of normal.
 */
:root[data-a11y-text="1"] { font-size: 112.5%; }
:root[data-a11y-text="2"] { font-size: 125%; }
:root[data-a11y-text="3"] { font-size: 150%; }
:root[data-a11y-text="4"] { font-size: 175%; }

/*
 * HIGH CONTRAST. Deliberately a small, generic set of declarations: forcing a palette onto every component is how an
 * overlay makes a site unusable. Black on white, a visible border on anything interactive, and links that stay
 * distinguishable.
 */
:root[data-a11y-contrast="on"] body {
	background: #fff;
	color: #000;
}

:root[data-a11y-contrast="on"] :where(p, li, td, th, dd, dt, label, legend, figcaption, small) {
	color: #000;
}

:root[data-a11y-contrast="on"] :where(h1, h2, h3, h4, h5, h6) {
	color: #000;
}

:root[data-a11y-contrast="on"] :where(a) {
	color: #00308f;
	text-decoration: underline;
}

:root[data-a11y-contrast="on"] :where(button, input, select, textarea) {
	border: 2px solid #000;
	background: #fff;
	color: #000;
}

/*
 * ENHANCED FOCUS. The product already has a visible focus indicator; this makes it unmistakable for somebody who
 * needs it larger. `:focus-visible` rather than `:focus`, so a mouse click does not paint a ring nobody asked for.
 */
:root[data-a11y-focus="on"] :where(a, button, input, select, textarea, summary, [tabindex]):focus-visible {
	outline: 4px solid #a4100f;
	outline-offset: 3px;
}

/* UNDERLINE LINKS: for a reader who cannot rely on colour to tell a link from text. */
:root[data-a11y-links="on"] :where(a) {
	text-decoration: underline;
	text-decoration-thickness: 2px;
	text-underline-offset: 2px;
}

/*
 * READABLE FONT. Local and system faces only — nothing is fetched, which keeps the promise that this toolbar makes no
 * network request. Arial and Verdana are the two most widely installed faces with open letterforms, and the Hebrew
 * fallbacks come first so Hebrew text does not lose its shaping.
 */
:root[data-a11y-font="on"] :where(body, button, input, select, textarea) {
	font-family: "Noto Sans Hebrew", "Arial Hebrew", Arial, Verdana, system-ui, sans-serif;
	letter-spacing: 0.01em;
}

/*
 * SPACING. Only the four properties WCAG 2.1's "Text Spacing" criterion names, at its values, and applied to text
 * containers rather than to everything — a global line-height change breaks buttons and table cells.
 */
:root[data-a11y-spacing="on"] :where(p, li, dd, dt, blockquote, figcaption) {
	margin-block-end: 2em;
	line-height: 1.8;
	letter-spacing: 0.12em;
	word-spacing: 0.16em;
}

/*
 * REDUCED MOTION from the toolbar. The product already honours the operating system's own
 * `prefers-reduced-motion: reduce` (below) — this is for the visitor whose system setting says one thing and who
 * wants something else on this site.
 *
 * `0.01ms` rather than `0` because a zero duration cancels the transitionend/animationend events some components
 * wait for, and cancelling those leaves a component stuck half-open. This is the standard remedy.
 */
:root[data-a11y-motion="on"] *,
:root[data-a11y-motion="on"] *::before,
:root[data-a11y-motion="on"] *::after {
	transition-duration: 0.01ms !important;
	animation-duration: 0.01ms !important;
	animation-iteration-count: 1 !important;
	scroll-behavior: auto !important;
}

/*
 * GREYSCALE. Offered because the brief allows it only if it is clean, and this is the clean version: one filter on
 * one element.
 *
 * IT MUST BE ON `:root` AND NOT ON `body`, and that is a correctness requirement rather than a preference. Any `filter`
 * other than `none` makes its element a containing block for fixed-positioned descendants — so with the filter on
 * `body`, the toolbar (`position: fixed`) stopped being pinned to the viewport and was laid out against the document
 * instead: measured on WebKit at 360×800, the viewport was 800 tall and the toolbar's top was at 1176, parked at the
 * bottom of the page and scrolled out of reach. Turning on the grayscale aid removed the panel that turned it on, and
 * detached the consent banner and every sticky element with it.
 *
 * The specification exempts the document root element from that rule, which is why this works and `body` cannot. The
 * toolbar therefore goes grey along with everything else, and stays usable because every toggle carries a tick glyph
 * rather than a colour for its state — the same glyph the colour-is-never-the-only-signal rule already required.
 */
:root[data-a11y-gray="on"] {
	filter: grayscale(100%);
}

/* ---------------------------------------------------------------- the operating system's own preference */

/*
 * Honoured whether or not the toolbar is used, and honoured FIRST: a visitor who has asked their system for reduced
 * motion has already told us, and should not have to find a widget to be believed.
 */
@media (prefers-reduced-motion: reduce) {
	*,
	*::before,
	*::after {
		transition-duration: 0.01ms !important;
		animation-duration: 0.01ms !important;
		animation-iteration-count: 1 !important;
		scroll-behavior: auto !important;
	}
}

/* ---------------------------------------------------------------- narrow screens and large text */

@media (width <= 30rem) {
	.a11y-toolbar {
		inset-block-end: 0.5rem;
		inset-inline-start: 0.5rem;
	}

	/*
	 * The panel takes the width it needs rather than a fixed 16rem, so it cannot push the page sideways on a 320px
	 * screen — horizontal overflow is the thing the browser gate measures and the thing that makes a phone unusable.
	 */
	.a11y-panel {
		inline-size: calc(100vw - 1.5rem);
		max-inline-size: 20rem;
	}
}

@media print {
	.a11y-toolbar {
		display: none;
	}
}
