/*
Theme Name: OSK IND Child
Theme URI: https://osk.ind
Description: Child theme for osk.ind, extending Storefront. Implements the approved Home page design — a repeating "platform section" (status ticker, hero, brand ticker, product grid) generated once per WooCommerce product category. See front-page.php and inc/template-tags.php for the loop, and inc/acf-fields.php for the per-category fields it depends on.
Author: 
Template: storefront
Version: 1.7.19
Text Domain: osk-ind-child
*/

@import url('https://fonts.googleapis.com/css2?family=Ubuntu+Mono:wght@400;700&display=swap');

/* ==========================================================================
   BRAND TOKENS — mirrors the WordPress child theme's style.css exactly.
   Edit here first; once settled, port back into style.css.
   ========================================================================== */
:root {
	--osk-bg:      #e4e4e2;
	--osk-accent:  #ffd10a;
	--osk-text:    #1a1a1a;
	--osk-border:  #787876;
	--osk-bg-alt:  #d8d8d6;

	--osk-font: 'Ubuntu Mono', 'Courier New', monospace;

	--osk-text-xs:   0.75rem;
	--osk-text-sm:   0.875rem;
	--osk-text-base: 1rem;
	--osk-text-md:   1.25rem;
	--osk-text-lg:   2rem;
	--osk-text-xl:   3.5rem;

	--osk-space-1: 0.5rem;
	--osk-space-2: 1rem;
	--osk-space-3: 1.5rem;
	--osk-space-4: 2rem;
	--osk-space-6: 3rem;
	--osk-space-8: 4rem;

	--osk-border-width: 2px;
	--osk-border-style: dashed;

	/* dash and gap set independently via border-image (native 'dashed'
	   can't decouple the two) */
	--osk-dash-len: 3px;
	--osk-dash-gap: 4px;
	--osk-dash-h: repeating-linear-gradient(to right, var(--osk-border) 0, var(--osk-border) var(--osk-dash-len), transparent var(--osk-dash-len), transparent calc(var(--osk-dash-len) + var(--osk-dash-gap)));
	--osk-dash-v: repeating-linear-gradient(to bottom, var(--osk-border) 0, var(--osk-border) var(--osk-dash-len), transparent var(--osk-dash-len), transparent calc(var(--osk-dash-len) + var(--osk-dash-gap)));
	--osk-dash-h-dark: repeating-linear-gradient(to right, var(--osk-text) 0, var(--osk-text) var(--osk-dash-len), transparent var(--osk-dash-len), transparent calc(var(--osk-dash-len) + var(--osk-dash-gap)));
	--osk-dash-v-dark: repeating-linear-gradient(to bottom, var(--osk-text) 0, var(--osk-text) var(--osk-dash-len), transparent var(--osk-dash-len), transparent calc(var(--osk-dash-len) + var(--osk-dash-gap)));
}

* { box-sizing: border-box; }
html { background: var(--osk-bg); }
body {
	font-family: var(--osk-font);
	background: var(--osk-bg);
	color: var(--osk-text);
	font-size: var(--osk-text-base);
	line-height: 1.6;
	margin: 0;
	-webkit-font-smoothing: antialiased;
}
img { max-width: 100%; display: block; }
a { color: inherit; text-decoration: none; }
button { font-family: var(--osk-font); }

/* ---- placeholder image block (stands in for real photography) ---- */
.ph {
	background: var(--osk-bg-alt);
	display: flex;
	align-items: center;
	justify-content: center;
	color: var(--osk-text);
	opacity: 0.35;
}
.ph svg { width: 30%; height: 30%; }

/* ==========================================================================
   HEADER  (sits BELOW the top ticker, not above it)
   ========================================================================== */
.osk-header {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--osk-space-3);
	padding: var(--osk-space-2) var(--osk-space-4);
	border-bottom: 1px solid transparent;
	border-image-source: var(--osk-dash-h);
	border-image-slice: 1;
	border-image-repeat: round;
	position: sticky;
	top: 0;
	z-index: 100;
	background: var(--osk-bg);
}
.osk-header__logo {
	display: flex;
	align-items: center;
	gap: 0.5em;
	font-weight: 400;
}
.osk-header__logo svg { width: 1.3em; height: 1.3em; }
.osk-header .osk-header__logo svg {
	height: 2em;                                     /* ~2x the "osk.ind" text height, per mockup */
	width: calc(2em * 22.07 / 19.81);                /* preserve the logo's aspect ratio */
	margin: 0 0.65em;                                /* modest gap, per mockup (+30%) */
}
.osk-header__nav { display: flex; gap: 0.4em; font-size: var(--osk-text-sm); }
.osk-header__nav a { padding: 0.25em 0.2em; }
.osk-header__nav a.is-active { border-bottom: 2px solid var(--osk-accent); }
.osk-header__tagline { font-size: var(--osk-text-sm); opacity: 0.75; }

/* ---- header account icon — links to My Account ---- */
.osk-header__tagline-group { display: flex; align-items: center; gap: 1ch; }
.osk-header__account {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 1.5em;
	height: 1.5em;
	flex-shrink: 0;
}
.osk-header__account svg { width: 100%; height: 100%; color: var(--osk-text); }
.osk-header__account.is-active svg { color: var(--osk-accent); }

/* ---- header cart icon — item-count badge, links to the Cart page ---- */
.osk-header__cart {
	position: relative;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 1.5em;
	height: 1.5em;
	flex-shrink: 0;
}
.osk-header__cart svg { width: 100%; height: 100%; color: var(--osk-text); }
.osk-header__cart-count {
	position: absolute;
	top: -0.35em;
	right: -0.6em;
	min-width: 1.3em;
	height: 1.3em;
	padding: 0 0.2em;
	display: flex;
	align-items: center;
	justify-content: center;
	background: var(--osk-accent);
	color: var(--osk-text);
	font-size: 0.65rem;
	font-weight: 700;
	line-height: 1;
	border-radius: 999px;
}
.osk-header__cart-count[hidden] { display: none; }

@media (max-width: 900px) {
	.osk-header { flex-wrap: wrap; row-gap: var(--osk-space-2); }
	.osk-header__tagline { display: none; }
}

/* ==========================================================================
   TICKER — measured from mockup: thin solid dark border top/bottom,
   uppercase, tight vertical padding (not roomy).
   ========================================================================== */
.osk-ticker {
	background: var(--osk-accent);
	overflow: hidden;
	white-space: nowrap;
	border-top: 1px solid transparent;
	border-bottom: 1px solid transparent;
	border-image-source: var(--osk-dash-h-dark);
	border-image-slice: 1;
	border-image-repeat: round;
}
.osk-ticker__track {
	display: inline-flex;
	animation: osk-ticker-scroll 28s linear infinite;
}
.osk-ticker__item {
	padding: 0.4em var(--osk-space-2);
	font-size: var(--osk-text-xs);
	letter-spacing: 0.03em;
	text-transform: uppercase;
	flex-shrink: 0;
}
@keyframes osk-ticker-scroll {
	from { transform: translateX(0); }
	to   { transform: translateX(-50%); }
}
.osk-ticker:hover .osk-ticker__track { animation-play-state: paused; }

/* ==========================================================================
   HERO — measured proportions: ~540px tall content area, text block
   BOTTOM-anchored (not centered) with a large empty gap above it.
   Image sits inset within the right column with real breathing room,
   not full-bleed to the column edge.
   ========================================================================== */
.osk-hero {
	display: grid;
	grid-template-columns: 2fr 3fr;
	min-height: 78vh;   /* was height:78vh — content could need more room than that,
	                       causing the text column (and its border) to overflow past
	                       the row and bleed into the ticker below it */
}
.osk-hero__text {
	display: flex;
	flex-direction: column;
	justify-content: flex-end;   /* bottom-anchored, per mockup */
	gap: 0.15em;
	padding: 0 var(--osk-space-4) var(--osk-space-6) var(--osk-space-4);
	border-right: 1px solid transparent;
	border-image-source: var(--osk-dash-v);
	border-image-slice: 1;
	border-image-repeat: round;
}
.osk-hero__name {
	display: inline-block;
	background: var(--osk-accent);
	font-size: calc(var(--osk-text-sm) * 7 * 0.7);
	font-weight: 400;
	padding: 0 1ch 0 0;   /* right gap = width of one monospace char, matching "_" */
	width: fit-content;
	line-height: 1;       /* tight so the box hugs the "_" top/bottom */
	margin-bottom: var(--osk-space-2);
}
.osk-hero__subtitle-line { line-height: 1.15; margin: 0; }
.osk-hero__subtitle { font-size: calc(var(--osk-text-sm) * 2 * 0.7); font-weight: 400; }
.osk-hero__tagline { font-size: calc(var(--osk-text-sm) * 0.7); opacity: 0.75; }
.osk-hero__scroll {
	display: inline-flex;
	align-items: center;
	gap: 0.4em;
	font-size: calc(var(--osk-text-xs) * 0.7);
	opacity: 0.45;
	margin-top: var(--osk-space-4);
}
.osk-hero__scroll svg {
	width: 1em;
	height: 1em;
	flex-shrink: 0;
}
.osk-hero__image {
	display: flex;
	align-items: center;
	justify-content: center;
	padding: var(--osk-space-8);
	position: relative;
}
.osk-hero__image .ph {
	width: 100%;
	aspect-ratio: 4/3;
	max-height: 100%;
	border-radius: 48px;
	position: relative;
	overflow: hidden;   /* so a real photo respects the rounded corners */
	opacity: 1;   /* override the shared .ph placeholder fade — this holds a real photo */
}
.osk-hero__photo {
	width: 100%;
	height: 100%;
	object-fit: cover;
	display: block;
}
.osk-hero__view-btn {
	position: absolute;
	bottom: var(--osk-space-3);
	left: 50%;
	transform: translateX(-50%);
	z-index: 2;
	display: inline-flex;
	align-items: center;
	gap: 0.4em;
	padding: 0.4em var(--osk-space-3);
	font-family: var(--osk-font);
	font-size: var(--osk-text-sm);
	letter-spacing: 0.04em;
	border: none;
	border-radius: 0;
	background: var(--osk-accent);
	color: var(--osk-text);
	cursor: pointer;
	transition: background-color 0.15s ease;
}
.osk-hero__view-btn:hover { background: var(--osk-text); color: var(--osk-bg); }
.osk-hero__icon {
	position: absolute;
	top: 14%;
	left: 50%;
	transform: translateX(-50%);
	width: 14%;
	height: auto;
	color: var(--osk-accent);
	opacity: 0.9;
	z-index: 2;
	filter: drop-shadow(0 2px 6px rgba(0,0,0,0.35));
}

@media (max-width: 900px) {
	.osk-hero { grid-template-columns: 1fr; height: auto; min-height: 0; }
	.osk-hero__text { order: 2; border-right: none; border-bottom: 1px solid transparent; border-image-source: var(--osk-dash-h); border-image-slice: 1; border-image-repeat: round; padding: var(--osk-space-4); justify-content: flex-start; }
	.osk-hero__image { order: 1; padding: var(--osk-space-2); min-height: 320px; }
	.osk-hero__name { font-size: calc(var(--osk-text-sm) * 4 * 0.7); }
}

/* ---- Platform Detail page hero variant — reworked to a stacked
   layout: text row first, centered, full width; then the photo below,
   also full width, edge-to-edge (no padding, no rounded corner box, no
   "View specs" button since we're already on this platform's page).
   Overrides Home's two-column .osk-hero grid above. Matches
   preview-platform-detail.html exactly. See osk_render_hero_section()
   / osk_render_hero_photo() in inc/template-tags.php. ---- */
.osk-hero--detail {
	display: flex;
	flex-direction: column;
}
.osk-hero--detail .osk-hero__text {
	align-items: center;
	text-align: center;
	justify-content: flex-start;
	order: 0;
	padding: var(--osk-space-6) var(--osk-space-4);
	border-right: none;
	border-bottom: 1px solid transparent;
	border-image-source: var(--osk-dash-h);
	border-image-slice: 1;
	border-image-repeat: round;
}
.osk-hero--detail .osk-hero__image {
	display: block;
	order: 0;
	flex: 1;
	min-height: 0;
	padding: 0;
	overflow: hidden;
}
.osk-hero--detail .osk-hero__icon {
	top: 8%;
	width: 12%;
}

@media (max-width: 900px) {
	.osk-hero--detail { min-height: 0; }
	.osk-hero--detail .osk-hero__text { padding: var(--osk-space-4); }
	.osk-hero--detail .osk-hero__image { height: 45vh; min-height: 0; flex: none; padding: 0; }
}

.osk-platform-section + .osk-platform-section {
	border-top: 1px solid transparent;
	border-image-source: var(--osk-dash-h);
	border-image-slice: 1;
	border-image-repeat: round;
}

/* ==========================================================================
   PRODUCT GRID — measured: images are FULL-BLEED and SHARP-CORNERED inside
   each card (no padding, no radius). Text block below has its own padding.
   Category label + description are italic. Add-to-cart is solid black fill.
   ========================================================================== */
.osk-grid-section { }
.osk-grid-section__label {
	font-size: var(--osk-text-sm);
	margin: var(--osk-space-3) var(--osk-space-4) var(--osk-space-2);
}
.osk-grid-section__label .num { opacity: 0.5; margin-right: 0.5em; }
.osk-grid-section__label .name { font-weight: 700; }

.osk-product-grid {
	display: grid;
	grid-template-columns: repeat(4, 1fr) 1.1fr;
	border-top: 1px solid transparent;
	border-image-source: var(--osk-dash-h);
	border-image-slice: 1;
	border-image-repeat: round;
	border-left: none;
	border-right: none;
}
.osk-product-card {
	border-right: 1px solid transparent;
	border-image-source: var(--osk-dash-v);
	border-image-slice: 1;
	border-image-repeat: round;
	display: flex;
	flex-direction: column;
}
.osk-product-card__image {
	aspect-ratio: 4/3;
	overflow: hidden;
	/* full bleed: no radius, no padding, no gap from card edges */
}
/* .has-photo is added in PHP only when a real product/variation image
   exists — keeps the faded "ghost" look for genuine empty placeholders,
   while a real photo displays at full opacity and fills the box. */
.osk-product-card__image.has-photo { opacity: 1; }
.osk-product-card__image.has-photo img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	display: block;
}
.osk-product-card__body {
	padding: var(--osk-space-2);
	display: flex;
	flex-direction: column;
	gap: 0.35em;
	flex-grow: 1;
}
.osk-product-card__label {
	font-size: var(--osk-text-xs);
	font-style: italic;
	opacity: 0.55;
}
.osk-product-card__name { font-weight: 700; font-size: var(--osk-text-sm); }
.osk-product-card__desc {
	font-size: var(--osk-text-xs);
	font-style: italic;
	opacity: 0.8;
	line-height: 1.45;
}
/* "read more" (osk_render_single_product_card()'s $platform_term) only
   makes sense once the description is actually truncated, which is
   mobile-only (see @media (max-width: 600px) below) — hidden by default. */
.osk-product-card__more {
	display: none;
	font-size: var(--osk-text-xs);
	text-decoration: underline;
	width: fit-content;
}
.osk-product-card__footer {
	display: flex;
	align-items: baseline;
	justify-content: space-between;
	gap: 0.5em;
	/* pushes the footer to the card's bottom regardless of how much
	   room the (now fixed-height, clamped) description + read-more
	   link above it actually use — replaces the old flex-grow on
	   .osk-product-card__desc, which did this job before clamping. */
	margin-top: auto;
	padding-top: 0.5em;
}
.osk-product-card__price { font-weight: 700; font-size: var(--osk-text-sm); }
.osk-product-card__price small { font-weight: 400; opacity: 0.55; font-size: 0.65em; font-style: italic; margin-left: 0.3em; }

.osk-btn--cart {
	background: var(--osk-text);
	color: var(--osk-bg);
	border: none;
	padding: 0.4em 0.8em;
	font-size: var(--osk-text-xs);
	letter-spacing: 0.02em;
	cursor: pointer;
	transition: opacity 0.15s ease;
}
.osk-btn--cart:hover { opacity: 0.75; }
.osk-add-to-cart.is-loading { opacity: 0.5; pointer-events: none; }

/* ---- "added to cart" toast — shop-add-to-cart.js, shop grid cards ---- */
.osk-toast {
	position: fixed;
	left: 50%;
	bottom: var(--osk-space-3);
	transform: translate(-50%, 0.5em);
	background: var(--osk-text);
	color: var(--osk-bg);
	border: var(--osk-border-width) var(--osk-border-style) var(--osk-accent);
	padding: 0.6em 1.2em;
	font-size: var(--osk-text-sm);
	font-style: italic;
	white-space: nowrap;
	opacity: 0;
	pointer-events: none;
	transition: opacity 0.2s ease, transform 0.2s ease;
	z-index: 200;
}
.osk-toast.is-visible { opacity: 1; transform: translate(-50%, 0); }
.osk-toast--error { border-color: var(--osk-border); }

.osk-btn {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	padding: var(--osk-space-1) var(--osk-space-3);
	font-size: var(--osk-text-sm);
	letter-spacing: 0.04em;
	border: 1px solid var(--osk-text);
	background: transparent;
	color: var(--osk-text);
	cursor: pointer;
	transition: background-color 0.15s ease, color 0.15s ease;
	white-space: nowrap;
}
.osk-btn:hover { background: var(--osk-text); color: var(--osk-bg); }

.osk-repo-card__body {
	padding: var(--osk-space-2);
	display: flex;
	flex-direction: column;
	justify-content: space-between;
	flex-grow: 1;
	gap: var(--osk-space-2);
}
.osk-repo-card__eyebrow { font-size: var(--osk-text-xs); opacity: 0.55; }
.osk-repo-card__tag {
	display: inline-block;
	background: var(--osk-accent);
	padding: 0.2em 0.5em;
	font-size: var(--osk-text-xs);
	font-weight: 700;
	width: fit-content;
}
.osk-repo-card__desc { font-size: var(--osk-text-xs); opacity: 0.85; flex-grow: 1; }
.osk-repo-card__link { font-size: var(--osk-text-xs); text-decoration: underline; width: fit-content; }

@media (max-width: 1100px) { .osk-product-grid { grid-template-columns: repeat(2, 1fr); } }

/* Phone: product cards become a horizontally-scrolling row (~2.3 cards
   visible at once) that drifts on its own, very slowly, via
   product-grid-scroll.js incrementing scrollLeft back and forth — no
   buttons, no manual drag handling. Native touch-swipe still works
   (plain overflow-x:auto) and briefly pauses the autoplay. Repo card
   dropped entirely on mobile (not worth the horizontal-scroll real
   estate). Swapped for a flex row instead of fighting
   grid-template-columns with a variable, unknown-in-advance card count. */
@media (max-width: 600px) {
	.osk-product-grid {
		display: flex;
		overflow-x: auto;
		-webkit-overflow-scrolling: touch;
		scrollbar-width: none;
	}
	.osk-product-grid::-webkit-scrollbar { display: none; }
	.osk-product-card { flex: 0 0 43%; }
	/* safety: price + button can get tight at ~43%-of-phone-width; wrap
	   instead of squeezing/overflowing if a longer price ever doesn't fit. */
	.osk-product-card__footer { flex-wrap: wrap; }
	.osk-repo-card { display: none; }
	/* description: 2-line clamp + "read more" link to the platform page,
	   phone-only — cards this narrow don't have room for the full text,
	   unlike desktop/tablet where it stays fully visible as before. */
	.osk-product-card__desc {
		display: -webkit-box;
		-webkit-line-clamp: 2;
		line-clamp: 2;
		-webkit-box-orient: vertical;
		overflow: hidden;
	}
	.osk-product-card__more { display: block; }
}

/* ==========================================================================
   FOOTER — left-aligned lockup, not spread edge-to-edge
   ========================================================================== */
.osk-footer {
	display: grid;
	grid-template-columns: 1fr auto 1fr;
	align-items: center;
	gap: var(--osk-space-2);
	padding: var(--osk-space-3) var(--osk-space-4);
	border-top: 1px solid transparent;
	border-image-source: var(--osk-dash-h);
	border-image-slice: 1;
	border-image-repeat: round;
	font-size: var(--osk-text-sm);
}
.osk-footer .osk-header__logo { grid-column: 2; justify-self: center; }
.osk-footer span.tagline { grid-column: 3; justify-self: end; }
.osk-footer .osk-header__logo { font-size: var(--osk-text-base); }
.osk-footer span.tagline { opacity: 0.5; }

@media (max-width: 900px) {
	.osk-footer { grid-template-columns: 1fr; row-gap: var(--osk-space-2); text-align: center; }
	.osk-footer .osk-header__logo { grid-column: 1; justify-self: center; }
	.osk-footer span.tagline { grid-column: 1; justify-self: center; }
}

/* ==========================================================================
   PLATFORM DETAIL PAGE — new sections specific to the "platform story"
   page (taxonomy-product_cat.php): story block, secondary photo,
   exploded diagram, assembly + specs. The hero, tickers, product grid,
   and repo card are all reused as-is from the sections above.
   ========================================================================== */

/* ---- story block: icon + copy + CTA, illustration alongside ---- */
.osk-story {
	display: grid;
	grid-template-columns: 1fr 1fr;
}
.osk-story__col--text {
	padding: var(--osk-space-8) var(--osk-space-4);
	border-right: 1px solid transparent;
	border-image-source: var(--osk-dash-v);
	border-image-slice: 1;
	border-image-repeat: round;
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: var(--osk-space-3);
}
.osk-story__icon {
	width: 10%;
	min-width: 70px;
	height: auto;
	color: var(--osk-text);
}
.osk-story__body {
	max-width: 46ch;
	font-size: var(--osk-text-sm);
	line-height: 1.6;
}
.osk-story__body p { margin: 0 0 1em; }
.osk-story__body p:last-child { margin-bottom: 0; }
.osk-story__col--image {
	display: flex;
	align-items: center;
	justify-content: center;
	padding: var(--osk-space-6);
}
.osk-story__col--image img { width: 100%; height: auto; }

@media (max-width: 900px) {
	.osk-story { grid-template-columns: 1fr; }
	.osk-story__col--text {
		border-right: none;
		border-bottom: 1px solid transparent;
		border-image-source: var(--osk-dash-h);
		border-image-slice: 1;
		border-image-repeat: round;
		padding: var(--osk-space-4);
	}
	.osk-story__col--image { order: -1; padding: var(--osk-space-4); }
}

/* ---- full-bleed secondary photo ---- */
.osk-secondary-photo {
	width: 100%;
	aspect-ratio: 21 / 8;
	overflow: hidden;
}
.osk-secondary-photo img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	display: block;
}
@media (max-width: 900px) {
	.osk-secondary-photo { aspect-ratio: 4 / 3; }
}

/* ---- exploded parts diagram: plain background, centered, no border ---- */
.osk-diagram-section {
	padding: var(--osk-space-8) var(--osk-space-4);
	display: flex;
	align-items: center;
	justify-content: center;
}
.osk-diagram-section img {
	max-width: 900px;
	width: 100%;
	height: auto;
}

/* ---- assembly + specs: the one boxed (bordered) section on this page ---- */
.osk-assembly {
	display: grid;
	grid-template-columns: 1fr 1fr;
	border-top: 1px solid transparent;
	border-bottom: 1px solid transparent;
	border-image-source: var(--osk-dash-h);
	border-image-slice: 1;
	border-image-repeat: round;
}
.osk-assembly__col {
	padding: var(--osk-space-6) var(--osk-space-4);
}
.osk-assembly__col--text {
	border-right: 1px solid transparent;
	border-image-source: var(--osk-dash-v);
	border-image-slice: 1;
	border-image-repeat: round;
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: var(--osk-space-3);
}
.osk-assembly__body {
	max-width: 46ch;
	font-size: var(--osk-text-sm);
	line-height: 1.6;
}
.osk-assembly__body p { margin: 0 0 1em; }
.osk-assembly__body p:last-child { margin-bottom: 0; }

.osk-specs-table__title {
	font-size: var(--osk-text-sm);
	opacity: 0.55;
	margin-bottom: var(--osk-space-2);
}
.osk-specs-table__row {
	display: flex;
	align-items: baseline;
	justify-content: space-between;
	gap: var(--osk-space-2);
	padding: 0.5em 0;
	border-bottom: 1px solid transparent;
	border-image-source: var(--osk-dash-h);
	border-image-slice: 1;
	border-image-repeat: round;
	font-size: var(--osk-text-sm);
}
.osk-specs-table__label {
	opacity: 0.55;
	text-transform: uppercase;
	font-size: var(--osk-text-xs);
	white-space: nowrap;
}
.osk-specs-table__value { text-align: right; }
.osk-specs-table__row--dynamic .osk-specs-table__value { text-decoration: underline dotted; text-underline-offset: 3px; }
.osk-specs-table--mobile { display: none; }

@media (max-width: 900px) {
	.osk-assembly { grid-template-columns: 1fr; }
	.osk-assembly__col--text {
		border-right: none;
		border-bottom: 1px solid transparent;
		border-image-source: var(--osk-dash-h);
		border-image-slice: 1;
		border-image-repeat: round;
	}
}

/* ---- gallery grid: full-bleed images, reuses osk-grid-section__label ---- */
.osk-gallery-grid {
	display: grid;
	grid-template-columns: repeat(3, 1fr);
}
.osk-gallery-grid__item { aspect-ratio: 1 / 1; overflow: hidden; }
.osk-gallery-grid__item img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	display: block;
}
@media (max-width: 900px) { .osk-gallery-grid { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 600px) { .osk-gallery-grid { grid-template-columns: 1fr; } }


/* ==========================================================================
   PRODUCT PAGE — one-screen "buy" layout: gallery | buy panel. Ported
   from mockups/preview-product.html. Fills the rest of the viewport
   below ticker+header on desktop (no page scroll); relaxes to a normal
   scrolling page on mobile, specs reached below the fold — same
   one-screen-on-desktop-only pattern as the rest of this theme's mobile
   breakpoints. See inc/template-tags.php for osk_render_product_page().
   ========================================================================== */
body.single-product main { display: flex; flex-direction: column; height: 100svh; }
.osk-pdp {
	flex: 1;
	min-height: 0;
	display: grid;
	grid-template-columns: 1.3fr 1fr;
}

/* ---- gallery: big image + thumbnail rail ---- */
.osk-pdp__gallery {
	display: flex;
	flex-direction: column;
	min-height: 0;
	border-right: 1px solid transparent;
	border-image-source: var(--osk-dash-v);
	border-image-slice: 1;
	border-image-repeat: round;
}
.osk-pdp__main-image { flex: 1; min-height: 0; overflow: hidden; }
.osk-pdp__main-image img { width: 100%; height: 100%; object-fit: cover; display: block; }
.osk-pdp__thumbs {
	display: flex;
	flex-shrink: 0;
	border-top: 1px solid transparent;
	border-image-source: var(--osk-dash-h);
	border-image-slice: 1;
	border-image-repeat: round;
}
.osk-pdp__thumb {
	width: 90px;
	height: 90px;
	overflow: hidden;
	border: none;
	border-right: 1px solid transparent;
	border-image-source: var(--osk-dash-v);
	border-image-slice: 1;
	border-image-repeat: round;
	cursor: pointer;
	opacity: 0.55;
	transition: opacity 0.15s ease;
	padding: 0;
	margin: 0;
	background: none;
	display: block;
}
.osk-pdp__thumb img { width: 100%; height: 100%; object-fit: cover; }
.osk-pdp__thumb:hover { opacity: 0.8; }
.osk-pdp__thumb.is-active { opacity: 1; box-shadow: inset 0 -3px 0 var(--osk-accent); }

/* ---- buy panel ---- */
.osk-pdp__info {
	display: flex;
	flex-direction: column;
	/* was justify-content: center — fine while content fit one screen, but
	   once .osk-pdp__info is actually height-capped (see body.single-product
	   main) any overflow gets centered too, pushing the top (title/price)
	   off-screen and unreachable by scrolling. flex-start lets it scroll
	   from the top down instead. */
	justify-content: flex-start;
	min-height: 0;
	padding: var(--osk-space-3) var(--osk-space-4);
	overflow-y: auto;
	gap: var(--osk-space-4);
}
.osk-pdp__group { display: flex; flex-direction: column; }
.osk-pdp__eyebrow { font-size: var(--osk-text-xs); opacity: 0.5; letter-spacing: 0.04em; margin-bottom: 0.3em; }
.osk-pdp__unit-logo { width: 4.8em; height: auto; color: var(--osk-text); margin-top: 0.8em; margin-bottom: 0.8em; }
.osk-pdp__title { font-size: var(--osk-text-lg); font-weight: 700; margin: 0 0 0.2em; }
.osk-pdp__price { font-size: var(--osk-text-md); font-weight: 700; margin-bottom: var(--osk-space-2); }
.osk-pdp__price .woocommerce-Price-amount { font-weight: 700; }
.osk-pdp__price small,
.osk-pdp__price .woocommerce-Price-suffix { font-size: var(--osk-text-sm); font-weight: 400; opacity: 0.5; margin-left: 0.4em; }

/* ---- Material x Size matrix ---- */
.osk-pdp__matrix-specs { display: grid; grid-template-columns: auto 1fr; gap: var(--osk-space-4); align-items: start; }
.osk-pdp__specs-col {
	border-left: 1px solid transparent;
	border-image-source: var(--osk-dash-v);
	border-image-slice: 1;
	border-image-repeat: round;
	padding-left: var(--osk-space-3);
}
.osk-pdp__matrix-label {
	font-size: var(--osk-text-xs);
	text-transform: uppercase;
	opacity: 0.55;
	letter-spacing: 0.04em;
	margin-bottom: 0.5em;
}
.osk-pdp__matrix { display: flex; align-items: stretch; margin-bottom: var(--osk-space-2); width: fit-content; }
.osk-pdp__matrix-grid { display: grid; }
.osk-pdp__matrix-cell {
	font-family: var(--osk-font);
	display: flex;
	align-items: center;
	justify-content: center;
	padding: 0.5em 1em;
	font-size: var(--osk-text-sm);
	text-align: center;
	background-repeat: no-repeat;
}
.osk-pdp__matrix-cell--corner { opacity: 0.3; }
.osk-pdp__matrix-cell--col-head,
.osk-pdp__matrix-cell--row-head {
	font-size: var(--osk-text-xs);
	text-transform: uppercase;
	opacity: 0.55;
	letter-spacing: 0.04em;
}
.osk-pdp__matrix-cell--row-head { justify-content: flex-start; padding-right: 0.75em; }
.osk-pdp__matrix-cell--value {
	border: none;
	background-color: transparent;
	color: var(--osk-text);
	cursor: pointer;
	font-weight: 700;
	transition: background-color 0.15s ease, color 0.15s ease;
}
.osk-pdp__matrix-cell--value:hover { background-color: var(--osk-bg-alt); }
.osk-pdp__matrix-cell--value.is-selected { background-color: var(--osk-accent); }
.osk-pdp__matrix-cell--value.is-disabled { opacity: 0.3; cursor: not-allowed; }

/* interior grid lines (dashed) instead of per-cell borders */
.osk-pdp__matrix-cell--div-r { background-image: var(--osk-dash-v-dark); background-position: right top; background-size: 1px 100%; }
.osk-pdp__matrix-cell--div-b { background-image: var(--osk-dash-h-dark); background-position: left bottom; background-size: 100% 1px; }
.osk-pdp__matrix-cell--div-r.osk-pdp__matrix-cell--div-b {
	background-image: var(--osk-dash-v-dark), var(--osk-dash-h-dark);
	background-position: right top, left bottom;
	background-size: 1px 100%, 100% 1px;
}

/* ---- real WooCommerce variation form: the matrix above proxies clicks
   into these selects (see the inline script osk_render_product_page()
   echoes), so once a matrix is showing, hide the native <table> of
   dropdowns and its own price/availability output — only its
   add-to-cart button stays, restyled to match the mockup. Falls back to
   showing the plain native form (unstyled) when there's no matrix
   (--matrix modifier absent), e.g. a future product that isn't a
   Material x Size variable product. ---- */
/* WooCommerce's own variation-form.js shows/hides these via inline
   style (jQuery .show()/.hide()), which beats a plain stylesheet rule
   regardless of selector specificity — !important is required here, not
   just to out-rank Storefront/WooCommerce's CSS but to out-rank JS.
   The quantity field stays (styled below) — it's the one native piece
   the mockup didn't have and now needs (live qty × price). */
.osk-pdp__native-variations--matrix table.variations,
.osk-pdp__native-variations--matrix .woocommerce-variation:not(.woocommerce-variation-add-to-cart),
.osk-pdp__native-variations--matrix .reset_variations { display: none !important; }

.osk-pdp__native-variations .woocommerce-variation-add-to-cart {
	display: flex !important;
	align-items: center;
	gap: var(--osk-space-2);
	flex-wrap: wrap;
}
.osk-pdp__native-variations .quantity {
	display: block !important;
	margin: var(--osk-space-1) 0 var(--osk-space-2);
}
.osk-pdp__native-variations .quantity .qty {
	width: 3.6em;
	padding: 0.5em 0.4em;
	font-family: var(--osk-font);
	font-size: var(--osk-text-sm);
	color: var(--osk-text);
	background-color: transparent;
	border: none;
	text-align: center;
	/* A single border-image source only varies along one axis, so it
	   dashes correctly on two sides and renders solid on the other two
	   (why the rest of the theme only ever uses --osk-dash-h OR
	   --osk-dash-v, never both, for a single border-image). For a real
	   4-sided dashed box, layer both patterns as 1px background strips
	   at each edge instead — same technique as the matrix grid lines. */
	background-image: var(--osk-dash-h), var(--osk-dash-h), var(--osk-dash-v), var(--osk-dash-v);
	background-position: left top, left bottom, left top, right top;
	background-size: 100% 1px, 100% 1px, 1px 100%, 1px 100%;
	background-repeat: no-repeat;
}

/* Express checkout (Apple Pay / Google Pay) — removed from the product
   page for now; will come back on the checkout page once payment
   methods are set up there. Scoped to the product page only.

   Two SEPARATE Stripe integrations are active on this site, each with
   its own express-checkout markup:
   - WooCommerce Payments (WooPayments): .wcpay-express-checkout-wrapper
     — renders immediately, was already covered here.
   - WooCommerce Stripe Gateway (a different plugin):
     #wc-stripe-express-checkout-element — initializes via its own JS
     bundle ~1s after page load, which is why Apple/Google Pay appeared
     to "load in late" even with the rule above in place. Both must be
     hidden or the second one shows through. */
body.single-product .wcpay-express-checkout-wrapper,
body.single-product #wc-stripe-express-checkout-element { display: none !important; }
/* Storefront/WooCommerce's own button.alt rule (e.g.
   ".woocommerce button.button.alt") outweighs a plain two-class selector
   on specificity alone, so the button rendered with the theme's default
   look no matter what we set here. Match its shape (repeat .button.alt)
   and add !important on the properties that matter, so this wins
   regardless of theme CSS load order. Sized/cased to match the mockup's
   .osk-pdp__add-to-cart (fit-content, lowercase) — not a full-width
   uppercase CTA. */
.osk-pdp__native-variations .single_add_to_cart_button,
.osk-pdp__native-variations button.single_add_to_cart_button.button.alt,
.osk-pdp__native-variations a.single_add_to_cart_button.button.alt {
	display: inline-flex !important;
	align-items: center;
	justify-content: center;
	width: fit-content !important;
	padding: 0.5em var(--osk-space-3) !important;
	margin: var(--osk-space-1) 0 var(--osk-space-2) !important;
	background: var(--osk-text) !important;
	color: var(--osk-bg) !important;
	border: none !important;
	border-radius: 0 !important;
	font-family: var(--osk-font) !important;
	font-size: var(--osk-text-sm) !important;
	font-weight: 400 !important;
	text-transform: none !important;
	letter-spacing: 0.02em !important;
	cursor: pointer;
	transition: opacity 0.15s ease;
}
.osk-pdp__native-variations .single_add_to_cart_button:hover { opacity: 0.8; }
.osk-pdp__native-variations .single_add_to_cart_button.disabled { opacity: 0.4 !important; cursor: not-allowed; }

/* ---- specs accordion: More info / Specifications / FAQ / Care & Maintenance ----
   Native <details>/<summary> — no JS needed, and it's free accessibility
   (keyboard toggle, screen readers announce expanded state). Sits inside
   .osk-pdp__info, so it scrolls with the buy panel on desktop rather than
   breaking the one-screen layout. */
.osk-pdp__accordion { display: flex; flex-direction: column; }
.osk-pdp__accordion-section {
	border-top: 1px solid transparent;
	border-image-source: var(--osk-dash-h);
	border-image-slice: 1;
	border-image-repeat: round;
}
.osk-pdp__accordion-section:last-child {
	border-bottom: 1px solid transparent;
	border-image-source: var(--osk-dash-h);
	border-image-slice: 1;
	border-image-repeat: round;
}
.osk-pdp__accordion-summary {
	display: flex;
	align-items: center;
	justify-content: space-between;
	padding: 0.9em 0.1em;
	font-size: var(--osk-text-sm);
	font-weight: 700;
	cursor: pointer;
	list-style: none;
	user-select: none;
}
.osk-pdp__accordion-summary::-webkit-details-marker { display: none; }
.osk-pdp__accordion-summary::after {
	content: '+';
	font-weight: 400;
	font-size: var(--osk-text-md);
	line-height: 1;
	opacity: 0.6;
	transition: transform 0.15s ease;
}
.osk-pdp__accordion-section[open] > .osk-pdp__accordion-summary::after { content: '\2212'; }
.osk-pdp__accordion-summary:hover { opacity: 0.75; }
.osk-pdp__accordion-body {
	padding: 0 0.1em var(--osk-space-3);
	font-size: var(--osk-text-xs);
	line-height: 1.5;
	opacity: 0.85;
}
.osk-pdp__accordion-body p { margin: 0 0 0.75em; }
.osk-pdp__accordion-body p:last-child { margin-bottom: 0; }
.osk-pdp__accordion-specs { width: 100%; border-collapse: collapse; }
.osk-pdp__accordion-specs th,
.osk-pdp__accordion-specs td {
	text-align: left;
	font-weight: 400;
	padding: 0.35em 0;
	vertical-align: top;
}
.osk-pdp__accordion-specs th { opacity: 0.55; padding-right: var(--osk-space-2); white-space: nowrap; }
.osk-pdp__accordion-faq-item { margin-bottom: var(--osk-space-2); }
.osk-pdp__accordion-faq-item:last-child { margin-bottom: 0; }
.osk-pdp__accordion-faq-q { font-weight: 700; opacity: 1; margin: 0 0 0.25em; }
.osk-pdp__accordion-faq-a { margin: 0; }

@media (max-width: 900px) {
	body.single-product main { height: auto; }
	.osk-pdp { display: flex; flex-direction: column; min-height: 0; }
	.osk-pdp__gallery { border-right: none; flex-shrink: 0; }
	.osk-pdp__main-image { flex: none; height: 28svh; }
	.osk-pdp__thumb { width: 60px; height: 60px; }
	.osk-pdp__info { flex: none; overflow-y: visible; padding: var(--osk-space-2) var(--osk-space-3); gap: var(--osk-space-2); }
	.osk-pdp__title { font-size: var(--osk-text-md); }
	.osk-pdp__matrix-specs { grid-template-columns: 1fr; }
	.osk-pdp__specs-col { display: none; } /* the --mobile table below the fold covers this instead */
	.osk-specs-table--mobile { display: block; padding: var(--osk-space-3); }
}

/* ==========================================================================
   REPOSITORY PAGE — ported from mockups/preview-repository.html.
   ========================================================================== */
.osk-repo-heading {
	padding: var(--osk-space-6) var(--osk-space-4) var(--osk-space-4);
}
.osk-repo-heading__title {
	display: inline-block;
	background: var(--osk-accent);
	font-size: calc(var(--osk-text-sm) * 4 * 0.7);
	font-weight: 400;
	padding: 0 1ch 0 0;
	width: fit-content;
	line-height: 1;
	margin-bottom: var(--osk-space-2);
}
.osk-repo-heading__tagline { font-size: var(--osk-text-sm); font-style: italic; opacity: 0.75; max-width: 42ch; }

/* pill row — reuses the plain-solid-border look (like .osk-btn) rather
   than the dashed border-image technique, which only dashes correctly
   on 2 of a fully-boxed element's 4 sides (see the Product page notes
   on this same limitation). */
.osk-repo-filter {
	display: flex;
	flex-wrap: wrap;
	gap: var(--osk-space-2);
	padding: var(--osk-space-3) var(--osk-space-4);
	border-bottom: 1px solid transparent;
	border-image-source: var(--osk-dash-h);
	border-image-slice: 1;
	border-image-repeat: round;
	position: sticky;
	top: 65px; /* sits right below the sticky .osk-header */
	z-index: 90;
	background: var(--osk-bg);
}
.osk-repo-filter__pill {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	padding: var(--osk-space-1) var(--osk-space-3);
	font-family: var(--osk-font);
	font-size: var(--osk-text-sm);
	letter-spacing: 0.02em;
	border: 1px solid var(--osk-text);
	background: transparent;
	color: var(--osk-text);
	cursor: pointer;
	transition: background-color 0.15s ease, color 0.15s ease;
	white-space: nowrap;
}
.osk-repo-filter__pill:hover { background: var(--osk-bg-alt); }
.osk-repo-filter__pill.is-active { background: var(--osk-accent); border-color: var(--osk-accent); font-weight: 700; }

.osk-repo-group + .osk-repo-group {
	border-top: 1px solid transparent;
	border-image-source: var(--osk-dash-h);
	border-image-slice: 1;
	border-image-repeat: round;
}
.osk-repo-group[hidden] { display: none; }
.osk-repo-group__label {
	font-size: var(--osk-text-sm);
	margin: var(--osk-space-3) var(--osk-space-4) var(--osk-space-2);
}
.osk-repo-group__label .num { opacity: 0.5; margin-right: 0.5em; }
.osk-repo-group__label .name { font-weight: 700; }

/* ==========================================================================
   COMPANY PAGE — ported from mockups/preview-company.html.
   ========================================================================== */
.osk-values {
	display: grid;
	grid-template-columns: repeat(4, 1fr);
	border-top: 1px solid transparent;
	border-image-source: var(--osk-dash-h);
	border-image-slice: 1;
	border-image-repeat: round;
}
.osk-value {
	padding: var(--osk-space-4);
	border-right: 1px solid transparent;
	border-image-source: var(--osk-dash-v);
	border-image-slice: 1;
	border-image-repeat: round;
}
.osk-value:last-child { border-right: none; }
.osk-value__num { font-size: var(--osk-text-sm); opacity: 0.5; display: block; margin-bottom: var(--osk-space-1); }
.osk-value__name { font-weight: 700; font-size: var(--osk-text-sm); display: block; margin-bottom: 0.5em; }
.osk-value__desc { font-size: var(--osk-text-xs); font-style: italic; opacity: 0.8; line-height: 1.5; }

@media (max-width: 1100px) {
	.osk-values { grid-template-columns: repeat(2, 1fr); }
	.osk-value:nth-child(2) { border-right: none; }
}
@media (max-width: 600px) {
	.osk-values { grid-template-columns: 1fr; }
	.osk-value { border-right: none; border-bottom: 1px solid transparent; border-image-source: var(--osk-dash-h); border-image-slice: 1; border-image-repeat: round; }
	.osk-value:last-child { border-bottom: none; }
}

.osk-contact {
	padding: var(--osk-space-8) var(--osk-space-4);
	text-align: center;
	border-top: 1px solid transparent;
	border-image-source: var(--osk-dash-h);
	border-image-slice: 1;
	border-image-repeat: round;
}
.osk-contact__title {
	display: inline-block;
	background: var(--osk-accent);
	font-size: calc(var(--osk-text-sm) * 3 * 0.7);
	font-weight: 400;
	padding: 0 1ch 0 0;
	line-height: 1;
	margin-bottom: var(--osk-space-2);
}
.osk-contact__desc { font-size: var(--osk-text-sm); font-style: italic; opacity: 0.75; max-width: 42ch; margin: 0 auto var(--osk-space-3); }
.osk-contact__email { font-size: var(--osk-text-md); font-weight: 700; }
.osk-contact__email:hover { color: var(--osk-accent); background: var(--osk-text); }

/* ==========================================================================
   CART PAGE — skins WooCommerce's native [woocommerce_cart] shortcode
   output (same approach as the Product page's native variation form:
   keep WooCommerce's own markup/AJAX for remove/coupon/update-cart/
   totals, only restyle it).

   Verified live against the real /cart/ page (added a product,
   inspected actual DOM/computed styles, tested ~2000px desktop, 768px
   tablet, and 375px mobile) after the first two ship-and-guess passes
   both missed layout bugs that only showed up against Storefront's
   actual cart markup:
   - .woocommerce (WooCommerce's shortcode wrapper) is itself a flex
     item of .osk-cart-wrap with no width rule, so it shrank to fit its
     children instead of filling the page.
   - .cart_totals carries Storefront's own float:right; width:48%,
     fighting our already-full-width sidebar column.
   - table-layout fights between Storefront's cart CSS and ours are
     resolved by forcing table/tr/td to block/flex display rather than
     tuning column widths (unpredictable once another stylesheet has
     opinions about the same table).
   - Storefront's responsive data-title labels (::before content) are
     suppressed since this design relies on visual grouping instead.
   ========================================================================== */
.osk-cart-wrap {
	display: grid;
	grid-template-columns: 320px minmax(0, 1fr);
	column-gap: var(--osk-space-4);
	align-items: stretch;
	width: 100%;
	border-top: 1px solid transparent;
	border-image-source: var(--osk-dash-h);
	border-image-slice: 1;
	border-image-repeat: round;
}
/* ---- left brand column, same width as the order-summary column on the
   far right (both 320px) — purely decorative, so it's dropped on mobile
   below rather than fighting the single-column stack for space. */
.osk-cart-brand {
	display: flex;
	align-items: center;
	justify-content: center;
	border-right: 1px solid transparent;
	border-image-source: var(--osk-dash-v);
	border-image-slice: 1;
	border-image-repeat: round;
}
.osk-cart-brand__mark { width: 40%; height: auto; color: var(--osk-text); opacity: 0.15; }
/* .woocommerce is CSS grid rather than flex specifically so the
   "Cart updated." notice (WooCommerce always renders it as the FIRST
   child, ahead of the cart form/sidebar) can be placed directly under
   the product list — row 2, column 1 — without a flex row/wrap
   pushing it below the taller sidebar column instead (verified live:
   that's what flex + order was doing). */
.osk-cart-wrap > .woocommerce {
	display: grid;
	grid-template-columns: minmax(0, 1fr) 320px;
	column-gap: var(--osk-space-4);
	align-items: start;
	width: 100%;
}
.osk-cart-wrap .woocommerce-cart-form {
	grid-column: 1;
	grid-row: 1;
	min-width: 0;
	/* Mockup's .osk-cart__items has a dashed vertical divider against the
	   order-summary column — verified live before porting. */
	border-right: 1px solid transparent;
	border-image-source: var(--osk-dash-v);
	border-image-slice: 1;
	border-image-repeat: round;
	padding-right: var(--osk-space-4);
}
/* Spans both rows so its height doesn't depend on whether the notice
   (row 2) is present. */
.osk-cart-wrap .cart-collaterals { grid-column: 2; grid-row: 1 / span 2; padding: var(--osk-space-4); }
.osk-cart-wrap .woocommerce-notices-wrapper {
	grid-column: 1;
	grid-row: 2;
	/* Content-sized, not a full-width banner. */
	justify-self: start;
	max-width: 100%;
}
/* WooCommerce hides its own order-attribution tracking inputs behind
   this custom element; give it no box so it can't disturb the grid. */
.osk-cart-wrap wc-order-attribution-inputs { display: none; }

/* ---- line-items table ----
   Storefront/WooCommerce's own cart CSS drives column widths off
   table-layout, and fighting that with more table CSS (width: auto,
   explicit column widths) still left a wide dead gap — table
   auto-layout's column-width algorithm doesn't behave predictably once
   another stylesheet has already opinionated the table. Sidestepping
   it: turn the table/row/cells into a flex row instead, so each
   column's width is exactly what's declared below, no browser layout
   algorithm involved. */
.osk-cart-wrap table.shop_table { width: 100%; border-collapse: collapse; font-size: var(--osk-text-sm); }
.osk-cart-wrap table.shop_table thead { display: none; } /* mockup has no header row */
/* Storefront's own responsive-table CSS adds a data-title label (e.g.
   "Price:", "Quantity:") via ::before on every td, meant for its own
   stacked mobile layout — verified live, and it clashes with ours
   (which relies on visual grouping instead), so suppress it everywhere. */
.osk-cart-wrap table.shop_table td::before { content: none; display: none; }
.osk-cart-wrap table.shop_table,
.osk-cart-wrap table.shop_table tbody { display: block; width: 100%; }
/* Every row defaults to block (covers the actions/coupon row below,
   which carries no row class to target specifically); the two known
   line-item row classes are overridden to a flex row right after. */
.osk-cart-wrap table.shop_table tr { display: block; width: 100%; }
/* Grid, not flex: .product-remove needs to sit visually under
   .product-name (matching the mockup's stacked platform/name/variant/
   remove body column) without moving it out of its own <td> in the
   DOM — WooCommerce's native AJAX remove handler is bound to
   `.product-remove > a`, so relocating the link itself (the coupon-box
   approach used elsewhere on this page) would break it. Grid areas let
   two same-named cells span rows/columns purely visually; "qty",
   "price" and "subtotal" each repeat across both rows so they stay
   vertically centered against the two-row name/remove column. */
.osk-cart-wrap table.shop_table tr.woocommerce-cart-form__cart-item,
.osk-cart-wrap table.shop_table tr.cart_item {
	display: grid;
	grid-template-columns: 96px 1fr auto auto auto;
	grid-template-areas:
		"thumb iname qty price subtotal"
		"thumb remove qty price subtotal";
	align-items: center;
	column-gap: var(--osk-space-2);
	row-gap: 0.3em;
	width: 100%;
	border-bottom: 1px solid transparent;
	border-image-source: var(--osk-dash-h);
	border-image-slice: 1;
	border-image-repeat: round;
}
.osk-cart-wrap table.shop_table td {
	display: block;
	padding: var(--osk-space-2) var(--osk-space-1);
	vertical-align: middle;
	/* WP core global styles (table:not(.has-background) tbody td, and a
	   :nth-child(2n) zebra-stripe variant) paint every td white/near-white
	   at higher specificity than a plain override reaches — verified live,
	   confirmed !important is required to beat the striped variant. */
	background: transparent !important;
}
.osk-cart-wrap td.product-remove { grid-area: remove; align-self: start; padding-top: 0; text-align: left; }
.osk-cart-wrap td.product-thumbnail { grid-area: thumb; }
.osk-cart-wrap td.product-thumbnail img {
	/* Verified live (getMatchedCSSRules-style scan of every rule that
	   touches this element): the actual culprit is Storefront's own
	   `table.cart .product-thumbnail img { max-width: 3.70633em; }` —
	   max-width caps the rendered width independently of width, even
	   at !important, so width:96px!important alone was never enough;
	   the computed box came out ~52x96 (its em-based max-width, not
	   96px). max-width needed its own !important override too. */
	max-width: 96px !important;
	width: 96px !important;
	height: 96px !important;
	object-fit: cover !important;
	object-position: center;
}
.osk-cart-wrap td.product-name { grid-area: iname; align-self: end; min-width: 0; }
.osk-cart-wrap td.product-name a { font-weight: 700; white-space: normal; word-break: normal; overflow-wrap: normal; }
.osk-cart-wrap td.product-price,
.osk-cart-wrap td.product-quantity,
.osk-cart-wrap td.product-subtotal { white-space: nowrap; }
/* Visual order (also drives the mobile stack below, where the row
   falls back to flex-direction: column — grid-area placement above is
   ignored there and `order` takes over). */
.osk-cart-wrap td.product-remove { order: 1; }
.osk-cart-wrap td.product-quantity { grid-area: qty; order: 2; }
.osk-cart-wrap td.product-price { grid-area: price; order: 3; }
.osk-cart-wrap td.product-subtotal { grid-area: subtotal; order: 4; }
/* ---- platform label (osk_cart_item_platform_label(), functions.php) ---- */
.osk-cart-item__platform {
	display: block;
	font-size: var(--osk-text-xs);
	font-style: italic;
	opacity: 0.55;
}
/* ---- variation data (Material/Size, native WooCommerce dl.variation)
   — labels hidden, values joined with " · " to match the mockup's
   .osk-cart-item__variant ("steel · 12u") instead of native
   "Material: Steel" / "Size: 12u" stacked rows. ---- */
.osk-cart-wrap td.product-name dl.variation {
	display: block;
	font-size: var(--osk-text-xs);
	opacity: 0.7;
	margin: 0.2em 0 0;
}
.osk-cart-wrap td.product-name dl.variation dt { display: none; }
.osk-cart-wrap td.product-name dl.variation dd { display: inline; margin: 0; }
.osk-cart-wrap td.product-name dl.variation dd p { display: inline; margin: 0; }
.osk-cart-wrap td.product-name dl.variation dd:not(:last-of-type)::after { content: " · "; }
/* ---- remove link: native text is the "×" glyph; hide it and show the
   mockup's "remove" label via ::before instead, so the click target
   and WooCommerce's own handler are untouched. ---- */
.osk-cart-wrap td.product-remove a.remove {
	/* WooCommerce's own inline "woocommerce-inline" stylesheet sizes
	   this link at width/height: 1.4em for its default "×" circle —
	   at our font-size: 0 that resolved to a 0×0 box, so the "remove"
	   text from ::before below had nowhere to go and wrapped
	   mid-word. Reset all of that explicitly instead of just the
	   font-size. */
	display: inline-block;
	width: auto !important;
	height: auto !important;
	font-size: 0;
	line-height: 0;
	white-space: nowrap;
	overflow: visible;
	border: none !important;
	border-radius: 0 !important;
	text-decoration: none;
	color: var(--osk-text) !important;
	background: none !important;
}
.osk-cart-wrap td.product-remove a.remove::before {
	content: "remove";
	display: inline-block;
	/* WooCommerce/Storefront's default "×" glyph on this link is drawn
	   from an icon font (not the literal character) on some builds —
	   this pseudo-element inherits font-family from the same <a>, so
	   without !important it was inheriting that icon font instead of
	   Ubuntu Mono. */
	font-family: var(--osk-font) !important;
	font-size: var(--osk-text-xs);
	line-height: normal;
	white-space: nowrap;
	text-decoration: underline;
	opacity: 0.6;
}
.osk-cart-wrap td.product-remove a.remove:hover::before { opacity: 1; }
.osk-cart-wrap td.product-price { font-weight: 400; white-space: nowrap; }
.osk-cart-wrap td.product-subtotal { font-weight: 700; white-space: nowrap; }

/* ---- quantity stepper — 4-side dashed box around native .quantity,
   -/+ buttons injected by cart.js, matches the mockup's .osk-qty /
   .osk-qty__btn / .osk-qty__input exactly (same technique as the
   Product page's qty field: a single border-image source only dashes
   2 of 4 sides correctly, so the pattern is layered as background
   strips on each edge instead). ---- */
.osk-cart-wrap .quantity {
	display: inline-flex;
	align-items: stretch;
	width: fit-content;
}
.osk-cart-wrap .quantity .osk-qty__btn {
	width: 1.8em;
	background: transparent;
	border: none;
	color: var(--osk-text);
	cursor: pointer;
	font-family: var(--osk-font);
	font-size: var(--osk-text-sm);
	background-image: var(--osk-dash-h), var(--osk-dash-h), var(--osk-dash-v);
	background-position: left top, left bottom, left top;
	background-size: 100% 1px, 100% 1px, 1px 100%;
	background-repeat: no-repeat;
}
.osk-cart-wrap .quantity .osk-qty__btn--plus {
	background-image: var(--osk-dash-h), var(--osk-dash-h), var(--osk-dash-v), var(--osk-dash-v);
	background-position: left top, left bottom, left top, right top;
	background-size: 100% 1px, 100% 1px, 1px 100%, 1px 100%;
}
.osk-cart-wrap .quantity .osk-qty__btn:hover { background-color: var(--osk-bg-alt); }
.osk-cart-wrap .quantity .qty {
	width: 2.6em;
	padding: 0.5em 0.2em;
	font-family: var(--osk-font);
	font-size: var(--osk-text-sm);
	color: var(--osk-text);
	background-color: transparent;
	border: none;
	text-align: center;
	background-image: var(--osk-dash-h), var(--osk-dash-h);
	background-position: left top, left bottom;
	background-size: 100% 1px, 100% 1px;
	background-repeat: no-repeat;
}

/* ---- coupon + update-cart row ---- */
.osk-cart-wrap .coupon { display: flex; flex-wrap: wrap; gap: 0.5em; align-items: center; margin-top: var(--osk-space-2); }
.osk-cart-wrap .coupon #coupon_code {
	padding: 0.5em 0.6em;
	font-family: var(--osk-font);
	font-size: var(--osk-text-xs);
	color: var(--osk-text);
	background: transparent;
	border: 1px solid var(--osk-text);
}
.osk-cart-wrap .coupon button,
.osk-cart-wrap button[name="update_cart"] {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	padding: var(--osk-space-1) var(--osk-space-3);
	font-family: var(--osk-font);
	font-size: var(--osk-text-sm);
	border: 1px solid var(--osk-text);
	background: transparent;
	color: var(--osk-text);
	cursor: pointer;
	transition: background-color 0.15s ease, color 0.15s ease;
}
.osk-cart-wrap .coupon button:hover,
.osk-cart-wrap button[name="update_cart"]:hover { background: var(--osk-text); color: var(--osk-bg); }
/* "Apply coupon" (native text, two words) was wrapping onto two lines
   in the sidebar's narrow column — shrinking along with #coupon_code's
   flex-grow — which made the button roughly twice #coupon_code's
   height. Same padding/font-size as the input plus no-wrap/no-shrink
   keeps both a single line at matching height. */
.osk-cart-wrap .coupon button {
	padding: 0.5em 0.6em;
	font-size: var(--osk-text-xs);
	white-space: nowrap;
	flex-shrink: 0;
}
/* The actions row (coupon + update-cart button) carries no row class
   of its own, only its <td class="actions"> does — display:flex on
   just the td (its <tr> stays the generic block rule above) lets
   coupon+button sit on one line. */
.osk-cart-wrap td.actions {
	display: flex;
	flex-wrap: wrap;
	gap: var(--osk-space-2);
	align-items: center;
	justify-content: space-between;
	width: 100%;
	padding-top: var(--osk-space-3);
	background: none;
	/* This row (coupon + update-cart) had no dashed line marking it off
	   from the line items above — just blank gap. Verified live before
	   porting; !important needed for the same reason as the td backgrounds
	   above (WP core global styles keep opinions about table cell borders
	   at higher specificity than this alone reaches). */
	border: none;
	border-top: 1px solid transparent !important;
	border-image-source: var(--osk-dash-h);
	border-image-slice: 1;
	border-image-repeat: round;
}
/* cart.js relocates the coupon into the sidebar and hides this row via
   inline style, but only once its MutationObserver callback runs —
   one or more paints after WooCommerce swaps in fresh server markup
   (native <td class="actions"> position), so the coupon/"Update cart"
   briefly flashed here first on every quantity change. Hiding it by
   CSS instead removes the wait entirely; scoped to .osk-js (set by
   cart.js on load, on the element WooCommerce never replaces) so a
   no-JS visitor still gets the native row as a working fallback,
   exactly as cart.js's own file header promises. */
.osk-cart-wrap .osk-js td.actions { display: none; }

/* ---- order summary sidebar ----
   Storefront gives .cart_totals its own float:right; width:48% (its
   own side-by-side-with-cart layout assumption) — verified live, and
   it fights our already-full-width .cart-collaterals column, leaving
   an empty gap where the float excluded space. Neutralize it. */
.osk-cart-wrap .cart_totals { float: none; width: 100%; }
.osk-cart-wrap .cart_totals > h2 { display: none; } /* mockup uses its own "> ORDER SUMMARY" label */
.osk-cart-wrap .cart_totals::before {
	content: "> ORDER SUMMARY";
	display: block;
	font-size: var(--osk-text-sm);
	font-weight: 700;
	margin-bottom: var(--osk-space-2);
}
/* Same block/flex-row treatment as the line-items table, for the same
   reason (Storefront's table-layout fights ours unpredictably). */
.osk-cart-wrap .cart_totals table,
.osk-cart-wrap .cart_totals table tbody { display: block; width: 100%; border-collapse: collapse; font-size: var(--osk-text-sm); }
.osk-cart-wrap .cart_totals table tr { display: flex; justify-content: space-between; align-items: baseline; width: 100%; }
.osk-cart-wrap .cart_totals table th,
.osk-cart-wrap .cart_totals table td {
	display: block;
	width: auto;
	padding: 0.5em 0;
	text-align: left;
	font-weight: 400;
	/* Same WP core global-styles override as the line-items table above. */
	background: transparent !important;
}
.osk-cart-wrap .cart_totals table td { text-align: right; }
.osk-cart-wrap .cart_totals tr.order-total,
.osk-cart-wrap .cart_totals tr.order-total th,
.osk-cart-wrap .cart_totals tr.order-total td { font-weight: 700; }
.osk-cart-wrap .cart_totals tr.order-total {
	border-top: 1px solid transparent;
	border-image-source: var(--osk-dash-h);
	border-image-slice: 1;
	border-image-repeat: round;
}
/* ---- shipping method radios ----
   Belt-and-suspenders: WooCommerce's own CSS already strips the
   bullet on ul#shipping_method, but that ul/li is inside .cart_totals,
   which WooCommerce's own AJAX replaces wholesale on every cart/
   shipping update (see cart.js) — reset explicitly here too so a
   bullet can never show no matter what generated the markup. */
.osk-cart-wrap .cart_totals ul.woocommerce-shipping-methods,
.osk-cart-wrap .cart_totals ul.woocommerce-shipping-methods li {
	list-style: none !important;
	margin-left: 0 !important;
	padding-left: 0 !important;
}
/* ---- coupon box, once relocated into the sidebar by cart.js ----
   Sits between the totals table and the checkout button (cart.js
   inserts it there) — a top dashed rule separates it from Total above,
   matching the design language used everywhere else on this page. */
.osk-cart-wrap .cart_totals .coupon {
	border-top: 1px solid transparent;
	border-image-source: var(--osk-dash-h);
	border-image-slice: 1;
	border-image-repeat: round;
	padding-top: var(--osk-space-2);
	margin-top: var(--osk-space-2);
}
.osk-cart-wrap .cart_totals .coupon { flex-wrap: nowrap; }
.osk-cart-wrap .cart_totals .coupon #coupon_code { flex: 1 1 auto; min-width: 0; }

/* ---- free-shipping note (osk_cart_free_shipping_note(), functions.php) ----
   Lifted (with the "Shipping to <city>" line and the "change shipping"
   calculator below) out of the shipping row's value <td> up to the <tr>
   itself by cart.js's relocate(), so each gets its own full-width line
   here instead of being squeezed into that th+td row's narrow value
   column. */
.osk-cart-wrap .cart_totals tr.shipping { flex-wrap: wrap; }
.osk-cart-wrap .cart_totals tr.shipping > .osk-cart-summary__note,
.osk-cart-wrap .cart_totals tr.shipping > .woocommerce-shipping-destination {
	flex: 1 1 100%;
	text-align: left;
}
/* The calculator <form> is wrapped in a plain <td> by cart.js before
   being appended to the row — see relocate()'s comment — so it needs
   the same full-width/left-align treatment applied to that wrapper
   instead of to the form directly. */
.osk-cart-wrap .cart_totals tr.shipping > td.osk-cart-shipping-calculator-cell {
	flex: 1 1 100%;
	display: block;
	width: 100%;
	padding: 0;
	text-align: left;
}
.osk-cart-wrap .cart_totals p.osk-cart-summary__note {
	font-size: var(--osk-text-xs);
	font-style: italic;
	opacity: 0.6;
	margin: var(--osk-space-2) 0 0;
}

/* ---- "change shipping" calculator toggle + its dropdown form ----
   Native WooCommerce markup: a.shipping-calculator-button toggles
   section.shipping-calculator-form (country/state/city/postcode +
   an "Update" submit), both inside form.woocommerce-shipping-calculator
   — unstyled by Storefront beyond basic form-row spacing. */
.osk-cart-wrap .shipping-calculator-button {
	display: block;
	margin-top: var(--osk-space-1);
	font-size: var(--osk-text-xs);
	text-decoration: underline;
	color: var(--osk-text);
	opacity: 0.6;
}
.osk-cart-wrap .shipping-calculator-button:hover { opacity: 1; }
.osk-cart-wrap .shipping-calculator-form {
	margin-top: var(--osk-space-2);
	padding-top: var(--osk-space-2);
	border-top: 1px solid transparent;
	border-image-source: var(--osk-dash-h);
	border-image-slice: 1;
	border-image-repeat: round;
}
.osk-cart-wrap .shipping-calculator-form .form-row { width: 100%; margin: 0 0 var(--osk-space-2); }
.osk-cart-wrap .shipping-calculator-form label {
	display: block;
	font-size: var(--osk-text-xs);
	opacity: 0.6;
	margin-bottom: 0.25em;
}
.osk-cart-wrap .shipping-calculator-form .required { color: var(--osk-text); opacity: 0.6; }
.osk-cart-wrap .shipping-calculator-form select,
.osk-cart-wrap .shipping-calculator-form input.input-text {
	display: block;
	width: 100%;
	padding: 0.5em 0.6em;
	font-family: var(--osk-font);
	font-size: var(--osk-text-xs);
	color: var(--osk-text);
	background: transparent;
	border: 1px solid var(--osk-text);
	border-radius: 0;
}
.osk-cart-wrap .shipping-calculator-form button[name="calc_shipping"] {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	padding: var(--osk-space-1) var(--osk-space-3);
	font-family: var(--osk-font);
	font-size: var(--osk-text-sm);
	border: 1px solid var(--osk-text);
	background: transparent;
	color: var(--osk-text);
	cursor: pointer;
	transition: background-color 0.15s ease, color 0.15s ease;
}
.osk-cart-wrap .shipping-calculator-form button[name="calc_shipping"]:hover {
	background: var(--osk-text);
	color: var(--osk-bg);
}

.osk-cart-wrap .wc-proceed-to-checkout { padding: var(--osk-space-2) 0 0; }
.osk-cart-wrap .wc-proceed-to-checkout a.checkout-button {
	display: flex;
	width: 100%;
	align-items: center;
	justify-content: center;
	padding: 0.6em var(--osk-space-3);
	background: var(--osk-text) !important;
	color: var(--osk-bg) !important;
	border: none !important;
	border-radius: 0 !important;
	font-family: var(--osk-font) !important;
	font-size: var(--osk-text-sm);
	text-align: center;
}
.osk-cart-wrap .wc-proceed-to-checkout a.checkout-button:hover { background: var(--osk-accent) !important; color: var(--osk-text) !important; }

/* ---- loading overlay (jQuery blockUI, applied by WooCommerce's own
   cart.js while an update is in flight) ----
   Verified live: WooCommerce sets background/opacity on .blockOverlay
   as an inline style (rgb(255,255,255) @ 0.6 opacity) via jQuery's
   .css(), not from a stylesheet — so this needs !important to win.
   The block itself still functionally happens (briefly blocks
   pointer-events on the form/totals, preventing a double-submit);
   only the white flash is removed. */
.osk-cart-wrap .blockUI.blockOverlay {
	background: transparent !important;
	opacity: 0 !important;
}
.osk-cart-wrap .blockUI.blockMsg { display: none !important; }

/* ---- WooCommerce notices ----
   Success notices ("Cart updated.", "N item removed. Undo?", "X has
   been added to your cart", "Coupon code applied successfully") are
   redundant now that quantity/remove/coupon all update the page
   instantly via AJAX — hidden outright rather than reskinned. This is
   CSS, not a server-side notice clear, specifically because it also
   has to catch the copy WooCommerce's own JS injects straight from the
   AJAX response on remove/update, which happens on a request path
   `osk_drop_added_to_cart_notice()` below (template_redirect) doesn't
   run on.
   Errors ("Please enter a valid coupon code") and info notices still
   carry information the AJAX-updated UI doesn't show elsewhere, so
   those keep the flat-text reskin (Storefront default: rounded
   corners, green/red background, a Font Awesome icon — none of it
   matches this design; no background/border, prefixed like "> CART",
   the accessibility focus ring kept but reskinned). */
.osk-cart-wrap .woocommerce-message { display: none !important; }
.osk-cart-wrap .woocommerce-error,
.osk-cart-wrap .woocommerce-info {
	display: inline-block;
	background: transparent !important;
	border: none !important;
	border-radius: 0 !important;
	/* WooCommerce's own default text color is white, meant to sit on
	   the green/red background we just removed — without this it was
	   basically invisible against the page's light gray. */
	color: var(--osk-text) !important;
	font-weight: 700;
	font-size: var(--osk-text-sm);
	padding: var(--osk-space-2) 0 !important;
	margin: var(--osk-space-3) 0 0 !important;
	box-shadow: none !important;
}
.osk-cart-wrap .woocommerce-error::before,
.osk-cart-wrap .woocommerce-info::before {
	content: "> " !important;
	font-family: var(--osk-font) !important;
	font-weight: 700;
	position: static !important;
	width: auto !important;
	height: auto !important;
	margin: 0 !important;
}
.osk-cart-wrap .woocommerce-error:focus,
.osk-cart-wrap .woocommerce-info:focus {
	outline: 2px dashed var(--osk-accent) !important;
	outline-offset: 2px;
}

/* ---- empty cart ----
   Verified live: in this state WooCommerce renders no cart-form/
   cart-totals, so `.wc-empty-cart-message` and `.return-to-shop` (both
   plain children of .woocommerce with no grid-area of their own) fell
   into CSS Grid's row-first auto-placement — landing in the 320px
   sidebar column instead of the wide left one, which is what pushed
   the button to the right. Pinning both to column 1 fixes it. */
.osk-cart-wrap > .woocommerce .wc-empty-cart-message,
.osk-cart-wrap > .woocommerce .return-to-shop { grid-column: 1; }
.osk-cart-wrap .cart-empty { padding: var(--osk-space-8) var(--osk-space-4); text-align: center; font-size: var(--osk-text-sm); font-style: italic; opacity: 0.7; }
.osk-cart-wrap .return-to-shop .button {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	padding: var(--osk-space-1) var(--osk-space-3);
	border: 1px solid var(--osk-text);
	background: var(--osk-text) !important;
	color: var(--osk-bg) !important;
	font-family: var(--osk-font);
	font-size: var(--osk-text-sm);
}

/* Brand column needs the cart-items column to keep its full single-line
   width (thumb/name/qty/price/subtotal side by side) alongside it —
   verified live: below ~1250px that column gets squeezed enough to
   break word-wrapping. Dropped here, well before the 900px breakpoint
   where the sidebar itself stacks below for the same reason. */
@media (max-width: 1300px) {
	.osk-cart-wrap { grid-template-columns: 1fr; }
	.osk-cart-brand { display: none; }
}

@media (max-width: 900px) {
	/* Sidebar stacks below at this width: single column, everything in
	   DOM order (products, then the notice, then the sidebar). */
	.osk-cart-wrap > .woocommerce { grid-template-columns: 1fr; }
	.osk-cart-wrap .woocommerce-cart-form { grid-column: 1; grid-row: 1; }
	.osk-cart-wrap .woocommerce-notices-wrapper { grid-row: 2; }
	.osk-cart-wrap .cart-collaterals { grid-column: 1; grid-row: 3; }
	/* Sidebar stacks below at this width, so the divider swaps from a
	   right-hand vertical line to a bottom horizontal one (mirrors the
	   mockup's own @media (max-width: 900px) swap on .osk-cart__items). */
	.osk-cart-wrap .woocommerce-cart-form {
		border-right: none;
		padding-right: 0;
		border-bottom: 1px solid transparent;
		border-image-source: var(--osk-dash-h);
		border-image-slice: 1;
		border-image-repeat: round;
		padding-bottom: var(--osk-space-4);
	}
	/* Below this width the flex row (thumbnail/name/price/qty/subtotal
	   all on one line) has nowhere to shrink to — verified live: forcing
	   flex-wrap and per-column flex-basis produced overflow/misalignment
	   fighting Storefront's own responsive assumptions. Falling back to
	   plain block stacking (each td full-width, one under another) is
	   less compact than a bespoke mobile grid but is robust and reads
	   fine; a tighter mobile layout is a possible follow-up. */
	/* flex-direction: column (not display: block) so the desktop
	   qty/price/subtotal `order` above still applies to the stack. */
	.osk-cart-wrap table.shop_table tr.woocommerce-cart-form__cart-item,
	.osk-cart-wrap table.shop_table tr.cart_item { display: flex; flex-direction: column; }
	.osk-cart-wrap table.shop_table td { width: 100%; text-align: left; }
	/* Same !important as the desktop rule above, max-width included —
	   the real culprit (Storefront's own max-width: 3.70633em) applies
	   at every width. */
	.osk-cart-wrap td.product-thumbnail img { max-width: 64px !important; width: 64px !important; height: 64px !important; }
}

/* ==========================================================================
   CHECKOUT PAGE — skins WooCommerce's native [woocommerce_checkout]
   shortcode output (form.checkout.woocommerce-checkout), same approach
   as the Cart page: reshapes native markup into the approved mockup's
   two-column layout (fields left, sticky order review right) via CSS
   only — billing/shipping validation, AJAX order-review updates on
   address change, and the payment gateways (incl. Stripe) all stay
   exactly as WooCommerce/the gateway plugin ship them.

   Native structure in play (WooCommerce core
   templates/checkout/form-checkout.php + form-billing.php +
   form-shipping.php + review-order.php):
     form.checkout.woocommerce-checkout
       .woocommerce-notices-wrapper
       #customer_details.col2-set
         .col-1 > .woocommerce-billing-fields, .woocommerce-additional-fields
         .col-2 > .woocommerce-shipping-fields (checkbox + .shipping_address)
       h3#order_review_heading
       #order_review.woocommerce-checkout-review-order
         table.shop_table.woocommerce-checkout-review-order-table
         #payment.woocommerce-checkout-payment
           ul.wc_payment_methods.payment_methods
             li.wc_payment_method > input + label + div.payment_box
           .form-row.place-order (terms checkbox + #place_order button)

   NOT verified against a live WooCommerce/Stripe install yet — see the
   README's "Checkout page setup" note. [woocommerce_checkout] also
   renders the order-received (thank-you) and pay-for-order states on
   its own; those use different markup/classes (not targeted below), so
   they inherit the page's base type/color but aren't individually
   skinned yet. */

.osk-checkout-wrap .woocommerce-notices-wrapper:empty { display: none; }
.osk-checkout-wrap .woocommerce-notices-wrapper { grid-column: 1 / -1; padding: 0 var(--osk-space-4); }
.osk-checkout-wrap .woocommerce-error,
.osk-checkout-wrap .woocommerce-message,
.osk-checkout-wrap .woocommerce-info {
	background: transparent !important;
	color: var(--osk-text) !important;
	border-radius: 0 !important;
	font-size: var(--osk-text-sm);
	border: 1px solid var(--osk-text);
	padding: var(--osk-space-2) var(--osk-space-3);
	margin: var(--osk-space-3) var(--osk-space-4) 0;
	list-style: none;
}
/* Storefront's own notice icon is an absolutely-positioned icon-font
   glyph sized for ITS wider left padding -- under our tighter padding
   it lands on top of the first letter of the notice text (same bug
   found live on My Account's identical notice block, 2026-09-18 --
   fixing here too since this CSS was the copy source). A plain
   bordered box reads fine in this design without an icon, so drop it
   rather than fight Storefront's positioning (previously just
   recolored it visible; that alone doesn't fix the overlap). */
.osk-checkout-wrap .woocommerce-error::before,
.osk-checkout-wrap .woocommerce-message::before,
.osk-checkout-wrap .woocommerce-info::before {
	content: none !important;
	display: none !important;
}

/* "Have a coupon?" removed per feedback -- coupons are applied on the
   Cart page instead; hide WooCommerce's native toggle + form on
   Checkout entirely rather than leave them reachable. */
.osk-checkout-wrap .woocommerce-form-coupon-toggle,
.osk-checkout-wrap .checkout_coupon.woocommerce-form-coupon { display: none !important; }

/* ---- two-column shell ---- */
.osk-checkout-wrap form.checkout {
	display: grid;
	/* Equal-width columns, per feedback (was 1fr/340px) -- billing
	   fields and order review sit side by side at the same width. */
	grid-template-columns: 1fr 1fr;
	align-items: start;
	border-top: 1px solid transparent;
	border-image-source: var(--osk-dash-h);
	border-image-slice: 1;
	border-image-repeat: round;
}

/* #customer_details (col2-set) holds billing (col-1) + shipping
   (col-2) as two DOM siblings; the mockup wants them stacked in one
   column, in the order billing -> ship-to-different toggle/fields ->
   order notes. display:contents on col-1/col-2 promotes their own
   children to direct flex items of #customer_details so `order` can
   reorder across what were two separate branches. */
.osk-checkout-wrap #customer_details.col2-set {
	grid-column: 1;
	/* verified live: a flex-column grid item with no explicit width
	   doesn't reliably stretch to fill its track (same class of bug as
	   #order_review's leftover width below) -- force it. */
	width: 100%;
	display: flex;
	flex-direction: column;
	padding: var(--osk-space-4);
	border-right: 1px solid transparent;
	border-image-source: var(--osk-dash-v);
	border-image-slice: 1;
	border-image-repeat: round;
}
.osk-checkout-wrap #customer_details .col-1,
.osk-checkout-wrap #customer_details .col-2 { display: contents; }
.osk-checkout-wrap .woocommerce-billing-fields { order: 1; }
.osk-checkout-wrap .woocommerce-shipping-fields { order: 2; margin-top: var(--osk-space-3); }
.osk-checkout-wrap .woocommerce-additional-fields { order: 3; margin-top: var(--osk-space-3); }

.osk-checkout-wrap .woocommerce-billing-fields > h3,
.osk-checkout-wrap .woocommerce-additional-fields > h3 {
	font-size: var(--osk-text-sm);
	font-weight: 700;
	margin: 0 0 var(--osk-space-2);
}
.osk-checkout-wrap .woocommerce-shipping-fields > h3 { display: none; } /* replaced by the checkbox label itself */

.osk-checkout-wrap #ship-to-different-address {
	display: flex;
	align-items: center;
	margin: 0 0 var(--osk-space-2);
}
.osk-checkout-wrap #ship-to-different-address label {
	display: flex;
	align-items: center;
	gap: 0.6em;
	font-size: var(--osk-text-sm);
	cursor: pointer;
	width: 100%;
}
.osk-checkout-wrap #ship-to-different-address-checkbox { width: 1em; height: 1em; accent-color: var(--osk-text); cursor: pointer; }
.osk-checkout-wrap .shipping_address {
	padding-top: var(--osk-space-2);
	margin-top: var(--osk-space-1);
	border-top: 1px solid transparent;
	border-image-source: var(--osk-dash-h);
	border-image-slice: 1;
	border-image-repeat: round;
}

/* ---- form fields (billing, shipping, additional) ---- */
.osk-checkout-wrap .form-row { width: 100%; margin: 0 0 var(--osk-space-2); }
.osk-checkout-wrap .form-row-first,
.osk-checkout-wrap .form-row-last { display: inline-block; width: calc(50% - var(--osk-space-1)); vertical-align: top; }
.osk-checkout-wrap .form-row-first { margin-right: var(--osk-space-2); }
.osk-checkout-wrap label { display: block; font-size: var(--osk-text-xs); opacity: 0.6; margin-bottom: 0.25em; }
.osk-checkout-wrap .form-row .required { color: var(--osk-text); opacity: 0.6; text-decoration: none; }
.osk-checkout-wrap .form-row .optional { font-style: italic; opacity: 0.6; }
.osk-checkout-wrap input.input-text,
.osk-checkout-wrap select,
.osk-checkout-wrap textarea,
.osk-checkout-wrap .select2-selection {
	width: 100%;
	padding: 0.6em 0.7em;
	font-family: var(--osk-font);
	font-size: var(--osk-text-sm);
	color: var(--osk-text);
	background: transparent;
	border: 1px solid var(--osk-text);
	border-radius: 0;
	height: auto;
}
.osk-checkout-wrap textarea { resize: vertical; min-height: 5em; }
.osk-checkout-wrap .select2-container { width: 100% !important; }
.osk-checkout-wrap .select2-selection__rendered { padding: 0 !important; line-height: normal !important; color: var(--osk-text) !important; }

/* ---- returning-customer login prompt -- rendered above the checkout
   form (sibling of form.checkout, output by WooCommerce's
   woocommerce_before_checkout_form hook) only when WooCommerce's
   "Allow customers to log into an existing account during checkout"
   setting (Settings -> Accounts & Privacy) is on. That setting isn't
   reachable without WP-admin access -- see README's "My account access
   -- settings needed" note. ---- */
.osk-checkout-wrap .woocommerce-form-login-toggle {
	width: 50%;
	box-sizing: border-box;
	padding: 0 var(--osk-space-4);
	margin: var(--osk-space-3) 0 var(--osk-space-4);
}
@media (max-width: 900px) {
	.osk-checkout-wrap .woocommerce-form-login-toggle { width: 100%; }
}
.osk-checkout-wrap .woocommerce-form-login-toggle .woocommerce-info {
	background: transparent !important;
	color: var(--osk-text) !important;
	border-radius: 0 !important;
	font-size: var(--osk-text-sm);
	border: 1px solid var(--osk-text);
	padding: var(--osk-space-2) var(--osk-space-3);
	list-style: none;
}
.osk-checkout-wrap .woocommerce-form-login-toggle .woocommerce-info::before { color: var(--osk-text) !important; }
.osk-checkout-wrap a.showlogin { text-decoration: underline; font-weight: 700; cursor: pointer; }

.osk-checkout-wrap form.woocommerce-form-login {
	width: 50%;
	box-sizing: border-box;
	margin: var(--osk-space-2) var(--osk-space-4) var(--osk-space-4);
	padding: var(--osk-space-3);
	border: 1px dashed var(--osk-text);
	display: flex;
	flex-direction: column;
	gap: var(--osk-space-2);
}
@media (max-width: 900px) {
	.osk-checkout-wrap form.woocommerce-form-login { width: 100%; }
}
.osk-checkout-wrap form.woocommerce-form-login .form-row { width: 100%; margin: 0; }
.osk-checkout-wrap form.woocommerce-form-login .woocommerce-form-login__rememberme {
	display: flex;
	align-items: center;
	gap: 0.5em;
	font-size: var(--osk-text-sm);
	cursor: pointer;
}
.osk-checkout-wrap form.woocommerce-form-login input#rememberme { width: 1em; height: 1em; accent-color: var(--osk-text); cursor: pointer; }
.osk-checkout-wrap form.woocommerce-form-login .lost_password { font-size: var(--osk-text-xs); margin: 0; }
.osk-checkout-wrap form.woocommerce-form-login .lost_password a { text-decoration: underline; }
.osk-checkout-wrap form.woocommerce-form-login button[type="submit"] {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	padding: var(--osk-space-1) var(--osk-space-3);
	width: fit-content;
	font-family: var(--osk-font);
	font-size: var(--osk-text-sm);
	background: var(--osk-text);
	color: var(--osk-bg);
	border: 1px solid var(--osk-text);
	cursor: pointer;
}
.osk-checkout-wrap form.woocommerce-form-login button[type="submit"]:hover { background: var(--osk-accent); color: var(--osk-text); border-color: var(--osk-accent); }

/* ---- "create an account?" checkbox + revealed account fields --
   rendered inside the billing fields column, only when WooCommerce's
   "Allow customers to create an account during checkout" setting is
   on. Same settings caveat as the login prompt above. ---- */
.osk-checkout-wrap .woocommerce-account-fields { margin-top: var(--osk-space-3); }
.osk-checkout-wrap p.create-account label {
	display: flex;
	align-items: center;
	gap: 0.6em;
	font-size: var(--osk-text-sm);
	cursor: pointer;
}
.osk-checkout-wrap p.create-account input[type="checkbox"] { width: 1em; height: 1em; accent-color: var(--osk-text); cursor: pointer; }
.osk-checkout-wrap .woocommerce-account-fields div.create-account {
	padding-top: var(--osk-space-2);
	margin-top: var(--osk-space-1);
	border-top: 1px solid transparent;
	border-image-source: var(--osk-dash-h);
	border-image-slice: 1;
	border-image-repeat: round;
}
.osk-checkout-wrap .select2-selection__arrow { display: none; }

/* ---- order review sidebar ---- */
.osk-checkout-wrap #order_review_heading { display: none; }
.osk-checkout-wrap #order_review.woocommerce-checkout-review-order {
	grid-column: 2;
	width: 100%;
	float: none;
	/* Storefront's own #order_review carries an INLINE
	   background-color:#fff (order-review.php template) plus a stray
	   width:46%/float:right from its col2-set-adjacent sidebar CSS --
	   verified live: without the !important here and the explicit
	   width:100% above, the sidebar rendered as a sliver a fraction of
	   the grid track's actual width, wrapping every product name
	   character-by-character. */
	background: transparent !important;
	padding: var(--osk-space-4);
	position: sticky;
	top: 130px;
}
.osk-checkout-wrap #order_review::before {
	content: "> YOUR ORDER";
	display: block;
	font-size: var(--osk-text-sm);
	font-weight: 700;
	margin-bottom: var(--osk-space-3);
}

.osk-checkout-wrap table.shop_table.woocommerce-checkout-review-order-table { width: 100%; border-collapse: collapse; font-size: var(--osk-text-sm); }
.osk-checkout-wrap table.shop_table.woocommerce-checkout-review-order-table thead { display: none; }
.osk-checkout-wrap table.shop_table.woocommerce-checkout-review-order-table,
.osk-checkout-wrap table.shop_table.woocommerce-checkout-review-order-table tbody,
.osk-checkout-wrap table.shop_table.woocommerce-checkout-review-order-table tfoot { display: block; width: 100%; }
.osk-checkout-wrap table.shop_table.woocommerce-checkout-review-order-table tr {
	display: flex;
	justify-content: space-between;
	align-items: baseline;
	gap: var(--osk-space-2);
	width: 100%;
}
.osk-checkout-wrap table.shop_table.woocommerce-checkout-review-order-table tbody tr + tr { margin-top: 0.5em; }
.osk-checkout-wrap table.shop_table.woocommerce-checkout-review-order-table td,
.osk-checkout-wrap table.shop_table.woocommerce-checkout-review-order-table th {
	padding: 0;
	border: none;
	text-align: left;
	/* Storefront gives every cell its own near-white background
	   (#f8f8f8 th / #fdfdfd td) for its default striped-table look --
	   verified live: survived every other reset here since none of
	   them touched background. */
	background: transparent !important;
}
/* Storefront's own .product-name carries width:45% +
   overflow-wrap:anywhere + word-break:break-word (sized for its
   default table layout) -- inside our flex tr that 45% resolves
   against a much narrower track than intended, and break-word/anywhere
   then wraps the name one character per line. Reset to natural flex
   sizing + normal wrapping; give product-total a fixed share instead
   so it doesn't get squeezed. */
.osk-checkout-wrap table.shop_table.woocommerce-checkout-review-order-table .product-name {
	width: auto;
	flex: 1 1 auto;
	min-width: 0;
	overflow-wrap: normal;
	word-break: normal;
}
.osk-checkout-wrap table.shop_table.woocommerce-checkout-review-order-table td.product-total { flex: 0 0 auto; white-space: nowrap; text-align: right; }
.osk-checkout-wrap table.shop_table.woocommerce-checkout-review-order-table .product-name .product-quantity { opacity: 0.6; font-size: var(--osk-text-xs); }
.osk-checkout-wrap table.shop_table.woocommerce-checkout-review-order-table .product-name dl.variation {
	display: block;
	font-size: var(--osk-text-xs);
	font-style: italic;
	opacity: 0.6;
	margin: 0.2em 0 0;
}
.osk-checkout-wrap table.shop_table.woocommerce-checkout-review-order-table .product-name dl.variation dt { display: none; }
.osk-checkout-wrap table.shop_table.woocommerce-checkout-review-order-table .product-name dl.variation dd { display: inline; margin: 0; }
.osk-checkout-wrap table.shop_table.woocommerce-checkout-review-order-table .product-name dl.variation dd p { display: inline; margin: 0; }

.osk-checkout-wrap table.shop_table.woocommerce-checkout-review-order-table tfoot {
	display: block;
	margin-top: var(--osk-space-2);
	padding-top: var(--osk-space-2);
	border-top: 1px solid transparent;
	border-image-source: var(--osk-dash-h);
	border-image-slice: 1;
	border-image-repeat: round;
}
.osk-checkout-wrap table.shop_table.woocommerce-checkout-review-order-table tfoot tr + tr { margin-top: 0.4em; }
.osk-checkout-wrap table.shop_table.woocommerce-checkout-review-order-table tfoot tr.order-total,
.osk-checkout-wrap table.shop_table.woocommerce-checkout-review-order-table tfoot tr.order-total th,
.osk-checkout-wrap table.shop_table.woocommerce-checkout-review-order-table tfoot tr.order-total td { font-weight: 700; font-size: var(--osk-text-md); }
.osk-checkout-wrap table.shop_table.woocommerce-checkout-review-order-table tfoot tr.order-total {
	margin-top: var(--osk-space-2);
	padding-top: var(--osk-space-2);
	border-top: 1px solid transparent;
	border-image-source: var(--osk-dash-h);
	border-image-slice: 1;
	border-image-repeat: round;
}
.osk-checkout-wrap ul.woocommerce-shipping-methods,
.osk-checkout-wrap ul.woocommerce-shipping-methods li { list-style: none; margin: 0; padding: 0; font-size: var(--osk-text-sm); }

/* ---- payment methods ---- */
.osk-checkout-wrap #payment.woocommerce-checkout-payment {
	margin-top: var(--osk-space-3);
	padding-top: var(--osk-space-3);
	border-top: 1px solid transparent;
	border-image-source: var(--osk-dash-h);
	border-image-slice: 1;
	border-image-repeat: round;
}
.osk-checkout-wrap #payment::before {
	content: "> PAYMENT";
	display: block;
	font-size: var(--osk-text-sm);
	font-weight: 700;
	margin-bottom: var(--osk-space-2);
}
.osk-checkout-wrap ul.wc_payment_methods.payment_methods { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 0.6em; }
/* Storefront gives the method row, its expanded panel, and the
   payment-form fieldset each their own near-white background
   (#f5f5f5 / #fafafa / #fbfbfb) -- verified live: none of the rules
   below happened to touch background, so all three still showed. */
.osk-checkout-wrap li.wc_payment_method { border: 1px solid var(--osk-text); background: transparent !important; }
.osk-checkout-wrap li.wc_payment_method > label {
	display: flex;
	align-items: center;
	gap: 0.6em;
	padding: 0.7em 0.8em;
	font-size: var(--osk-text-sm);
	cursor: pointer;
	margin: 0;
}
.osk-checkout-wrap li.wc_payment_method input.input-radio { accent-color: var(--osk-text); cursor: pointer; }
.osk-checkout-wrap li.wc_payment_method img { max-height: 1.2em; margin-left: auto; opacity: 0.7; }
.osk-checkout-wrap .payment_box { padding: 0 0.8em 0.8em; font-size: var(--osk-text-xs); background: transparent !important; }
.osk-checkout-wrap .payment_box::before { content: none; } /* remove Storefront's default speech-bubble arrow */
.osk-checkout-wrap .payment_box p { margin: 0 0 0.6em; }
.osk-checkout-wrap .payment_box fieldset { border: none; padding: 0; margin: 0; background: transparent !important; }

.osk-checkout-wrap .woocommerce-terms-and-conditions-wrapper { margin-top: var(--osk-space-3); font-size: var(--osk-text-xs); }
.osk-checkout-wrap .woocommerce-form__label-for-checkbox { display: flex; align-items: center; cursor: pointer; }
.osk-checkout-wrap .woocommerce-form__input-checkbox { width: 1em; height: 1em; accent-color: var(--osk-text); cursor: pointer; }
.osk-checkout-wrap a.woocommerce-terms-and-conditions-link { text-decoration: underline; }

.osk-checkout-wrap .form-row.place-order { margin-top: var(--osk-space-3); background: transparent !important; }
.osk-checkout-wrap #place_order.button.alt {
	display: flex;
	width: 100%;
	align-items: center;
	justify-content: center;
	padding: 0.6em var(--osk-space-3);
	font-family: var(--osk-font);
	font-size: var(--osk-text-sm);
	letter-spacing: 0.04em;
	background: var(--osk-text) !important;
	color: var(--osk-bg) !important;
	border: 1px solid var(--osk-text) !important;
	border-radius: 0 !important;
	cursor: pointer;
}
.osk-checkout-wrap #place_order.button.alt:hover {
	background: var(--osk-accent) !important;
	color: var(--osk-text) !important;
	border-color: var(--osk-accent) !important;
}
.osk-checkout-wrap .woocommerce-privacy-policy-text { font-size: var(--osk-text-xs); opacity: 0.55; font-style: italic; margin-top: var(--osk-space-2); }

/* ---- blockUI overlay during AJAX order-review updates (address
   change, coupon apply) — same transparent/no-spinner treatment as
   Cart. ---- */
.osk-checkout-wrap .blockUI.blockOverlay { background: transparent !important; }
.osk-checkout-wrap .blockUI.blockMsg { display: none !important; }

@media (max-width: 900px) {
	.osk-checkout-wrap form.checkout { grid-template-columns: 1fr; }
	.osk-checkout-wrap #customer_details.col2-set {
		grid-column: 1;
		border-right: none;
		border-bottom: 1px solid transparent;
		border-image-source: var(--osk-dash-h);
		border-image-slice: 1;
		border-image-repeat: round;
	}
	.osk-checkout-wrap .woocommerce-notices-wrapper { grid-column: 1; }
	.osk-checkout-wrap #order_review.woocommerce-checkout-review-order { grid-column: 1; position: static; }
	.osk-checkout-wrap .form-row-first,
	.osk-checkout-wrap .form-row-last { width: 100%; margin-right: 0; }
}

/* ==========================================================================
   MY ACCOUNT PAGE — skins WooCommerce's native [woocommerce_my_account]
   shortcode output, same approach as Cart/Checkout: reshapes native
   markup into the approved mockup's sidebar-nav + content layout via
   CSS only — order history, address editing, account-details editing
   and the login/register form (logged out) all stay exactly as
   WooCommerce ships them.

   Native structure in play (WooCommerce core
   templates/myaccount/my-account.php + navigation.php + orders.php +
   my-address.php + form-edit-account.php):
     nav.woocommerce-MyAccount-navigation
       ul > li.woocommerce-MyAccount-navigation-link[.is-active] > a
     div.woocommerce-MyAccount-content
       (Dashboard: welcome text + quick links)
       table.woocommerce-orders-table.shop_table (Orders)
       .woocommerce-Addresses > .woocommerce-Address (Addresses)
       form.woocommerce-EditAccountForm (Account details)
       form.woocommerce-form-login / form.woocommerce-form-register
         (logged out)

   NOT verified against a live WooCommerce install yet — built and
   CSS-lint-reasoned against WooCommerce core's documented My Account
   markup, same as the first Checkout pass before its live-verification
   round. The login/register form (logged-out state) intentionally
   isn't individually skinned below — same call as Checkout's
   order-received/pay-for-order states — it inherits the page's base
   type/color only; it wasn't part of the approved mockup. */

/* [woocommerce_my_account]'s own shortcode class wraps its whole
   output in <div class="woocommerce">...</div> (WC_Shortcodes::
   shortcode_wrapper(), core default) -- nav and content are direct
   children of THAT div, not of .osk-account-wrap. Confirmed live
   2026-09-18: the grid below was originally placed on .osk-account-wrap
   itself with nav/content targeted via a `>` child combinator, which
   silently no-ops grid-column on a non-direct-child, collapsing the
   whole layout into a single ~80px auto-placed column. Same wrapper
   Cart already accounts for (".osk-cart-wrap > .woocommerce"). */
.osk-account-wrap > .woocommerce {
	display: grid;
	grid-template-columns: 220px 1fr;
	align-items: start;
	border-top: 1px solid transparent;
	border-image-source: var(--osk-dash-h);
	border-image-slice: 1;
	border-image-repeat: round;
}

/* ---- nav ---- */
.osk-account-wrap > .woocommerce > nav.woocommerce-MyAccount-navigation {
	grid-column: 1;
	/* same "flex-column grid item doesn't reliably stretch to fill its
	   track without an explicit width" class of bug already hit on
	   Checkout's #customer_details and #order_review -- force it here
	   too rather than assume. */
	width: 100%;
	padding: var(--osk-space-4) var(--osk-space-3);
	border-right: 1px solid transparent;
	border-image-source: var(--osk-dash-v);
	border-image-slice: 1;
	border-image-repeat: round;
	position: sticky;
	top: 90px;
}
.osk-account-wrap nav.woocommerce-MyAccount-navigation ul { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 0.2em; }
.osk-account-wrap nav.woocommerce-MyAccount-navigation li { margin: 0; }
.osk-account-wrap nav.woocommerce-MyAccount-navigation a {
	display: block;
	padding: 0.5em 0.4em;
	font-size: var(--osk-text-sm);
}
.osk-account-wrap nav.woocommerce-MyAccount-navigation li.is-active a { background: var(--osk-accent); }
.osk-account-wrap nav.woocommerce-MyAccount-navigation li.woocommerce-MyAccount-navigation-link--customer-logout {
	margin-top: var(--osk-space-2);
	padding-top: calc(var(--osk-space-2) + 0.5em);
	border-top: 1px solid transparent;
	border-image-source: var(--osk-dash-h);
	border-image-slice: 1;
	border-image-repeat: round;
	opacity: 0.7;
}

/* ---- content pane ---- */
.osk-account-wrap > .woocommerce > div.woocommerce-MyAccount-content { grid-column: 2; width: 100%; padding: var(--osk-space-4); }
.osk-account-wrap .woocommerce-MyAccount-content > p:first-child { font-size: var(--osk-text-sm); margin-top: 0; }
.osk-account-wrap .woocommerce-MyAccount-content mark { background: var(--osk-accent); padding: 0 0.2em; }
.osk-account-wrap .woocommerce-MyAccount-content a:not(.button):not(.woocommerce-Button) { text-decoration: underline; }

/* ---- orders table (Orders tab) ---- */
.osk-account-wrap table.woocommerce-orders-table thead { display: none; } /* mockup has no header row, same as Cart */
.osk-account-wrap table.woocommerce-orders-table,
.osk-account-wrap table.woocommerce-orders-table tbody { display: block; width: 100%; border-collapse: collapse; }
.osk-account-wrap table.woocommerce-orders-table tr {
	display: grid;
	grid-template-columns: auto 1fr 1fr auto;
	grid-template-rows: auto auto;
	column-gap: var(--osk-space-2);
	align-items: center;
	padding: var(--osk-space-2) 0;
	border-bottom: 1px solid transparent;
	border-image-source: var(--osk-dash-h);
	border-image-slice: 1;
	border-image-repeat: round;
}
.osk-account-wrap table.woocommerce-orders-table td { padding: 0; border: none; font-size: var(--osk-text-sm); }
.osk-account-wrap table.woocommerce-orders-table td::before { content: none; display: none; } /* disable native data-title responsive label -- our own grid handles layout, same as Cart */
.osk-account-wrap table.woocommerce-orders-table td.woocommerce-orders-table__cell-order-number { grid-column: 1; grid-row: 1; font-weight: 700; }
.osk-account-wrap table.woocommerce-orders-table td.woocommerce-orders-table__cell-order-date { grid-column: 1; grid-row: 2; font-size: var(--osk-text-xs); opacity: 0.6; }
.osk-account-wrap table.woocommerce-orders-table td.woocommerce-orders-table__cell-order-status { grid-column: 2; grid-row: 1 / span 2; font-size: var(--osk-text-xs); font-style: italic; }
.osk-account-wrap table.woocommerce-orders-table td.woocommerce-orders-table__cell-order-total { grid-column: 3; grid-row: 1 / span 2; }
.osk-account-wrap table.woocommerce-orders-table td.woocommerce-orders-table__cell-order-actions { grid-column: 4; grid-row: 1 / span 2; display: flex; gap: 0.4em; justify-content: flex-end; }
.osk-account-wrap table.woocommerce-orders-table td.woocommerce-orders-table__cell-order-actions .woocommerce-button,
.osk-account-wrap table.woocommerce-orders-table td.woocommerce-orders-table__cell-order-actions a.button {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	padding: 0.35em 0.8em;
	font-size: var(--osk-text-xs);
	letter-spacing: 0.04em;
	border: 1px solid var(--osk-text);
	background: transparent;
	color: var(--osk-text);
	white-space: nowrap;
}
.osk-account-wrap table.woocommerce-orders-table td.woocommerce-orders-table__cell-order-actions .woocommerce-button:hover { background: var(--osk-text); color: var(--osk-bg); }

.osk-account-wrap .woocommerce-Pagination { padding-top: var(--osk-space-3); font-size: var(--osk-text-sm); }

/* ---- addresses (Addresses tab) ---- */
.osk-account-wrap .woocommerce-Addresses { display: grid; grid-template-columns: 1fr 1fr; gap: var(--osk-space-3); }
.osk-account-wrap .woocommerce-Address {
	border: 1px solid var(--osk-text);
	padding: var(--osk-space-3);
}
.osk-account-wrap .woocommerce-Address-title { display: flex; align-items: center; justify-content: space-between; gap: 0.6em; margin: 0 0 0.6em; }
.osk-account-wrap .woocommerce-Address-title h2,
.osk-account-wrap .woocommerce-Address-title h3 { font-size: var(--osk-text-xs); text-transform: uppercase; letter-spacing: 0.03em; opacity: 0.6; font-weight: 400; margin: 0; }
.osk-account-wrap .woocommerce-Address-title a.edit {
	display: inline-flex;
	align-items: center;
	padding: 0.3em 0.7em;
	font-size: var(--osk-text-xs);
	border: 1px solid var(--osk-text);
	white-space: nowrap;
}
.osk-account-wrap .woocommerce-Address-title a.edit:hover { background: var(--osk-text); color: var(--osk-bg); }
.osk-account-wrap .woocommerce-Address address { font-style: normal; font-size: var(--osk-text-sm); line-height: 1.5; }

/* ---- forms (Account details / Add-Edit address) -- same field/button
   skin as Checkout's billing form, scoped to this page. ---- */
.osk-account-wrap .form-row { width: 100%; margin: 0 0 var(--osk-space-2); }
.osk-account-wrap .form-row-first,
.osk-account-wrap .form-row-last { display: inline-block; width: calc(50% - var(--osk-space-1)); vertical-align: top; }
.osk-account-wrap .form-row-first { margin-right: var(--osk-space-2); }
.osk-account-wrap label { display: block; font-size: var(--osk-text-xs); opacity: 0.6; margin-bottom: 0.25em; }
.osk-account-wrap .form-row .required { color: var(--osk-text); opacity: 0.6; text-decoration: none; }
.osk-account-wrap .form-row .optional { font-style: italic; opacity: 0.6; }
.osk-account-wrap input.input-text,
.osk-account-wrap select,
.osk-account-wrap textarea,
.osk-account-wrap .select2-selection {
	width: 100%;
	padding: 0.6em 0.7em;
	font-family: var(--osk-font);
	font-size: var(--osk-text-sm);
	color: var(--osk-text);
	background: transparent !important;
	border: 1px solid var(--osk-text);
	border-radius: 0;
}
.osk-account-wrap fieldset { border: 1px dashed var(--osk-text); padding: var(--osk-space-3); margin: var(--osk-space-3) 0 0; }
.osk-account-wrap fieldset legend { font-size: var(--osk-text-xs); text-transform: uppercase; letter-spacing: 0.03em; opacity: 0.6; padding: 0 0.4em; }
.osk-account-wrap button.woocommerce-Button,
.osk-account-wrap button[type="submit"] {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	padding: var(--osk-space-1) var(--osk-space-3);
	font-family: var(--osk-font);
	font-size: var(--osk-text-sm);
	letter-spacing: 0.04em;
	background: var(--osk-text);
	color: var(--osk-bg);
	border: 1px solid var(--osk-text);
	border-radius: 0 !important; /* browser UA default rounds <button>, seen live */
	cursor: pointer;
	margin-top: var(--osk-space-2);
}
.osk-account-wrap button.woocommerce-Button:hover,
.osk-account-wrap button[type="submit"]:hover { background: var(--osk-accent); color: var(--osk-text); border-color: var(--osk-accent); }

/* ---- password field show/hide toggle (core WP/WooCommerce markup:
   <span class="password-input"><input>...<button
   class="show-password-input">) -- default is an unstyled gray UA
   button, seen live sitting oddly next to our flat/bordered inputs.
   Strip it down to a plain icon-only toggle, no box. ---- */
.osk-account-wrap .show-password-input {
	background: transparent !important;
	border: none !important;
	box-shadow: none !important;
	padding: 0 !important;
	width: 1.6em;
	height: 1.6em;
	cursor: pointer;
	opacity: 0.6;
}
.osk-account-wrap .show-password-input:hover { opacity: 1; }

/* ---- logged-out login/register --------------------------------------
   Rendered by WC_Shortcode_My_Account::login() directly into the
   shortcode's .woocommerce wrapper -- a different code path than the
   nav+content dashboard above, so none of that padding reaches it.
   Confirmed live 2026-09-18: h2/form were sitting flush against the
   page edge with the browser's own default heading font, unlike the
   rest of the page.
   Structure (WooCommerce core templates/myaccount/form-login.php):
   with registration OFF (WooCommerce's default), <h2>Login</h2> +
   form.woocommerce-form-login sit directly inside .woocommerce; with
   registration ON (WooCommerce -> Settings -> Accounts & Privacy ->
   "Allow customers to create an account on the 'My account' page" --
   off by default, not something I can toggle without WP-admin access)
   they move into #customer_login.u-columns.col2-set, each half in its
   own .u-column1/.u-column2 with its own <h2> + form. Styled for both
   cases so this doesn't need a third pass once that setting is on. */
.osk-account-wrap > .woocommerce > h2,
.osk-account-wrap #customer_login h2 {
	font-family: var(--osk-font);
	font-size: var(--osk-text-md);
	font-weight: 400;
	margin: 0 0 var(--osk-space-3);
}
.osk-account-wrap > .woocommerce > h2,
.osk-account-wrap > .woocommerce > .woocommerce-notices-wrapper,
.osk-account-wrap > .woocommerce > form.woocommerce-form-login,
.osk-account-wrap > .woocommerce > form.woocommerce-form-register,
.osk-account-wrap #customer_login {
	padding-left: var(--osk-space-4);
	padding-right: var(--osk-space-4);
}
.osk-account-wrap > .woocommerce > form.woocommerce-form-login,
.osk-account-wrap > .woocommerce > form.woocommerce-form-register {
	max-width: 26em; /* no approved mockup for this state -- a modest cap so the field doesn't stretch edge-to-edge on a wide screen */
	padding-bottom: var(--osk-space-4);
}
.osk-account-wrap #customer_login {
	display: grid;
	grid-template-columns: 1fr 1fr;
	gap: var(--osk-space-4);
	padding-bottom: var(--osk-space-4);
}
.osk-account-wrap #customer_login .u-column1,
.osk-account-wrap #customer_login .u-column2 { padding: 0; }
@media (max-width: 900px) {
	.osk-account-wrap #customer_login { grid-template-columns: 1fr; }
}

/* ---- notices (e.g. "Address changed successfully.", validation
   errors, the empty-orders/link-past-orders prompts) ---- */
.osk-account-wrap .woocommerce-error,
.osk-account-wrap .woocommerce-message,
.osk-account-wrap .woocommerce-info {
	display: flex;
	align-items: center;
	justify-content: space-between;
	flex-wrap: wrap;
	gap: var(--osk-space-2);
	background: transparent !important;
	color: var(--osk-text) !important;
	border-radius: 0 !important;
	font-size: var(--osk-text-sm);
	border: 1px solid var(--osk-text);
	padding: var(--osk-space-2) var(--osk-space-3);
	margin: 0 0 var(--osk-space-3);
	list-style: none;
}
/* Storefront's own notice icon is an absolutely-positioned icon-font
   glyph sized for ITS wider left padding -- under our own tighter
   padding it lands on top of the first letter of the text (seen live,
   e.g. "Confirm your..." rendering as "[icon]onfirm your..."). A
   plain bordered box reads fine in this design without an icon, so
   drop it rather than fight Storefront's positioning. */
.osk-account-wrap .woocommerce-error::before,
.osk-account-wrap .woocommerce-message::before,
.osk-account-wrap .woocommerce-info::before { content: none !important; display: none !important; }
/* The "Confirm email address" / "Browse products" action links inside
   these notices inherit Storefront's white button text (meant to sit
   on Storefront's own colored notice background) -- our notices are
   transparent, so that text was rendering barely visible against the
   page background. Skin it like .osk-btn instead. `order: 2` keeps it
   trailing/right-aligned regardless of where WooCommerce's own markup
   places it relative to the message text. */
.osk-account-wrap .woocommerce-error a.button,
.osk-account-wrap .woocommerce-message a.button,
.osk-account-wrap .woocommerce-info a.button,
.osk-account-wrap .woocommerce-error a.woocommerce-Button,
.osk-account-wrap .woocommerce-message a.woocommerce-Button,
.osk-account-wrap .woocommerce-info a.woocommerce-Button {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	order: 2;
	padding: 0.35em 0.8em;
	font-family: var(--osk-font);
	font-size: var(--osk-text-xs);
	letter-spacing: 0.04em;
	background: transparent !important;
	color: var(--osk-text) !important;
	border: 1px solid var(--osk-text) !important;
	border-radius: 0 !important;
	white-space: nowrap;
}
.osk-account-wrap .woocommerce-error a.button:hover,
.osk-account-wrap .woocommerce-message a.button:hover,
.osk-account-wrap .woocommerce-info a.button:hover,
.osk-account-wrap .woocommerce-error a.woocommerce-Button:hover,
.osk-account-wrap .woocommerce-message a.woocommerce-Button:hover,
.osk-account-wrap .woocommerce-info a.woocommerce-Button:hover { background: var(--osk-text) !important; color: var(--osk-bg) !important; }

@media (max-width: 900px) {
	.osk-account-wrap > .woocommerce { grid-template-columns: 1fr; }
	.osk-account-wrap > .woocommerce > nav.woocommerce-MyAccount-navigation {
		position: static;
		border-right: none;
		border-bottom: 1px solid transparent;
		border-image-source: var(--osk-dash-h);
		border-image-slice: 1;
		border-image-repeat: round;
	}
	.osk-account-wrap nav.woocommerce-MyAccount-navigation ul { flex-direction: row; flex-wrap: wrap; gap: 0.5em 1em; }
	.osk-account-wrap nav.woocommerce-MyAccount-navigation li.woocommerce-MyAccount-navigation-link--customer-logout { margin-top: 0; padding-top: 0; border-top: none; }
	.osk-account-wrap > .woocommerce > div.woocommerce-MyAccount-content { grid-column: 1; }
	.osk-account-wrap table.woocommerce-orders-table tr { grid-template-columns: 1fr auto; grid-template-rows: auto auto auto auto; row-gap: 0.3em; }
	.osk-account-wrap table.woocommerce-orders-table td.woocommerce-orders-table__cell-order-number { grid-column: 1; grid-row: 1; }
	.osk-account-wrap table.woocommerce-orders-table td.woocommerce-orders-table__cell-order-date { grid-column: 1; grid-row: 2; }
	.osk-account-wrap table.woocommerce-orders-table td.woocommerce-orders-table__cell-order-status { grid-column: 1; grid-row: 3; }
	.osk-account-wrap table.woocommerce-orders-table td.woocommerce-orders-table__cell-order-total { grid-column: 1; grid-row: 4; }
	.osk-account-wrap table.woocommerce-orders-table td.woocommerce-orders-table__cell-order-actions { grid-column: 2; grid-row: 1 / span 4; align-self: center; }
	.osk-account-wrap .woocommerce-Addresses { grid-template-columns: 1fr; }
	.osk-account-wrap .form-row-first,
	.osk-account-wrap .form-row-last { width: 100%; margin-right: 0; }
}
