/**
 * Search pill - the shared component
 *
 * One implementation, three users: the header search, the blog hero search and
 * searchform.php (anything that calls get_search_form()). Before this file
 * existed there were two independent copies, which is why the same overflow
 * bug had to be fixed twice - the header on 2026-08-28 and the blog on
 * 2026-08-29, the second only because someone noticed it separately.
 *
 * WHAT THIS FILE OWNS
 *
 * Everything structural: the flex row, the inset hairline, the field's cascade
 * defences against Astra, the button's geometry, hover, focus and reduced
 * motion. If a rule would be identical in two places, it belongs here.
 *
 * WHAT AN INSTANCE OWNS
 *
 * Custom properties only. An instance sets tokens; it does not re-declare
 * behaviour. That is the whole point of the split, and it is what keeps the
 * three in step:
 *
 *     --ml-search-radius       corner radius (and the button's right corners)
 *     --ml-search-height       pill height
 *     --ml-search-bg           pill background
 *     --ml-search-btn-width    submit button width
 *     --ml-search-font         field font size
 *     --ml-search-pad          field padding
 *     --ml-search-ring         the inset hairline (state-driven)
 *     --ml-search-glow         the focus ring (state-driven)
 *     --ml-search-shadow       optional drop shadow
 *     --ml-search-icon         submit icon at rest
 *     --ml-search-icon-active  submit icon on hover and focus
 *
 * The header sets a full-round radius; the blog keeps the theme's 8px. That is
 * the only difference either of them needs to state.
 *
 * TOKENS IN THE box-shadow LIST
 *
 * The three shadow slots are always present and always in the same order, so a
 * state only has to change the slot it cares about. Their "off" values are
 * `0 0 0 0 transparent`, NOT `none` - `none` is illegal inside a box-shadow
 * list and would invalidate the whole declaration, taking the hairline with
 * it.
 *
 * ASTRA
 *
 * Astra reaches the field through `input[type="search"]` at (0,1,1) and the
 * button through a bare `button` rule. The selectors here are (0,2,1), which
 * wins on specificity alone, independent of stylesheet order.
 *
 * Specificity is only half of it. A rule wins the properties it NAMES, and the
 * blog's old block had the right specificity yet still lost `width`, `height`,
 * `border-radius` and `box-shadow` simply by not mentioning them. Astra's
 * `width: 100%` was the one that broke the row: with `flex: 1 1 auto` the basis
 * comes from `width`, so the field claimed the whole content box and pushed the
 * button out of the pill. Every property Astra sets on an input is therefore
 * declared explicitly below, whether or not it currently looks necessary.
 */

.ml-search {
	--ml-search-radius: var(--ml-radius);
	--ml-search-height: 48px;
	--ml-search-bg: var(--ml-white);
	--ml-search-btn-width: 58px;
	--ml-search-font: 14.5px;
	--ml-search-pad: 0 18px;

	/*
	 * The submit is an icon inside the field, not a coloured block. At rest it
	 * carries the same ink as the field's text, so the pill reads as one
	 * continuous control.
	 *
	 * --ml-search-icon-active is BRAND CYAN as of 2026-09-03, changed from
	 * #0077B6 by the site owner with the measurements in hand. It is a decision,
	 * not an oversight - do not revert it as one.
	 *
	 *     #373536 resting   12.17:1 on white   11.24:1 on the header's #f4f6f8
	 *     #00AFF0  ACTIVE    2.50:1             2.31:1
	 *     #0098d1            3.28:1             3.02:1
	 *     #0077B6  was       4.87:1             4.49:1
	 *
	 * Two consequences, both accepted:
	 *
	 * 1. The icon is HARDER to see on hover than at rest - 12.17:1 falling to
	 *    2.50:1 - so the affordance dims exactly as the pointer arrives. Hover
	 *    is an enhancement, so no criterion is breached by that alone.
	 *
	 * 2. THIS TOKEN ALSO PAINTS THE :focus-visible OUTLINE, further down. A
	 *    focus indicator sits squarely inside WCAG 1.4.11's 3:1, which cyan
	 *    misses on both pill backgrounds - so unlike (1) this one is a real
	 *    miss, not a judgement call.
	 *
	 * If (2) ever has to be fixed without giving up the cyan hover, split the
	 * token: keep --ml-search-icon-active for the icon and give the outline its
	 * own --ml-search-ring-active of #0077B6. That is a two-line change and
	 * costs nothing visually at rest.
	 */
	--ml-search-icon: var(--ml-charcoal);
	--ml-search-icon-active: var(--ml-cyan);

	/*
	 * The FOCUS RING, split from the icon ink on 2026-09-05 exactly as the
	 * note above proposed. A focus indicator is squarely inside WCAG 1.4.11's
	 * 3:1, and brand cyan measures 2.50:1 on white and 2.31:1 on the header's
	 * pill - a real miss rather than a judgement call. --ml-accent is #0077B6,
	 * 4.87:1, so the ring passes while the hover ink stays the cyan the owner
	 * chose. Nothing changes at rest.
	 */
	--ml-search-ring-active: var(--ml-cyan);

	--ml-search-ring: inset 0 0 0 1px var(--ml-line);
	--ml-search-glow: 0 0 0 0 transparent;
	--ml-search-shadow: 0 0 0 0 transparent;

	display: flex;
	align-items: stretch;
	height: var(--ml-search-height);
	background: var(--ml-search-bg);

	/*
	 * The hairline is an INSET SHADOW, not a border.
	 *
	 * A border paints outside the padding box, so a child can never cover it -
	 * that left a guaranteed 1px line along the blue button's top, right and
	 * bottom. An inset shadow paints above the background but BELOW children,
	 * so the opaque button covers it exactly where it sits and the ring still
	 * shows everywhere else.
	 */
	border: 0;
	border-radius: var(--ml-search-radius);
	box-shadow: var(--ml-search-ring), var(--ml-search-glow), var(--ml-search-shadow);
	transition: box-shadow var(--ml-t-base) var(--ml-e-standard);
}

/*
 * `overflow: hidden` is deliberately absent and must not be added.
 *
 * It clipped the button to the padding box and anti-aliased the blue against
 * the pill's background along the curve, which read as a pale fringe. The
 * button draws its own right-hand curve instead - see below.
 */

.ml-search:hover {
	--ml-search-ring: inset 0 0 0 1px #cfd8e2;
}

.ml-search:focus-within {
	--ml-search-ring: inset 0 0 0 3px var(--ml-cyan);
	--ml-search-glow: 0 0 0 3px rgba(0, 175, 240, 0.22);
}

/* ---------- Field ---------- */

.ml-search input[type="search"] {
	flex: 1 1 auto;
	/* Basis comes from `width`; auto means content, not the whole container. */
	width: auto;
	min-width: 0;
	height: auto;
	box-sizing: border-box;
	margin: 0;
	border: 0;
	border-radius: 0;
	outline: 0;
	padding: var(--ml-search-pad);
	background: transparent;
	box-shadow: none;
	font-family: var(--ml-font);
	font-size: var(--ml-search-font);
	line-height: 1.2;
	color: var(--ml-charcoal);
}

/*
 * Astra paints a dotted border and its own ring on `input:focus`. The pill's
 * :focus-within ring is the affordance, so the field itself stays flat in
 * every state.
 */
.ml-search input[type="search"]:focus,
.ml-search input[type="search"]:focus-visible {
	border: 0;
	outline: 0;
	box-shadow: none;
	background: transparent;
}

.ml-search input[type="search"]::placeholder {
	color: var(--ml-muted);
	opacity: 1;
}

/* Remove the native clear button so the field matches the design. */
.ml-search input[type="search"]::-webkit-search-cancel-button {
	-webkit-appearance: none;
	appearance: none;
}

/* ---------- Submit ---------- */

/*
 * The submit is an icon sitting inside the field, not a block beside it.
 *
 * `background: transparent` is what removes the seam - the pill's own
 * --ml-search-bg shows straight through, so the header's grey and the blog's
 * white each read as one continuous control.
 *
 * NO border-radius. The button had `0 radius radius 0` to shape a coloured
 * right edge against the pill's curve; with no fill there is no edge to shape,
 * and a radius on an invisible box only matters again at :focus-visible, which
 * sets its own below.
 *
 * `align-self: stretch` still makes the button's height the pill's height, and
 * flex-shrink 0 holds the width steady while the field absorbs changes in the
 * row's width - the icon is the same size at 1440 as at 375.
 *
 * The 44px minimums are the tap target. Every instance already clears them
 * (58-62px wide; 46-50px tall from --ml-search-height), so they never engage
 * today - they are a floor for whoever next shrinks a token.
 */
.ml-search button[type="submit"] {
	flex: 0 0 auto;
	width: var(--ml-search-btn-width);
	min-width: 44px;
	min-height: 44px;
	align-self: stretch;
	margin: 0;
	padding: 0;
	border: 0;
	/* Astra's bare `button` rule adds a 1px drop shadow to every button. */
	box-shadow: none;
	background: transparent;
	color: var(--ml-search-icon);
	display: flex;
	align-items: center;
	justify-content: center;
	cursor: pointer;
	transition: color var(--ml-t-base) var(--ml-e-standard);
}

/* Scaled separately from the button so the button box itself never moves. */
.ml-search button[type="submit"] svg {
	transition: transform var(--ml-t-base) var(--ml-e-standard);
}

/*
 * `:focus-visible`, not `:focus` - `:focus` fires on a mouse click too, which
 * leaves the button stuck in its hover colour after being clicked. Keyboard
 * users get the identical state, colour and scale both.
 *
 * The background stays transparent in every state: the colour change is the
 * icon's, so the field never grows a second block back.
 */
.ml-search button[type="submit"]:hover,
.ml-search button[type="submit"]:focus-visible {
	background: transparent;
	color: var(--ml-search-icon-active);
}

.ml-search button[type="submit"]:hover svg,
.ml-search button[type="submit"]:focus-visible svg {
	transform: scale(1.08);
}

/*
 * The pill's :focus-within ring fires for the field AND the button, so on its
 * own it cannot say WHICH of the two has focus. This inner outline is what
 * distinguishes them - without it, tabbing from the field to the button looks
 * like nothing happened.
 *
 * The old rule painted this white, which was legible only because the button
 * used to be a blue block. On a transparent button over a white or #f4f6f8
 * pill a white outline is invisible, so it takes the active ink instead.
 *
 * THAT INK IS NOW BRAND CYAN and this indicator no longer clears 1.4.11:
 * 2.50:1 on white, 2.31:1 on the header's pill, against the 3:1 a focus
 * indicator is held to. It measured 4.87:1 / 4.49:1 until 2026-09-03.
 *
 * The cyan was chosen deliberately for the hover ink (see the token block at
 * the top of this file); the outline inherited it because both read the same
 * variable. If this needs fixing, give the outline its own token rather than
 * changing --ml-search-icon-active back - the hover colour is a decision the
 * owner made, this side effect is not.
 *
 * The radius exists only to round this outline; the button has no visible edge
 * otherwise.
 */
.ml-search button[type="submit"]:focus-visible {
	outline: 3px solid var(--ml-search-ring-active);
	outline-offset: -6px;
	border-radius: 8px;
}

/* ---------- Standalone ----------
 *
 * The modifier searchform.php uses. It has no container sizing it, so it needs
 * a width of its own; the header and blog instances are sized by their layouts.
 */

.ml-search--block {
	width: 100%;
	max-width: 520px;
}

/* -------------------------------------------------------------------------
 * Reduced motion
 *
 * The colour still changes on hover and on keyboard focus - it just changes
 * instantly. Nothing scales and nothing eases.
 * ---------------------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
	.ml-search,
	.ml-search button[type="submit"],
	.ml-search button[type="submit"] svg {
		transition: none;
	}

	.ml-search button[type="submit"]:hover svg,
	.ml-search button[type="submit"]:focus-visible svg {
		transform: none;
	}
}
