/*
 * Auth screen styling (`add-marketing-site` §6).
 *
 * Eighth pass (2026-08-07, client-directed): the seventh pass shipped at the *dashboard's*
 * type and control scale, and the client's report was blunt — "everything is small". It was:
 * a 28px heading, 15px inputs and a 48px button, sized for a dense app shell, holding a
 * two-field form in a half-viewport column. This pass rescales the auth screens on their own
 * terms (38px heading, 16px inputs, 56px controls, 420px form track), moves the field labels
 * back above their inputs so the typing target is the full control rather than a 24px line
 * inside a shared box, repoints the brand colour onto the marketing site's own CTA blue
 * (#2575fc, sampled from the live home page rather than guessed), and replaces the
 * placeholder wordmark with the client's supplied logo asset. All of it is scoped to
 * `.wcai-auth` (see that rule) so `dashboard.css`, which shares these token names, is
 * untouched.
 *
 * Seventh pass (2026-08-07, client-directed — Upsellix rebrand): the split shell was rebuilt
 * against a new reference mockup. Form column moved to the left and the decorative panel to
 * the right; the panel's full-bleed indigo gradient became a warm off-white canvas; the CSS
 * dashboard-preview card became a pull quote over line art; and the placeholder single-letter
 * brand tile became the real Upsellix lockup (`templates/partials/brand-logo.php`). The token
 * ramp below is untouched by that pass — the indigo is still the product's brand colour, it
 * simply stopped being used as a background wash. Per-section docblocks carry the details;
 * see `.wcai-auth__visual` for why the panel went quiet, and `auth-split-close.php` for why
 * the reference's attributed customer testimonial is not reproduced literally.
 *
 * Fifth pass (2026-08-02, client-directed): repointed onto the same design system as the
 * dashboard and Owner Panel (`owner-design-system.css`'s indigo `#4f46e5` ramp), replacing
 * this file's own independent `#1b1aff` electric-blue palette. Before this pass the product
 * had *three* palettes across four surfaces — client plugin, dashboard/Owner Panel (indigo),
 * and auth (electric blue) — so a merchant's first screen (login) and their next one
 * (dashboard) visibly disagreed about what the brand colour was. The values below are the
 * same ones `owner-design-system.css` derives from the client plugin's
 * `plugin/admin/design-system.css`, copied rather than loaded as a dependency: this file is
 * also enqueued stand-alone on screens `owner-design-system.css` never reaches
 * (`/lost-password`, `/reset-password` render no dashboard chrome), so the tokens need to
 * live here directly rather than assume a second stylesheet is present.
 *
 * Structure carried over from the fourth pass unchanged — an explicit token scale rather
 * than ad-hoc per-rule values, all of `dashboard.css` inherits it:
 *
 *   - A 4px spacing scale (`--wcai-space-*`). Every margin/padding/gap in both files
 *     resolves to one of these, so vertical rhythm is consistent by construction instead of
 *     by eye.
 *   - A neutral, near-greyscale ramp (`--wcai-ink-*`, `--wcai-line-*`, `--wcai-surface-*`) —
 *     matching the client system's own choice to keep colour out of the neutrals entirely,
 *     see `owner-design-system.css`'s docblock on why a blue-tinted grey was reverted.
 *   - A brand ramp anchored on the shared `#4f46e5` indigo — 50/100/200/500/600/700 steps.
 *   - Layered shadows (`--wcai-shadow-*`): the client system runs shadows as "borders'
 *     assistants" (1-3px soft ambient), tighter than this file's previous cinematic blooms;
 *     kept as a slightly richer scale here only because the split-panel hero and the CSS
 *     product-preview card need more depth than a settings form does, but pulled in from the
 *     previous pass's values toward the shared system's restraint.
 *   - A type ramp (`--wcai-text-*`) with paired line-heights and one tracking value for
 *     display sizes.
 *
 * Tokens are declared on `:root` so `dashboard.css` (enqueued with `wcai-auth` as a
 * dependency — see `Assets.php`) resolves them without redeclaring a parallel palette.
 */

:root {
	/* -- Brand ramp — the shared blue, matching `owner-design-system.css` exactly. -------
	   Ninth pass (2026-08-07): was `#4f46e5` indigo. The eighth pass moved the auth screens
	   onto the marketing site's own CTA blue but scoped it to `.wcai-auth` to avoid
	   restyling the dashboard as a side effect; this pass moves the shared ramp too, so the
	   dashboard and Owner Panel — which inherit these tokens through `dashboard.css` — stop
	   disagreeing with the login screen a merchant just came from.

	   `#236fef`, not the home page's exact `#2575fc`: see the contrast note on `.wcai-auth`
	   below. The auth-scoped override there is now redundant with this ramp but is kept, so
	   the auth screens stay correct even if this shared ramp is repointed again later. */
	--wcai-brand-50: #eef4ff;
	--wcai-brand-100: #dbe7fe;
	--wcai-brand-200: #b8cffd;
	--wcai-brand-500: #236fef;
	--wcai-brand-600: #1a5fd4;
	--wcai-brand-700: #164ead;
	--wcai-primary: var(--wcai-brand-500);

	/* -- Neutrals. Near-greyscale, matching the client system's own posture: colour enters
	   through the brand and status triad only, never the neutrals — see
	   `owner-design-system.css`'s docblock for why a blue-tinted grey was reverted there. */
	--wcai-ink-900: #191c22;
	--wcai-ink-800: #22262e;
	--wcai-ink-700: #3a3f4a;
	--wcai-ink-500: #5b616e;
	/* Matches `owner-design-system.css`'s own `--wcai-ink-400` and its measured rationale:
	   4.7:1 on a white card, 4.4:1 on `--wcai-surface-50` — AA for normal-size text on both
	   surfaces this token actually appears on (field labels, meta copy, empty-state text). */
	--wcai-ink-400: #676e7b;
	--wcai-line-200: rgba(16, 24, 40, 0.16);
	--wcai-line-100: rgba(16, 24, 40, 0.09);
	--wcai-surface-0: #ffffff;
	--wcai-surface-50: #f7f8fa;
	--wcai-surface-100: #f1f2f4;

	/* Legacy aliases — kept so any selector still referencing the third-pass token names
	   resolves to the new ramp instead of breaking. */
	--wcai-body-text: var(--wcai-ink-500);
	--wcai-heading-text: var(--wcai-ink-900);
	--wcai-section-bg: var(--wcai-surface-50);

	/* -- Status. Matches the shared system's triad exactly. --------------------------- */
	--wcai-error: #d1242f;
	--wcai-error-bg: rgba(209, 36, 47, 0.08);
	--wcai-error-line: rgba(209, 36, 47, 0.26);
	--wcai-success: #1a7f42;
	--wcai-success-bg: rgba(26, 127, 66, 0.1);
	--wcai-success-line: rgba(26, 127, 66, 0.28);
	--wcai-warning: #9a6700;
	--wcai-warning-bg: rgba(154, 103, 0, 0.1);
	--wcai-warning-line: rgba(154, 103, 0, 0.28);

	/* -- 4px spacing scale ----------------------------------------------------------- */
	--wcai-space-1: 4px;
	--wcai-space-2: 8px;
	--wcai-space-3: 12px;
	--wcai-space-4: 16px;
	--wcai-space-5: 20px;
	--wcai-space-6: 24px;
	--wcai-space-8: 32px;
	--wcai-space-10: 40px;
	--wcai-space-12: 48px;
	--wcai-space-16: 64px;

	/* -- Type ramp ------------------------------------------------------------------- */
	--wcai-text-xs: 12px;
	--wcai-text-sm: 13px;
	--wcai-text-base: 14px;
	--wcai-text-md: 15px;
	--wcai-text-lg: 18px;
	--wcai-text-xl: 22px;
	--wcai-text-2xl: 28px;
	--wcai-text-3xl: 34px;
	--wcai-leading-tight: 1.25;
	--wcai-leading-normal: 1.5;
	--wcai-leading-relaxed: 1.65;
	/* Negative tracking on display sizes only — large type set at default tracking reads
	   loose, small type set tight reads cramped. */
	--wcai-tracking-display: -0.02em;

	/* -- Radii ------------------------------------------------------------------------
	   Tighter than the fourth pass's 8/10/14/20px scale, matching the shared system's
	   7/10px controls/cards — tight corners are most of what makes the client plugin and
	   dashboard read as an instrument rather than a consumer app; the split-panel hero and
	   preview card keep one step up (`--radius-lg`) since they are the one deliberately
	   more "marketing" surface in the product. */
	--wcai-radius-sm: 7px;
	--wcai-radius-md: 10px;
	--wcai-radius-lg: 14px;
	--wcai-radius-xl: 20px;
	--wcai-radius-pill: 999px;
	--wcai-card-radius: var(--wcai-radius-lg);
	--wcai-button-radius: var(--wcai-radius-sm);

	/* -- Layered shadows: contact + ambient, never a single wide blur ----------------- */
	--wcai-shadow-xs: 0 1px 2px rgba(16, 24, 40, 0.05);
	--wcai-shadow-sm: 0 1px 2px rgba(16, 24, 40, 0.06), 0 4px 12px rgba(16, 24, 40, 0.05);
	--wcai-shadow-md: 0 2px 4px rgba(16, 24, 40, 0.05), 0 6px 16px rgba(16, 24, 40, 0.07);
	--wcai-shadow-lg: 0 4px 8px rgba(16, 24, 40, 0.05), 0 16px 40px rgba(16, 24, 40, 0.09);
	/* The primary button's shadow, restated in indigo. The shared dashboard system maps
	   this token onto plain `--shadow-sm` (a neutral admin surface has no business putting a
	   coloured glow under a button); this file keeps a *soft* brand-tinted version instead,
	   because the split-panel auth screen is the one deliberately more expressive surface —
	   restrained relative to the old 0.24-alpha bloom, not eliminated. */
	--wcai-shadow-brand: 0 1px 2px rgba(22, 78, 173, 0.16), 0 8px 20px rgba(35, 111, 239, 0.18);
	--wcai-shadow-brand-hover: 0 1px 2px rgba(22, 78, 173, 0.18), 0 12px 28px rgba(35, 111, 239, 0.24);

	--wcai-ring: 0 0 0 4px var(--wcai-brand-100);
	--wcai-ring-error: 0 0 0 4px var(--wcai-error-line);

	/* System font stack, not a Google-hosted webfont. The client system rejects third-party
	   font requests explicitly (GDPR exposure, CSP/air-gapped breakage, render-blocking
	   round trip — see `owner-design-system.css`'s docblock); auth is the *first* page an
	   evaluating merchant loads, so it is the worst possible surface to add a blocking
	   external request to. */
	--wcai-font: ui-sans-serif, "Segoe UI", system-ui, -apple-system, "Helvetica Neue", sans-serif;
	--wcai-font-mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;

	--wcai-ease: cubic-bezier(0.4, 0, 0.2, 1);
	/* A slight overshoot for entrance motion (card/field arrivals) — matched to the
	   dashboard's own `--wcai-ease` for anything continuous (hover, focus). */
	--wcai-ease-out: cubic-bezier(0.16, 1, 0.3, 1);
}

/* The auth root — the whole page, not a block inside a themed one. `min-height` rather than
   `height` so a tall form (register with four fields plus stacked validation notices)
   scrolls instead of overflowing a clipped viewport. */
.wcai-auth {
	/* -- Auth-scoped overrides (eighth pass, 2026-08-07, client-directed) ----------------
	   Two corrections, both declared *here* on the auth root rather than on `:root` above.
	   That is deliberate and load-bearing: `dashboard.css` is enqueued with `wcai-auth` as a
	   dependency and consumes the same `:root` token names, so editing the global ramp would
	   silently restyle every dashboard screen too. Scoping to `.wcai-auth` keeps this pass
	   confined to the four auth screens, which is what was asked for.

	   1. Brand colour is the marketing site's own CTA blue, sampled from the live home page's
	      buttons (`rgb(37, 117, 252)` = #2575fc), not the `#4f46e5` indigo the fifth pass
	      adopted. The auth screens sit directly between the home page and the dashboard, and
	      a merchant clicking a blue "Get started" button should not land on a violet form.
	      The supplied logo's own electric blue (#0f02fd) is close to this and reads as the
	      same colour family; it is left untouched inside the image asset, as a logo should be.

	      The value below is #236fef, not the sampled #2575fc exactly: measured against white,
	      #2575fc gives 4.18:1, which fails WCAG AA (4.5:1) for the two places this colour
	      carries *text* — the submit button's white label and the "Forgot?"/"Create one"
	      links, none of which qualify as large text at 14-16px. #236fef is the nearest step
	      that passes (4.57:1 both ways) and is a 5% darkening, which is imperceptible beside
	      the home page's buttons. Both figures are computed, not estimated.

	   2. Everything is a size step larger. The seventh pass inherited a type and control
	      scale built for the *dashboard* — 14px body, 15px inputs, 28px headings, 48px
	      buttons — which is right for a dense app shell and much too tight for a page holding
	      two fields in a half-viewport column. The client's report was simply "everything is
	      small", and measured against the reference mockups it was: the heading ran ~30%
	      smaller and the controls ~20% shorter than the screens being matched. */
	--wcai-brand-50: #eef4ff;
	--wcai-brand-100: #dbe7fe;
	--wcai-brand-200: #b8cffd;
	--wcai-brand-500: #236fef;
	--wcai-brand-600: #1a5fd4;
	--wcai-brand-700: #164ead;
	--wcai-primary: var(--wcai-brand-500);
	--wcai-ring: 0 0 0 4px var(--wcai-brand-100);
	--wcai-shadow-brand: 0 1px 2px rgba(21, 80, 186, 0.16), 0 8px 20px rgba(37, 117, 252, 0.2);
	--wcai-shadow-brand-hover: 0 1px 2px rgba(21, 80, 186, 0.2), 0 12px 28px rgba(37, 117, 252, 0.28);

	/* The auth-only type steps. Named apart from the `--wcai-text-*` ramp rather than
	   overriding it, so it is obvious at every call site which scale a rule is using and a
	   later dashboard change cannot drift into these. */
	--upx-title: 38px;
	--upx-subtitle: 16px;
	--upx-label: 14px;
	--upx-input: 16px;
	--upx-button: 16px;
	--upx-quote: 21px;
	--upx-point: 15px;

	/* Control geometry. 56px is the tap-target height the reference mockups use and comfortably
	   clears the 44px accessibility minimum; 12px radius is a step softer than the home page's
	   5px because these controls are much taller — a tight radius on a 56px box reads square. */
	--upx-control-h: 56px;
	--upx-control-r: 12px;
	--upx-form-w: 420px;

	display: flex;
	box-sizing: border-box;
	min-height: 100vh;
	font-family: var(--wcai-font);
	color: var(--wcai-ink-500);
	-webkit-font-smoothing: antialiased;
	-moz-osx-font-smoothing: grayscale;
}

/* -- Entrance motion (2026-08-02) ---------------------------------------------------------
   A small, once-per-load choreography rather than a general animate-everything pass: the
   form column's content rises in as one staggered sequence (title, subtitle, each field row,
   the button, the footer), and the opposite panel's quote block settles in alongside it.
   Each element's own delay is expressed as a CSS custom
   property set per-selector below, so the keyframes stay single-purpose and the timing table
   is readable in one place rather than smeared across N `animation-delay` declarations.

   Kept out of `prefers-reduced-motion` entirely at the *keyframe* level — `@media
   (prefers-reduced-motion: reduce)` at the bottom of this file zeroes every
   `animation-duration`, which collapses each step to its end state instantly rather than
   skipping the animation system altogether. That is what "reduced", not "removed", motion
   means: the layout never depends on JS having run or an animation having completed. */

@keyframes wcai-auth-rise {
	from {
		opacity: 0;
		transform: translateY(10px);
	}
	to {
		opacity: 1;
		transform: translateY(0);
	}
}

@keyframes wcai-auth-quote-settle {
	from {
		opacity: 0;
		transform: translateY(14px);
	}
	to {
		opacity: 1;
		transform: translateY(0);
	}
}

.wcai-auth__title,
.wcai-auth__subtitle,
.wcai-auth__card--split .wcai-auth__field,
.wcai-auth__card--split .wcai-auth__field--toggle,
.wcai-auth__card--split form > p:not([class]),
.wcai-auth__card--split .woocommerce-privacy-policy-text,
.wcai-auth__card--split .wcai-auth__button,
.wcai-auth__card--split .wcai-auth__footer {
	animation: wcai-auth-rise 0.5s var(--wcai-ease-out) both;
	/* Staggered via `nth-of-type` below rather than a per-element inline delay: the set of
	   elements present differs by screen (login has no toggle, /lost-password has no fields
	   at all), so an index-based selector keeps each screen's own sequence correctly ordered
	   without a template-side counter. */
	animation-delay: calc(var(--wcai-auth-step, 0) * 55ms + 80ms);
}

.wcai-auth__title {
	--wcai-auth-step: 0;
}
.wcai-auth__subtitle {
	--wcai-auth-step: 1;
}
.wcai-auth__card--split .wcai-auth__field:nth-of-type(1),
.wcai-auth__card--split form > .wcai-auth__field:first-child {
	--wcai-auth-step: 2;
}
.wcai-auth__card--split .wcai-auth__field:nth-of-type(2) {
	--wcai-auth-step: 3;
}
.wcai-auth__card--split .wcai-auth__field:nth-of-type(3) {
	--wcai-auth-step: 4;
}
.wcai-auth__card--split .wcai-auth__field:nth-of-type(4) {
	--wcai-auth-step: 5;
}
.wcai-auth__card--split .wcai-auth__field--toggle {
	--wcai-auth-step: 4;
}
.wcai-auth__card--split form > p:not([class]),
.wcai-auth__card--split .woocommerce-privacy-policy-text {
	--wcai-auth-step: 6;
}
.wcai-auth__card--split .wcai-auth__button {
	--wcai-auth-step: 7;
}
.wcai-auth__card--split .wcai-auth__footer {
	--wcai-auth-step: 8;
}

.wcai-auth__visual-body {
	animation: wcai-auth-quote-settle 0.6s var(--wcai-ease-out) 0.15s both;
}

/* The brand lockup leads the sequence — it is the first thing that should be present, since
   it is what tells a merchant whose login screen they landed on. */
.wcai-auth__brand {
	animation: wcai-auth-rise 0.5s var(--wcai-ease-out) both;
}

/* Base card box — the `--split` modifier below layers geometry on top of this. */
.wcai-auth__card {
	width: 100%;
	background: var(--wcai-surface-0);
	padding: var(--wcai-space-10) var(--wcai-space-8);
}

/* Neutralizes the Sierra/Elementor theme's `.woocommerce-account form.login, form.register`
   rule (keydesign-woocommerce.css), which paints bare <form> elements with the theme's own
   light-blue card background, padding and max-width. Defensive: `.woocommerce-account` is
   not among the body classes on these routes, but this keeps the form's presentation
   independent of whatever classes WooCommerce adds on a future POST/redisplay. */
.wcai-page .wcai-auth__card form.login,
.wcai-page .wcai-auth__card form.register {
	background: transparent;
	border: none;
	padding: 0;
	margin: 0;
	max-width: none;
}

.wcai-auth__title {
	font-family: var(--wcai-font);
	font-weight: 700;
	font-size: var(--upx-title);
	line-height: 1.15;
	letter-spacing: -0.024em;
	color: var(--wcai-ink-900);
	margin: 0 0 var(--wcai-space-3);
}

.wcai-auth__subtitle {
	font-size: var(--upx-subtitle);
	line-height: var(--wcai-leading-relaxed);
	color: var(--wcai-ink-500);
	margin: 0 0 var(--wcai-space-8);
}

.wcai-auth__field {
	margin-bottom: var(--wcai-space-4);
}

/* Register-only grouping: Username/Email (account identity) and Password/Confirm
   (credentials) previously read as one undifferentiated stack of four identical boxes — a
   density problem the fields' own spacing couldn't fix without also loosening every other
   auth form's single-purpose field list. A rule above the credentials group is enough to
   read as two sections; keyed on `:has(input[name="password"])` rather than a template-side
   wrapper element, since the four fields are conditionally rendered siblings
   (`RegistrationFields`'s username/password toggles — see login.php's docblock) and a
   structural class would have to be threaded through both conditionals to land on the same
   place this selector finds directly.

   Scoped to `form.register` as of the seventh pass (2026-08-07). The comment above always
   said "register-only", but the selector did not say so: `.wcai-auth__field:has(input
   [name="password"])` matches the password field on **/login** too, where there is no
   second group to divide from a first. So every login screen has been rendering a stray
   1px rule above its password field plus 20px of top padding — which made that field 71px
   tall against the email field's 58px, an unequal pair on a two-field form. Measured, not
   guessed: the diagnostic that found it read `padding-top: 20px` on /login's password
   wrapper and 7px on its email wrapper.

   `form.register` is the honest expression of the existing intent and needs no template
   change — WooCommerce's own `woocommerce-form-register register` classes are already on
   that form (see login.php), and /login's form carries `login` instead. */
.wcai-page form.register .wcai-auth__field:has(input[name="password"]) {
	margin-top: var(--wcai-space-2);
	padding-top: var(--wcai-space-5);
	border-top: 1px solid var(--wcai-line-100);
}

.wcai-auth__label {
	display: block;
	font-weight: 500;
	font-size: var(--wcai-text-base);
	color: var(--wcai-ink-800);
	margin-bottom: var(--wcai-space-2);
}

.wcai-auth__input {
	width: 100%;
	box-sizing: border-box;
	/* The theme (`keydesign-framework.css`) pins every text input to
	   `height: var(--component-height, 50px)`, which silently overrides the padding below —
	   the field would render at the theme's height, not the one this padding describes.
	   Reset to `auto` so padding is what actually sizes the control. */
	height: auto;
	padding: var(--wcai-space-3) var(--wcai-space-4);
	font-size: var(--wcai-text-md);
	font-family: var(--wcai-font);
	color: var(--wcai-ink-900);
	background: var(--wcai-surface-0);
	border: 1px solid var(--wcai-line-200);
	border-radius: var(--wcai-radius-md);
	transition: border-color 0.15s var(--wcai-ease), box-shadow 0.15s var(--wcai-ease);
}

.wcai-auth__input::placeholder {
	color: var(--wcai-ink-400);
}

.wcai-auth__input:focus {
	outline: none;
	border-color: var(--wcai-brand-500);
	box-shadow: var(--wcai-ring);
}

/* WooCommerce injects its own paragraphs into these forms through
   `woocommerce_register_form` (the privacy-policy notice on /register) and
   `woocommerce_login_form` — they arrive with the theme's own default margins, which on
   /register collapsed to nothing above the submit button and left the privacy text touching
   it. Given a consistent gap here rather than per-hook, since any future hook output lands
   in the same place. */
.wcai-auth__card form > p:not([class]),
.wcai-auth__card .woocommerce-privacy-policy-text {
	margin: 0 0 var(--wcai-space-6);
}

.wcai-auth__card form > p:not([class]),
.wcai-auth__card .woocommerce-privacy-policy-text p {
	font-size: var(--wcai-text-sm);
	line-height: var(--wcai-leading-relaxed);
	color: var(--wcai-ink-400);
	/* The inner <p> carries the theme's own bottom margin; the wrapper above supplies the
	   single gap, so this one is zeroed. */
	margin: 0;
}

.wcai-auth__card .woocommerce-privacy-policy-text a {
	color: var(--wcai-ink-500);
	text-decoration: underline;
	text-underline-offset: 2px;
}

/* Scoped under `.wcai-page` rather than declared on `.wcai-auth__button` alone (2026-08-02
   fix): every submit button on this site, including this one, also matches the
   Sierra/Elementor theme's own `global.css` rule — a long selector list ending in
   `[type="submit"]` that sets `min-height`, `padding`, `border-radius`, `color`,
   `background-color` and more, tuned to the theme's own component-height and Elementor kit
   colour (`--e-global-color-primary`). `[type="submit"]` alone and the bare class below are
   equal specificity (0,1,0 each), and the theme sheet is enqueued after this one (`site.css`
   → `auth.css` → … → `variables.css`/`global.css`), so it was winning every tied property —
   not just colour: the button was rendering at the theme's 50px height and 12px radius, not
   this file's declared 48px/`--button-radius`. That the *colour* collision went unnoticed
   through the fourth pass is what made the rest invisible too — `--e-global-color-primary`
   was `#1b1aff`, the old auth palette's exact anchor, so the two coincided by accident, not
   by any rule protecting one from the other. `.wcai-page` is this file's existing scoping
   hook for exactly this situation — see the `.wcai-page .wcai-auth__card form.login` reset
   above — reused here rather than inventing a second pattern for the same problem. */
.wcai-page .wcai-auth__button {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 100%;
	box-sizing: border-box;
	min-height: var(--upx-control-h);
	margin-top: var(--wcai-space-2);
	padding: var(--wcai-space-3) var(--wcai-space-6);
	font-family: var(--wcai-font);
	font-weight: 600;
	font-size: var(--upx-button);
	letter-spacing: 0;
	text-align: center;
	color: #ffffff;
	background: var(--wcai-brand-500);
	border: none;
	border-radius: var(--upx-control-r);
	box-shadow: var(--wcai-shadow-brand);
	cursor: pointer;
	/* `opacity` on hover (the previous pass's approach) fades the button against the page
	   and reads as "disabled" rather than "interactive" — a darker brand step plus a small
	   lift is the standard affordance and keeps contrast. */
	transition: background 0.15s var(--wcai-ease), box-shadow 0.15s var(--wcai-ease), transform 0.15s var(--wcai-ease);
}

.wcai-page .wcai-auth__button:hover {
	background: var(--wcai-brand-600);
	transform: translateY(-1px);
	box-shadow: var(--wcai-shadow-brand-hover);
}

.wcai-page .wcai-auth__button:active {
	background: var(--wcai-brand-700);
	transform: translateY(0);
	box-shadow: var(--wcai-shadow-xs);
}

.wcai-auth__button:focus-visible {
	outline: none;
	box-shadow: var(--wcai-ring), var(--wcai-shadow-brand);
}

.wcai-auth__footer {
	margin-top: var(--wcai-space-8);
	font-size: var(--upx-subtitle);
	text-align: center;
	color: var(--wcai-ink-500);
}

.wcai-auth__footer a,
.wcai-auth__link {
	color: var(--wcai-brand-500);
	font-weight: 600;
	text-decoration: none;
	border-radius: var(--wcai-radius-sm);
}

.wcai-auth__footer a:hover,
.wcai-auth__link:hover {
	color: var(--wcai-brand-600);
	text-decoration: underline;
	text-underline-offset: 2px;
}

.wcai-auth__footer a:focus-visible,
.wcai-auth__link:focus-visible {
	outline: 2px solid var(--wcai-brand-500);
	outline-offset: 2px;
}

/* -- Notices --------------------------------------------------------------------------- */

/* NOT `display: flex`. WooCommerce's own notice strings contain inline markup — the
   wrong-password error is "The password you entered for the username <strong>x</strong> is
   incorrect. <a>Lost your password?</a>" — and a flex container makes every one of those
   inline elements a separate flex *item*, so the sentence rendered as three narrow stacked
   columns instead of a paragraph. Block layout with a floated marker keeps the text as
   normal inline flow, which is what a sentence containing arbitrary markup needs. */
.wcai-auth__notice {
	display: block;
	padding: var(--wcai-space-3) var(--wcai-space-4);
	padding-left: var(--wcai-space-8);
	position: relative;
	border-radius: var(--wcai-radius-md);
	font-size: var(--wcai-text-base);
	line-height: var(--wcai-leading-normal);
	margin-bottom: var(--wcai-space-5);
}

/* Leading dot as a status marker rather than an icon font or an SVG per notice: it carries
   the status colour at a glance without adding an asset dependency. Absolutely positioned
   so it sits in the gutter the `padding-left` above reserves, and takes no part in the
   text's own layout. The notice's `role="alert"`/`role="status"` (set in
   `templates/partials/notices.php`) is what conveys status non-visually. */
.wcai-auth__notice::before {
	content: "";
	position: absolute;
	left: var(--wcai-space-4);
	top: 15px;
	width: 8px;
	height: 8px;
	border-radius: 50%;
	background: currentColor;
}

/* WooCommerce notice strings arrive as a bare text node plus inline elements, with no
   wrapping <p>; when a theme's global <p> margins do apply to injected markup, this keeps
   the notice from growing an extra blank line. */
.wcai-auth__notice p {
	margin: 0;
	color: inherit;
}

.wcai-auth__notice--error {
	background: var(--wcai-error-bg);
	color: var(--wcai-error);
	border: 1px solid var(--wcai-error-line);
}

.wcai-auth__notice--success {
	background: var(--wcai-success-bg);
	color: var(--wcai-success);
	border: 1px solid var(--wcai-success-line);
}

/* WooCommerce notices arrive as markup with their own link colours; keep them legible
   against the tinted notice background rather than inheriting the brand blue. */
.wcai-auth__notice a {
	color: inherit;
	font-weight: 600;
	text-decoration: underline;
	text-underline-offset: 2px;
}

.wcai-auth__field-error {
	display: block;
	margin-top: var(--wcai-space-2);
	font-size: var(--wcai-text-sm);
	color: var(--wcai-error);
}

.wcai-auth__input--invalid {
	border-color: var(--wcai-error);
}

.wcai-auth__input--invalid:focus {
	border-color: var(--wcai-error);
	box-shadow: var(--wcai-ring-error);
}

/* -- Two-panel auth layout ------------------------------------------------------------
   Full-viewport split: the visual panel spans edge to edge and fills the viewport height,
   with no surrounding canvas, no card corners and no drop shadow (there is nothing left for
   a card to float above). Applies to every auth screen so the whole flow reads as one
   product. The shell markup lives in `templates/partials/auth-split-open.php` /
   `auth-split-close.php`. */

.wcai-auth--split {
	align-items: stretch;
	justify-content: stretch;
}

.wcai-auth__panel-wrap {
	display: flex;
	width: 100%;
	background: var(--wcai-surface-0);
	min-height: 100vh;
	/* Clips the visual panel's gradient and the decorative shapes inside it to the panel
	   box. */
	overflow: hidden;
	align-items: stretch;
}

/* -- Brand lockup ---------------------------------------------------------------------
   The client's supplied logo, rendered as an image by `templates/partials/brand-logo.php`
   (see that file for why it is an `<img>` and not inline SVG). Nothing here recolours it —
   it is a fixed multi-colour mark and is reproduced exactly as supplied.

   In normal flow at the top of the column, `flex: 0 0 auto` so it never shrinks. Its height
   is what the card's auto margins centre against — see `.wcai-auth__form-col` for why it is
   deliberately not positioned absolutely. `align-self: flex-start` shrink-wraps the link to
   the artwork so its focus ring does not draw across the whole column. */
.wcai-auth__brand {
	flex: 0 0 auto;
	align-self: flex-start;
	display: inline-block;
	line-height: 0;
	margin-bottom: var(--wcai-space-8);
	text-decoration: none;
	border-radius: var(--wcai-radius-sm);
}

.wcai-auth__brand:focus-visible {
	outline: 2px solid var(--wcai-brand-500);
	outline-offset: 6px;
}

/* `height: auto` against the element's own `width` (set inline by the partial from its
   `$upx_logo_width`) is what preserves the artwork's 4.13:1 ratio — the `width`/`height`
   attributes in the markup exist to reserve layout space before load, not to size it. */
.upx-logo {
	display: block;
	height: auto;
	max-width: 100%;
}

/* WordPress core ships this class, but these pages render without a theme stylesheet
   (`standalone-header.php` emits its own document shell), so core's copy may not be present.
   Declared here so the logo's accessible text name never renders visibly. */
.wcai-auth .screen-reader-text {
	position: absolute;
	width: 1px;
	height: 1px;
	margin: -1px;
	padding: 0;
	overflow: hidden;
	clip: rect(0, 0, 0, 0);
	white-space: nowrap;
	border: 0;
}

/* -- Right visual panel ---------------------------------------------------------------
   Seventh pass (2026-08-07, Upsellix rebrand). Three things changed from the sixth pass,
   all of them following the client's reference mockup:

   - The panel moved to the *right* and the form to the left (previously the reverse). The
     markup moved with it (`auth-split-close.php`) rather than being reordered in CSS, so DOM
     order and visual order agree and tab order lands on the form first.
   - The saturated indigo gradient became a warm, low-chroma tint. A full-height slab of
     `--brand-500` is the loudest thing on a merchant's first screen, and it forced every
     element inside it to be white-on-blue — which is why the previous pass needed a
     translucent brand tile, white checkmark discs and a near-opaque card just to stay
     legible. A quiet canvas lets the panel's contents use the *same* ink and brand tokens as
     the form beside it, so the two halves read as one page.
   - The CSS dashboard preview became a pull quote plus line-art illustration. See
     `auth-split-close.php` for why the reference's attributed testimonial is not reproduced
     literally.

   `--wcai-canvas` is derived here rather than added to the `:root` ramp: it is a warm off-
   white specific to this one surface, and nothing else in the product consumes it. */
.wcai-auth__visual {
	--wcai-canvas: #f6f5f1;

	flex: 0 0 46%;
	position: relative;
	isolation: isolate;
	display: flex;
	flex-direction: column;
	/* `flex-end`, not `center`. The artwork is pinned to the panel's bottom edge, so centring
	   the quote independently opens an arbitrary gap between the two that grows with viewport
	   height — the same failure the sixth pass hit with the old preview card, for the same
	   reason (two things positioned against different anchors in an unbounded box). Bottom-
	   aligning the copy means it sits a fixed distance above the skyline at every height, and
	   the slack collects above the quote instead of between the quote and the drawing. */
	justify-content: flex-end;
	padding: var(--wcai-space-12) var(--wcai-space-10);
	box-sizing: border-box;
	overflow: hidden;
	background:
		radial-gradient(90% 70% at 78% 8%, rgba(35, 111, 239, 0.07) 0%, rgba(35, 111, 239, 0) 60%),
		var(--wcai-canvas);
	/* Separates the two halves at their shared edge. A 1px line rather than a shadow: the
	   panels are flush and full-bleed, so there is no gap for a shadow to fall into. */
	border-left: 1px solid var(--wcai-line-100);
}

/* Sits above the illustration and reserves the room the artwork occupies at the bottom of
   the panel, so the quote never overlaps the skyline on a short viewport. */
.wcai-auth__visual-body {
	position: relative;
	z-index: 1;
	width: 100%;
	max-width: 480px;
	margin: 0 auto;
	/* The gap between the copy and the skyline below it, now that the panel bottom-aligns this
	   block (see `.wcai-auth__visual`). Well under the scene's full height because the scene's
	   top quarter is masked to transparent, so the buildings begin a long way below its box's
	   top edge — this is the distance to where the drawing actually starts, not to its box.
	   Measured against the *tallest* element in the drawing, the centre tower's antenna, which
	   is what the last checklist line collided with at 200px. */
	padding-bottom: 246px;
}

/* The opening quote glyph, set as a display character rather than an image. Sized well above
   the text it introduces and tinted back to a light brand step so it reads as a typographic
   ornament rather than a heading — the same treatment the reference uses. */
.wcai-auth__quote-mark {
	display: block;
	font-family: Georgia, "Times New Roman", serif;
	font-size: 46px;
	line-height: 0.6;
	color: var(--wcai-brand-200);
	margin-bottom: var(--wcai-space-3);
	/* Pulls the glyph's own left side-bearing back so its visual edge aligns with the text
	   below it rather than sitting indented. */
	margin-left: -0.06em;
}

/* The panel's primary voice — deliberately larger and darker than anything in the form
   column, since it is the only thing competing for attention on an otherwise quiet canvas.
   `max-width` in `ch` keeps the measure near 45 characters at any panel width, which is the
   readable range for text at this size. */
/* Sized one step *below* the form's own `<h1>` (`--text-2xl`), not above it. The quote is
   supporting material on a screen whose job is the login form; set larger it becomes the
   page's focal point and the form reads as secondary — which is what the first cut of this
   pass did at `--text-xl` with a 30ch measure, filling the panel with five lines of heavy
   type. `--text-lg` at a 38ch measure keeps it to three or four comfortable lines and lets
   the form hold the eye. */
.wcai-auth__quote {
	font-size: var(--upx-quote);
	font-weight: 500;
	line-height: 1.5;
	letter-spacing: -0.01em;
	color: var(--wcai-ink-800);
	margin: 0;
	max-width: 40ch;
}

.wcai-auth__visual-points {
	list-style: none;
	margin: var(--wcai-space-8) 0 0;
	padding: 0;
	display: flex;
	flex-direction: column;
	gap: var(--wcai-space-3);
	max-width: 40ch;
}

.wcai-auth__visual-points li {
	display: flex;
	align-items: flex-start;
	gap: var(--wcai-space-3);
	font-size: var(--upx-point);
	line-height: var(--wcai-leading-normal);
	color: var(--wcai-ink-500);
}

/* Checkmark as an inline-SVG data URI rather than two crossed linear-gradients (the first
   attempt): stacked gradients cannot produce the two *different-length* strokes meeting at a
   right angle that read as a tick — they rendered as a small smudge. An SVG path draws the
   real shape, still needs no icon font or external asset, and stays crisp at any DPI.
   Stroke colour is the brand indigo now that the disc sits on a light canvas rather than a
   saturated panel; `margin-top` optically centres the 18px disc against the first line of a
   label that may wrap to two. */
.wcai-auth__visual-points li::before {
	content: "";
	flex: 0 0 auto;
	width: 18px;
	height: 18px;
	margin-top: 2px;
	border-radius: 50%;
	background-color: var(--wcai-brand-50);
	background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23236fef' stroke-width='3.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 6 9 17l-5-5'/%3E%3C/svg%3E");
	background-size: 11px 11px;
	background-position: center;
	background-repeat: no-repeat;
}

/* -- The line-art scene ----------------------------------------------------------------
   Anchored to the panel's bottom edge, full-bleed across its width. `currentColor` on the
   `<g>` is what the ink colour below sets, so the whole drawing recolours from one property
   — the strokes and the three tinted fills each pick it up or override it individually.

   Not `position: absolute` on the SVG element with a `height` — the viewBox is 2:1 and the
   panel is much taller than it is wide, so a height-driven box would scale the drawing up
   until the buildings dwarfed the quote. Pinning left/right/bottom and letting
   `preserveAspectRatio="xMidYMax slice"` crop the sides keeps the buildings at a constant
   scale regardless of how wide the panel gets. */
.wcai-auth__scene {
	position: absolute;
	left: 50%;
	bottom: 0;
	/* Wider than the panel so the outermost buildings and the ground line run past both
	   edges — the skyline should continue beyond the frame rather than sit inside it like a
	   picture. `translateX(-50%)` against `left: 50%` keeps the drawing's centre on the
	   panel's centre while it overhangs symmetrically. */
	width: 118%;
	transform: translateX(-50%);
	/* Taller than the seventh pass's 210px. With the copy bottom-aligned above it, the
	   drawing's height is what decides where the quote sits: at 210px the panel's whole top
	   third was empty canvas. 300px lifts the copy toward the optical centre and gives the
	   artwork enough presence to balance the form column opposite it. */
	height: 300px;
	z-index: 0;
	pointer-events: none;
	color: var(--wcai-brand-700);
	opacity: 0.55;
	/* Fades the top of the skyline into the canvas so the drawing reads as receding into the
	   panel rather than being a band pasted across its bottom edge — the same trick the
	   reference's artwork uses, achieved here without a second asset. */
	-webkit-mask-image: linear-gradient(to bottom, transparent 0%, #000 26%);
	mask-image: linear-gradient(to bottom, transparent 0%, #000 26%);
}

.wcai-auth__scene-ink {
	fill: none;
}

/* Three flat washes behind the line work so the skyline has depth without shading. Kept very
   pale — the drawing is a background texture, and anything stronger competes with the quote
   sitting directly above it. */
.wcai-auth__scene-fill-a {
	fill: rgba(35, 111, 239, 0.07);
}

.wcai-auth__scene-fill-b {
	fill: rgba(217, 119, 66, 0.1);
}

.wcai-auth__scene-fill-c {
	fill: rgba(26, 127, 66, 0.09);
}

/* -- Left form panel -------------------------------------------------------------------
   The column carries the brand lockup at the top and the form card centred beneath it, so
   the logo sits at the panel's top-left corner (the reference's placement) while the form
   stays optically centred in the viewport rather than pushed down by the logo's height. */

/* The logo sits at the column's top-left and the form is optically centred beneath it.

   Both are in normal flow, and the centring comes from `margin: auto 0` on the card (see
   `.wcai-auth__card--split`) rather than `justify-content: center` on this column. That
   distinction is the whole point: auto margins distribute *free* space, so when the card is
   short (login: two fields) it centres, and when the card is tall (register: four fields plus
   the privacy notice) the free space runs out, the auto margins collapse to zero, and the
   card simply starts below the logo.

   The eighth pass had the logo `position: absolute` instead, which centred the card against
   the viewport without the logo's height entering the layout — and on /register that put the
   tall card's own top *above* the logo, so "Create your account" rendered straight through
   the wordmark. Nothing about a fixed offset can fix that; the logo has to occupy real space
   for the card to be pushed clear of it. */
.wcai-auth__form-col {
	position: relative;
	flex: 1 1 54%;
	display: flex;
	flex-direction: column;
	justify-content: flex-start;
	box-sizing: border-box;
	padding: var(--wcai-space-10) var(--wcai-space-12);
	background: var(--wcai-surface-0);
	min-width: 0;
}

/* `margin: auto 0` is what vertically centres the card in the column's remaining space, and
   it is chosen over the column's `justify-content: center` precisely because auto margins
   degrade correctly: they distribute free space when there is any and collapse to zero when
   there is none, so a tall register form can never be pushed up into the logo above it. See
   `.wcai-auth__form-col`. `align-items: center` horizontally centres the form track inside
   the wider column. */
.wcai-auth__card--split {
	flex: 0 0 auto;
	margin: auto 0;
	box-shadow: none;
	border-radius: 0;
	max-width: none;
	width: auto;
	padding: 0;
	display: flex;
	flex-direction: column;
	align-items: center;
}

/* The readable form column inside the wider left panel — a fixed column rather than fields
   stretched to 700px+ on a wide monitor. Direct children rather than a wrapper element so no
   markup change was needed. */
.wcai-auth__card--split > * {
	width: 100%;
	max-width: var(--upx-form-w);
}

/* The <form> needs its own rule at matching specificity rather than relying on the `> *`
   above: the defensive theme-reset near the top of this file
   (`.wcai-page .wcai-auth__card form.login`, specificity 0,3,1) sets `max-width: none` to
   undo the theme's own form width, and that beats `> *`'s (0,2,0) — so without this the form
   alone stretches to the full panel width while every sibling correctly holds 380px. Same
   specificity shape as the reset it has to outrank, no `!important` needed. */
.wcai-page .wcai-auth__card--split form.login,
.wcai-page .wcai-auth__card--split form.register {
	width: 100%;
	max-width: var(--upx-form-w);
}

/* The reference centres the heading, subtitle and the footer link over a left-aligned form.
   Applied to those three rather than the card, so the fields and their labels stay left —
   centring a label above a left-aligned input reads as a mistake. */
.wcai-auth__card--split .wcai-auth__title,
.wcai-auth__card--split .wcai-auth__subtitle,
.wcai-auth__card--split .wcai-auth__footer {
	text-align: center;
}

/* Vertical rhythm for the two *form-less* split states — /lost-password's
   `?reset-link-sent=true` confirmation and /reset-password's invalid-key message. Both are
   heading + subtitle + a single link; the subtitle's bottom margin was sized to bracket a
   form, and with no form between them it stacks into a void that reads as a rendering fault.
   `:has()` keys off the actual absence of a form instead of adding a state-specific class, so
   there is no chance of the class and the branch drifting apart. */
.wcai-auth__card--split:not(:has(form)) .wcai-auth__subtitle {
	margin-bottom: 0;
}

/* Conversely, /reset-password's new-password form state has a heading and no subtitle, so the
   title's small bottom margin (sized as a heading-to-subtitle gap) leaves the first field
   almost touching the <h1>. Keyed on the *card* having no subtitle rather than on the title's
   adjacent sibling: a notice sits between the two on some states, which would make an
   adjacent-sibling test flip this rule on and off depending on whether a validation error
   happens to be showing. */
.wcai-auth__card--split:not(:has(.wcai-auth__subtitle)) .wcai-auth__title {
	margin-bottom: var(--wcai-space-8);
}

/* -- Auth fields ------------------------------------------------------------------------
   Eighth pass (2026-08-07, client-directed): the label moved back *out* of the field box and
   sits above it, and the control grew to `--upx-control-h` (56px).

   The seventh pass and earlier used an "inset" treatment — the border on the wrapper, the
   label inside it above the value, the input stripped bare. That packs a label and a value
   into one 58px box, which is the right trade in a dense settings screen but is what made the
   login form read as small: the actual typing target inside that box was a 24px line, and the
   label competed with the value for the same box. Label above, full-height control below, is
   both larger and calmer, and it matches the client's reference mockups.

   The `--inset` modifier name is kept rather than renamed across four templates: it still
   distinguishes the auth treatment from the plain stacked fields the Account Settings screen
   (`templates/pages/dashboard-account.php`) reuses `.wcai-auth__field`/`__input`/`__label`
   for. Only what the modifier *draws* changed, not which fields opt into it. */
.wcai-auth__field--inset {
	position: relative;
	border: none;
	border-radius: 0;
	background: none;
	padding: 0;
	margin-bottom: var(--wcai-space-5);
}

/* `--wcai-ink-800`, a step darker than the inset treatment's `ink-500`: the label is no
   longer a small caption tucked inside a bordered box, it is the field's heading, and at
   14px it carries that weight. Measures 11.6:1 on white. */
.wcai-auth__field--inset .wcai-auth__label {
	display: block;
	margin-bottom: var(--wcai-space-2);
	font-size: var(--upx-label);
	font-weight: 500;
	line-height: 1.4;
	color: var(--wcai-ink-800);
	letter-spacing: 0;
}

/* `height` set explicitly rather than derived from padding. The theme's
   `keydesign-framework.css` pins every text input to `height: var(--component-height, 50px)`
   through a long type-selector list, so a padding-only control silently renders at the
   theme's height instead of this one — the failure the previous pass documented at
   `height: auto`. Declaring the height this design actually wants overrides it directly and
   is what makes the control 56px rather than 50px.

   16px text, not 15px: below 16px, iOS Safari zooms the viewport on focus, which on a login
   form throws the layout sideways the moment a merchant taps the first field. */
.wcai-auth__field--inset .wcai-auth__input {
	width: 100%;
	box-sizing: border-box;
	height: var(--upx-control-h);
	padding: 0 var(--wcai-space-4);
	border: 1px solid var(--wcai-line-200);
	border-radius: var(--upx-control-r);
	background: var(--wcai-surface-0);
	font-size: var(--upx-input);
	font-family: var(--wcai-font);
	line-height: normal;
	color: var(--wcai-ink-900);
	transition: border-color 0.15s var(--wcai-ease), box-shadow 0.15s var(--wcai-ease);
}

.wcai-auth__field--inset .wcai-auth__input::placeholder {
	color: var(--wcai-ink-400);
}

.wcai-auth__field--inset .wcai-auth__input:focus {
	outline: none;
	border-color: var(--wcai-brand-500);
	box-shadow: var(--wcai-ring);
}

/* Chrome's autofill repaints the input's own background a pale yellow. A long inset shadow is
   the only reliable way to override it (the background property itself is locked by the UA);
   the text colour needs its own property for the same reason. */
.wcai-auth__field--inset .wcai-auth__input:-webkit-autofill,
.wcai-auth__field--inset .wcai-auth__input:-webkit-autofill:hover,
.wcai-auth__field--inset .wcai-auth__input:-webkit-autofill:focus {
	-webkit-box-shadow: 0 0 0 100px var(--wcai-surface-0) inset;
	-webkit-text-fill-color: var(--wcai-ink-900);
	caret-color: var(--wcai-ink-900);
}

/* The invalid state is back on the input itself, now that the input draws the border again —
   the wrapper-level `:has()` rule the inset treatment needed is gone with it. */
.wcai-auth__field--inset .wcai-auth__input--invalid {
	border-color: var(--wcai-error);
}

.wcai-auth__field--inset .wcai-auth__input--invalid:focus {
	border-color: var(--wcai-error);
	box-shadow: var(--wcai-ring-error);
}

/* "Forgot?" sits on the label's row, right-aligned. Absolutely positioned against the field
   wrapper rather than laid out in flow: the label and input are plain siblings (the markup
   WooCommerce's own handlers expect), so there is no row element to make a flex container
   without adding a wrapper div to every password field in every template. `top: 0` and a
   matching `line-height` put it on the label's own baseline. */
.wcai-auth__field--inset .wcai-auth__forgot-link {
	position: absolute;
	top: 0;
	right: 0;
	margin-top: 0;
	font-size: var(--wcai-text-base);
	line-height: 1.4;
	font-weight: 600;
	background: none;
	padding-left: var(--wcai-space-2);
}

.wcai-auth__forgot-link {
	display: block;
	margin-top: var(--wcai-space-2);
	font-size: var(--wcai-text-base);
	color: var(--wcai-brand-500);
	text-decoration: none;
	text-align: right;
}

.wcai-auth__forgot-link:hover {
	color: var(--wcai-brand-600);
	text-decoration: underline;
	text-underline-offset: 2px;
}

/* -- Password visibility toggle --------------------------------------------------------
   The eye control in the client's reference mockup. The button is real (not decorative):
   `auth.js` swaps the input's `type` between `password` and `text` and keeps
   `aria-pressed`/`aria-label` in sync. Rendered only when JS is available — see `auth.js` —
   so it can never sit inert on the page, which is this codebase's established rule about
   non-functional controls. */
.wcai-auth__field--inset:has(.wcai-auth__reveal) .wcai-auth__input {
	/* Reserves the track the button occupies so a long value never runs under it. */
	padding-right: 52px;
}

/* Centred on the input, which is now the wrapper's only full-height child — so the button can
   be anchored to the input's own box (`bottom: 0` + the control height) rather than measured
   back from the wrapper's padding the way the inset treatment required. */
.wcai-auth__reveal {
	position: absolute;
	right: 8px;
	bottom: 0;
	height: var(--upx-control-h);
	width: 40px;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	padding: 0;
	border: none;
	border-radius: var(--wcai-radius-sm);
	background: transparent;
	color: var(--wcai-ink-400);
	cursor: pointer;
	transition: color 0.15s var(--wcai-ease);
}

.wcai-auth__reveal:hover {
	color: var(--wcai-ink-700);
}

.wcai-auth__reveal:focus-visible {
	outline: 2px solid var(--wcai-brand-500);
	outline-offset: -2px;
	color: var(--wcai-ink-700);
}

.wcai-auth__reveal svg {
	width: 20px;
	height: 20px;
	display: block;
	pointer-events: none;
}

/* Only one of the two icons shows at a time, driven off the button's own pressed state, so
   the swap needs no JS beyond flipping the attribute. */
.wcai-auth__reveal .wcai-auth__reveal-off {
	display: none;
}

.wcai-auth__reveal[aria-pressed="true"] .wcai-auth__reveal-on {
	display: none;
}

.wcai-auth__reveal[aria-pressed="true"] .wcai-auth__reveal-off {
	display: block;
}

/* -- Password strength + match hints ---------------------------------------------------
   Both are progressive enhancement written by `auth.js`; the elements are empty and
   `hidden` in the markup until it populates them, so a JS-less visitor sees a clean form
   and the server-side confirm-password check (`RegistrationFields`) still enforces the
   real rule. */
.wcai-auth__hint {
	display: flex;
	align-items: center;
	gap: var(--wcai-space-2);
	margin: calc(var(--wcai-space-2) * -1) 0 var(--wcai-space-4);
	font-size: var(--wcai-text-xs);
	font-weight: 500;
	color: var(--wcai-ink-400);
	min-height: 16px;
}

.wcai-auth__hint[hidden] {
	display: none;
}

.wcai-auth__hint--ok {
	color: var(--wcai-success);
}

.wcai-auth__hint--bad {
	color: var(--wcai-error);
}

.wcai-auth__strength {
	display: flex;
	gap: 4px;
	flex: 0 0 auto;
	width: 76px;
}

.wcai-auth__strength i {
	flex: 1 1 0;
	height: 4px;
	border-radius: var(--wcai-radius-pill);
	background: var(--wcai-line-200);
	transition: background 0.2s var(--wcai-ease);
}

.wcai-auth__strength[data-score="1"] i:nth-child(-n + 1),
.wcai-auth__strength[data-score="2"] i:nth-child(-n + 2),
.wcai-auth__strength[data-score="3"] i:nth-child(-n + 3),
.wcai-auth__strength[data-score="4"] i:nth-child(-n + 4) {
	background: currentColor;
}

/* -- Remember-me toggle ----------------------------------------------------------------
   The real `<input type="checkbox">` stays in the DOM and is only visually hidden (not
   `display: none`), so it remains keyboard-focusable and still submits `rememberme=forever`
   to `WC_Form_Handler::process_login()` unchanged; the track/knob is drawn from the sibling
   span and driven off `:checked`. */
.wcai-auth__field--toggle {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--wcai-space-4);
	margin-bottom: var(--wcai-space-6);
}

.wcai-auth__toggle {
	display: flex;
	align-items: center;
	gap: var(--wcai-space-3);
	font-size: var(--upx-label);
	color: var(--wcai-ink-700);
	cursor: pointer;
	user-select: none;
}

/* Standard visually-hidden recipe, plus `pointer-events: none`: without it the input's 1x1
   absolutely-positioned box still sits under `.wcai-auth__toggle-track`, and a click aimed
   at the input lands on the track span instead. Clicks are meant to reach the input through
   its wrapping <label>, not by hitting the hidden box, so taking the box out of hit-testing
   removes the ambiguity without changing any real interaction — label association and
   keyboard focus both still work. */
.wcai-auth__toggle input {
	position: absolute;
	width: 1px;
	height: 1px;
	margin: 0;
	padding: 0;
	overflow: hidden;
	clip: rect(0 0 0 0);
	clip-path: inset(50%);
	white-space: nowrap;
	border: 0;
	pointer-events: none;
}

.wcai-auth__toggle-track {
	flex: 0 0 auto;
	position: relative;
	display: inline-block;
	width: 38px;
	height: 22px;
	background: var(--wcai-line-200);
	border-radius: var(--wcai-radius-pill);
	transition: background 0.18s var(--wcai-ease);
}

.wcai-auth__toggle-track::after {
	content: "";
	position: absolute;
	top: 3px;
	left: 3px;
	width: 16px;
	height: 16px;
	background: #ffffff;
	border-radius: 50%;
	box-shadow: var(--wcai-shadow-sm);
	transition: transform 0.18s var(--wcai-ease);
}

.wcai-auth__toggle input:checked + .wcai-auth__toggle-track {
	background: var(--wcai-brand-500);
}

.wcai-auth__toggle input:checked + .wcai-auth__toggle-track::after {
	transform: translateX(16px);
}

/* Focus ring lives on the track, since the input it belongs to is visually hidden —
   without this the toggle would be reachable by keyboard but give no focus feedback. */
.wcai-auth__toggle input:focus-visible + .wcai-auth__toggle-track {
	outline: 2px solid var(--wcai-brand-500);
	outline-offset: 2px;
}

/* -- Responsive ------------------------------------------------------------------------ */

/* The scale steps down through the breakpoints by reassigning the auth-scoped size tokens on
   `.wcai-auth` rather than restating each rule's `font-size` — one declaration block per
   breakpoint instead of one per element, and a rule added later inherits the responsive
   behaviour automatically. */
@media (max-width: 1180px) {
	.wcai-auth {
		--upx-title: 34px;
		--upx-quote: 19px;
	}

	.wcai-auth__form-col {
		padding: var(--wcai-space-8) var(--wcai-space-10);
	}

	.wcai-auth__visual {
		padding: var(--wcai-space-10) var(--wcai-space-8);
	}
}

@media (max-width: 900px) {
	.wcai-auth {
		--upx-title: 32px;
		--upx-quote: 18px;
		--upx-control-h: 54px;
	}

	.wcai-auth__panel-wrap {
		flex-direction: column;
	}

	/* Stacked, the form comes first and the decorative panel sits beneath it — which is what
	   the source order already produces, so no `order` is needed. That is the right priority
	   on a phone: the form is why the visitor is here, and burying it under a full-width
	   marketing banner costs a scroll before anything actionable is on screen. */
	.wcai-auth__form-col {
		flex: 0 0 auto;
		padding: var(--wcai-space-8) var(--wcai-space-6) var(--wcai-space-10);
	}

	/* Stacked, the column is only as tall as its content, so there is no free space for the
	   card's `margin: auto 0` to distribute — it already collapses to zero on its own. Zeroing
	   it explicitly is still worth doing: without it, a short viewport that *does* leave slack
	   would centre the form against the panel below rather than sitting under the logo. */
	.wcai-auth__card--split {
		margin: 0;
	}

	/* `flex: 0 0 auto` beats the desktop `flex: 0 0 46%`, which in a column flex container
	   would otherwise mean 46% of the *height*. The border moves from the left edge to the
	   top, since that is where the two panels now meet. */
	/* `justify-content` returns to `flex-start`: stacked, the panel's height is its content's
	   height, so there is no slack for the desktop bottom-alignment to distribute. */
	.wcai-auth__visual {
		flex: 0 0 auto;
		min-height: 0;
		justify-content: flex-start;
		padding: var(--wcai-space-10) var(--wcai-space-6) 0;
		border-left: none;
		border-top: 1px solid var(--wcai-line-100);
	}

	/* The illustration keeps its full height here rather than dropping: stacked, it is what
	   gives the panel a bottom edge, and unlike the previous pass's product-preview card
	   (11px monospace, illegible below desktop widths) line art has no legibility floor. The
	   quote's reserved space shrinks with it. */
	.wcai-auth__scene {
		height: 170px;
	}

	/* A larger clearance than the desktop panel's, not a smaller one: stacked, the checklist
	   runs to two lines per item at this width and ends much closer to the panel's bottom
	   edge, so the drawing needs more room below the copy or the last item sits on top of the
	   buildings. */
	.wcai-auth__visual-body {
		padding-bottom: 175px;
		max-width: none;
	}

	.wcai-auth__quote-mark {
		font-size: 52px;
		margin-bottom: var(--wcai-space-3);
	}

	/* A tighter gap than the desktop list: the panel is now competing with the form above it
	   for the fold instead of having its own half of the viewport. */
	.wcai-auth__visual-points {
		margin-top: var(--wcai-space-5);
		gap: var(--wcai-space-2);
	}

	.wcai-auth__visual-points li {
		font-size: var(--wcai-text-base);
	}
}

@media (max-width: 480px) {
	.wcai-auth {
		--upx-title: 28px;
		--upx-quote: 17px;
		--upx-subtitle: 15px;
	}

	.wcai-auth__form-col {
		padding: var(--wcai-space-6) var(--wcai-space-5) var(--wcai-space-8);
	}

	.wcai-auth__visual {
		padding: var(--wcai-space-8) var(--wcai-space-5) 0;
	}

	/* The logo steps down with the rest — 168px against a 320px-wide column reads oversized,
	   and the artwork stays legible well below that. `!important` is required and is not a
	   specificity shortcut: `brand-logo.php` sets the width as an *inline style* (so a caller
	   can size the lockup per surface without a modifier class per size), and inline styles
	   outrank any selector. This is the documented exception to overriding them. */
	.upx-logo {
		width: 140px !important;
	}

	.wcai-auth__quote-mark {
		font-size: 40px;
	}

	.wcai-auth__scene {
		height: 130px;
	}

	.wcai-auth__visual-body {
		padding-bottom: 135px;
	}
}

/* Honors a system-level reduced-motion preference: the transforms above are decorative
   affordances, not information. */
@media (prefers-reduced-motion: reduce) {
	.wcai-auth *,
	.wcai-auth *::before,
	.wcai-auth *::after {
		transition-duration: 0.01ms !important;
		animation-duration: 0.01ms !important;
	}

	.wcai-auth__button:hover {
		transform: none;
	}

	/* No per-element `transform: none` override needed here. `animation-duration: 0.01ms`
	   above still runs each entrance animation to its `to` keyframe, effectively instantly,
	   and every one of those end states is `opacity: 1; transform: translateY(0)` — nothing
	   left to force. */
}
