/*
 * Cart drawer (T-010) — the bag becomes a slide-over panel, layered as a
 * progressive enhancement over the always-real /cart/ page. Lives in its
 * own stylesheet rather than style.css: S-004's chain A does not edit that
 * file this sprint (chain B owns it), so every chain-A rule goes in a
 * component stylesheet instead, the same split already proven for the
 * builder plugin's assets/builder.css (see state/repos/goldvion.md's
 * "Cascade order between builder.css and style.css" note — this file is
 * enqueued with `array( 'goldvion' )` as its dependency in functions.php
 * for the same reason: guaranteed to load after style.css regardless of
 * registration order, so it reliably wins any equal-specificity collision.
 * That dependency is load-bearing, not free insurance: `.gv-cart-drawer__close`
 * below (0,1,0) ties exactly with style.css's `.gv-icon-btn` (0,1,0) —
 * parts/header.html puts both classes on the same close button — and only
 * this file loading after style.css is what makes the 2rem override win.
 * Drop the dependency and the close button silently reverts to 2.5rem.
 *
 * No-JS contract (ADR-019): parts/header.html's cart icon is a plain
 * `<a href>` to the real cart page and stays one — with scripting off, that
 * anchor's default navigation IS the entire cart feature, and everything
 * below (the drawer, the scrim) starts and stays in its closed state
 * forever, because nothing but assets/js/cart-drawer.js ever adds the
 * `.is-open` class either rule below keys off. A closed drawer is
 * `visibility: hidden` (not just off-screen), removing it from the tab
 * order and the accessibility tree in every browser with no script
 * required — same mechanism style.css already uses for #gv-drawer.
 *
 * Scroll-lock is the same CSS-only `:has()` mechanism already proven for
 * the header nav drawer (style.css, `html:has(.gv-drawer-toggle:checked)`)
 * and the charm modal (builder.css, `html:has(.gv-charm-open:checked)`):
 * JS only ever flips one class, and the cascade — not JS touching
 * `overflow` directly — is what applies and releases the lock. Those two
 * precedents reach that class from a checkbox's `:checked` because both
 * controls are independently operable with no JS at all. The cart drawer
 * has no such no-JS-operable state of its own — its one no-JS affordance
 * is the anchor's default navigation above, which needs no drawer state at
 * all — so a plain class set by cart-drawer.js is the honest equivalent
 * here rather than wiring up a checkbox with no real no-JS behaviour behind
 * it.
 */

.gv-cart-scrim {
	position: fixed;
	inset: 0;
	z-index: 61;
	background: color-mix( in srgb, var( --wp--preset--color--charcoal ) 30%, transparent );
	backdrop-filter: blur( 6px );
	-webkit-backdrop-filter: blur( 6px );
	opacity: 0;
	pointer-events: none;
	transition: opacity 350ms ease;
}

.gv-cart-scrim.is-open {
	opacity: 1;
	pointer-events: auto;
}

/* z-index: 62. Acceptance requires "above the header navigation drawer
   (60) and no higher than the tier modal (64 scrim / 65 panel)" — checked
   against those elements' own computed z-index, not against the numbers in
   this comment. The 60 comparison is real: the nav drawer is this drawer's
   sibling inside the same stacking context (style.css puts
   `position: sticky; z-index: 50` on the header wrapper both live in), so
   61/62 and 60 compete directly there and 62 wins. The 64/65 comparison is
   not a same-context number race, though the outcome is still correct: the
   charm modal lives in page content, a sibling subtree under
   `.wp-site-blocks` rather than inside the header's stacking context, so it
   is the header wrapper's own z-index: 50 — not this drawer's 62 — that
   competes against the modal's 64/65, and 50 loses. If that header
   `z-index: 50` is ever changed or removed, the drawer/modal relationship
   can invert with nothing here to warn you. */
.gv-cart-drawer {
	position: fixed;
	inset: 0 0 0 auto;
	width: 100%;
	max-width: 448px;
	z-index: 62;
	display: flex;
	flex-direction: column;
	background: var( --wp--preset--color--ivory );
	box-shadow: -8px 0 32px color-mix( in srgb, var( --wp--preset--color--charcoal ) 16%, transparent );
	transform: translateX( 100% );
	visibility: hidden;
	transition: transform 350ms ease, visibility 0s linear 350ms;
}

.gv-cart-drawer.is-open {
	transform: translateX( 0 );
	visibility: visible;
	transition: transform 350ms ease, visibility 0s linear 0s;
}

html:has( .gv-cart-drawer.is-open ),
body:has( .gv-cart-drawer.is-open ) {
	overflow: hidden;
}

.gv-cart-drawer__top {
	display: flex;
	align-items: center;
	justify-content: space-between;
	flex: none;
	padding: 1.25rem var( --wp--preset--spacing--gutter, 1.5rem );
	border-bottom: 1px solid var( --wp--preset--color--hairline );
}

.gv-cart-drawer__eyebrow {
	font-size: var( --wp--preset--font-size--micro );
	letter-spacing: 0.15em;
	text-transform: uppercase;
	color: var( --wp--preset--color--muted-soft, var( --wp--preset--color--muted ) );
}

.gv-cart-drawer__close {
	width: 2rem;
	height: 2rem;
}

/* Every interactive control inside the drawer gets its own visible
   focus-visible ring on itself — never a shared/ambiguous one. This is a
   different situation from the charm modal fix this task copies: there,
   ONE rule fired identically for either of TWO checkboxes stacked on the
   same tile, so the two needed visibly DIFFERENT rings to tell them apart.
   Nothing in this drawer shares a single focus trigger between two
   possible targets — :focus-visible always scopes to the one element that
   actually has focus — so one consistent, clearly visible ring style
   satisfies "never an invisible stop" without inventing an artificial
   distinction nothing here needs. */
.gv-cart-drawer button:focus-visible,
.gv-cart-drawer a:focus-visible {
	outline: 2px solid var( --wp--preset--color--charcoal );
	outline-offset: 2px;
}

.gv-cart-drawer__body {
	flex: 1 1 auto;
	overflow-y: auto;
	padding: 0 var( --wp--preset--spacing--gutter, 1.5rem );
}

.gv-cart-drawer__status {
	padding: 2rem 0;
	text-align: center;
	color: var( --wp--preset--color--muted-soft, var( --wp--preset--color--muted ) );
}

.gv-cart-drawer__status[data-gv-cart-error] {
	color: var( --wp--preset--color--charcoal );
}

/* Empty state: bag icon, message, link back to the builder. */
.gv-cart-drawer__empty {
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	text-align: center;
	height: 100%;
	min-height: 20rem;
	padding: 2rem 0;
	gap: 1rem;
}

.gv-cart-drawer__empty svg {
	color: var( --wp--preset--color--gold );
	opacity: 0.6;
}

.gv-cart-drawer__empty p {
	font-family: var( --wp--preset--font-family--display );
	font-size: var( --wp--preset--font-size--x-large );
	color: var( --wp--preset--color--charcoal );
}

.gv-cart-drawer__empty a {
	font-size: var( --wp--preset--font-size--eyebrow );
	letter-spacing: 0.15em;
	text-transform: uppercase;
	color: var( --wp--preset--color--gold );
	text-decoration: none;
}

.gv-cart-drawer__empty a:hover {
	text-decoration: underline;
}

/* Line items. */
.gv-cart-drawer__lines {
	list-style: none;
	margin: 0;
	padding: 0;
}

.gv-cart-line {
	padding: 1.25rem 0;
	border-bottom: 1px solid var( --wp--preset--color--hairline );
}

.gv-cart-line__head {
	display: flex;
	align-items: flex-start;
	justify-content: space-between;
	gap: 0.75rem;
}

.gv-cart-line__name {
	margin: 0;
	font-family: var( --wp--preset--font-family--display );
	font-size: var( --wp--preset--font-size--large );
	color: var( --wp--preset--color--charcoal );
}

.gv-cart-line__remove {
	flex: none;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 1.75rem;
	height: 1.75rem;
	padding: 0;
	background: none;
	border: 0;
	color: color-mix( in srgb, var( --wp--preset--color--charcoal ) 40%, transparent );
	cursor: pointer;
}

.gv-cart-line__remove:hover {
	color: var( --wp--preset--color--charcoal );
}

/* The brief — base, tone, every charm by name, packaging, and whatever
   else Goldvion_Cart::format() emits through woocommerce_get_item_data.
   Rendered verbatim, in the order the Store API returns it, so this is
   provably the same row set the cart page renders through the same
   filter — not a hand-picked subset. See cart-drawer.js. */
.gv-cart-line__brief {
	display: flex;
	flex-direction: column;
	gap: 0.15rem;
	margin-top: 0.5rem;
	font-size: var( --wp--preset--font-size--x-small );
	color: var( --wp--preset--color--muted-soft, var( --wp--preset--color--muted ) );
}

.gv-cart-line__foot {
	display: flex;
	align-items: center;
	justify-content: space-between;
	margin-top: 0.75rem;
}

.gv-cart-line__qty {
	display: flex;
	align-items: center;
	gap: 0.75rem;
}

.gv-cart-line__qty-btn {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 1.5rem;
	height: 1.5rem;
	padding: 0;
	background: none;
	border: 0;
	color: color-mix( in srgb, var( --wp--preset--color--charcoal ) 55%, transparent );
	cursor: pointer;
}

.gv-cart-line__qty-btn:hover:not( :disabled ) {
	color: var( --wp--preset--color--charcoal );
}

.gv-cart-line__qty-btn:disabled {
	opacity: 0.3;
	cursor: not-allowed;
}

.gv-cart-line__qty-value {
	min-width: 1.25rem;
	text-align: center;
	font-size: var( --wp--preset--font-size--small );
	color: var( --wp--preset--color--charcoal );
}

.gv-cart-line__price {
	font-family: var( --wp--preset--font-family--display );
	font-size: var( --wp--preset--font-size--large );
	color: var( --wp--preset--color--charcoal );
}

/* Footer — subtotal, total, Checkout. No promo/discount field anywhere:
   B-027 forbids it (documentation/business-model.md; the export's
   promoApplied is a prototype stub applying a hardcoded 10% to any
   non-empty string) — see cart-drawer.js, which never renders one. */
.gv-cart-drawer__footer {
	flex: none;
	padding: 1.25rem var( --wp--preset--spacing--gutter, 1.5rem );
	border-top: 1px solid var( --wp--preset--color--hairline );
}

.gv-cart-drawer__row {
	display: flex;
	align-items: baseline;
	justify-content: space-between;
	font-size: var( --wp--preset--font-size--small );
	color: var( --wp--preset--color--muted-soft, var( --wp--preset--color--muted ) );
}

.gv-cart-drawer__row--total {
	margin-top: 0.5rem;
	font-family: var( --wp--preset--font-family--display );
	font-size: var( --wp--preset--font-size--x-large );
	color: var( --wp--preset--color--charcoal );
}

.gv-cart-drawer__checkout {
	display: block;
	margin-top: 1rem;
	padding: 0.9rem 1rem;
	border-radius: var( --wp--custom--radius--pill, 999px );
	background: var( --wp--preset--color--charcoal );
	color: var( --wp--preset--color--ivory );
	text-align: center;
	text-decoration: none;
	font-size: var( --wp--preset--font-size--eyebrow );
	letter-spacing: 0.15em;
	text-transform: uppercase;
	transition: background-color 0.2s, color 0.2s;
}

.gv-cart-drawer__checkout:hover {
	background: var( --wp--preset--color--gold );
	color: var( --wp--preset--color--charcoal );
}

@media ( max-width: 480px ) {
	.gv-cart-drawer {
		max-width: 100vw;
	}
}
