/**
 * WooCommerce, wearing the TSF design.
 *
 * Loaded only on storefront pages (see TSF_Core::enqueue_assets), where
 * WooCommerce's own stylesheets are also present -- tsf-asset-trim suppresses
 * those everywhere else. Woo's CSS assumes a light theme; this is a near-black
 * site, so almost everything here is a correction rather than a decoration.
 *
 * Everything is scoped under `body.tsf-scope`. The body element is not there for
 * looks: WooCommerce's form rules are three classes deep (`.woocommerce form
 * .form-row .input-text`) and its stylesheet is enqueued after this one, so an
 * equally specific rule of ours loses the tie and the inputs come out white on a
 * near-black page. The element selector settles every such tie at once, and
 * without a single !important.
 *
 * The design language is borrowed wholesale from the bespoke form widget in
 * widgets.css: pill buttons, uppercase tracked labels, 0.75rem/1rem inputs on
 * the page ground with a hairline border, brand-red focus ring.
 */

/* --------------------------------------------------- WooCommerce tokens */

/*
 * WooCommerce draws from its own custom properties, and several of the rules
 * that use them carry !important -- `a.remove { color: var(--wc-red) !important }`
 * is the one that shows, painting the cart's remove control a flat #AA0000 that
 * belongs to no palette on this site.
 *
 * Redefining Woo's tokens is cleaner than out-shouting each rule: it settles
 * every one of them at once, needs no !important of ours, and keeps working for
 * rules we have not met yet. Woo declares these on :root, so a class beats them.
 */
body.tsf-scope {
	--wc-red: var(--tsf-brand-bright);
	--wc-destructive: var(--tsf-brand-bright);
	--wc-orange: var(--tsf-state-wait);
	--wc-green: var(--tsf-state-good);
	--wc-blue: var(--tsf-muted-fg);

	--wc-primary: var(--tsf-brand);
	--wc-primary-text: var(--tsf-on-brand);
	--wc-secondary: var(--tsf-surface-2);
	--wc-secondary-text: var(--tsf-fg);
	--wc-highlight: var(--tsf-brand);
	/* Woo's own spelling, not ours. */
	--wc-highligh-text: var(--tsf-on-brand);

	--wc-content-bg: var(--tsf-bg);
	--wc-subtext: var(--tsf-muted-fg);
	--wc-card-border-radius: var(--tsf-radius-xl);

	--wc-form-color-text: var(--tsf-fg);
	--wc-form-color-background: var(--tsf-bg);
	--wc-form-border-color: rgba(255, 255, 255, 0.1);
	--wc-form-border-width: 1px;
	--wc-form-border-radius: var(--tsf-radius-lg);
}

/* ----------------------------------------------------------- page shell */

/*
 * Woo pages come through singular.php's non-Elementor branch, which already
 * wraps them in .tsf-container.tsf-band. All that is missing is a readable
 * measure and the display face on the title.
 */

body.tsf-scope .woocommerce {
	color: var(--tsf-fg);
	font-size: 0.9375rem;
	line-height: 1.65;
}

/*
 * Red as TYPE is --tsf-brand-bright on this surface; red as FILL or RULE stays
 * --tsf-brand. Measured: #E31E24 is 4.2 / 3.9 / 3.7:1 on the three grounds
 * here, which fails AA and, more to the point, sinks into the near-black --
 * that is what "there is no red" actually describes. #FF3F45 is 5.7 / 5.3 /
 * 5.0:1. Buttons are excluded: they are a red fill carrying white type.
 */
body.tsf-scope .woocommerce a:not(.button):not(.woocommerce-Button) {
	color: var(--tsf-brand-bright);
	text-underline-offset: 2px;
}

body.tsf-scope .woocommerce a:not(.button):not(.woocommerce-Button):hover {
	color: var(--tsf-fg);
	text-decoration-color: var(--tsf-brand-bright);
}

body.tsf-scope .woocommerce h2,
body.tsf-scope .woocommerce h3,
body.tsf-scope .woocommerce legend {
	font-family: var(--tsf-font-display);
	font-weight: 400;
	letter-spacing: var(--tsf-display-tracking);
	line-height: 1.1;
	text-transform: uppercase;
	color: var(--tsf-fg);
}

body.tsf-scope .woocommerce h2 { font-size: clamp(1.25rem, 3vw, 1.6rem); margin: 0 0 1.25rem; }
body.tsf-scope .woocommerce h3 { font-size: 1.05rem; margin: 0 0 1rem; }

/*
 * The 3rem x 2px brand rule above a heading, lifted from .tsf-showcase__rule.
 * WooCommerce gives us no eyebrow element, so the rule carries that slot on its
 * own -- this is the single largest visual change on the storefront, and it
 * adds no red fill anywhere.
 */
body.tsf-scope .woocommerce h2,
body.tsf-scope .woocommerce h3 {
	position: relative;
	padding-top: 1.25rem;
}

body.tsf-scope .woocommerce h2::before,
body.tsf-scope .woocommerce h3::before {
	content: "";
	position: absolute;
	top: 0;
	left: 0;
	width: 3rem;
	height: 0.125rem;
	background-color: var(--tsf-brand);
}

/* Headings that are not section headings: a checkbox label, a gateway panel,
   and the two utility drawers above the checkout form. */
body.tsf-scope .woocommerce h3#ship-to-different-address,
body.tsf-scope .woocommerce .payment_box h3,
body.tsf-scope .woocommerce form.login h2,
body.tsf-scope .woocommerce form.login h3,
body.tsf-scope .woocommerce form.checkout_coupon h2,
body.tsf-scope .woocommerce form.checkout_coupon h3 {
	padding-top: 0;
}

body.tsf-scope .woocommerce h3#ship-to-different-address::before,
body.tsf-scope .woocommerce .payment_box h3::before,
body.tsf-scope .woocommerce form.login h2::before,
body.tsf-scope .woocommerce form.login h3::before,
body.tsf-scope .woocommerce form.checkout_coupon h2::before,
body.tsf-scope .woocommerce form.checkout_coupon h3::before {
	content: none;
}

/* --------------------------------------------------------------- notices */

body.tsf-scope .woocommerce-notices-wrapper:empty { display: none; }

body.tsf-scope .woocommerce-message,
body.tsf-scope .woocommerce-info,
body.tsf-scope .woocommerce-error,
body.tsf-scope .woocommerce-notice {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 0.75rem 1rem;
	margin: 0 0 1.5rem;
	padding: 0.9rem 1.15rem;
	border: 1px solid var(--tsf-border-strong);
	border-left: 3px solid var(--tsf-brand);
	border-radius: 0 var(--tsf-radius-lg) var(--tsf-radius-lg) 0;
	background-color: var(--tsf-surface-1);
	color: var(--tsf-fg);
	font-size: 0.875rem;
	list-style: none;
}

body.tsf-scope .woocommerce-error { border-left-color: var(--tsf-brand-bright); }

/* Woo ships ::before pseudo-icons from its own icon font. */
body.tsf-scope .woocommerce-message::before,
body.tsf-scope .woocommerce-info::before,
body.tsf-scope .woocommerce-error::before { content: none; }

body.tsf-scope .woocommerce-message .button,
body.tsf-scope .woocommerce-info .button { margin-left: auto; }

/* ----------------------------------------------------------------- forms */

body.tsf-scope .woocommerce form .form-row,
body.tsf-scope .woocommerce-form-row {
	display: flex;
	flex-direction: column;
	gap: 0.5rem;
	margin: 0 0 1.25rem;
	padding: 0;
}

body.tsf-scope .woocommerce form .form-row label,
body.tsf-scope .woocommerce-form-row label,
body.tsf-scope .woocommerce-form__label {
	display: block;
	margin: 0;
	font-size: 0.75rem;
	font-weight: 700;
	letter-spacing: 0.1em;
	text-transform: uppercase;
	color: rgba(255, 255, 255, 0.8);
	line-height: 1.4;
}

body.tsf-scope .woocommerce .required {
	color: var(--tsf-brand);
	text-decoration: none;
	border: 0;
}

body.tsf-scope .woocommerce .optional {
	font-weight: 600;
	text-transform: none;
	letter-spacing: 0;
	color: rgba(255, 255, 255, 0.4);
}

body.tsf-scope .woocommerce input[type="text"],
body.tsf-scope .woocommerce input[type="email"],
body.tsf-scope .woocommerce input[type="tel"],
body.tsf-scope .woocommerce input[type="password"],
body.tsf-scope .woocommerce input[type="number"],
body.tsf-scope .woocommerce input[type="date"],
body.tsf-scope .woocommerce input[type="search"],
body.tsf-scope .woocommerce textarea,
body.tsf-scope .woocommerce select,
body.tsf-scope .woocommerce .input-text,
body.tsf-scope .woocommerce .woocommerce-Input {
	box-sizing: border-box;
	width: 100%;
	margin: 0;
	border-radius: var(--tsf-radius-lg);
	border: 1px solid rgba(255, 255, 255, 0.1);
	background-color: var(--tsf-bg);
	padding: 0.75rem 1rem;
	font-family: inherit;
	font-size: 0.875rem;
	line-height: 1.5;
	color: var(--tsf-fg);
	transition: border-color 0.15s var(--tsf-ease), box-shadow 0.15s var(--tsf-ease);
}

body.tsf-scope .woocommerce textarea { min-height: 7rem; resize: vertical; line-height: 1.6; }

body.tsf-scope .woocommerce ::placeholder { color: rgba(255, 255, 255, 0.3); opacity: 1; }

body.tsf-scope .woocommerce input:focus,
body.tsf-scope .woocommerce textarea:focus,
body.tsf-scope .woocommerce select:focus {
	outline: none;
	border-color: var(--tsf-brand);
	box-shadow: 0 0 0 1px var(--tsf-brand);
}

/* The browser's own autofill background is opaque white and unstyleable except
   by painting through the inset shadow. */
body.tsf-scope .woocommerce input:-webkit-autofill,
body.tsf-scope .woocommerce input:-webkit-autofill:focus {
	-webkit-text-fill-color: var(--tsf-fg);
	box-shadow: 0 0 0 100px var(--tsf-bg) inset;
}

body.tsf-scope .woocommerce select {
	appearance: none;
	-webkit-appearance: none;
	padding-right: 2.5rem;
	/* The same chevron the bespoke form draws inline, as a background image. */
	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' stroke='rgba(255,255,255,0.5)' stroke-width='1.5'%3E%3Cpath d='m1 1 5 5 5-5'/%3E%3C/svg%3E");
	background-repeat: no-repeat;
	background-position: right 1rem center;
}

body.tsf-scope .woocommerce select option { background-color: var(--tsf-surface-2); color: var(--tsf-fg); }

/* Two columns on wider screens, matching the bespoke form's grid. */
@media (min-width: 640px) {
	body.tsf-scope .woocommerce form .form-row-first,
	body.tsf-scope .woocommerce form .form-row-last {
		float: none;
		width: 100%;
	}

	/*
	 * .create-account is NOT in this list: it holds the password field on its
	 * own, so a two-column grid left it at half width beside empty space.
	 */
	body.tsf-scope .woocommerce .woocommerce-billing-fields__field-wrapper,
	body.tsf-scope .woocommerce-form-register > p:not(.woocommerce-form-row):not(.form-row) {
		display: grid;
		grid-template-columns: repeat(2, minmax(0, 1fr));
		gap: 0 1.25rem;
	}

	body.tsf-scope .woocommerce .woocommerce-billing-fields__field-wrapper > .form-row-wide,
	body.tsf-scope .woocommerce .woocommerce-billing-fields__field-wrapper > .form-row { grid-column: 1 / -1; }

	body.tsf-scope .woocommerce .woocommerce-billing-fields__field-wrapper > .form-row-first,
	body.tsf-scope .woocommerce .woocommerce-billing-fields__field-wrapper > .form-row-last { grid-column: span 1; }
}

/* ---- player details ----
 *
 * One fieldset per membership in the basket, so a parent enrolling two children
 * can see which name belongs to which group.
 */
body.tsf-scope .woocommerce .tsf-players { margin-bottom: 2rem; }

body.tsf-scope .woocommerce .tsf-player {
	margin: 0 0 1rem;
	padding: 0;
	border: 0;
}

body.tsf-scope .woocommerce .tsf-players .tsf-player:last-child { margin-bottom: 0; }

/* Only worth a frame when there is more than one child to tell apart. */
body.tsf-scope .woocommerce .tsf-player:has(.tsf-player__group) {
	padding: 1.25rem;
	border: 1px solid var(--tsf-border);
	border-left: 2px solid var(--tsf-brand);
	border-radius: 0 var(--tsf-radius-lg) var(--tsf-radius-lg) 0;
	background-color: var(--tsf-surface-1);
}

body.tsf-scope .woocommerce .tsf-player__group {
	display: block;
	float: none;
	width: 100%;
	margin: 0 0 1rem;
	padding: 0;
	font-family: var(--tsf-font-sans);
	font-size: 0.6875rem;
	font-weight: 700;
	letter-spacing: 0.14em;
	text-transform: uppercase;
	color: var(--tsf-brand-bright);
}

/* Two-up on wider screens, matching the billing grid. */
@media (min-width: 640px) {
	body.tsf-scope .woocommerce .tsf-player {
		display: grid;
		grid-template-columns: repeat(2, minmax(0, 1fr));
		gap: 0 1.25rem;
	}

	body.tsf-scope .woocommerce .tsf-player > .tsf-player__group { grid-column: 1 / -1; }
}

/*
 * Country is required by WooCommerce -- it decides which other address fields
 * exist and how they format -- but every parent here is in the UK and it is
 * defaulted, so asking is noise. Hidden, not removed: removing it fails the order.
 */
body.tsf-scope .woocommerce .tsf-field-hidden { display: none; }

/*
 * iOS Safari gives a date input an intrinsic width from its own date format and
 * will not shrink below it, so `width: 100%` is not enough -- the field runs off
 * the right of a 375px screen. appearance:none drops the native sizing,
 * min-width:0 lets it shrink, and max-width caps it whatever else happens.
 */
body.tsf-scope .woocommerce input[type="date"] {
	-webkit-appearance: none;
	appearance: none;
	display: block;
	min-width: 0;
	max-width: 100%;
}

/* A native date input paints its own light calendar glyph. */
body.tsf-scope .woocommerce input[type="date"]::-webkit-calendar-picker-indicator {
	filter: invert(1);
	opacity: 0.5;
	cursor: pointer;
}

body.tsf-scope .woocommerce input[type="date"]::-webkit-calendar-picker-indicator:hover { opacity: 1; }

/* ---- checkboxes ---- */

/* `form .form-row label` above is four classes deep and sets display:block, so
   a three-class rule here lost and the checkbox stacked above its own text. */
body.tsf-scope .woocommerce form .form-row label.woocommerce-form__label-for-checkbox,
body.tsf-scope .woocommerce label.woocommerce-form__label-for-checkbox,
body.tsf-scope .woocommerce .woocommerce-form-login__rememberme,
body.tsf-scope .woocommerce .woocommerce-terms-and-conditions-checkbox-text {
	display: flex;
	align-items: flex-start;
	gap: 0.625rem;
	font-size: 0.8125rem;
	font-weight: 400;
	letter-spacing: 0;
	text-transform: none;
	line-height: 1.6;
	color: rgba(255, 255, 255, 0.7);
}

body.tsf-scope .woocommerce input[type="checkbox"] {
	flex: none;
	width: 1.15rem;
	height: 1.15rem;
	margin: 0.15rem 0 0;
	accent-color: var(--tsf-brand);
}

/* The required marker sits after the text span inside the flex label; left to
   itself it becomes a third flex item and drops to its own line. */
body.tsf-scope .woocommerce label.woocommerce-form__label-for-checkbox .woocommerce-terms-and-conditions-checkbox-text {
	display: inline;
}

body.tsf-scope .woocommerce label.woocommerce-form__label-for-checkbox > .required,
body.tsf-scope .woocommerce label.woocommerce-form__label-for-checkbox > abbr.required {
	order: 1;
	align-self: center;
	margin-left: -0.35rem;
}

body.tsf-scope .woocommerce .woocommerce-privacy-policy-text,
body.tsf-scope .woocommerce .woocommerce-terms-and-conditions-wrapper {
	font-size: 0.8125rem;
	line-height: 1.6;
	color: rgba(255, 255, 255, 0.6);
}

/* --------------------------------------------------------------- buttons */

body.tsf-scope .woocommerce .button,
body.tsf-scope .woocommerce button.button,
body.tsf-scope .woocommerce input.button,
body.tsf-scope .woocommerce a.button,
body.tsf-scope .woocommerce .woocommerce-Button,
body.tsf-scope .woocommerce .woocommerce-button,
body.tsf-scope .woocommerce #place_order {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: 0.5rem;
	/* Without this, any `width: 100%` below adds 4rem of padding on top and
	   overflows its column -- which is what the cart's checkout button did. */
	box-sizing: border-box;
	width: auto;
	border: 1px solid transparent;
	border-radius: var(--tsf-radius-pill);
	padding: 0.75rem 2rem;
	background-color: var(--tsf-brand);
	color: var(--tsf-on-brand);
	font-family: inherit;
	font-size: 0.75rem;
	font-weight: 700;
	letter-spacing: 0.15em;
	text-transform: uppercase;
	text-decoration: none;
	line-height: 1.4;
	cursor: pointer;
	transition: transform 0.2s var(--tsf-ease), background-color 0.2s var(--tsf-ease),
		color 0.2s var(--tsf-ease), border-color 0.2s var(--tsf-ease);
}

body.tsf-scope .woocommerce .button:hover,
body.tsf-scope .woocommerce button.button:hover,
body.tsf-scope .woocommerce a.button:hover,
body.tsf-scope .woocommerce .woocommerce-Button:hover,
body.tsf-scope .woocommerce #place_order:hover {
	background-color: var(--tsf-brand-bright);
	color: var(--tsf-on-brand);
	transform: translateY(-2px);
}

body.tsf-scope .woocommerce .button:focus-visible,
body.tsf-scope .woocommerce button:focus-visible,
body.tsf-scope .woocommerce a:focus-visible {
	outline: 2px solid var(--tsf-brand-bright);
	outline-offset: 3px;
}

body.tsf-scope .woocommerce .button:disabled,
body.tsf-scope .woocommerce .button.disabled {
	opacity: 0.5;
	cursor: not-allowed;
	transform: none;
}

/* Secondary actions read as outlines so the primary one stays obvious. */
body.tsf-scope .woocommerce .button.wc-backward,
body.tsf-scope .woocommerce a.button.cancel,
body.tsf-scope .woocommerce .woocommerce-orders-table__cell .button,
body.tsf-scope .woocommerce .subscription_details .button,
body.tsf-scope .woocommerce .order-again .button {
	background-color: transparent;
	color: var(--tsf-fg);
	border-color: rgba(255, 255, 255, 0.25);
}

body.tsf-scope .woocommerce .button.wc-backward:hover,
body.tsf-scope .woocommerce a.button.cancel:hover,
body.tsf-scope .woocommerce .woocommerce-orders-table__cell .button:hover,
body.tsf-scope .woocommerce .subscription_details .button:hover,
body.tsf-scope .woocommerce .order-again .button:hover {
	background-color: transparent;
	border-color: var(--tsf-brand);
	color: var(--tsf-brand);
}

/* ---------------------------------------------------------------- tables */

body.tsf-scope .woocommerce table.shop_table {
	width: 100%;
	margin: 0 0 2rem;
	border: 1px solid var(--tsf-border);
	border-radius: var(--tsf-radius-xl);
	border-collapse: separate;
	border-spacing: 0;
	background-color: var(--tsf-surface-1);
	overflow: hidden;
	font-size: 0.875rem;
}

body.tsf-scope .woocommerce table.shop_table th,
body.tsf-scope .woocommerce table.shop_table td {
	padding: 0.9rem 1.15rem;
	border: 0;
	border-bottom: 1px solid var(--tsf-border);
	text-align: left;
	vertical-align: middle;
	color: var(--tsf-fg);
}

body.tsf-scope .woocommerce table.shop_table thead th {
	font-size: 0.6875rem;
	font-weight: 700;
	letter-spacing: 0.18em;
	text-transform: uppercase;
	color: var(--tsf-brand-bright);
	background-color: transparent;
	border-bottom: 2px solid var(--tsf-brand);
}

body.tsf-scope .woocommerce table.shop_table tbody tr:last-child td,
body.tsf-scope .woocommerce table.shop_table tfoot tr:last-child th,
body.tsf-scope .woocommerce table.shop_table tfoot tr:last-child td { border-bottom: 0; }

body.tsf-scope .woocommerce table.shop_table tfoot th {
	font-size: 0.6875rem;
	font-weight: 700;
	letter-spacing: 0.12em;
	text-transform: uppercase;
	color: var(--tsf-muted-fg);
}

body.tsf-scope .woocommerce table.shop_table tfoot td,
body.tsf-scope .woocommerce table.shop_table th.product-total,
body.tsf-scope .woocommerce table.shop_table td.product-total {
	text-align: right;
	font-variant-numeric: tabular-nums;
}

/*
 * The total row. `:last-child` as well as `.order-total`, because the
 * Subscriptions totals table prints its rows with no class at all -- the
 * `.order-total` selector alone never matched there.
 */
body.tsf-scope .woocommerce table.shop_table tfoot tr:last-child th,
body.tsf-scope .woocommerce table.shop_table tfoot tr:last-child td,
body.tsf-scope .woocommerce table.shop_table .order-total th,
body.tsf-scope .woocommerce table.shop_table .order-total td {
	border-top: 1px solid var(--tsf-border-strong);
	padding-block: 1.15rem;
}

/*
 * The one red in the table -- the job .tsf-eyebrow does on the marketing pages:
 * a small uppercase label, not a fill. --tsf-brand-bright rather than
 * --tsf-brand: the brand red measures 3.9:1 on this ground, under the 4.5:1 an
 * 11px bold label needs. Bright measures 5.3:1.
 */
body.tsf-scope .woocommerce table.shop_table tfoot tr:last-child th,
body.tsf-scope .woocommerce table.shop_table .order-total th {
	color: var(--tsf-brand-bright);
	letter-spacing: 0.2em;
}

body.tsf-scope .woocommerce table.shop_table tfoot tr:last-child td,
body.tsf-scope .woocommerce table.shop_table .order-total td {
	font-size: 1.0625rem;
	color: var(--tsf-fg);
}

body.tsf-scope .woocommerce .woocommerce-Price-amount { font-variant-numeric: tabular-nums; }

body.tsf-scope .woocommerce table.shop_table .product-name a { color: var(--tsf-fg); text-decoration: none; }
body.tsf-scope .woocommerce table.shop_table .product-name a:hover { color: var(--tsf-brand); }

body.tsf-scope .woocommerce .subscription-price,
body.tsf-scope .woocommerce .subscription-details {
	color: var(--tsf-muted-fg);
	font-size: 0.8125rem;
}

/* ---- status ----
 *
 * Not a pill. Both WooCommerce and Subscriptions print the status as a bare
 * text node inside the cell -- there is no element to hang one on -- and the
 * previous rule put `display: inline-block` on that <td>, which takes the cell
 * out of the table box model: the column stops contributing a width and the
 * chip detaches from its row. That was the visible defect.
 *
 * The state is carried the way this design system already carries small state:
 * coloured uppercase micro-type. Both plugins stamp the state on the ROW, so it
 * is read into a custom property once and the cell inherits it.
 */
body.tsf-scope .woocommerce .woocommerce-orders-table__row--status-active,
body.tsf-scope .woocommerce .woocommerce-orders-table__row--status-completed,
body.tsf-scope .woocommerce .woocommerce-orders-table__row--status-processing {
	--tsf-state: var(--tsf-state-good);
}

/* "failed" waits rather than ends: the row grows a Pay button. */
body.tsf-scope .woocommerce .woocommerce-orders-table__row--status-on-hold,
body.tsf-scope .woocommerce .woocommerce-orders-table__row--status-pending,
body.tsf-scope .woocommerce .woocommerce-orders-table__row--status-pending-cancel,
body.tsf-scope .woocommerce .woocommerce-orders-table__row--status-failed {
	--tsf-state: var(--tsf-state-wait);
}

body.tsf-scope .woocommerce .woocommerce-orders-table__row--status-cancelled,
body.tsf-scope .woocommerce .woocommerce-orders-table__row--status-expired,
body.tsf-scope .woocommerce .woocommerce-orders-table__row--status-refunded,
body.tsf-scope .woocommerce .woocommerce-orders-table__row--status-switched {
	--tsf-state: var(--tsf-state-ended);
}

/* `table.shop_table` in the selector is load-bearing: the generic cell rule
   further up is `.woocommerce table.shop_table td`, which sets colour at a
   higher specificity than a bare `.woocommerce td.<class>` and was winning. */
body.tsf-scope .woocommerce table.shop_table td.woocommerce-orders-table__cell-order-status,
body.tsf-scope .woocommerce table.shop_table td.order-status,
body.tsf-scope .woocommerce table.shop_table td.subscription-status {
	font-size: 0.6875rem;
	font-weight: 700;
	letter-spacing: 0.12em;
	text-transform: uppercase;
	line-height: 1.4;
	white-space: nowrap;
	color: var(--tsf-state, var(--tsf-fg));
}

/* 769 rather than 768: Woo stacks its tables at max-width 768, so 768 itself is
   still stacked. width:1% shrinks the column to its content, which is what the
   pale pill was faking. */
@media (min-width: 769px) {
	body.tsf-scope .woocommerce table.shop_table td.woocommerce-orders-table__cell-order-status,
	body.tsf-scope .woocommerce table.shop_table td.order-status,
	body.tsf-scope .woocommerce table.shop_table td.subscription-status {
		width: 1%;
	}

	body.tsf-scope .woocommerce table.shop_table td.woocommerce-orders-table__cell-order-status::before,
	body.tsf-scope .woocommerce table.shop_table td.order-status::before,
	body.tsf-scope .woocommerce table.shop_table td.subscription-status::before {
		content: "";
		display: inline-block;
		width: 0.4rem;
		height: 0.4rem;
		margin-right: 0.5rem;
		border-radius: var(--tsf-radius-pill);
		background-color: currentColor;
		vertical-align: 0.05em;
	}
}

/* view-order.php sets the status inside <mark>, which the browser paints
   yellow-on-black. No state class is available there. */
body.tsf-scope .woocommerce mark.order-status,
body.tsf-scope .woocommerce mark {
	background-color: transparent;
	color: var(--tsf-fg);
	font-weight: 700;
	letter-spacing: 0.06em;
	text-transform: uppercase;
}

/* The Total column reads "GBP 120.00 for 1 item"; only the money is the value. */
body.tsf-scope .woocommerce table.shop_table td.woocommerce-orders-table__cell-order-total {
	color: var(--tsf-muted-fg);
	font-size: 0.8125rem;
}

body.tsf-scope .woocommerce td.woocommerce-orders-table__cell-order-total .woocommerce-Price-amount {
	font-size: 0.9375rem;
	font-weight: 600;
	color: var(--tsf-fg);
}

/* --------------------------------------------------------- my account */

body.tsf-scope.woocommerce-account .woocommerce {
	display: grid;
	gap: 2rem;
	align-items: start;
}

@media (min-width: 900px) {
	body.tsf-scope.woocommerce-account .woocommerce {
		grid-template-columns: 15rem minmax(0, 1fr);
		gap: 3rem;
	}

	/*
	 * Placed explicitly. WooCommerce renders a notices wrapper before the nav, so
	 * auto-placement gives column one to an empty div, pushes the nav into column
	 * two and drops the content onto a second row.
	 */
	body.tsf-scope.woocommerce-account .woocommerce > .woocommerce-notices-wrapper {
		grid-column: 1 / -1;
		grid-row: 1;
	}

	/* width/float are Woo's own two-column shim, which the grid replaces. Left
	   alone, its `width: 30%` shrinks the nav to 30% of the grid track. */
	body.tsf-scope.woocommerce-account .woocommerce-MyAccount-navigation {
		grid-column: 1;
		grid-row: 2;
		width: auto;
		float: none;
	}

	body.tsf-scope.woocommerce-account .woocommerce-MyAccount-content {
		grid-column: 2;
		grid-row: 2;
		width: auto;
		float: none;
	}
}

/* ---- logged out: login and register ----
 *
 * The old rule set a 34rem max-width with no auto margin, so the whole block
 * hung off the left of a 1280px page. Inside it, WooCommerce's own float shim
 * (.col-1/.col-2 at 48%) made each column 48% of that, which is where the
 * ~190px columns came from.
 */
body.tsf-scope.woocommerce-account:not(.logged-in) .woocommerce {
	display: block;
	max-width: 58rem;
	margin-inline: auto;
}

body.tsf-scope.woocommerce-account:not(.logged-in) .tsf-container > h1 {
	max-width: 58rem;
	margin-inline: auto;
	text-align: center;
}

/* Woo draws the col2-set clearfix as `content:" "; display:table`. Harmless
   beside floats; in a grid they become two anonymous grid items that push both
   columns onto row two. */
body.tsf-scope .woocommerce #customer_login::before,
body.tsf-scope .woocommerce #customer_login::after { content: none; }

body.tsf-scope .woocommerce #customer_login {
	display: grid;
	gap: 1.5rem;
}

@media (min-width: 820px) {
	/*
	 * Login is the primary action -- almost everyone arriving here already has an
	 * account, because accounts are created at checkout. Register is the second
	 * door, so it is narrower and quieter rather than an equal twin.
	 */
	body.tsf-scope .woocommerce #customer_login {
		grid-template-columns: minmax(0, 1.15fr) minmax(0, 0.85fr);
		gap: 2rem;
		align-items: start;
	}
}

/* The card shell moves off the forms and onto the columns, so each heading sits
   inside its own card. Before this only form.login was styled and form.register
   was still wearing WooCommerce's light-theme border -- which is why the two
   boxes did not match. */
body.tsf-scope .woocommerce #customer_login > .col-1,
body.tsf-scope .woocommerce #customer_login > .col-2 {
	float: none;
	width: auto;
	min-width: 0;
	display: flex;
	flex-direction: column;
	margin: 0;
	border: 1px solid var(--tsf-border);
	border-top: 2px solid var(--tsf-brand);
	border-radius: var(--tsf-radius-xl);
	background-color: var(--tsf-surface-1);
	padding: 1.75rem;
}

@media (min-width: 820px) {
	body.tsf-scope .woocommerce #customer_login > .col-1,
	body.tsf-scope .woocommerce #customer_login > .col-2 { padding: 2rem 2rem 1.75rem; }
}

body.tsf-scope.woocommerce-account #customer_login form.login,
body.tsf-scope.woocommerce-account #customer_login form.register {
	flex: 1 1 auto;
	display: flex;
	flex-direction: column;
	margin: 0;
	padding: 0;
	border: 0;
	border-radius: 0;
	background-color: transparent;
}

body.tsf-scope .woocommerce #customer_login > .col-1 > h2,
body.tsf-scope .woocommerce #customer_login > .col-2 > h2 {
	margin: 0 0 1.5rem;
}

/* Only the primary card wears the brand rule. */
body.tsf-scope .woocommerce #customer_login > .col-2 {
	border-top: 1px solid var(--tsf-border);
	background-color: transparent;
}

body.tsf-scope .woocommerce #customer_login > .col-2 > h2 {
	font-size: 0.95rem;
	color: var(--tsf-muted-fg);
}

/* An outline button, so the one solid red on the screen is Log in. */
body.tsf-scope .woocommerce #customer_login > .col-2 .button {
	background-color: transparent;
	color: var(--tsf-fg);
	border-color: rgba(255, 255, 255, 0.25);
}

body.tsf-scope .woocommerce #customer_login > .col-2 .button:hover {
	background-color: transparent;
	border-color: var(--tsf-brand);
	color: var(--tsf-brand-bright);
}

body.tsf-scope .woocommerce #customer_login form.register > p:not([class]) {
	margin: 0 0 1.25rem;
	font-size: 0.8125rem;
	line-height: 1.6;
	color: var(--tsf-muted-fg);
}

/* Both submits pinned to the foot of their card so the two actions line up. */
body.tsf-scope .woocommerce #customer_login form > p:has(button[type="submit"]) {
	margin-top: auto;
	padding-top: 0.5rem;
}

body.tsf-scope .woocommerce #customer_login .button {
	width: 100%;
	margin-top: 0.5rem;
	padding-block: 0.95rem;
}

/* accent-color only tints the CHECKED state; unchecked was still the raw OS
   control, which is what looked unfinished on near-black. */
body.tsf-scope .woocommerce #customer_login input[type="checkbox"] {
	appearance: none;
	-webkit-appearance: none;
	flex: none;
	width: 1.15rem;
	height: 1.15rem;
	margin: 0.1rem 0 0;
	border: 1px solid var(--tsf-border-strong);
	border-radius: var(--tsf-radius);
	background-color: var(--tsf-bg);
	cursor: pointer;
	transition: background-color 0.15s var(--tsf-ease), border-color 0.15s var(--tsf-ease);
}

body.tsf-scope .woocommerce #customer_login input[type="checkbox"]:hover { border-color: var(--tsf-brand); }

body.tsf-scope .woocommerce #customer_login input[type="checkbox"]:checked {
	border-color: var(--tsf-brand);
	background-color: var(--tsf-brand);
	background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='10' viewBox='0 0 12 10' fill='none' stroke='%23fff' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m1 5 3.5 3.5L11 1.5'/%3E%3C/svg%3E");
	background-repeat: no-repeat;
	background-position: center;
	background-size: 0.7rem auto;
}

body.tsf-scope .woocommerce #customer_login .woocommerce-LostPassword { margin: 0.875rem 0 0; }

body.tsf-scope .woocommerce #customer_login .woocommerce-LostPassword a {
	font-size: 0.6875rem;
	font-weight: 700;
	letter-spacing: 0.12em;
	text-transform: uppercase;
	text-decoration: none;
}

body.tsf-scope .woocommerce-MyAccount-navigation ul {
	margin: 0;
	padding: 0.5rem;
	list-style: none;
	border: 1px solid var(--tsf-border);
	border-radius: var(--tsf-radius-xl);
	background-color: var(--tsf-surface-1);
}

body.tsf-scope .woocommerce-MyAccount-navigation li { margin: 0; }

body.tsf-scope .woocommerce-MyAccount-navigation li a {
	display: block;
	padding: 0.6rem 0.9rem;
	border-radius: var(--tsf-radius);
	font-size: 0.75rem;
	font-weight: 700;
	letter-spacing: 0.1em;
	text-transform: uppercase;
	text-decoration: none;
	color: rgba(255, 255, 255, 0.65);
	transition: background-color 0.15s var(--tsf-ease), color 0.15s var(--tsf-ease);
}

body.tsf-scope .woocommerce-MyAccount-navigation li a:hover {
	background-color: rgba(255, 255, 255, 0.05);
	color: var(--tsf-fg);
}

body.tsf-scope .woocommerce-MyAccount-navigation li.is-active a {
	background-color: var(--tsf-brand);
	color: var(--tsf-on-brand);
}

body.tsf-scope .woocommerce-MyAccount-content { min-width: 0; }
body.tsf-scope .woocommerce-MyAccount-content > p:first-child { margin-top: 0; }

body.tsf-scope .woocommerce .tsf-cancel-note {
	margin: 1.25rem 0 0;
	padding: 0.9rem 1.15rem;
	border: 1px solid var(--tsf-border);
	border-left: 2px solid var(--tsf-brand);
	border-radius: 0 var(--tsf-radius-lg) var(--tsf-radius-lg) 0;
	background-color: var(--tsf-surface-1);
	font-size: 0.8125rem;
	line-height: 1.65;
	color: var(--tsf-muted-fg);
}

/* ---- subscription detail ---- */

/*
 * Subscriptions renders BOTH columns of this table as <td> -- there is not a
 * single <th> in the template -- so the old `th` rule matched nothing and label
 * and value came out at identical weight.
 */
body.tsf-scope .woocommerce table.subscription_details td:first-child {
	width: 40%;
	vertical-align: top;
	padding-top: 1.1rem;
	font-size: 0.6875rem;
	font-weight: 700;
	letter-spacing: 0.12em;
	text-transform: uppercase;
	line-height: 1.5;
	color: var(--tsf-muted-fg);
}

body.tsf-scope .woocommerce table.subscription_details td:last-child {
	font-size: 0.9375rem;
	font-weight: 500;
	color: var(--tsf-fg);
}

/* Row one is always Status. Without a state class it cannot be coloured, but it
   can stop reading as prose. */
body.tsf-scope .woocommerce table.subscription_details tbody tr:first-child td:last-child {
	font-size: 0.75rem;
	font-weight: 700;
	letter-spacing: 0.12em;
	text-transform: uppercase;
}

@media (min-width: 640px) {
	body.tsf-scope .woocommerce table.subscription_details td:first-child { width: 26%; }
}

/* ---- lost password / set a new password ----
 *
 * WooCommerce already gives these their own endpoints, so they are real,
 * separate screens -- they had simply never been styled and arrived as a bare
 * full-width form. Both the "email me a link" step and the "choose a new
 * password" step use form.woocommerce-ResetPassword, so one card covers both.
 *
 * Narrower than the two-card login screen: this is one short task, and a 928px
 * input for an email address looks like a mistake.
 */
body.tsf-scope.woocommerce-account:not(.logged-in) .woocommerce:has(form.woocommerce-ResetPassword),
body.tsf-scope.woocommerce-account:not(.logged-in) .woocommerce:has(form.woocommerce-ResetPassword) ~ * {
	max-width: 32rem;
}

body.tsf-scope .woocommerce form.woocommerce-ResetPassword {
	margin: 0;
	border: 1px solid var(--tsf-border);
	border-top: 2px solid var(--tsf-brand);
	border-radius: var(--tsf-radius-xl);
	background-color: var(--tsf-surface-1);
	padding: 1.75rem;
}

@media (min-width: 640px) {
	body.tsf-scope .woocommerce form.woocommerce-ResetPassword { padding: 2rem; }
}

/* The instruction line above the field is unclassed, so it arrived unstyled. */
body.tsf-scope .woocommerce form.woocommerce-ResetPassword > p:not([class]) {
	margin: 0 0 1.5rem;
	font-size: 0.875rem;
	line-height: 1.65;
	color: var(--tsf-muted-fg);
}

body.tsf-scope .woocommerce form.woocommerce-ResetPassword .button {
	width: 100%;
	margin-top: 0.5rem;
	padding-block: 0.95rem;
}

/* Woo hides the reset key and login in hidden inputs inside their own <p>. */
body.tsf-scope .woocommerce form.woocommerce-ResetPassword .woocommerce-form-row:has(> input[type="hidden"]:only-child) {
	display: none;
}

/* A way back, so the only route off this screen is not the browser button. */
body.tsf-scope.woocommerce-account:not(.logged-in) .woocommerce-ResetPassword + p,
body.tsf-scope .woocommerce form.woocommerce-ResetPassword ~ p {
	margin: 1.25rem 0 0;
	text-align: center;
	font-size: 0.6875rem;
	font-weight: 700;
	letter-spacing: 0.12em;
	text-transform: uppercase;
}

/* ---------------------------------------------------------- checkout */

body.tsf-scope.woocommerce-checkout .woocommerce { display: block; }

@media (min-width: 960px) {
	body.tsf-scope.woocommerce-checkout form.checkout {
		display: grid;
		grid-template-columns: minmax(0, 1.15fr) minmax(0, 0.85fr);
		/*
		 * Row one holds only the "Your order" eyebrow, so it is sized to its
		 * content -- left to auto it took a share of the details column, which
		 * spans both rows, and opened a 100px hole under the eyebrow. And the
		 * gap is columns only: a row gap here separates the eyebrow from the
		 * card it labels.
		 */
		grid-template-rows: min-content auto;
		column-gap: 3rem;
		row-gap: 0;
		align-items: start;
	}

	/* The form has exactly three children: the details block, the review heading
	   and the review. Rows are set explicitly -- left to auto-placement the
	   review lands on row three of column two, well below the fold. */
	body.tsf-scope.woocommerce-checkout form.checkout > #customer_details {
		grid-column: 1;
		grid-row: 2;
	}

	body.tsf-scope.woocommerce-checkout form.checkout > #order_review_heading {
		grid-column: 2;
		grid-row: 1;
		margin-top: 0;
	}

	body.tsf-scope.woocommerce-checkout form.checkout > #order_review {
		grid-column: 2;
		grid-row: 2;
	}

	/* The review column sticks while the longer form column scrolls. */
	body.tsf-scope.woocommerce-checkout form.checkout > #order_review {
		position: sticky;
		top: 7rem;
	}
}

body.tsf-scope.woocommerce-checkout #customer_details .col-1,
body.tsf-scope.woocommerce-checkout #customer_details .col-2 {
	float: none;
	width: 100%;
}

body.tsf-scope.woocommerce-checkout #order_review_heading { margin-top: 0; }

body.tsf-scope.woocommerce-checkout .woocommerce-checkout-review-order-table { margin-bottom: 1.5rem; }

/* ---- the login and coupon toggles above the form ---- */

/*
 * The "Returning customer?" and "Have a coupon?" bars are utility links, not
 * alerts, and they were costing 94px each: a 54px box, plus 24px of margin on
 * the .woocommerce-info inside, plus 16px on the wrapper around it. Three of
 * them stacked is most of a screen before the form begins.
 */
body.tsf-scope .woocommerce-form-login-toggle,
body.tsf-scope .woocommerce-form-coupon-toggle { margin-bottom: 0.75rem; }

body.tsf-scope .woocommerce-form-login-toggle .woocommerce-info,
body.tsf-scope .woocommerce-form-coupon-toggle .woocommerce-info {
	margin: 0;
	padding: 0.7rem 1rem;
	border-width: 1px;
	border-left-width: 2px;
	background-color: transparent;
	font-size: 0.8125rem;
}

/* The notices wrapper sits above them and its last child's margin collapses
   through, adding a gap nobody asked for. */
body.tsf-scope .woocommerce-notices-wrapper > :last-child { margin-bottom: 0; }
body.tsf-scope .woocommerce-notices-wrapper:not(:empty) { margin-bottom: 1.25rem; }

body.tsf-scope .woocommerce form.login,
body.tsf-scope .woocommerce form.checkout_coupon {
	margin: 0 0 1.5rem;
	padding: 1.25rem;
	border: 1px solid var(--tsf-border);
	border-radius: var(--tsf-radius-xl);
	background-color: var(--tsf-surface-1);
}

/* ---- payment methods ---- */

body.tsf-scope .woocommerce #payment {
	border-radius: var(--tsf-radius-xl);
	border: 1px solid var(--tsf-border);
	background-color: var(--tsf-surface-1);
	padding: 1.25rem;
}

body.tsf-scope .woocommerce #payment ul.payment_methods {
	margin: 0;
	padding: 0;
	border: 0;
	list-style: none;
}

body.tsf-scope .woocommerce #payment ul.payment_methods li {
	margin: 0 0 0.5rem;
	padding: 0.75rem 0.9rem;
	border: 1px solid var(--tsf-border);
	border-radius: var(--tsf-radius-lg);
	background-color: var(--tsf-bg);
}

body.tsf-scope .woocommerce #payment ul.payment_methods li label {
	display: inline-flex;
	align-items: center;
	gap: 0.5rem;
	margin: 0;
	font-size: 0.8125rem;
	font-weight: 600;
	letter-spacing: 0;
	text-transform: none;
	color: var(--tsf-fg);
	cursor: pointer;
}

body.tsf-scope .woocommerce #payment ul.payment_methods li input[type="radio"] {
	width: 1.05rem;
	height: 1.05rem;
	margin: 0;
	accent-color: var(--tsf-brand);
}

body.tsf-scope .woocommerce #payment .payment_box {
	margin: 0.75rem 0 0;
	padding: 0.75rem 0.9rem;
	border-radius: var(--tsf-radius);
	background-color: rgba(255, 255, 255, 0.04);
	font-size: 0.8125rem;
	color: var(--tsf-muted-fg);
}

body.tsf-scope .woocommerce #payment .payment_box::before { content: none; }

body.tsf-scope .woocommerce #payment .place-order { padding: 1rem 0 0; margin: 0; }
body.tsf-scope .woocommerce #payment #place_order { width: 100%; margin-top: 0.5rem; }

/* -------------------------------------------------------------- cart */

/*
 * The cart was not badly styled, it was badly shaped: three of its six columns
 * carried nothing. A placeholder image (these are virtual memberships with no
 * artwork, so every row drew a white square -- the loudest thing on a near-black
 * page), a quantity cell that is always empty because the products are sold
 * individually, and a subtotal that for quantity 1 is the price again. What is
 * left is a two-column list: what you are buying, and what it costs.
 */
body.tsf-scope.woocommerce-cart .woocommerce {
	display: grid;
	gap: 2rem;
	align-items: start;
}

@media (min-width: 960px) {
	body.tsf-scope.woocommerce-cart .woocommerce {
		grid-template-columns: minmax(0, 1fr) minmax(0, 21rem);
		gap: 3rem;
	}

	body.tsf-scope.woocommerce-cart .woocommerce > .woocommerce-notices-wrapper { grid-column: 1 / -1; }

	body.tsf-scope.woocommerce-cart .cart-collaterals { position: sticky; top: 7rem; }
}

body.tsf-scope.woocommerce-cart .woocommerce-cart-form { min-width: 0; }
body.tsf-scope.woocommerce-cart .cart-collaterals { width: auto; min-width: 0; }

/* Woo's own two-column float shim, which the grid replaces. */
body.tsf-scope .woocommerce .cart-collaterals .cart_totals {
	float: none;
	width: auto;
	max-width: none;
	margin: 0;
}

body.tsf-scope .woocommerce table.cart { margin-bottom: 0; }

/* Pinned to .woocommerce-placeholder so a product that does have artwork keeps
   showing it. */
body.tsf-scope .woocommerce td.product-thumbnail img.woocommerce-placeholder { display: none; }

body.tsf-scope .woocommerce table.cart th.product-thumbnail,
body.tsf-scope .woocommerce table.cart td.product-thumbnail,
body.tsf-scope .woocommerce table.cart th.product-quantity,
body.tsf-scope .woocommerce table.cart td.product-quantity,
body.tsf-scope .woocommerce table.cart th.product-subtotal,
body.tsf-scope .woocommerce table.cart td.product-subtotal { display: none; }

body.tsf-scope .woocommerce table.cart th.product-remove,
body.tsf-scope .woocommerce table.cart td.product-remove { width: 3.25rem; padding-right: 0; }

body.tsf-scope .woocommerce table.cart th.product-price,
body.tsf-scope .woocommerce table.cart td.product-price {
	text-align: right;
	white-space: nowrap;
	color: var(--tsf-fg);
}

body.tsf-scope .woocommerce table.cart td { padding-block: 1.15rem; }

body.tsf-scope .woocommerce table.cart td.product-name {
	font-size: 0.9375rem;
	font-weight: 600;
	line-height: 1.4;
}

body.tsf-scope .woocommerce table.cart td.product-name > a { color: var(--tsf-fg); }

/* The renewal line drops back so the product name is the row. */
body.tsf-scope .woocommerce table.cart td.product-name dl.variation,
body.tsf-scope .woocommerce table.cart td.product-name .subscription-details {
	margin: 0.35rem 0 0;
	font-size: 0.8125rem;
	font-weight: 400;
	color: var(--tsf-muted-fg);
}

/* The remove control takes .tsf-card__badge's tinted-icon treatment rather than
   reading as a grey system button. */
body.tsf-scope .woocommerce td.product-remove a.remove {
	display: inline-grid;
	place-items: center;
	width: 1.75rem;
	height: 1.75rem;
	border-radius: var(--tsf-radius-pill);
	background-color: rgba(227, 30, 36, 0.12);
	color: var(--tsf-brand-bright);
	font-size: 1rem;
	line-height: 1;
	text-decoration: none;
	transition: background-color 0.15s var(--tsf-ease), color 0.15s var(--tsf-ease);
}

body.tsf-scope .woocommerce td.product-remove a.remove:hover {
	background-color: var(--tsf-brand);
	color: var(--tsf-on-brand);
}

/* The coupon row reads as a deliberate tray rather than leftover controls. */
body.tsf-scope .woocommerce table.cart td.actions {
	padding: 1.15rem;
	background-color: var(--tsf-bg);
}

body.tsf-scope .woocommerce table.cart td.actions .coupon {
	display: flex;
	gap: 0.75rem;
	flex-wrap: wrap;
	align-items: center;
}

body.tsf-scope .woocommerce table.cart td.actions .coupon .input-text {
	width: auto;
	flex: 1 1 11rem;
}

/* Secondary next to Proceed to Checkout. */
body.tsf-scope .woocommerce table.cart td.actions .coupon .button {
	background-color: transparent;
	color: var(--tsf-fg);
	border-color: rgba(255, 255, 255, 0.25);
}

body.tsf-scope .woocommerce table.cart td.actions .coupon .button:hover {
	background-color: transparent;
	border-color: var(--tsf-brand);
	color: var(--tsf-brand-bright);
}

/* Quantity is fixed at one per child, so Update Cart can never do anything. */
body.tsf-scope .woocommerce table.cart td.actions > button[name="update_cart"],
body.tsf-scope .woocommerce table.cart td.actions > input[name="update_cart"] { display: none; }

body.tsf-scope .woocommerce .tsf-qty-fixed { color: var(--tsf-muted-fg); }

body.tsf-scope .woocommerce .wc-proceed-to-checkout { padding: 1.25rem 0 0; }
body.tsf-scope .woocommerce .wc-proceed-to-checkout .checkout-button { width: 100%; }

body.tsf-scope .woocommerce .quantity .qty {
	width: 4.5rem;
	text-align: center;
	padding-inline: 0.5rem;
}

body.tsf-scope .woocommerce .actions .coupon { display: flex; gap: 0.75rem; flex-wrap: wrap; }
body.tsf-scope .woocommerce .actions .coupon .input-text { width: auto; flex: 1 1 12rem; }

/* --------------------------------------------------------- select2 ----
   WooCommerce renders the country and state fields through select2, which
   paints its own white dropdown. */

body.tsf-scope .select2-container--default .select2-selection--single {
	height: auto;
	border-radius: var(--tsf-radius-lg);
	border: 1px solid rgba(255, 255, 255, 0.1);
	background-color: var(--tsf-bg);
	padding: 0.75rem 1rem;
}

body.tsf-scope .select2-container--default .select2-selection--single .select2-selection__rendered {
	padding: 0;
	line-height: 1.5;
	font-size: 0.875rem;
	color: var(--tsf-fg);
}

body.tsf-scope .select2-container--default .select2-selection--single .select2-selection__arrow { top: 50%; translate: 0 -50%; right: 0.75rem; }
body.tsf-scope .select2-container--default .select2-selection--single .select2-selection__placeholder { color: rgba(255, 255, 255, 0.3); }

/* The dropdown is appended to <body>, outside .woocommerce, so it is scoped on
   body.tsf-scope alone. */
body.tsf-scope .select2-dropdown {
	border: 1px solid var(--tsf-border-strong);
	border-radius: var(--tsf-radius-lg);
	background-color: var(--tsf-surface-2);
	color: var(--tsf-fg);
	overflow: hidden;
}

body.tsf-scope .select2-container--default .select2-search--dropdown .select2-search__field {
	border: 1px solid rgba(255, 255, 255, 0.1);
	border-radius: var(--tsf-radius);
	background-color: var(--tsf-bg);
	color: var(--tsf-fg);
	padding: 0.5rem 0.75rem;
	font-size: 0.875rem;
}

body.tsf-scope .select2-container--default .select2-results__option { padding: 0.5rem 0.9rem; font-size: 0.875rem; }

body.tsf-scope .select2-container--default .select2-results__option--highlighted[aria-selected],
body.tsf-scope .select2-container--default .select2-results__option--highlighted[data-selected] {
	background-color: var(--tsf-brand);
	color: var(--tsf-on-brand);
}

body.tsf-scope .select2-container--default .select2-results__option[aria-selected="true"] {
	background-color: rgba(255, 255, 255, 0.06);
	color: var(--tsf-fg);
}

/* -------------------------------------------------- small screens ---- */

@media (max-width: 767px) {
	/* Woo's responsive tables reflow to a label/value stack; its own rules assume
	   a light theme and a visible cell border. */
	body.tsf-scope .woocommerce table.shop_table_responsive tr td {
		display: flex;
		justify-content: space-between;
		gap: 1rem;
		text-align: right;
	}

	body.tsf-scope .woocommerce table.shop_table_responsive tr td::before {
		font-size: 0.68rem;
		font-weight: 700;
		letter-spacing: 0.1em;
		text-transform: uppercase;
		color: rgba(255, 255, 255, 0.5);
	}

	body.tsf-scope .woocommerce table.shop_table_responsive thead { display: none; }

	body.tsf-scope .woocommerce .button { width: 100%; }
}

/* ------------------------------------------- checkout: the money column */

/*
 * The summary had no internal hierarchy: every row was drawn at one weight, so
 * the number the parent is committing to read exactly like the word "Subtotal".
 * Worse, the old `.order-total` rule matched BOTH the one-off first payment and
 * the recurring total, so the one distinction the page most needs to make was
 * the one the CSS erased.
 */

/* "Your order" stops competing with the page title and becomes the eyebrow. */
body.tsf-scope.woocommerce-checkout #order_review_heading {
	font-family: var(--tsf-font-sans);
	font-size: 0.75rem;
	font-weight: 700;
	letter-spacing: 0.3em;
	line-height: 1.5;
	text-transform: uppercase;
	color: var(--tsf-brand-bright);
	margin: 0 0 0.75rem;
	padding-top: 0;
}

body.tsf-scope.woocommerce-checkout #order_review_heading::before { content: none; }

@media (max-width: 959px) {
	body.tsf-scope.woocommerce-checkout #order_review_heading { margin-top: 3rem; }
}

/* The card lifts a step above the form furniture and takes the 2px brand cap
   this design uses to top a block. */
body.tsf-scope.woocommerce-checkout .woocommerce table.woocommerce-checkout-review-order-table {
	margin-bottom: 1rem;
	border: 1px solid var(--tsf-border-strong);
	border-top: 2px solid var(--tsf-brand);
	border-radius: var(--tsf-radius-xl);
	background-color: var(--tsf-surface-2);
	box-shadow: 0 24px 48px -32px rgb(0 0 0 / 0.9);
}

body.tsf-scope.woocommerce-checkout .woocommerce .woocommerce-checkout-review-order-table th,
body.tsf-scope.woocommerce-checkout .woocommerce .woocommerce-checkout-review-order-table td {
	padding: 1rem 1.25rem;
}

/* One right edge for every figure. */
body.tsf-scope.woocommerce-checkout .woocommerce .woocommerce-checkout-review-order-table td,
body.tsf-scope.woocommerce-checkout .woocommerce .woocommerce-checkout-review-order-table thead th.product-total {
	text-align: right;
}

body.tsf-scope.woocommerce-checkout .woocommerce .woocommerce-checkout-review-order-table tbody .product-name {
	text-align: left;
	font-weight: 600;
	color: var(--tsf-fg);
}

/* Items above, money below. */
body.tsf-scope.woocommerce-checkout .woocommerce .woocommerce-checkout-review-order-table tfoot tr:first-child > * {
	border-top: 1px solid var(--tsf-border-strong);
}

body.tsf-scope.woocommerce-checkout .woocommerce .woocommerce-checkout-review-order-table tfoot th {
	text-align: left;
}

/* The first payment is the largest thing in the card. `:not(.recurring-total)`
   is what finally separates today's charge from the monthly commitment. */
body.tsf-scope.woocommerce-checkout .woocommerce .woocommerce-checkout-review-order-table tfoot tr.order-total:not(.recurring-total) > * {
	vertical-align: baseline;
	padding-block: 1.15rem;
}

body.tsf-scope.woocommerce-checkout .woocommerce .woocommerce-checkout-review-order-table tfoot tr.order-total:not(.recurring-total) th {
	font-size: 0.6875rem;
	letter-spacing: 0.14em;
	color: var(--tsf-fg);
}

body.tsf-scope.woocommerce-checkout .woocommerce .woocommerce-checkout-review-order-table tfoot tr.order-total:not(.recurring-total) td {
	font-family: var(--tsf-font-display);
	font-weight: 400;
	font-size: 1.875rem;
	line-height: 1;
	letter-spacing: var(--tsf-display-tracking);
	color: var(--tsf-fg);
}

/* Woo wraps the figure in <strong>; Archivo Black ships one weight, so an
   inherited bold would be synthesised and smear. */
body.tsf-scope.woocommerce-checkout .woocommerce .woocommerce-checkout-review-order-table tfoot td strong { font-weight: 400; }

/* The recurring rows become one commitment panel rather than three more table
   rows: a brand tint and a red spine down the left edge, the same device the
   notices use. */
body.tsf-scope.woocommerce-checkout .woocommerce .woocommerce-checkout-review-order-table tfoot tr.recurring-totals > *,
body.tsf-scope.woocommerce-checkout .woocommerce .woocommerce-checkout-review-order-table tfoot tr.recurring-total > * {
	background-color: rgba(227, 30, 36, 0.07);
	border-top: 0;
}

body.tsf-scope.woocommerce-checkout .woocommerce .woocommerce-checkout-review-order-table tfoot tr.recurring-totals > *:first-child,
body.tsf-scope.woocommerce-checkout .woocommerce .woocommerce-checkout-review-order-table tfoot tr.recurring-total > *:first-child {
	box-shadow: inset 2px 0 0 0 var(--tsf-brand);
}

body.tsf-scope.woocommerce-checkout .woocommerce .woocommerce-checkout-review-order-table tfoot tr.recurring-totals th {
	padding-top: 1.15rem;
	padding-bottom: 0.35rem;
	font-size: 0.6875rem;
	letter-spacing: 0.2em;
	color: var(--tsf-brand-bright);
}

body.tsf-scope.woocommerce-checkout .woocommerce .woocommerce-checkout-review-order-table tfoot tr.recurring-total th,
body.tsf-scope.woocommerce-checkout .woocommerce .woocommerce-checkout-review-order-table tfoot tr.recurring-total td {
	color: var(--tsf-fg);
}

body.tsf-scope.woocommerce-checkout .woocommerce .woocommerce-checkout-review-order-table tfoot tr.recurring-total td .woocommerce-Price-amount {
	font-size: 1.125rem;
	font-weight: 700;
}

/* The renewal date arrives as an unstyled <small> -- the faintest text in the
   column, carrying the most consequential fact on the page. */
body.tsf-scope.woocommerce-checkout .woocommerce .first-payment-date {
	display: block;
	margin-top: 0.4rem;
	font-size: 0.75rem;
	line-height: 1.5;
	color: var(--tsf-muted-fg);
}

body.tsf-scope.woocommerce-checkout .woocommerce .first-payment-date small { font-size: inherit; }

/* Woo marks a validated field with its own green. Two colours on this site, not
   three. */
body.tsf-scope .woocommerce .woocommerce-validated .input-text,
body.tsf-scope .woocommerce .woocommerce-validated input.input-text,
body.tsf-scope .woocommerce .woocommerce-validated select {
	border-color: rgba(255, 255, 255, 0.1);
}

/* Order notes are switched off, so this wrapper is always empty. */
body.tsf-scope .woocommerce .woocommerce-additional-fields:empty,
body.tsf-scope .woocommerce .woocommerce-additional-fields > :only-child:empty { display: none; }

/* --------------------------------------------------- checkout: sections */

/*
 * form-billing.php prints its heading, then fires the hook we render into, then
 * the fields -- so "Billing details" announced the player fields and the parent
 * fields had no heading of their own. Flex plus order puts the player block
 * above the heading without fighting the template.
 */
body.tsf-scope .woocommerce .woocommerce-billing-fields {
	display: flex;
	flex-direction: column;
}

body.tsf-scope .woocommerce .woocommerce-billing-fields > .tsf-players { order: -1; }

body.tsf-scope .woocommerce .woocommerce-billing-fields > h3 { margin-top: 0.5rem; }

/* ---- password ---- */

body.tsf-scope .woocommerce .woocommerce-account-fields .create-account,
body.tsf-scope .woocommerce #account_password_field { width: 100%; }

/*
 * WordPress paints the strength meter in its own palette -- a pale green bar and
 * a pink error box, both of which land on this page as if they came from a
 * different site.
 */
body.tsf-scope .woocommerce .woocommerce-password-strength {
	display: block;
	margin-top: 0.5rem;
	padding: 0.5rem 0.75rem;
	border: 1px solid var(--tsf-border-strong);
	border-radius: var(--tsf-radius);
	background-color: var(--tsf-surface-1);
	font-size: 0.6875rem;
	font-weight: 700;
	letter-spacing: 0.12em;
	text-transform: uppercase;
	text-align: left;
	color: var(--tsf-muted-fg);
}

body.tsf-scope .woocommerce .woocommerce-password-strength.strong,
body.tsf-scope .woocommerce .woocommerce-password-strength.good {
	border-color: rgba(63, 191, 127, 0.35);
	background-color: var(--tsf-state-good-soft);
	color: var(--tsf-state-good);
}

body.tsf-scope .woocommerce .woocommerce-password-strength.short,
body.tsf-scope .woocommerce .woocommerce-password-strength.bad {
	border-color: rgba(240, 168, 37, 0.35);
	background-color: var(--tsf-state-wait-soft);
	color: var(--tsf-state-wait);
}

body.tsf-scope .woocommerce .woocommerce-password-hint {
	display: block;
	margin-top: 0.5rem;
	font-size: 0.75rem;
	line-height: 1.6;
	font-weight: 400;
	letter-spacing: 0;
	text-transform: none;
	color: var(--tsf-muted-fg);
}

/* The show/hide eye WooCommerce injects into password fields. */
body.tsf-scope .woocommerce .show-password-input {
	color: var(--tsf-muted-fg);
	top: 0.85rem;
}

body.tsf-scope .woocommerce .show-password-input::after { color: inherit; }

/* ------------------------------------------------- my account nav colour */

/*
 * The site-wide link colour rule is four classes deep and was repainting every
 * item in the account menu brand red -- including the active one, which sits on
 * a brand red fill. Red on red. These need to outrank it.
 */
/* The :not() is there to match the link rule's four classes and win on element
   count -- these are menu items, not body copy, and should not read as links. */
body.tsf-scope .woocommerce .woocommerce-MyAccount-navigation li a:not(.button) {
	color: rgba(255, 255, 255, 0.65);
}

body.tsf-scope .woocommerce .woocommerce-MyAccount-navigation li a:not(.button):hover {
	color: var(--tsf-fg);
}

body.tsf-scope .woocommerce .woocommerce-MyAccount-navigation li.is-active a:not(.button),
body.tsf-scope .woocommerce .woocommerce-MyAccount-navigation li.is-active a:not(.button):hover {
	background-color: var(--tsf-brand);
	color: var(--tsf-on-brand);
}
