/**
 * The member account area.
 *
 * MEASUREMENT
 *
 * Every value above the first media query is read off the two design exports
 * (`member-login.html`, `member-portal.html`) at their 1280px preview width,
 * where the page container is 1240px with 24px of horizontal padding — a 1192px
 * content column. That is the SAME 1192px the cart page lands on, and for the
 * same reason: Astra's `.ast-container` is 1200px at x120 on this site, so a
 * max-width alone centres our column exactly where the design puts it. Adding
 * horizontal padding here would stack on the theme's and squeeze it to 1152.
 *
 * Where a number looks odd — 14.5px, 12.5px, 11.5px, 0.14em — it is odd in the
 * export too. Reproduced rather than tidied, because "tidied" is how a rebuild
 * drifts a pixel at a time.
 *
 * `line-height: normal`, not a number. The design's ratio runs 1.18–1.24 and is
 * Inter's own metrics rather than a chosen value; any single number drifts up to
 * a pixel a line and compounds down the page. Same decision as the cart and the
 * order confirmation.
 *
 * SCOPING
 *
 * Every selector starts `.optic-`, `body.optic-account-page`, or `:root`. This
 * stylesheet loads on a live WordPress page, where an unscoped rule restyles the
 * whole site — `build-account.sh` refuses to build a zip containing one.
 *
 * RESPONSIVE
 *
 * The design exports have no breakpoints; they are desktop renders that stop
 * being usable below about 900px. Everything below the first media query is
 * therefore a DECISION, not a measurement, and is marked as such.
 */

.optic-account,
.optic-auth {
	--oa-blue: #1569ff;
	--oa-blue-hover: #0f5ae0;
	--oa-ink: #181818;
	--oa-slate: #6f7887;
	--oa-faint: #9aa3ae;
	--oa-cloud: #f3f4f6;
	--oa-border: #e6e8ec;
	--oa-card: #fff;
	--oa-tint: #eaf1ff;
	/* Two greens, both on the page: the dark one is text, the light one is only
	   ever a dot or a bar fill. Using the fill colour as a label makes it
	   noticeably lighter than the design. */
	--oa-good: #078a5b;
	--oa-good-bg: rgba( 11, 193, 127, 0.12 );
	--oa-green: #0bc17f;
	--oa-warn: #92600a;
	--oa-warn-bg: rgba( 245, 158, 11, 0.12 );
	--oa-bad: #b33636;
	--oa-bad-bg: rgba( 220, 60, 60, 0.08 );

	--oa-radius: 18px;
	--oa-radius-lg: 22px;
	--oa-radius-sm: 10px;
	--oa-pill: 999px;

	--oa-gap: 16px;
	--oa-pad: 24px;

	box-sizing: border-box;
	width: 100%;
	max-width: 1192px;
	margin: 0 auto;
	padding: 0;
	color: var( --oa-ink );
	font-family: Inter, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
	font-size: 14px;
	line-height: normal;
}

.optic-account *,
.optic-account *::before,
.optic-account *::after,
.optic-auth *,
.optic-auth *::before,
.optic-auth *::after {
	box-sizing: border-box;
}

/* The page background belongs to <body>; every wrapper between is transparent. */
body.optic-account-page {
	background-color: #f3f4f6;
}

/*
 * Astra underlines content links and restyles buttons, and it targets the
 * content area more specifically than a plugin can target its own components —
 * the same fight the cart page and the confirmation page both had. Forced,
 * scoped, and limited to appearance.
 */
.optic-account a,
.optic-account a:hover,
.optic-account a:focus,
.optic-auth a,
.optic-auth a:hover,
.optic-auth a:focus {
	text-decoration: none !important;
	box-shadow: none !important;
}

.optic-account h1,
.optic-account h2,
.optic-auth h1,
.optic-auth h2 {
	margin: 0;
	line-height: normal;
}

.optic-card {
	background: var( --oa-card );
	border: 1px solid var( --oa-border );
	border-radius: var( --oa-radius );
}

.optic-card__title {
	display: block;
	font-size: 15px;
	font-weight: 600;
	color: var( --oa-ink );
}

.optic-label {
	display: block;
	font-size: 11px;
	font-weight: 600;
	letter-spacing: 0.14em;
	text-transform: uppercase;
	color: var( --oa-slate );
}

/* ═══════════════════════════════════════════════════════════════════════════
   SIGN IN / REGISTER / PASSWORD  — member-login.html
   ═══════════════════════════════════════════════════════════════════════════ */

.optic-auth {
	display: flex;
	align-items: center;
	justify-content: center;
	/* The export's 48px top / 72px bottom around a vertically centred card. */
	padding: 48px 0 72px;
}

.optic-auth__card {
	display: flex;
	flex-direction: column;
	gap: 18px;
	width: 100%;
	max-width: 440px;
	padding: 40px;
	background: var( --oa-card );
	border: 1px solid var( --oa-border );
	border-radius: var( --oa-radius-lg );
}

.optic-auth__card--centred {
	text-align: center;
	align-items: center;
}

.optic-auth__head {
	display: flex;
	flex-direction: column;
	gap: 4px;
}

.optic-auth__title {
	font-size: 22px;
	font-weight: 600;
	letter-spacing: -0.02em;
	color: var( --oa-ink );
}

.optic-auth__sub {
	font-size: 13px;
	color: var( --oa-slate );
	line-height: 1.5;
}

.optic-auth__mark {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 56px;
	height: 56px;
	border-radius: 50%;
	background: var( --oa-tint );
	color: var( --oa-blue );
}

.optic-auth__form {
	display: flex;
	flex-direction: column;
	gap: 18px;
	margin: 0;
}

.optic-auth__note,
.optic-auth__legal {
	margin: 0;
	font-size: 11px;
	line-height: 1.6;
	color: var( --oa-slate );
	text-align: center;
}

/*
 * WooCommerce's privacy-policy paragraph, which arrives through
 * `woocommerce_register_form` and is a legal notice this plugin must not drop.
 * It was rendering as full-size body copy inside a 440px card whose every other
 * secondary line is 11px — so it read as the loudest thing on a screen where the
 * email field is the point. Given the card's own small-print treatment.
 */
.optic-auth .woocommerce-privacy-policy-text p,
.optic-auth .woocommerce-privacy-policy-text {
	margin: 0;
	font-size: 11px;
	line-height: 1.6;
	color: var( --oa-slate );
	text-align: center;
}

.optic-auth .woocommerce-privacy-policy-text a {
	color: var( --oa-blue ) !important;
	font-weight: 500;
}

.optic-account .optic-auth__minor,
.optic-auth .optic-auth__minor {
	font-size: 12px;
	font-weight: 500;
	color: var( --oa-blue );
}

/* The "New to Hero?" rule: two hairlines with a label between them. */
.optic-auth__rule {
	display: flex;
	align-items: center;
	gap: 12px;
}

.optic-auth__rule span {
	flex: 1;
	height: 1px;
	background: var( --oa-border );
}

.optic-auth__rule em {
	font-size: 11.5px;
	font-style: normal;
	color: var( --oa-slate );
}

/* ── Fields ──────────────────────────────────────────────────────────────── */

.optic-field {
	display: flex;
	flex-direction: column;
	gap: 6px;
	margin: 0;
}

.optic-field label,
.optic-field > label {
	font-size: 13px;
	font-weight: 500;
	color: var( --oa-slate );
}

.optic-field__row {
	display: flex;
	align-items: baseline;
	justify-content: space-between;
	gap: 12px;
}

.optic-field__hint {
	font-size: 11.5px;
	line-height: 1.5;
	color: var( --oa-faint );
}

.optic-field__lead {
	margin: 0 0 4px;
	font-size: 13px;
	line-height: 1.55;
	color: var( --oa-slate );
}

.optic-account .optic-input,
.optic-auth .optic-input {
	width: 100%;
	/*
	 * ONE height for every field on every form screen. Measured, there were three:
	 * address fields 44px (from the `.optic-form__fields` block, which already
	 * carried this), edit-account text inputs 40px, and every password input 43px —
	 * so the sign-in card stacked a 40px email on a 43px password, and the account
	 * screen mixed 40 and 43 in the same column. 44px is what the design's own
	 * `padding: 12px 14px` on a 14px normal line box comes to; the other two were
	 * the theme's line-height showing through.
	 */
	min-height: 44px;
	padding: 12px 14px;
	border: 1px solid var( --oa-border );
	border-radius: var( --oa-radius-sm );
	background: #fff;
	font-family: inherit;
	font-size: 14px;
	line-height: normal;
	color: var( --oa-ink );
	/* Astra sets its own input styles; this is the whole surface, stated. */
	box-shadow: none;
	appearance: none;
}

.optic-account .optic-input::placeholder,
.optic-auth .optic-input::placeholder {
	color: var( --oa-faint );
}

.optic-account .optic-input:focus,
.optic-auth .optic-input:focus {
	outline: 3px solid rgba( 21, 105, 255, 0.35 );
	outline-offset: -1px;
	border-color: var( --oa-blue );
}

/*
 * The password field's SHOW/HIDE button is injected by account.js, so the
 * padding that makes room for it is applied by the same script — a field that
 * reserves 44px for a control that never arrives has a permanent empty gutter
 * for anybody whose JavaScript is blocked.
 */
.optic-input-wrap {
	position: relative;
	display: flex;
}

.optic-input-wrap .optic-input {
	flex: 1;
}

.optic-input-wrap.has-toggle .optic-input {
	padding-right: 44px;
}

/*
 * WOOCOMMERCE ADDS A SECOND REVEAL BUTTON, and both were rendering.
 *
 * `woocommerce.js` finds every `input[type=password]`, adds `password-input` to
 * its wrapper and appends its own `<button class="show-password-input">` — an
 * eye icon, absolutely positioned at the right edge. On the account-details
 * screen that produced SIX toggles for three fields, stacked on top of one
 * another: measured live as `class="optic-input-wrap has-toggle password-input"`
 * carrying both.
 *
 * WooCommerce's is hidden rather than this plugin's, because the design's
 * control is a text button reading SHOW / HIDE and that is what the export
 * draws. The feature is not lost — it is the same feature, drawn to the design,
 * and `account.js` still creates it on every password field WooCommerce touches.
 *
 * Hidden, not removed: it is WooCommerce's element and its script keeps a
 * reference to it.
 */
.optic-input-wrap .show-password-input {
	display: none !important;
}

.optic-account .optic-reveal,
.optic-auth .optic-reveal {
	position: absolute;
	right: 6px;
	top: 50%;
	transform: translateY( -50% );
	padding: 6px;
	border: 0;
	background: none;
	font-family: inherit;
	font-size: 11.5px;
	font-weight: 600;
	letter-spacing: 0.02em;
	color: var( --oa-slate );
	cursor: pointer;
	/*
	 * Sized for the wider of the two labels so the button does not change width
	 * when it is pressed. `right` pins the trailing edge, so all of the shrink came
	 * off the LEFT edge — 9.4px at 1440px — directly under the pointer that had
	 * just clicked it. In `ch` rather than px because both strings are localisable
	 * through `opticAccount.show` / `.hide`, and a pixel floor only holds in English.
	 *
	 * 6.6ch is measured, not picked. `1ch` in this button's own typography — 600
	 * 11.5px Inter with 0.23px tracking — is 7.578px, and the box is border-box, so
	 * the 49.4px "SHOW" occupies needs 6.52ch. The first cut used 5.5ch, which
	 * resolves to 41.73px: exactly the width of "HIDE". It pinned the button to the
	 * NARROWER label, so the shrink still happened and the fix measured as no fix.
	 */
	min-width: 6.6ch;
	text-align: center;
}

.optic-account .optic-reveal:hover,
.optic-auth .optic-reveal:hover {
	color: var( --oa-ink );
}

/* ── Checkbox ────────────────────────────────────────────────────────────── */

.optic-check {
	display: flex;
	align-items: center;
	gap: 10px;
	font-size: 13px;
	color: var( --oa-ink );
	cursor: pointer;
}

/*
 * The real input, kept in the DOM and kept focusable.
 *
 * `display: none` would take it out of the tab order and stop it being posted
 * by some browsers' autofill — and `rememberme` is the field that decides
 * whether the member is still signed in tomorrow. Clipped to a pixel instead,
 * so it is present, focusable, and posted.
 */
.optic-check__box {
	position: absolute;
	width: 1px;
	height: 1px;
	margin: -1px;
	padding: 0;
	overflow: hidden;
	clip: rect( 0 0 0 0 );
	white-space: nowrap;
	border: 0;
}

.optic-check__mark {
	display: flex;
	flex: none;
	align-items: center;
	justify-content: center;
	width: 20px;
	height: 20px;
	border: 1px solid var( --oa-border );
	border-radius: 6px;
	background: #fff;
	color: transparent;
	transition: background 0.15s ease, border-color 0.15s ease, color 0.15s ease;
}

.optic-check__box:checked + .optic-check__mark {
	background: var( --oa-blue );
	border-color: var( --oa-blue );
	color: #fff;
}

.optic-check__box:focus-visible + .optic-check__mark {
	outline: 3px solid rgba( 21, 105, 255, 0.35 );
	outline-offset: 1px;
}

/* ═══════════════════════════════════════════════════════════════════════════
   BUTTONS
   ═══════════════════════════════════════════════════════════════════════════ */

.optic-account .optic-btn,
.optic-auth .optic-btn {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	flex: 0 0 auto;
	padding: 9px 18px;
	border: 1px solid transparent;
	border-radius: var( --oa-pill ) !important;
	font-family: inherit;
	font-size: 13px;
	font-weight: 600;
	line-height: normal;
	text-align: center;
	cursor: pointer;
	transition: background 0.15s ease, border-color 0.15s ease, color 0.15s ease;
}

.optic-account .optic-btn--primary,
.optic-auth .optic-btn--primary {
	background: var( --oa-blue );
	border-color: var( --oa-blue );
	color: #fff !important;
}

.optic-account .optic-btn--primary:hover,
.optic-auth .optic-btn--primary:hover {
	background: var( --oa-blue-hover );
	border-color: var( --oa-blue-hover );
}

.optic-account .optic-btn--secondary,
.optic-auth .optic-btn--secondary {
	background: #fff;
	border-color: var( --oa-border );
	color: var( --oa-ink ) !important;
}

.optic-account .optic-btn--secondary:hover,
.optic-auth .optic-btn--secondary:hover {
	border-color: var( --oa-blue );
	color: var( --oa-blue ) !important;
}

.optic-account .optic-btn--ghost,
.optic-auth .optic-btn--ghost {
	background: transparent;
	border-color: var( --oa-border );
	color: var( --oa-ink ) !important;
}

.optic-account .optic-btn--ghost:hover,
.optic-auth .optic-btn--ghost:hover {
	border-color: var( --oa-blue );
	color: var( --oa-blue ) !important;
}

/* The login card's full-width primary: 14px/24px padding, 14.5px type. */
.optic-account .optic-btn--block,
.optic-auth .optic-btn--block {
	width: 100%;
	padding: 14px 24px;
	font-size: 14.5px;
}

.optic-account .optic-btn--ghost.optic-btn--block,
.optic-auth .optic-btn--ghost.optic-btn--block {
	padding: 12px 24px;
	font-size: 13.5px;
}

.optic-account .optic-btn--sm {
	padding: 8px 16px;
	font-size: 12.5px;
}

/* The quiet destructive link — cancel a membership. Never a button. */
.optic-account .optic-quiet {
	margin-left: auto;
	font-size: 12.5px;
	font-weight: 500;
	color: var( --oa-slate ) !important;
	text-decoration: underline !important;
	text-underline-offset: 3px;
	cursor: pointer;
}

.optic-account .optic-quiet:hover {
	color: var( --oa-bad ) !important;
}

/* ═══════════════════════════════════════════════════════════════════════════
   THE PORTAL SHELL  — member-portal.html
   ═══════════════════════════════════════════════════════════════════════════ */

.optic-account {
	display: flex;
	flex-direction: column;
	gap: 24px;
	padding: 36px 0 72px;
}

.optic-account__content {
	display: flex;
	flex-direction: column;
	gap: var( --oa-gap );
}

/* ── Hero ────────────────────────────────────────────────────────────────── */

.optic-hero {
	display: flex;
	align-items: center;
	justify-content: space-between;
	flex-wrap: wrap;
	gap: 24px;
	padding: 32px 36px;
	border-radius: var( --oa-radius-lg );
	background: linear-gradient( 180deg, #1569ff 0%, #4884fe 55%, #719fff 100% );
	color: #fff;
}

.optic-hero__intro {
	display: flex;
	flex-direction: column;
	gap: 6px;
	min-width: 0;
}

.optic-hero__eyebrow {
	font-size: 11px;
	font-weight: 600;
	letter-spacing: 0.14em;
	color: rgba( 255, 255, 255, 0.8 );
}

.optic-account .optic-hero__title {
	font-size: 28px;
	font-weight: 500;
	letter-spacing: -0.02em;
	color: #fff;
}

.optic-hero__meta {
	display: inline-flex;
	align-items: center;
	flex-wrap: wrap;
	gap: 8px;
	font-size: 13px;
	color: rgba( 255, 255, 255, 0.85 );
}

.optic-hero__badge {
	padding: 3px 12px;
	border: 1px solid rgba( 255, 255, 255, 0.3 );
	border-radius: var( --oa-pill );
	background: rgba( 255, 255, 255, 0.16 );
	font-size: 11px;
	font-weight: 700;
	letter-spacing: 0.08em;
	/*
	 * Inherited, not #fff. The design declares no colour on the badge, so it
	 * takes the meta line's `rgba(255,255,255,.85)` — the badge is part of that
	 * sentence, not a brighter thing sitting in it.
	 */
	color: inherit;
}

.optic-hero__stats {
	display: flex;
	gap: 28px;
}

.optic-stat {
	display: flex;
	flex-direction: column;
	align-items: flex-end;
	gap: 2px;
}

/*
 * No `line-height` here on purpose. The design sets none on the stat figure, so
 * it resolves to `normal` — Inter's own ~1.21 — which is what `.optic-account`
 * already establishes for the whole subtree. This rule used to pin it to 1.1,
 * the one number in this file that contradicted its own opening rule, and it
 * pulled every stat caption ~1.5px closer to its figure.
 */
.optic-stat__value {
	font-size: 26px;
	font-weight: 600;
	color: #fff;
	white-space: nowrap;
}

/* wc_price() wraps its output; the span must not reassert its own size. */
.optic-stat__value .woocommerce-Price-amount {
	font-size: inherit;
	font-weight: inherit;
	color: inherit;
}

.optic-stat__label {
	font-size: 12px;
	color: rgba( 255, 255, 255, 0.75 );
	white-space: nowrap;
}

/* ── Pills ───────────────────────────────────────────────────────────────── */

.optic-tabs {
	display: flex;
	align-items: center;
	flex-wrap: wrap;
	gap: 8px;
}

.optic-account .optic-tab {
	padding: 9px 18px;
	border: 1px solid var( --oa-border );
	border-radius: var( --oa-pill );
	background: #fff;
	font-size: 13px;
	font-weight: 600;
	color: var( --oa-ink ) !important;
	transition: background 0.15s ease, border-color 0.15s ease, color 0.15s ease;
}

.optic-account .optic-tab:hover {
	border-color: var( --oa-blue );
	color: var( --oa-blue ) !important;
}

.optic-account .optic-tab.is-current {
	background: var( --oa-ink );
	border-color: var( --oa-ink );
	color: #fff !important;
}

.optic-account .optic-tabs__out {
	margin-left: auto;
	font-size: 12.5px;
	font-weight: 500;
	color: var( --oa-slate ) !important;
}

.optic-account .optic-tabs__out:hover {
	color: var( --oa-ink ) !important;
}

/* ── Sub-nav, inside the Account pill ────────────────────────────────────── */

/*
 * A segmented control, so it must be only as wide as its items. As a block-level
 * flex container it stretched the full 1192px and read as an empty white bar
 * with four words at its left end — seen on the live account hub.
 */
.optic-subnav {
	display: inline-flex;
	align-self: flex-start;
	flex-wrap: wrap;
	gap: 6px;
	padding: 5px;
	border: 1px solid var( --oa-border );
	border-radius: var( --oa-pill );
	background: #fff;
}

.optic-account .optic-subnav__item {
	padding: 7px 14px;
	border-radius: var( --oa-pill );
	font-size: 12.5px;
	font-weight: 600;
	color: var( --oa-slate ) !important;
	transition: background 0.15s ease, color 0.15s ease;
}

.optic-account .optic-subnav__item:hover {
	color: var( --oa-ink ) !important;
}

.optic-account .optic-subnav__item.is-current {
	background: var( --oa-cloud );
	color: var( --oa-ink ) !important;
}

/* ── Status pills ────────────────────────────────────────────────────────── */

.optic-pill {
	display: inline-flex;
	align-items: center;
	gap: 6px;
	padding: 4px 12px;
	border-radius: var( --oa-pill );
	font-size: 11.5px;
	font-weight: 600;
	white-space: nowrap;
}

.optic-pill__dot {
	width: 7px;
	height: 7px;
	border-radius: 50%;
	background: currentColor;
	flex: none;
}

.optic-pill--good {
	background: var( --oa-good-bg );
	color: var( --oa-good );
}

.optic-pill--wait {
	background: var( --oa-warn-bg );
	color: var( --oa-warn );
}

.optic-pill--bad {
	background: rgba( 192, 57, 43, 0.1 );
	color: #a5342a;
}

.optic-pill--off {
	background: var( --oa-cloud );
	color: var( --oa-slate );
}

/* ═══════════════════════════════════════════════════════════════════════════
   ORDERS & TRACKING
   ═══════════════════════════════════════════════════════════════════════════ */

.optic-current {
	display: flex;
	flex-direction: column;
	gap: 18px;
	padding: var( --oa-pad );
}

.optic-current__head {
	display: flex;
	align-items: center;
	justify-content: space-between;
	flex-wrap: wrap;
	gap: 10px;
}

.optic-current__id {
	display: flex;
	flex-direction: column;
	gap: 2px;
	min-width: 0;
}

.optic-current__items {
	font-size: 16px;
	font-weight: 600;
	color: var( --oa-ink );
}

.optic-track-wrap {
	display: flex;
	flex-direction: column;
	gap: 8px;
}

/*
 * A single continuous track, which is what THIS design draws — unlike the order
 * confirmation, which splits it into four segments so each sits above the stage
 * it reports. The arithmetic behind the two is shared
 * (`Optic_ThankYou_Page::progress()`), so they can never disagree about where an
 * order is; only the drawing differs, because the two designs differ.
 */
.optic-track {
	display: flex;
	height: 8px;
	border-radius: var( --oa-pill );
	background: var( --oa-cloud );
	overflow: hidden;
}

.optic-track__fill {
	display: block;
	height: 100%;
	border-radius: var( --oa-pill );
	background: var( --oa-blue );
}

.optic-account .optic-steps {
	display: grid;
	grid-template-columns: repeat( 4, 1fr );
	gap: 4px;
	margin: 0;
	padding: 0;
	list-style: none;
	font-size: 11.5px;
	color: var( --oa-slate );
}

.optic-account .optic-steps li {
	margin: 0;
	padding: 0;
	list-style: none;
}

.optic-account .optic-steps li:last-child {
	text-align: right;
}

.optic-step.is-done {
	font-weight: 600;
	color: var( --oa-blue );
}

.optic-actions {
	display: flex;
	align-items: center;
	flex-wrap: wrap;
	gap: 10px;
}

/* ── The history table ───────────────────────────────────────────────────── */

.optic-table {
	overflow: hidden;
}

.optic-table__head {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 12px;
	padding: 18px var( --oa-pad );
	border-bottom: 1px solid var( --oa-border );
}

.optic-table__title {
	font-size: 15px;
	font-weight: 600;
}

.optic-account .optic-table__more {
	font-size: 12px;
	font-weight: 500;
	color: var( --oa-blue ) !important;
}

.optic-table__more--plain {
	color: var( --oa-slate ) !important;
}

/*
 * The row's own grid, matching the export's column widths exactly:
 * 76 / flexible / 70 / 74 / 70 / auto, with a 16px gutter.
 */
/*
 * EVERY ROW IS ITS OWN GRID, so any column that sizes to CONTENT is sized per
 * row — and the columns after it move.
 *
 * The last two used to be `minmax( 70px, auto )` and `auto`. Measured on the live
 * account, that put the date column at three different x positions in one table:
 * 998.9px on the seven rows with a single action, 882.4px on the failed order that
 * offers three (Pay now / View / Cancel), and 976.7px on the refunded one, whose
 * total carries `<del>`+`<ins>` markup and so is wider. 116.5px of drift down a
 * list the design draws as one aligned tabular column.
 *
 * Both are fixed now, so all six tracks resolve identically on every row and the
 * flexible `1fr` items column absorbs the difference instead of the fixed ones.
 *
 * 116px, and the number is measured rather than chosen. The widest set this store
 * produces is a failed order's "Pay now" (51.0px) + "Cancel" (41.5px) with one
 * 12px gap — 104.5px. 116px carries that plus room for a longer translation.
 *
 * It used to be 146px, sized for a three-action set that included "View". That
 * set measured 146.6px against a 146px track, so it wrapped: Cancel fell to a
 * second line and the row stood 34px tall beside its 15px neighbours. "View" is
 * gone now — the order number and the item summary in the same row are both
 * already links to it — which both removes the wrap and hands 30px back to the
 * description column that the fixed-track fix had taken.
 *
 * `flex-wrap` stays on the cell as the safety valve: a third-party action or a
 * long translation wraps rather than pushing the alignment back out.
 *
 * The proper fix for both at once is one grid for the whole table — `display:
 * contents` on the row, columns sized to the widest cell ACROSS rows. It is not
 * done here because the row box carries the padding, the separator and the hover,
 * and below 720px it re-declares itself with `grid-template-areas`; that is a
 * restructure, and this is a cosmetic defect.
 */
.optic-row {
	display: grid;
	grid-template-columns: 76px minmax( 0, 1fr ) 70px 74px 70px 116px;
	align-items: center;
	gap: 16px;
	padding: 14px var( --oa-pad );
}

.optic-row + .optic-row {
	border-top: 1px solid var( --oa-border );
}

.optic-account .optic-row__id {
	font-size: 12.5px;
	font-weight: 600;
	color: var( --oa-slate ) !important;
	white-space: nowrap;
}

.optic-account .optic-row__id:hover {
	color: var( --oa-blue ) !important;
}

.optic-account .optic-row__items {
	min-width: 0;
	overflow: hidden;
	font-size: 13.5px;
	font-weight: 500;
	color: var( --oa-ink ) !important;
	text-overflow: ellipsis;
	white-space: nowrap;
}

.optic-account .optic-row__items:hover {
	color: var( --oa-blue ) !important;
}

.optic-row__date {
	font-size: 12.5px;
	color: var( --oa-slate );
	white-space: nowrap;
}

/* The status pill in a row is centred in a fixed 74px cell, without the dot. */
.optic-row__status {
	justify-content: center;
	width: 74px;
	padding: 3px 10px;
	font-size: 11px;
}

/*
 * The column is `minmax(70px, auto)`, not a flat 70px.
 *
 * The design's 70px fits "$232.75". A REFUNDED order's total is not one figure:
 * `get_formatted_order_total()` returns `<del>$70.00</del> <ins>$0.00</ins>`,
 * which is twice as wide. Measured on the live account, where it overflowed the
 * cell and printed straight through the "View" link beside it.
 *
 * `minmax` keeps the design's width for every ordinary order and lets the one
 * row that needs more take it from the flexible description column.
 */
.optic-row__total {
	font-size: 13.5px;
	font-weight: 600;
	text-align: right;
	white-space: nowrap;
}

/* WooCommerce marks the pre-refund figure up as <del> and the new one as <ins>. */
.optic-row__total del {
	margin-right: 4px;
	font-weight: 500;
	color: var( --oa-faint );
}

.optic-row__total ins {
	text-decoration: none;
}

.optic-row__total .woocommerce-Price-amount {
	font-size: inherit;
	font-weight: inherit;
	color: inherit;
}

.optic-row__actions {
	display: flex;
	align-items: center;
	justify-content: flex-end;
	gap: 12px;
	/* An action set wider than its track wraps rather than widening the column
	   and pushing every fixed column on the row out of line. See `.optic-row`. */
	flex-wrap: wrap;
	row-gap: 4px;
}

.optic-account .optic-row__action {
	font-size: 12.5px;
	font-weight: 600;
	color: var( --oa-blue ) !important;
	white-space: nowrap;
}

/* Cancelling an order is destructive; it is never the same weight as "View". */
.optic-account .optic-row__action--cancel {
	font-weight: 500;
	color: var( --oa-slate ) !important;
}

.optic-account .optic-row__action--cancel:hover {
	color: var( --oa-bad ) !important;
}

/*
 * Text for assistive technology only. Rows share their action labels — several
 * read "View", several read "Reorder" — so the visible label alone never says
 * which order it acts on; the order number rides here instead of cluttering the
 * row.
 *
 * WordPress ships this class, but only on admin screens and only when
 * `wp-admin` styles are loaded — on the front end it must be defined.
 */
.optic-account .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;
}

.optic-row--download {
	grid-template-columns: minmax( 0, 1fr ) 110px 80px auto;
}

/* ── Empty states ────────────────────────────────────────────────────────── */

.optic-empty {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: 8px;
	padding: 32px var( --oa-pad );
}

.optic-account .optic-empty__title {
	margin: 0;
	font-size: 15px;
	font-weight: 600;
	color: var( --oa-ink );
}

.optic-account .optic-empty__text {
	margin: 0 0 6px;
	max-width: 46ch;
	font-size: 13px;
	line-height: 1.55;
	color: var( --oa-slate );
}

.optic-pager {
	display: flex;
	align-items: center;
	justify-content: center;
	gap: 14px;
}

.optic-pager__count {
	font-size: 12.5px;
	color: var( --oa-slate );
}

/* ═══════════════════════════════════════════════════════════════════════════
   ORDER DETAIL
   ═══════════════════════════════════════════════════════════════════════════ */

.optic-order {
	display: flex;
	flex-direction: column;
	gap: var( --oa-gap );
}

.optic-account .optic-back {
	align-self: flex-start;
	font-size: 12.5px;
	font-weight: 600;
	color: var( --oa-slate ) !important;
}

.optic-account .optic-back:hover {
	color: var( --oa-blue ) !important;
}

.optic-meta {
	display: grid;
	grid-template-columns: repeat( 4, 1fr );
	gap: 12px;
	padding: 20px var( --oa-pad );
}

.optic-meta__item {
	display: flex;
	flex-direction: column;
	gap: 2px;
	min-width: 0;
}

.optic-meta__value {
	font-size: 15px;
	font-weight: 600;
	color: var( --oa-ink );
}

.optic-meta__value .woocommerce-Price-amount {
	font-size: inherit;
	font-weight: inherit;
	color: inherit;
}

.optic-notes {
	padding: 20px var( --oa-pad );
}

.optic-account .optic-notes__list {
	display: flex;
	flex-direction: column;
	gap: 12px;
	margin: 12px 0 0;
	padding: 0;
	list-style: none;
}

.optic-account .optic-notes__list li {
	margin: 0;
	padding: 0;
	list-style: none;
}

.optic-note {
	display: grid;
	grid-template-columns: 92px minmax( 0, 1fr );
	gap: 12px;
	font-size: 13px;
	line-height: 1.55;
}

.optic-note__date {
	font-size: 12px;
	color: var( --oa-slate );
}

.optic-account .optic-note__body p {
	margin: 0;
	color: var( --oa-ink );
}

.optic-items {
	overflow: hidden;
}

.optic-account .optic-items__head {
	padding: 18px var( --oa-pad );
	border-bottom: 1px solid var( --oa-border );
	font-size: 15px;
	font-weight: 600;
}

.optic-item {
	display: grid;
	grid-template-columns: 60px minmax( 0, 1fr ) auto;
	align-items: center;
	gap: 16px;
	padding: 18px var( --oa-pad );
}

.optic-item + .optic-item {
	border-top: 1px solid var( --oa-border );
}

.optic-item__thumb {
	width: 60px;
	height: 60px;
	border-radius: 12px;
	overflow: hidden;
	background: linear-gradient( 180deg, #eaf3fc 0%, #d2e3f5 100% );
}

.optic-item__thumb img {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
}

.optic-item__text {
	min-width: 0;
}

.optic-item__name {
	font-size: 14.5px;
	font-weight: 600;
	color: var( --oa-ink );
}

.optic-item__meta {
	margin-top: 3px;
	font-size: 12.5px;
	color: var( --oa-slate );
}

/* wc_display_item_meta() prints a <ul>; flatten it onto the one line. */
.optic-item__meta ul,
.optic-item__meta li,
.optic-item__meta p {
	display: inline;
	margin: 0;
	padding: 0;
	list-style: none;
	font-size: inherit;
	color: inherit;
}

.optic-item__meta li::after {
	content: " · ";
}

.optic-item__price {
	font-size: 14.5px;
	font-weight: 600;
	white-space: nowrap;
}

.optic-totals {
	margin: 0;
	padding: 0 var( --oa-pad );
	border-top: 1px solid var( --oa-border );
}

.optic-total {
	display: flex;
	align-items: baseline;
	justify-content: space-between;
	gap: 12px;
	padding: 12px 0;
	font-size: 13px;
	color: var( --oa-slate );
}

.optic-total + .optic-total {
	border-top: 1px solid var( --oa-border );
}

.optic-total dt,
.optic-total dd {
	margin: 0;
}

.optic-total dd {
	font-weight: 600;
	color: var( --oa-ink );
	white-space: nowrap;
}

.optic-total.is-grand,
.optic-total.is-grand dd {
	font-size: 14.5px;
	font-weight: 700;
	color: var( --oa-ink );
}

/*
 * The shipping method reads BEFORE its amount — the same fix, for the same
 * reason, as the order confirmation. WooCommerce builds the value as
 * `<amount>&nbsp;<small class="shipped_via">via …</small>`, which leaves the one
 * figure in the column not ending at the column's right edge.
 */
.optic-total dd:has( .shipped_via ) {
	display: flex;
	flex-direction: row-reverse;
	flex-wrap: wrap;
	align-items: baseline;
	justify-content: flex-start;
}

.optic-total dd:has( .shipped_via ) .shipped_via {
	margin-right: 6px;
	font-size: 11.5px;
	font-weight: 400;
	color: var( --oa-slate );
}

/* `auto-fit` so a lone billing card fills the row — see thankyou.css. */
.optic-addresses {
	display: grid;
	grid-template-columns: repeat( auto-fit, minmax( 240px, 1fr ) );
	gap: var( --oa-gap );
	align-items: start;
}

.optic-address {
	padding: 20px var( --oa-pad );
}

.optic-account .optic-address address,
.optic-account .optic-hub__pair address {
	margin: 8px 0 0;
	font-style: normal;
	font-size: 13.5px;
	line-height: 1.6;
	color: var( --oa-ink );
}

.optic-account .optic-address__email {
	display: inline-block;
	margin-top: 5px;
	font-size: 12.5px;
	color: var( --oa-blue ) !important;
}

.optic-account .optic-address__email:hover {
	text-decoration: underline !important;
}

.optic-account .optic-support {
	margin: 5px 0 0;
	text-align: center;
	font-size: 11.5px;
	color: var( --oa-slate );
}

.optic-account .optic-support a {
	margin-left: 6px;
	font-weight: 600;
	color: var( --oa-blue ) !important;
}

/*
 * WooCommerce's own "Order again" button, which arrives through
 * `woocommerce_order_details_after_order_table`. It is not ours to re-mark-up —
 * it is another plugin's hook point — so it is styled where it lands.
 */
.optic-account .woocommerce-button,
.optic-account .button.order-again {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	margin: 0 var( --oa-pad ) 20px;
	padding: 8px 16px;
	border: 1px solid var( --oa-border );
	border-radius: var( --oa-pill ) !important;
	background: #fff;
	font-family: inherit;
	font-size: 12.5px;
	font-weight: 600;
	color: var( --oa-ink ) !important;
}

/* ═══════════════════════════════════════════════════════════════════════════
   SPECIAL DEALS
   ═══════════════════════════════════════════════════════════════════════════ */

.optic-deals {
	display: grid;
	grid-template-columns: repeat( 3, minmax( 0, 1fr ) );
	gap: var( --oa-gap );
	/* The tag badge sits 11px above each card; without room the first row clips. */
	padding-top: 11px;
}

.optic-deal {
	position: relative;
	display: flex;
	flex-direction: column;
	gap: 12px;
	padding: 26px;
	background: var( --oa-card );
	border: 1px solid var( --oa-border );
	border-radius: var( --oa-radius );
}

.optic-deal__tag {
	position: absolute;
	top: -11px;
	left: 20px;
	padding: 4px 12px;
	border-radius: var( --oa-pill );
	background: var( --oa-blue );
	font-size: 10px;
	font-weight: 700;
	letter-spacing: 0.08em;
	color: #fff;
	white-space: nowrap;
}

.optic-deal__headline {
	font-size: 24px;
	font-weight: 600;
	letter-spacing: -0.02em;
	color: var( --oa-blue );
}

.optic-deal__name {
	font-size: 15px;
	font-weight: 600;
	color: var( --oa-ink );
}

.optic-deal__desc {
	font-size: 13px;
	line-height: 1.55;
	color: var( --oa-slate );
}

.optic-deal__foot {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 12px;
	margin-top: auto;
}

.optic-account .optic-code {
	padding: 6px 12px;
	border: 0;
	border-radius: var( --oa-radius-sm );
	background: var( --oa-tint );
	font-family: ui-monospace, "SF Mono", Menlo, monospace;
	font-size: 12px;
	font-weight: 600;
	color: var( --oa-blue );
	cursor: pointer;
	/* Still selectable for anyone whose browser refuses the clipboard API. */
	user-select: text;
}

.optic-account .optic-code.is-copied {
	background: var( --oa-good-bg );
	color: var( --oa-good );
}

.optic-deal__on {
	font-size: 12px;
	font-weight: 600;
	color: var( --oa-good );
}

/* ═══════════════════════════════════════════════════════════════════════════
   MEMBERSHIP
   ═══════════════════════════════════════════════════════════════════════════ */

.optic-membership {
	display: grid;
	grid-template-columns: 1.2fr 1fr;
	gap: var( --oa-gap );
	align-items: start;
}

.optic-membership + .optic-membership {
	margin-top: var( --oa-gap );
}

.optic-plan {
	display: flex;
	flex-direction: column;
	gap: 18px;
	padding: 26px;
}

.optic-plan__head {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 12px;
}

.optic-plan__product {
	display: flex;
	align-items: center;
	gap: 14px;
	padding: 16px 18px;
	border-radius: 14px;
	background: linear-gradient( 180deg, #eaf3fc 0%, #d2e3f5 100% );
}

.optic-plan__thumb {
	flex: none;
	width: 56px;
	height: 56px;
	border-radius: 12px;
	overflow: hidden;
	background: #fff;
}

.optic-plan__thumb img {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: contain;
}

/*
 * The stand-in for a product with no image of its own — which is every
 * membership, because a membership is not a thing with a photograph. Same 56px
 * tile as the design's product image, so the row's geometry is unchanged.
 */
.optic-plan__mark {
	display: flex;
	flex: none;
	align-items: center;
	justify-content: center;
	width: 56px;
	height: 56px;
	border-radius: 12px;
	background: #fff;
	color: var( --oa-blue );
}

.optic-plan__names {
	display: flex;
	flex: 1;
	flex-direction: column;
	gap: 1px;
	min-width: 0;
}

.optic-plan__name {
	font-size: 14.5px;
	font-weight: 600;
	color: var( --oa-ink );
}

.optic-plan__terms {
	font-size: 12.5px;
	line-height: 1.45;
	color: var( --oa-slate );
}

.optic-plan__price {
	flex: none;
	font-size: 16px;
	font-weight: 700;
	text-align: right;
	color: var( --oa-ink );
}

.optic-plan__price .woocommerce-Price-amount {
	font-size: inherit;
	font-weight: inherit;
	color: inherit;
}

/* WooCommerce Subscriptions appends "/ month" in a <span class="subscription-details">. */
.optic-plan__price .subscription-details {
	font-size: 12.5px;
	font-weight: 500;
	color: var( --oa-slate );
}

.optic-facts {
	display: flex;
	flex-direction: column;
	margin: 0;
}

.optic-fact {
	display: flex;
	align-items: baseline;
	justify-content: space-between;
	gap: 16px;
	padding: 10px 0;
	border-bottom: 1px solid var( --oa-border );
	font-size: 13px;
}

.optic-fact:last-child {
	border-bottom: 0;
}

.optic-fact dt,
.optic-fact dd {
	margin: 0;
}

.optic-fact dt {
	color: var( --oa-slate );
}

.optic-fact dd {
	font-weight: 600;
	color: var( --oa-ink );
	text-align: right;
}

.optic-account .optic-fact__edit {
	margin-left: 8px;
	font-size: 12px;
	font-weight: 500;
	color: var( --oa-blue ) !important;
}

.optic-account .optic-alert {
	margin: 0;
	padding: 12px 14px;
	border: 1px solid rgba( 245, 158, 11, 0.3 );
	border-radius: var( --oa-radius-sm );
	background: var( --oa-warn-bg );
	font-size: 12.5px;
	line-height: 1.55;
	color: var( --oa-warn );
}

.optic-account .optic-alert--plain {
	border-color: var( --oa-border );
	background: var( --oa-cloud );
	color: var( --oa-slate );
}

.optic-account .optic-hint {
	margin: 0;
	font-size: 12px;
	line-height: 1.5;
	color: var( --oa-slate );
}

.optic-side {
	display: flex;
	flex-direction: column;
	gap: var( --oa-gap );
}

.optic-benefits-card {
	display: flex;
	flex-direction: column;
	gap: 12px;
	padding: 26px;
}

.optic-account .optic-benefits {
	display: flex;
	flex-direction: column;
	gap: 10px;
	margin: 0;
	padding: 0;
	list-style: none;
	font-size: 13px;
	color: var( --oa-ink );
}

.optic-account .optic-benefits li {
	display: flex;
	align-items: center;
	gap: 10px;
	margin: 0;
	padding: 0;
	list-style: none;
	/* The design sets none here; `normal` is what the rest of this file uses. */
	line-height: normal;
}

.optic-benefits__dot {
	flex: none;
	width: 7px;
	height: 7px;
	border-radius: 50%;
	background: var( --oa-green );
}

.optic-help {
	display: flex;
	flex-direction: column;
	gap: 10px;
	padding: 22px var( --oa-pad );
	border-radius: var( --oa-radius );
	background: var( --oa-tint );
}

.optic-help__title {
	font-size: 14px;
	font-weight: 600;
	color: var( --oa-ink );
}

.optic-help__text {
	font-size: 12.5px;
	line-height: 1.55;
	color: var( --oa-slate );
}

.optic-account .optic-help a {
	font-size: 13px;
	font-weight: 600;
	color: var( --oa-blue ) !important;
}

/* ── Not a member yet ────────────────────────────────────────────────────── */

.optic-join {
	padding: 32px 36px;
	border-radius: var( --oa-radius-lg );
	background: var( --oa-tint );
}

.optic-join__text {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: 10px;
	max-width: 56ch;
}

.optic-account .optic-join__title {
	font-size: 22px;
	font-weight: 600;
	letter-spacing: -0.02em;
}

.optic-account .optic-join__sub {
	margin: 0;
	font-size: 13.5px;
	line-height: 1.55;
	color: var( --oa-slate );
}

/* ═══════════════════════════════════════════════════════════════════════════
   ACCOUNT HUB, FORMS, CARDS
   ═══════════════════════════════════════════════════════════════════════════ */

.optic-hub {
	display: grid;
	grid-template-columns: 1fr 1fr;
	gap: var( --oa-gap );
	align-items: start;
}

.optic-hub__card {
	display: flex;
	flex-direction: column;
	gap: 14px;
	padding: var( --oa-pad );
}

.optic-hub__head {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 12px;
}

.optic-account .optic-hub__edit {
	font-size: 12.5px;
	font-weight: 600;
	color: var( --oa-blue ) !important;
}

.optic-hub__pair {
	display: grid;
	grid-template-columns: 1fr 1fr;
	gap: 16px;
}

.optic-account .optic-hub__cards {
	display: flex;
	flex-direction: column;
	gap: 8px;
	margin: 0;
	padding: 0;
	list-style: none;
	font-size: 13.5px;
	font-weight: 500;
}

.optic-account .optic-hub__cards li {
	margin: 0;
	padding: 0;
	list-style: none;
}

.optic-account .optic-hub__none {
	margin: 0;
	font-size: 13px;
	line-height: 1.55;
	color: var( --oa-slate );
}

.optic-hub__card--out {
	align-items: flex-start;
}

.optic-tagline {
	margin-left: 6px;
	padding: 2px 8px;
	border-radius: var( --oa-pill );
	background: var( --oa-tint );
	font-size: 10.5px;
	font-weight: 600;
	letter-spacing: 0.06em;
	text-transform: uppercase;
	color: var( --oa-blue );
}

.optic-form {
	display: flex;
	flex-direction: column;
	gap: var( --oa-gap );
	margin: 0;
}

.optic-form__card {
	display: flex;
	flex-direction: column;
	gap: 16px;
	padding: 26px;
}

.optic-form__grid {
	display: grid;
	grid-template-columns: 1fr 1fr;
	gap: 16px;
}

.optic-form__foot {
	display: flex;
	align-items: center;
	gap: 12px;
}

/*
 * "Save changes" sat 3px right and 13px low of where "Save address" sits, on two
 * screens that are otherwise the same form.
 *
 * `woocommerce-grid.min.css` ships
 * `.woocommerce-account .woocommerce-EditAccountForm .woocommerce-Button
 * { margin-top: 1em; margin-left: 3px }`, and it reaches only this button because
 * `form-edit-account.php` carries the `woocommerce-Button` class and
 * `form-edit-address.php` does not. The class stays — third-party scripts target
 * it — and the margin it drags along is cancelled here instead.
 */
body.optic-account-page .optic-form__foot .optic-btn {
	margin: 0;
}

/*
 * WooCommerce's own `woocommerce_form_field()` markup, styled where it lands.
 * See `templates/myaccount/form-edit-address.php` for why these inputs are not
 * hand-written: the country and state selectors, the per-country field ordering
 * and the postcode rules all come from WooCommerce's address locales, and
 * reproducing that markup means reproducing that table.
 */
.optic-form__fields {
	display: grid;
	grid-template-columns: 1fr 1fr;
	gap: 16px;
}

.optic-account .optic-form__fields .form-row {
	display: flex;
	flex-direction: column;
	gap: 6px;
	margin: 0;
	padding: 0;
}

.optic-account .optic-form__fields .form-row-wide,
.optic-account .optic-form__fields #billing_address_1_field,
.optic-account .optic-form__fields #billing_address_2_field,
.optic-account .optic-form__fields #shipping_address_1_field,
.optic-account .optic-form__fields #shipping_address_2_field {
	grid-column: 1 / -1;
}

.optic-account .optic-form__fields label {
	font-size: 13px;
	font-weight: 500;
	color: var( --oa-slate );
}

/*
 * The required marker, raised above WooCommerce's own.
 *
 * `woocommerce-grid.min.css` ships `.woocommerce form .form-row .required
 * { color: red; font-weight: 700 }` at (0,3,1) and the rule here was (0,3,0), so
 * it lost by one point: the address asterisk computed pure rgb(255,0,0) and bold,
 * against a design whose palette contains no pure red. The SAME span on
 * edit-account computed rgb(111,120,135) — identical to the label beside it, so
 * the marker was invisible on the one screen where two empty required fields
 * silently refuse the whole form.
 *
 * `font-weight` is declared for the same reason as the colour: the winning
 * WooCommerce rule sets both, so correcting only the colour left the two screens
 * bold and regular and still not matching. The second selector reaches the
 * hand-written labels on edit-account, and `margin-left` gives them the space
 * WooCommerce's own `&nbsp;` gives the address ones — without editing either
 * template.
 */
body.optic-account-page .optic-form__fields .form-row .required,
.optic-account .optic-field label .required {
	color: var( --oa-bad );
	font-weight: 400;
	margin-left: 3px;
	text-decoration: none;
}

.optic-account .optic-form__fields input[type="text"],
.optic-account .optic-form__fields input[type="email"],
.optic-account .optic-form__fields input[type="tel"],
.optic-account .optic-form__fields select,
.optic-account .optic-form__fields .select2-selection {
	width: 100%;
	height: auto;
	min-height: 44px;
	padding: 12px 14px;
	border: 1px solid var( --oa-border );
	border-radius: var( --oa-radius-sm );
	/*
	 * LONGHAND, and that is the entire point. As `background: #fff` this shorthand
	 * also reset `background-image`, which is what erased the dropdown caret from
	 * the Country/Region and State selects — a 250-item picker that looked exactly
	 * like a text input. Proven by disabling this stylesheet on the live page,
	 * which flipped the computed `background-image` from `none` straight back to
	 * the theme's arrow. The caret is painted below rather than borrowed back:
	 * relying on Astra to keep shipping its inline SVG is not a design decision.
	 */
	background-color: #fff;
	font-family: inherit;
	font-size: 14px;
	line-height: normal;
	color: var( --oa-ink );
	box-shadow: none;
}

.optic-account .optic-form__fields input:focus,
.optic-account .optic-form__fields select:focus {
	outline: 3px solid rgba( 21, 105, 255, 0.35 );
	outline-offset: -1px;
	border-color: var( --oa-blue );
}

/* Select2 is what WooCommerce upgrades the country/state selects into. */
.optic-account .optic-form__fields .select2-selection__rendered {
	padding: 0 !important;
	line-height: normal !important;
	color: var( --oa-ink ) !important;
}

/*
 * Select2's own arrow element is NOT styled back into view, and the rule that
 * used to try is gone. WooCommerce's grid CSS sets that `b` to `display: none` at
 * 0x0, so the rule was decorating something permanently invisible — and
 * un-hiding it would make this design depend on Astra continuing to ship its
 * inline arrow SVG. The caret is drawn here instead, on both the plain `<select>`
 * and the Select2 box that replaces it, so the two look the same during the
 * moment before Select2 upgrades the field.
 *
 * At (0,4,2) — the `.form-row` is there for the specificity, same as the border
 * block near the end of this file — so it clears both Astra and WooCommerce.
 */
body.optic-account-page .optic-form__fields .form-row select,
body.optic-account-page .optic-form__fields .form-row .select2-selection {
	padding-right: 38px;
	background-color: #fff;
	background-image: url( "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8' fill='none'%3E%3Cpath d='M1 1.5L6 6.5L11 1.5' stroke='%236F7887' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E" );
	background-repeat: no-repeat;
	background-position: right 14px center;
	background-size: 12px 8px;
	appearance: none;
	-webkit-appearance: none;
}

/*
 * Select2 ships `.select2-container .select2-selection--single { margin: 0 0 -4px }`,
 * and that negative margin ate exactly 4px of the wrapper's content height — so
 * the Country and State rows stood 62px where every other row stood 66px.
 *
 * Cancelled at the cause. Every line-height experiment failed to move it, which
 * is the tell: it was never the text box, it was the margin underneath it.
 */
body.optic-account-page .optic-form__fields .select2-container .select2-selection--single {
	margin-bottom: 0;
}

/* ── Saved cards ─────────────────────────────────────────────────────────── */

.optic-cards {
	display: flex;
	flex-direction: column;
	gap: 10px;
}

.optic-cardrow {
	display: grid;
	grid-template-columns: 20px minmax( 0, 1fr ) auto auto;
	align-items: center;
	gap: 14px;
	padding: 16px var( --oa-pad );
}

.optic-cardrow__brand {
	display: flex;
	color: var( --oa-slate );
}

.optic-cardrow__label {
	font-size: 14px;
	font-weight: 600;
	color: var( --oa-ink );
}

.optic-cardrow__expiry {
	font-size: 12.5px;
	color: var( --oa-slate );
	white-space: nowrap;
}

.optic-cardrow__actions {
	display: flex;
	gap: 14px;
}

.optic-account .optic-cardrow__action {
	font-size: 12.5px;
	font-weight: 600;
	color: var( --oa-blue ) !important;
	white-space: nowrap;
}

.optic-account .optic-cardrow__action.is-destructive {
	font-weight: 500;
	color: var( --oa-slate ) !important;
}

.optic-account .optic-cardrow__action.is-destructive:hover {
	color: var( --oa-bad ) !important;
}

/* ═══════════════════════════════════════════════════════════════════════════
   WOOCOMMERCE NOTICES — the design's error banner
   ═══════════════════════════════════════════════════════════════════════════ */

/*
 * Restyled where WooCommerce prints them rather than reprinted inside the card.
 * Two notice regions on a login page means an error can appear twice, or — far
 * worse — appear in the pretty one and not in the real one.
 */
body.optic-account-page .woocommerce-error,
body.optic-account-page .woocommerce-message,
body.optic-account-page .woocommerce-info,
body.optic-account-page .woocommerce-notice {
	box-sizing: border-box;
	width: 100%;
	max-width: 1192px;
	margin: 0 auto;
	padding: 12px 16px;
	border: 1px solid var( --oa-border, #e6e8ec );
	border-radius: 10px;
	background: #fff;
	font-family: Inter, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
	font-size: 12.5px;
	line-height: 1.55;
	list-style: none;
	color: #181818;
}

body.optic-account-page .woocommerce-error {
	border-color: rgba( 220, 60, 60, 0.25 );
	background: rgba( 220, 60, 60, 0.08 );
	color: #b33636;
}

body.optic-account-page .woocommerce-message {
	border-color: rgba( 11, 193, 127, 0.3 );
	background: rgba( 11, 193, 127, 0.12 );
	color: #078a5b;
}

body.optic-account-page .woocommerce-info {
	border-color: rgba( 21, 105, 255, 0.25 );
	background: #eaf1ff;
	color: #0f5ae0;
}

body.optic-account-page .woocommerce-error li,
body.optic-account-page .woocommerce-message li,
body.optic-account-page .woocommerce-info li {
	margin: 0;
	padding: 0;
	list-style: none;
}

body.optic-account-page .woocommerce-error::before,
body.optic-account-page .woocommerce-message::before,
body.optic-account-page .woocommerce-info::before {
	content: none;
}

/*
 * On the login screen the notice belongs above the 440px card, not spanning the
 * full column — otherwise "Incorrect email or password" is a banner four times
 * wider than the form it is about.
 *
 * The spacing above the card is closed from a BODY CLASS, not with a negative
 * margin and not with a `.woocommerce-error + .optic-auth` sibling rule.
 * `.optic-auth` carries 48px of top padding to centre its card, and a notice
 * above it needs that reduced — but only when a notice is actually there. The
 * sibling form would work and is unscoped by this stylesheet's own rule (its
 * first compound is a WooCommerce class, so it reads as a rule that could apply
 * anywhere). `Optic_Account::body_class()` asks `wc_notice_count()` instead,
 * which it can do because notices are queued on `wp_loaded`, long before the
 * theme calls `body_class()`.
 */
body.optic-account-out .woocommerce-error,
body.optic-account-out .woocommerce-message,
body.optic-account-out .woocommerce-info {
	max-width: 440px;
	margin-top: 48px;
}

body.optic-has-notice .optic-auth {
	padding-top: 18px;
}

/*
 * Astra prints the page title above the content, and the portal's gradient hero
 * already says who you are — "My account" in the theme's H1 above "Welcome back,
 * Jordan" is the same sentence twice, in a worse typeface. The filters in
 * `class-optic-account.php` handle the themes that offer one; this is the
 * fallback for the ones that do not, scoped to this page so it cannot hide a
 * heading anywhere else.
 */
body.optic-account-page .entry-title,
body.optic-account-page .ast-archive-title {
	display: none;
}

/* ═══════════════════════════════════════════════════════════════════════════
   THE SCREENS THIS PLUGIN DELIBERATELY DOES NOT REBUILD
   ═══════════════════════════════════════════════════════════════════════════

   Two screens keep WooCommerce's own markup, on purpose:

     - `view-subscription`, WooCommerce Subscriptions' detail page. It carries
       switching, change-payment-method, resubscribe, the related-order tables
       and whatever an extension has added. Rebuilding it would mean owning that
       list forever, and losing a control to a redesign is worse than a table
       that is merely consistent rather than bespoke.
     - `add-payment-method`, which renders the GATEWAY's own card form. That form
       is Square's tokeniser; its markup belongs to the payment plugin.

   So they are styled where they land. This is the seam, and it is a deliberate,
   bounded one: same fonts, same card, same colours, same radii — a table rather
   than the design's fact rows.
   ═══════════════════════════════════════════════════════════════════════════ */

.optic-account__content > h2,
.optic-account__content > h3 {
	margin: 0;
	font-size: 15px;
	font-weight: 600;
	color: var( --oa-ink );
}

.optic-account__content table.shop_table,
.optic-account__content table.woocommerce-table {
	width: 100%;
	margin: 0;
	border: 1px solid var( --oa-border );
	border-radius: var( --oa-radius );
	border-collapse: separate;
	border-spacing: 0;
	background: var( --oa-card );
	overflow: hidden;
	font-size: 13.5px;
}

.optic-account__content table.shop_table th,
.optic-account__content table.shop_table td {
	padding: 14px var( --oa-pad );
	border: 0;
	border-bottom: 1px solid var( --oa-border );
	text-align: left;
	vertical-align: middle;
}

.optic-account__content table.shop_table th {
	font-size: 11px;
	font-weight: 600;
	letter-spacing: 0.14em;
	text-transform: uppercase;
	color: var( --oa-slate );
}

.optic-account__content table.shop_table tr:last-child td {
	border-bottom: 0;
}

.optic-account__content table.shop_table td.woocommerce-orders-table__cell-order-actions,
.optic-account__content table.shop_table td[data-title="Actions"] {
	text-align: right;
}

/* WooCommerce's own buttons, wherever they land on an unswapped screen. */
.optic-account__content .button,
.optic-account__content button.button,
.optic-account__content input.button {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-height: 36px;
	padding: 8px 16px;
	border: 1px solid var( --oa-border );
	border-radius: var( --oa-pill ) !important;
	background: #fff;
	font-family: inherit;
	font-size: 12.5px;
	font-weight: 600;
	color: var( --oa-ink ) !important;
	box-shadow: none;
}

.optic-account__content .button.alt,
.optic-account__content button.button[type="submit"] {
	border-color: var( --oa-blue );
	background: var( --oa-blue );
	color: #fff !important;
}

.optic-account__content .subscription_details,
.optic-account__content .order_details {
	margin-top: var( --oa-gap );
}

/* =========================================================================
   THEME OVERRIDES
   Astra styles headings, lists, paragraphs and <address> inside the content
   area more specifically than a plugin can style its own components. Each rule
   here exists because the theme was winning — the same list the cart page and
   the order confirmation each had to write.
   ========================================================================= */

/*
 * The auth screens' heading is an H1, not an H2.
 *
 * The theme's page title is hidden on this page (the portal's gradient hero is
 * the H1 there), which on a sign-in screen would otherwise leave the document
 * with no top-level heading at all. Astra styles H1 far more aggressively than
 * H2 — 2.85rem with its own line-height — so both have to be pinned here.
 */
body.optic-account-page .optic-account h1,
body.optic-account-page .optic-account h2,
body.optic-account-page .optic-auth h1,
body.optic-account-page .optic-auth h2 {
	margin: 0;
	line-height: normal;
	font-family: inherit;
}

body.optic-account-page .optic-account p,
body.optic-account-page .optic-auth p {
	margin-bottom: 0;
}

/*
 * The list reset, minus the one list that is not a list.
 *
 * WooCommerce prints an error notice as `<ul class="woocommerce-error">` while a
 * success and an info notice are `<div>`s. Inside `.optic-account` this reset is
 * (0,2,2) and the notice block above is (0,2,1), so the reset won and every error
 * notice on an account screen rendered with `padding: 0` — a 21px strip of red
 * text where the green one beside it was a padded 45px card.
 *
 * It survived because nothing on these screens had ever PRODUCED an error notice.
 * It took a Reorder of an order holding a variable product with no variation —
 * which WooCommerce refuses and reports — to draw one for the first time.
 *
 * Excluded rather than out-specified: the notice block already says what a notice
 * looks like, and a second rule repeating its padding is one more place to forget.
 *
 * The four classes are named individually rather than matched on a
 * `[class*="woocommerce-"]` prefix, which would also stop resetting any other
 * WooCommerce list that lands on these screens. The `:not()`s raise this to
 * (0,6,2); checked against every other list rule in this file first — all of them
 * target an `li` or a specifically-classed container, and every one sets the same
 * `margin: 0; padding: 0; list-style: none`, so nothing wants a plain `ul` here to
 * keep a padding this could now beat.
 */
body.optic-account-page .optic-account ul:not( .woocommerce-error ):not( .woocommerce-message ):not( .woocommerce-info ):not( .woocommerce-notice ),
body.optic-account-page .optic-account ol {
	margin: 0;
	padding: 0;
	list-style: none;
}

body.optic-account-page .optic-account address {
	font-style: normal;
}

/*
 * WooCommerce draws a BOX around every <address> it prints:
 *
 *     .woocommerce .col-1 address, .woocommerce address {
 *         border: 1px solid; border-radius: 5px; padding: 6px 12px;
 *     }
 *
 * The design has addresses as plain text under a label — on the account hub, on
 * the addresses screen and on the order detail. Seen on the live hub as a
 * bordered rectangle sitting inside an already-bordered card, twice.
 */
/*
 * WooCommerce gives `.woocommerce-order-details` and `.woocommerce-customer-details`
 * a bottom margin of their own. `.optic-order` already spaces its children with
 * a 16px flex gap, so that margin was added to it — measured at 48px between the
 * Order details card and the addresses beneath it.
 */
body.optic-account-page .optic-account .woocommerce-order-details,
body.optic-account-page .optic-account .woocommerce-customer-details,
body.optic-account-page .optic-account .woocommerce-order-downloads {
	margin-bottom: 0;
}

/*
 * WooCommerce's password-strength meter, which appears inside the styled card
 * the moment a member types a new password. Not suppressed — it is real advice
 * on a real form — but drawn in this plugin's own idiom instead of as a raw
 * coloured bar.
 */
body.optic-account-page .optic-account .woocommerce-password-strength,
body.optic-account-page .optic-account .woocommerce-password-hint {
	display: block;
	margin: 6px 0 0;
	padding: 0;
	border: 0;
	background: none;
	font-size: 11.5px;
	font-weight: 500;
	line-height: 1.5;
	text-align: left;
	color: var( --oa-slate );
}

body.optic-account-page .optic-account .woocommerce-password-strength.short,
body.optic-account-page .optic-account .woocommerce-password-strength.bad {
	color: var( --oa-bad );
}

body.optic-account-page .optic-account .woocommerce-password-strength.good,
body.optic-account-page .optic-account .woocommerce-password-strength.strong {
	color: var( --oa-good );
}

body.optic-account-page .optic-account address,
body.optic-account-page .optic-hub__pair address,
body.optic-account-page .optic-address address {
	border: 0;
	border-radius: 0;
	padding: 0;
	background: none;
}

/* =========================================================================
   THE ADDRESS FORM — four WooCommerce rules, all of them winning.

   This screen is the one that renders WooCommerce's own field markup, so it is
   where the most of WooCommerce's own stylesheet lands. Each rule below was read
   out of woocommerce-layout.css / woocommerce.css and each effect was measured
   on the live form.
   ========================================================================= */

/*
 * 1. FIELD WIDTH — the worst of them.
 *
 *     .woocommerce form .form-row-first,
 *     .woocommerce form .form-row-last { width: 47%; overflow: visible }
 *     .woocommerce form .form-row-first { float: left }
 *     .woocommerce form .form-row-last  { float: right }
 *
 * WooCommerce's address fields are a two-column FLOAT layout at 47% each. This
 * design lays them out on a CSS grid, so the 47% is a width inside a track that
 * is already half the card — measured live: a 264px input sitting in a 561px
 * grid cell. Every first/last pair on the form was under half the width it
 * should be.
 *
 * `.optic-account .optic-form__fields .form-row` is (0,3,0) and already beats
 * WooCommerce's (0,2,1); it simply never declared a width, so there was nothing
 * to beat it with.
 */
body.optic-account-page .optic-form__fields .form-row,
body.optic-account-page .optic-form__fields .form-row-first,
body.optic-account-page .optic-form__fields .form-row-last {
	float: none;
	width: auto;
	max-width: none;
}

/*
 * 2. THE CLEARFIX.
 *
 *     .woocommerce form .form-row::after,
 *     .woocommerce form .form-row::before { content: " "; display: table }
 *
 * A float clearfix, which is right for WooCommerce's float layout and wrong
 * here: `.form-row` is a flex COLUMN, so each pseudo-element becomes a flex item
 * and the 6px label-to-input gap is paid twice more — once above the label and
 * once below the input. Measured live: both pseudo-elements present, `display:
 * table`.
 */
body.optic-account-page .optic-form__fields .form-row::before,
body.optic-account-page .optic-form__fields .form-row::after {
	content: none;
	display: none;
}

/*
 * 3. LABEL LINE-HEIGHT.
 *
 *     .woocommerce form .form-row label { line-height: 2 }
 *
 * (0,2,1), which TIES `.optic-account .optic-form__fields label` — and a tie is
 * decided by source order, which this plugin does not control. WooCommerce won:
 * measured live at 25.2px against the design's ~15.7px, so every label on the
 * form carried nine pixels of dead space beneath it.
 */
body.optic-account-page .optic-form__fields label {
	font-size: 13px;
	font-weight: 500;
	line-height: normal;
	color: var( --oa-slate );
}

/*
 * 4. THE FOCUS RING, for the same tie-breaking reason as the labels.
 */
body.optic-account-page .optic-form__fields .form-row input:focus,
body.optic-account-page .optic-form__fields .form-row select:focus,
body.optic-account-page .optic-form__fields .form-row textarea:focus {
	outline: 3px solid rgba( 21, 105, 255, 0.35 );
	outline-offset: -1px;
	/*
	 * `!important`, and this is the one place in this file that earns it.
	 *
	 * Traced with the pseudo-state forced, the winning rule is
	 *
	 *     input:focus, input[type="text"]:focus,
	 *     .woocommerce .woocommerce-address-fields … input:focus {
	 *         border-color: inherit;
	 *     }
	 *
	 * `inherit` on a border colour is a reset, not a design decision — it takes
	 * the wrapper's, which resolves to `currentColor`, the field's own near-black
	 * text. Measured live at rgb(24,24,24) on a focused field.
	 *
	 * And it matches BECAUSE OF AN EARLIER FIX IN THIS FILE: the address section
	 * carries `woocommerce-address-fields` so that WooCommerce's locale script can
	 * find the fields. Winning that back by specificity would mean naming a
	 * selector longer than a rule this plugin does not own and cannot pin.
	 *
	 * The outline in this same block was landing correctly the whole time, so the
	 * focus was never invisible — this is the border beside it.
	 */
	border: 1px solid var( --oa-blue ) !important;
}

/* =========================================================================
   FOUR SMALLER ONES, each measured
   ========================================================================= */

/*
 * The status dot is the BRIGHTER green, not the label's.
 *
 * The design gives the dot `background: var(--green)` — #0BC17F — inside a pill
 * whose text is #078A5B. `background: currentColor` collapses the two into the
 * darker one; measured live at rgb(7,138,91). The two greens are deliberate and
 * this file's own token comment says so.
 *
 * Only the `good` tone: the design has no other pill, and for `wait`, `bad` and
 * `off` a dot matching its label is the right default.
 */
body.optic-account-page .optic-pill--good .optic-pill__dot {
	background: var( --oa-green );
}

/*
 * Astra ships `dt { font-weight: 600 }`, and `.optic-fact dt` declared colour
 * only — so every fact LABEL on the membership screen was as bold as its value.
 * Measured live at 600 against the design's 400.
 */
body.optic-account-page .optic-fact dt {
	font-weight: 400;
	color: var( --oa-slate );
}

/*
 * The order count beside "Order history" is static text, not a link. Its
 * modifier was (0,1,0) against a base rule that is both (0,2,0) and
 * `!important`, so it never applied and the count printed in Hero Blue at
 * weight 500 — identical to every real link on the page. Measured live at
 * rgb(21,105,255)/500 against the design's #6F7887/400.
 */
body.optic-account-page .optic-table__more--plain {
	font-weight: 400;
	color: var( --oa-slate ) !important;
}

/*
 * WooCommerce's own tables, on the two screens this plugin deliberately does not
 * rebuild. `.woocommerce table.shop_table` carries a border, a 5px radius, a
 * -1px right margin and `td { padding: 9px 12px; line-height: 1.5em }`, all of
 * which tie or beat the seam rules above. Named under the body class so the
 * seam is at least consistent with the cards around it.
 */
/* =========================================================================
   VIEW-SUBSCRIPTION — WooCommerce Subscriptions' own detail page.

   This plugin does not rebuild it, and that decision stands: the page carries
   change-payment-method, switching, resubscribe and the related-order tables,
   and owning that list means losing a control to a redesign one day. What was
   wrong was the conclusion drawn from it — that "styled where it lands" could
   mean a handful of table rules. Rendered, it looked like bare WooCommerce
   dropped into a designed account area.

   So every element WooCommerce Subscriptions emits on that screen is named and
   given the design's own shape. The MARKUP is untouched, so every feature,
   every nonce and every hook on it still works; only its appearance changes.

   The markup, read off the live page rather than assumed:

     table.shop_table.subscription_details   tbody > tr > td, td      label/value rows
     h2                                      "Subscription totals"
     table.shop_table.order_details          thead th / tbody td / tfoot th, td
     section.woocommerce-customer-details     h2.woocommerce-column__title + address
   ========================================================================= */

body.optic-account-page .optic-account__content table.shop_table {
	width: 100%;
	margin: 0;
	border: 1px solid var( --oa-border );
	border-radius: var( --oa-radius );
	border-collapse: separate;
	border-spacing: 0;
	background: var( --oa-card );
	overflow: hidden;
	font-size: 13px;
}

body.optic-account-page .optic-account__content table.shop_table td,
body.optic-account-page .optic-account__content table.shop_table th,
body.optic-account-page .optic-account__content table.shop_table tfoot td,
body.optic-account-page .optic-account__content table.shop_table tfoot th {
	padding: 14px var( --oa-pad );
	border: 0;
	border-bottom: 1px solid var( --oa-border );
	line-height: normal;
	vertical-align: middle;
	text-align: left;
}

/*
 * The subscription's own facts are a label/value list, exactly like
 * `.optic-facts` on the membership screen — so they are given the same shape:
 * the label quiet on the left, the value bold and hard right.
 */
body.optic-account-page .optic-account__content table.subscription_details td:first-child {
	width: 40%;
	font-weight: 400;
	color: var( --oa-slate );
}

body.optic-account-page .optic-account__content table.subscription_details td:last-child {
	font-weight: 600;
	color: var( --oa-ink );
	text-align: right;
}

/* The money table keeps its column heads, at the design's label scale. */
body.optic-account-page .optic-account__content table.order_details thead th,
body.optic-account-page .optic-account__content table.order_details tfoot th {
	font-size: 11px;
	font-weight: 600;
	letter-spacing: 0.14em;
	text-transform: uppercase;
	color: var( --oa-slate );
}

body.optic-account-page .optic-account__content table.order_details td.product-total,
body.optic-account-page .optic-account__content table.order_details tfoot td,
body.optic-account-page .optic-account__content table.order_details th.product-total {
	text-align: right;
	font-weight: 600;
	color: var( --oa-ink );
}

body.optic-account-page .optic-account__content table.order_details tfoot tr:last-child th,
body.optic-account-page .optic-account__content table.order_details tfoot tr:last-child td {
	font-size: 14.5px;
	font-weight: 700;
	letter-spacing: normal;
	text-transform: none;
	color: var( --oa-ink );
}

body.optic-account-page .optic-account__content table.shop_table tr:last-child td,
body.optic-account-page .optic-account__content table.shop_table tr:last-child th {
	border-bottom: 0;
}

body.optic-account-page .optic-account__content .product-quantity {
	font-weight: 500;
	color: var( --oa-slate );
}

/*
 * The bare `h2` between the two tables, and the one inside the address section.
 * Astra styles both at 2.28rem with its own line-height; the first is a section
 * heading and the second is a card title, and neither is a page heading.
 */
body.optic-account-page .optic-account__content > h2,
body.optic-account-page .optic-account__content .woocommerce-column__title {
	margin: 0 0 12px;
	font-size: 15px;
	font-weight: 600;
	line-height: normal;
	letter-spacing: normal;
	color: var( --oa-ink );
	/*
	 * WooCommerce boxes this heading:
	 *
	 *     .woocommerce .woocommerce-MyAccount-content .woocommerce-column__title {
	 *         background: #fbfbfb; padding: .5em; border-width: 1px 1px 0 1px;
	 *     }
	 *
	 * — the top half of a bordered panel whose bottom half is the <address> below
	 * it. This design has already made the whole section a card, so the heading's
	 * own three-sided border drew a second rectangle around the words "Billing
	 * address" alone. Named at (0,3,1) against its (0,3,0), and the properties
	 * have to be restated: winning the selector is not the same as winning a
	 * property that was never declared.
	 */
	padding: 0;
	border: 0;
	background: none;
}

body.optic-account-page .optic-account__content > h2 {
	margin-top: 4px;
}

/* The address block becomes a card, like every other address in this plugin. */
body.optic-account-page .optic-account__content .woocommerce-customer-details {
	padding: 20px var( --oa-pad );
	border: 1px solid var( --oa-border );
	border-radius: var( --oa-radius );
	background: var( --oa-card );
}

body.optic-account-page .optic-account__content .woocommerce-customer-details address {
	margin: 0;
	font-size: 13.5px;
	line-height: 1.6;
	color: var( --oa-ink );
}

body.optic-account-page .optic-account__content .woocommerce-customer-details--email {
	display: block;
	margin: 6px 0 0;
	font-size: 12.5px;
	color: var( --oa-blue );
}

/* WooCommerce Subscriptions' float clearer, which has nothing to clear here. */
body.optic-account-page .optic-account__content > .clear {
	display: none;
}

/*
 * THE ACTION BUTTONS, which were the loudest thing on the page: blue fills with
 * near-black labels, because Astra was winning the background while this
 * plugin's own rule was winning the colour. Named at (0,3,2) so one rule owns
 * both, and split by INTENT the way the membership screen splits them —
 * cancelling is quiet, renewing is the primary act.
 */
body.optic-account-page .optic-account__content a.button,
body.optic-account-page .optic-account__content button.button,
body.optic-account-page .optic-account__content input.button {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-height: 36px;
	margin: 0 8px 0 0;
	padding: 8px 16px;
	border: 1px solid var( --oa-border );
	border-radius: var( --oa-pill ) !important;
	background: #fff !important;
	background-image: none !important;
	font-family: inherit;
	font-size: 12.5px;
	font-weight: 600;
	line-height: normal;
	color: var( --oa-ink ) !important;
	text-shadow: none;
	box-shadow: none;
}

body.optic-account-page .optic-account__content a.button:hover,
body.optic-account-page .optic-account__content button.button:hover {
	border-color: var( --oa-blue );
	color: var( --oa-blue ) !important;
}

/* Renew, resubscribe and pay are the primary act on this page. */
body.optic-account-page .optic-account__content a.button.subscription_renewal_early,
body.optic-account-page .optic-account__content a.button.resubscribe,
body.optic-account-page .optic-account__content a.button.pay,
body.optic-account-page .optic-account__content a.button.reactivate,
body.optic-account-page .optic-account__content a.button.alt {
	border-color: var( --oa-blue );
	background: var( --oa-blue ) !important;
	color: #fff !important;
}

body.optic-account-page .optic-account__content a.button.subscription_renewal_early:hover,
body.optic-account-page .optic-account__content a.button.resubscribe:hover,
body.optic-account-page .optic-account__content a.button.pay:hover,
body.optic-account-page .optic-account__content a.button.reactivate:hover,
body.optic-account-page .optic-account__content a.button.alt:hover {
	border-color: var( --oa-blue-hover );
	background: var( --oa-blue-hover ) !important;
	color: #fff !important;
}

/* Cancelling is quiet, and never a filled button. */
body.optic-account-page .optic-account__content a.button.cancel {
	min-height: 0;
	padding: 8px 0;
	border: 0;
	background: none !important;
	font-weight: 500;
	color: var( --oa-slate ) !important;
	text-decoration: underline !important;
	text-underline-offset: 3px;
}

body.optic-account-page .optic-account__content a.button.cancel:hover {
	color: var( --oa-bad ) !important;
}

/* The actions cell holds several of these; give it a row that wraps. */
body.optic-account-page .optic-account__content table.subscription_details td:last-child:has( a.button ) {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: flex-end;
	gap: 10px;
}

@media ( max-width: 720px ) {
	/*
	 * WooCommerce's own responsive table mode stacks these into label/value
	 * pairs via `td::before`. It is not enabled here, so the two-column table is
	 * kept and simply given room: the label column stops being 40% and both
	 * cells drop their side padding to the card's own.
	 */
	body.optic-account-page .optic-account__content table.shop_table td,
	body.optic-account-page .optic-account__content table.shop_table th {
		padding: 12px 16px;
	}

	body.optic-account-page .optic-account__content table.subscription_details td:first-child {
		width: 42%;
	}
}

/*
 * "Order again" is WooCommerce's markup, and the selector that was meant to
 * style it named classes the template does not emit. `order/order-again.php`
 * emits `<p class="order-again"><a class="button woocommerce-button …">`.
 */
body.optic-account-page .optic-account .order-again {
	margin: 0 var( --oa-pad ) 20px;
}

body.optic-account-page .optic-account .order-again a.button {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-height: 36px;
	padding: 8px 16px;
	border: 1px solid var( --oa-border );
	border-radius: var( --oa-pill ) !important;
	background: #fff;
	font-family: inherit;
	font-size: 12.5px;
	font-weight: 600;
	color: var( --oa-ink ) !important;
}

/*
 * INPUTS. The one theme override in this file whose absence is VISIBLE rather
 * than subtle, and it was found by measuring the live page in Chrome rather than
 * by reading anything.
 *
 * Astra's WooCommerce compatibility sheet carries:
 *
 *     .woocommerce form .form-row textarea,
 *     .woocommerce input[type="email"], … {
 *         border-color: var(--ast-border-color);
 *         border-radius: 0;
 *     }
 *
 * at specificity (0,2,1) — a class plus an attribute plus an element — against
 * `.optic-auth .optic-input` at (0,2,0). It wins on both properties, and it wins
 * on every account screen because `.woocommerce` wraps all of them.
 *
 * Measured on the live sign-in page: 30 of 35 design values matched exactly, and
 * the two that did not were `border-radius: 0px` where the design says 10, and
 * `rgb(209,213,219)` where it says `#E6E8EC`. Square-cornered fields in the wrong
 * grey — the sort of thing a fixture can never show, because a fixture has no
 * Astra in it.
 *
 * Fixed by naming the ELEMENT as well as the class, under the body class:
 * (0,2,2) beats (0,2,1) without reaching for `!important`.
 *
 * `select` and `textarea` carry no measurement of their own — they appear only on
 * the address form, which is behind a login this check could not pass. They are
 * included because they are in the same Astra selector list, and being right
 * there costs one line each.
 */
body.optic-account-page input.optic-input,
body.optic-account-page select.optic-input,
body.optic-account-page textarea.optic-input {
	border: 1px solid var( --oa-border );
	border-radius: var( --oa-radius-sm );
	background: #fff;
	box-shadow: none;
}

/*
 * The focus ring, repeated here for the one reason a repeat is warranted: the
 * base rule at :316 loses.
 *
 * `.optic-auth .optic-input:focus` is (0,3,0). Astra ships
 * `.woocommerce-js input[type="text"]:focus, input[type="email"]:focus { outline-style: unset }`
 * at (0,3,1) and takes it by a single point. Measured with
 * `CSS.forcePseudoState` on the sign-in card: `#username` computed
 * `outline-style: none` while `#password`, 60px below it in the same card, kept
 * the full 3px ring — because `input[type="password"]` is absent from Astra's
 * selector list. One card, two fields, two different focus treatments.
 *
 * This block is (0,3,2) and already outranks Astra, which is why the outline joins
 * the border-color here rather than becoming a new rule with a made-up selector.
 */
body.optic-account-page input.optic-input:focus,
body.optic-account-page select.optic-input:focus,
body.optic-account-page textarea.optic-input:focus {
	border-color: var( --oa-blue );
	outline: 3px solid rgba( 21, 105, 255, 0.35 );
	outline-offset: -1px;
}

/*
 * THE BOX AROUND THE SIGN-IN FORM.
 *
 * WooCommerce ships, and Astra restates at a higher specificity:
 *
 *     body .woocommerce form.login {
 *         border: 1px solid var(--ast-border-color);
 *         padding: 20px;
 *         margin: 2em 0;
 *         border-radius: 5px;
 *     }
 *
 * (0,2,2), against `.optic-auth__form` at (0,1,0). The design has the fields
 * sitting directly inside the 22px card; this drew a SECOND rectangle inside it —
 * a different radius, a different border colour, 20px of padding and 28px of
 * margin that nothing in the design asks for.
 *
 * It applies to `form.login` and `form.register`, which are the two forms
 * WooCommerce's own stylesheet singles out, so both auth screens had it. The
 * password-reset forms carry `lost_reset_password` and were never affected; they
 * are matched here anyway because one selector for all four is one thing to
 * remember instead of two.
 *
 * INVISIBLE TO THE NUMERIC CHECK. Every value that check measured — card, title,
 * label, input, checkbox, button, wrapper — was already correct, and it reported
 * 34/34. Finding this took looking at a screenshot. A measurement only catches
 * what it thought to measure; a picture catches what nobody thought of.
 */
body.optic-account-page .optic-auth form.optic-auth__form {
	margin: 0;
	padding: 0;
	border: 0;
	border-radius: 0;
}

/*
 * THE CONTENT COLUMN. The single most damaging rule on this page.
 *
 *     .woocommerce-account .woocommerce-MyAccount-content { float: right; width: 68%; }
 *
 * That is WooCommerce's own two-column My Account layout — a 25% sidebar of
 * links beside a 68% content column. This design has no sidebar; the pills
 * replace it and the content is meant to span the full 1192px.
 *
 * The class stays on the div deliberately (third-party scripts target
 * `.woocommerce-MyAccount-content`, and dropping it to dodge one rule would
 * break them), so the rule has to be beaten instead: (0,2,0) needs (0,3,0).
 *
 * Measured: every card under the pills rendered 808px wide inside a 1192px page,
 * hard against the left edge with 384px of dead space beside it. Every design
 * token was already correct — the gradient, the radii, the type — which is why
 * the numbers all passed while the page looked nothing like the design.
 *
 * The `float` is belt-and-braces. `.optic-account` is a flex container, and
 * floats on flex items are ignored per spec, so today only the width bites. That
 * stops being true the moment anything makes this a block container again.
 */
body.optic-account-page .optic-account .optic-account__content {
	float: none;
	width: 100%;
	max-width: none;
}

/*
 * The same fight, on the fields WooCommerce renders itself in the address form.
 * `.optic-account .optic-form__fields input[type="text"]` is already (0,3,1) and
 * wins, but the bare `select` in that block is (0,2,1) and merely TIES Astra —
 * which makes the winner depend on stylesheet order, and stylesheet order is not
 * something this plugin controls.
 */
/*
 * `.form-row` IS IN THE SELECTOR, and the arithmetic is why.
 *
 *     .woocommerce form .form-row .input-text,
 *     .woocommerce form .form-row select {
 *         border: var(--wc-form-border-width) solid var(--wc-form-border-color);
 *     }
 *
 * is (0,3,1) for the input and (0,2,2) for the select. Naming only
 * `.optic-form__fields input` gives (0,2,2) — a loss and a tie respectively — so
 * WooCommerce's border won, and `--wc-form-border-color` is undefined on this
 * store, which resolves to `currentColor`: the field's own near-black text.
 * Measured live at rgb(24,24,24) where the design says #E6E8EC.
 *
 * Adding `.form-row` takes ours to (0,4,2), clear of both.
 */
body.optic-account-page .optic-form__fields .form-row input.input-text,
body.optic-account-page .optic-form__fields .form-row select,
body.optic-account-page .optic-form__fields .form-row textarea,
body.optic-account-page .optic-form__fields .form-row .select2-selection {
	border: 1px solid var( --oa-border );
	border-radius: var( --oa-radius-sm );
}

/* =========================================================================
   RESPONSIVE — decisions, not measurements.
   The design exports have no breakpoints; below ~1000px the three-column deals
   grid and the 1.2fr/1fr membership split both stop fitting.
   ========================================================================= */

@media ( max-width: 1000px ) {
	.optic-deals {
		grid-template-columns: repeat( 2, minmax( 0, 1fr ) );
	}

	/*
	 * The membership stacks rather than narrowing. At 1.2fr/1fr on a 900px
	 * viewport the left card's fact rows put "Next billing date" and its value on
	 * two lines each, which turns a five-row list into ten.
	 */
	.optic-membership,
	.optic-hub {
		grid-template-columns: 1fr;
	}
}

@media ( max-width: 860px ) {
	.optic-account {
		padding: 24px 0 48px;
		gap: 20px;
	}

	.optic-hero {
		flex-direction: column;
		align-items: flex-start;
		gap: 20px;
		padding: 26px 24px;
		border-radius: var( --oa-radius );
	}

	.optic-account .optic-hero__title {
		font-size: 24px;
	}

	/*
	 * The stats keep their row and gain a left edge. Stacked they would be three
	 * more lines under a heading that is already three lines; side by side they
	 * are still readable at 24px of gap, which is where three values stop fitting
	 * a 375px screen.
	 */
	.optic-hero__stats {
		gap: 24px;
		width: 100%;
	}

	.optic-stat {
		align-items: flex-start;
	}

	.optic-meta {
		grid-template-columns: 1fr 1fr;
		gap: 16px 12px;
	}

	.optic-addresses,
	.optic-hub__pair,
	.optic-form__grid,
	.optic-form__fields {
		grid-template-columns: 1fr;
	}

	.optic-deals {
		grid-template-columns: 1fr;
	}

	.optic-auth {
		padding: 24px 0 48px;
	}

	.optic-auth__card {
		padding: 28px 22px;
	}

	body.optic-account-out .woocommerce-error,
	body.optic-account-out .woocommerce-message,
	body.optic-account-out .woocommerce-info {
		margin-top: 24px;
	}
}

@media ( max-width: 720px ) {
	/*
	 * The order row becomes two lines: identity and description on top, then the
	 * date, status, total and action beneath. Six columns in 375px gives each
	 * about 50px, which truncates every one of them to an ellipsis.
	 */
	.optic-row {
		grid-template-columns: minmax( 0, 1fr ) auto;
		grid-template-areas:
			"items  total"
			"id     status"
			"date   action";
		row-gap: 6px;
		padding: 16px var( --oa-pad );
	}

	/*
	 * `.optic-account .optic-row__items` is (0,2,0) in the base rules; a bare
	 * `.optic-row__items` here is (0,1,0), and a media query adds nothing. The
	 * ellipsis therefore survived into the two-line layout this block exists to
	 * create, which is the one place the description has room to wrap.
	 */
	.optic-account .optic-row__items {
		grid-area: items;
		overflow: visible;
		white-space: normal;
		text-overflow: clip;
	}
	.optic-row__total { grid-area: total; }
	.optic-account .optic-row__id { grid-area: id; }
	.optic-row__status { grid-area: status; justify-self: end; }
	.optic-row__date { grid-area: date; }
	/*
	 * The ORDER row's actions are wrapped in `<span class="optic-row__actions">`,
	 * so the anchor below is a flex item of that span and not a grid item — both
	 * declarations on it are inert here. Measured at 390px: `.optic-row__actions`
	 * reported `grid-area: auto` while every sibling reported its named area. It
	 * still landed in the right cell, but only because the five named placements
	 * happened to leave exactly one free.
	 *
	 * Named explicitly now. The rule below stays for the DOWNLOAD row, where the
	 * anchor really is a direct grid child. Nothing moves today; what changes is
	 * that adding or reordering a child of `.optic-row` can no longer silently
	 * relocate the actions — a failure that would only ever appear below 720px.
	 */
	.optic-row__actions { grid-area: action; justify-self: end; }

	.optic-account .optic-row__action { grid-area: action; justify-self: end; }

	.optic-row--download {
		grid-template-columns: minmax( 0, 1fr ) auto;
		grid-template-areas:
			"items  items"
			"date   total"
			"action action";
	}

	.optic-row--download .optic-row__action {
		justify-self: start;
	}

	/*
	 * The four stage labels stop fitting side by side long before the bar does.
	 * They become a vertical list — and the bar above still carries the progress
	 * at a glance. Same decision as the order confirmation, at the same width.
	 */
	.optic-account .optic-steps {
		grid-template-columns: 1fr;
		gap: 6px;
		margin-top: 4px;
	}

	.optic-account .optic-steps li:last-child {
		text-align: left;
	}

	.optic-item {
		grid-template-columns: 52px minmax( 0, 1fr );
		grid-template-areas:
			"thumb text"
			"price price";
		row-gap: 10px;
	}

	.optic-item__thumb { grid-area: thumb; width: 52px; height: 52px; }
	.optic-item__text  { grid-area: text; }
	.optic-item__price { grid-area: price; text-align: right; }

	.optic-plan,
	.optic-benefits-card,
	.optic-form__card {
		padding: 22px 20px;
	}

	.optic-plan__product {
		flex-wrap: wrap;
	}

	.optic-plan__price {
		width: 100%;
		text-align: left;
	}

	.optic-cardrow {
		grid-template-columns: 20px minmax( 0, 1fr );
		grid-template-areas:
			"brand   label"
			"expiry  expiry"
			"actions actions";
		row-gap: 8px;
	}

	.optic-cardrow__brand   { grid-area: brand; }
	.optic-cardrow__label   { grid-area: label; }
	.optic-cardrow__expiry  { grid-area: expiry; }
	.optic-cardrow__actions { grid-area: actions; }

	.optic-note {
		grid-template-columns: 1fr;
		gap: 2px;
	}

	/* The cancel link stops being pushed to a right edge that no longer exists. */
	.optic-account .optic-quiet {
		margin-left: 0;
	}

	.optic-actions .optic-btn {
		flex: 1 1 auto;
	}

	/*
	 * `margin-left: auto` puts Log out at the right of the pill row. Once the
	 * pills wrap to two lines it pushed the link past the viewport edge instead
	 * — measured at 390px on the live page, where it was clipped mid-word. The
	 * row already wraps; the link joins the wrap.
	 */
	.optic-account .optic-tabs__out {
		margin-left: 0;
	}
}

/*
 * TOUCH TARGETS — keyed on the input device, not on the width.
 *
 * Every size above is measured off a 1280px desktop render made for a mouse, and
 * a fingertip needs about 44px. Keyed on width alone this would miss the one
 * device category it exists for: an iPad in portrait is 768px, which has a
 * finger and sits above the phone breakpoints. Same reasoning, same boundary, as
 * the cart page and the order confirmation.
 */
@media ( pointer: coarse ), ( max-width: 860px ) {
	.optic-account .optic-btn,
	.optic-auth .optic-btn {
		min-height: 44px;
	}

	.optic-account .optic-btn--sm {
		min-height: 40px;
		font-size: 13px;
	}

	.optic-account .optic-tab,
	.optic-account .optic-subnav__item {
		min-height: 40px;
		display: inline-flex;
		align-items: center;
	}

	/* Row actions are the smallest tap targets on the page and the most used. */
	.optic-account .optic-row__action,
	.optic-account .optic-cardrow__action,
	.optic-account .optic-hub__edit,
	.optic-account .optic-fact__edit {
		display: inline-flex;
		align-items: center;
		min-height: 32px;
	}

	.optic-account .optic-reveal,
	.optic-auth .optic-reveal {
		/*
		 * `max`, not a flat 44px. This block exists for the touch-target floor, but
		 * 44px is BELOW the 49.4px "SHOW" actually measures, so on its own it never
		 * applied and the button still resized on press. Taking the larger of the
		 * two keeps the touch target and the stable width at the same time.
		 */
		min-width: max( 44px, 6.6ch );
		min-height: 36px;
		justify-content: center;
		display: inline-flex;
		align-items: center;
	}

	.optic-account .optic-code {
		min-height: 36px;
	}
}

@media ( prefers-reduced-motion: reduce ) {
	.optic-account *,
	.optic-auth * {
		transition: none !important;
	}
}
