/**
 * product.css — the single product page.
 *
 * Pairs with woocommerce/content-single-product.php, which owns the markup and
 * explains why that template exists at all. This file owns the three-column
 * row, the sticky buy rail, and every state the page can be in.
 *
 * THE PAGE IS WHITE AND THE RAIL IS THE SHOP'S LIGHT BLUE. That is the one
 * colour decision here and everything else follows it: the description column
 * sits directly on the canvas with no card, no border and no shadow, so the
 * single tinted box on the page is the one holding the price and the button.
 * Nothing else may take a fill, or the rail stops being the thing the eye lands
 * on.
 *
 * WIDTH AND GUTTER COME FROM base.css. The page container is already capped at
 * --bedi-content-width with --bedi-gutter either side; nothing in this file
 * declares a page measure.
 *
 * MOTION. Every interactive element here has a resting state, a hover, a focus
 * ring and a press — in that order and with the identity value at rest, so a
 * touch device that never hovers gets a control that looks finished. Durations
 * come from motion.css; nothing here invents one. The whole section is undone
 * under prefers-reduced-motion at the end.
 *
 * Sections
 *   1. Layout — head, three columns, the sticky rail
 *   2. The head: title, rating, wishlist
 *   3. The description column
 *   4. The buy rail: price, stock, form, buttons, payment
 *   5. Specifications and help
 *   6. Narrow, reduced motion, forced colours
 */

/* =========================================================================
 * 1. LAYOUT
 * ====================================================================== */

.bedi-product {
	--bedi-prod-rail: #eaf0fa;
	--bedi-prod-radius: var(--bedi-radius-lg);
	/* The header is sticky and ~90px tall plus the utility band; the rail has to
	   clear it or its top row hides under the bar on every scroll. */
	--bedi-prod-rail-top: 112px;

	display: flex;
	flex-direction: column;
	/*
	 * md, not xl. 48px between the breadcrumb, the title and the content read
	 * as three unrelated blocks on a page whose first screen is mostly white —
	 * the client's note was "too big gaps". 24px still separates them clearly
	 * and puts the gallery above the fold.
	 */
	gap: var(--bedi-space-md);
}

/* Woo's breadcrumb sits directly above the title and needs no room of its own
   beyond the stack's gap. */
.bedi-woo .woocommerce-breadcrumb {
	margin-block: 0;
}

/*
 * TWO COLUMNS: EVERYTHING, AND THE RAIL.
 *
 * It was three — gallery, description, rail — with the specifications and the
 * help section full width underneath. That unstuck the rail the moment the
 * visitor reached the spec table, which is exactly where the price and the
 * button are most needed.
 *
 * So the left column now holds the whole product and the rail runs the full
 * height beside it. `align-items: start` is what allows sticky to work at all:
 * the default `stretch` makes the rail as tall as the column next to it, and an
 * element that is already the height of its container has nothing to stick
 * within.
 *
 * The rail is a fixed 368px rather than a fraction. A price, a quantity box and
 * two buttons need about that and stop improving after it; at `1fr` it grew to
 * 500px on a wide screen while the column that has something to say got the
 * same.
 */
.bedi-product__layout {
	align-items: start;
	display: grid;
	gap: var(--bedi-space-lg);
	grid-template-columns: minmax(0, 1fr) 368px;
}

/* The left column: gallery + description on one row, then the spec table and
   the help section stacked under them. */
.bedi-product__body {
	display: flex;
	flex-direction: column;
	gap: var(--bedi-space-lg);
	min-inline-size: 0;
}

.bedi-product__top {
	display: grid;
	gap: var(--bedi-space-lg);
	grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
}

.bedi-product__buy {
	position: sticky;
	inset-block-start: var(--bedi-prod-rail-top);
	min-inline-size: 0;
}

.bedi-product__buy-inner {
	display: flex;
	flex-direction: column;
	gap: var(--bedi-space-sm);
}

.bedi-product__gallery,
.bedi-product__summary {
	min-inline-size: 0;
}

/* =========================================================================
 * 2. THE HEAD
 * ====================================================================== */

.bedi-product__head {
	align-items: start;
	column-gap: var(--bedi-space-md);
	display: flex;
	flex-wrap: wrap;
	justify-content: space-between;
	row-gap: var(--bedi-space-2xs);
}

.bedi-product__head-text {
	flex: 1 1 24rem;
	min-inline-size: 0;
}

/*
 * The title is Woo's own `.product_title`, so it is selected by that rather
 * than re-classed — a plugin that replaces the title template still produces
 * an element with this class and still gets the right type.
 */
.bedi-product .product_title {
	font-family: var(--bedi-font-display);
	font-size: var(--bedi-text-3xl);
	font-weight: var(--bedi-weight-bold);
	line-height: 1.25;
	margin: 0;
	text-wrap: balance;
}

/*
 * The head's wishlist button moved into the rail's Save/Share pair
 * (product-buy.css section 7). Two wishlist controls on one page, forty pixels
 * apart and in two different visual languages, was the actual bug.
 */

/* =========================================================================
 * 3. THE DESCRIPTION COLUMN
 * ====================================================================== */

.bedi-product__section-title {
	font-family: var(--bedi-font-display);
	font-size: var(--bedi-text-xl);
	font-weight: var(--bedi-weight-bold);
	margin: 0 0 var(--bedi-space-2xs);
}

.bedi-product__sku {
	color: var(--bedi-ink-muted);
	font-size: var(--bedi-text-base);
	margin: 0 0 var(--bedi-space-sm);
}

.bedi-product__sku-label {
	color: var(--bedi-accent);
	font-weight: var(--bedi-weight-medium);
}

.bedi-product__sku-value {
	color: var(--bedi-ink);
}

/*
 * THE FULL DESCRIPTION. It replaced the excerpt (see the template), so it is
 * arbitrary editor content — paragraphs, lists, sometimes a bare stack of
 * <p> tags one line each, which is what this catalogue's imported copy looks
 * like. The tightened margin is for exactly that case: at the theme's default
 * paragraph spacing a spec sheet imported as fifteen one-line paragraphs became
 * a column three screens tall.
 */
.bedi-product__description {
	color: var(--bedi-ink-muted);
	font-size: var(--bedi-text-base);
	line-height: 1.6;
}

.bedi-product__description p {
	margin-block: 0 var(--bedi-space-2xs);
}

.bedi-product__description p:last-child,
.bedi-product__description ul:last-child {
	margin-block-end: 0;
}

.bedi-product__description ul,
.bedi-product__description ol {
	margin-block: 0 var(--bedi-space-2xs);
	padding-inline-start: var(--bedi-space-sm);
}

/*
 * NO HEIGHT CAP AND NO INNER SCROLLER ON THIS COLUMN.
 *
 * A previous pass capped it at 26rem with `overflow-y: auto` and
 * `overscroll-behavior-y: contain`, to stop a long imported description driving
 * the row's height. It worked and it was wrong: the description is the widest
 * target on the upper half of the page, so a wheel gesture anywhere over the
 * copy scrolled the box instead of the page, and `contain` stopped the scroll
 * chaining out once the box hit its end. The page simply refused to move.
 *
 * The row is allowed to be as tall as the copy. The gallery beside it sits at
 * the top of its cell, which is the correct place for it, and the buy rail is
 * sticky precisely so a long column costs the visitor nothing.
 */

/*
 * Woo prints the SKU and the category list again at priority 40. Both are
 * already on the page — the SKU above, the categories in the breadcrumb — so
 * the duplicate is hidden rather than removed, because remove_action() there
 * would also take out anything a plugin appended to the same callback.
 */
.bedi-product .product_meta {
	display: none;
}

/*
 * The assurance list that lived here moved into the buy rail's trust group
 * (product-buy.css section 8) — beside the button, where reassurance is
 * actually consumed, rather than under a description most visitors never
 * scroll to.
 */
/* =========================================================================
 * 4. THE BUY RAIL
 *
 * MOVED, IN FULL, TO assets/css/product-buy.css. The rail is a component group
 * with its own tokens, its own keyframes and its own forced-colors contract,
 * and it is the part of this page most likely to be reworked again — keeping
 * half of it here is how the next edit lands in the wrong file.
 *
 * One rule stayed behind with it and is worth knowing about: Woo echoes
 * wc_get_stock_html() BEFORE it opens <form class="cart">, so that element is a
 * SIBLING of the form rather than a descendant and `form.cart .stock` silently
 * matches nothing. The child-combinator rule that hides it lives in
 * product-buy.css section 1.
 * ====================================================================== */

/* =========================================================================
 * 5. SPECIFICATIONS AND HELP
 * ====================================================================== */

.bedi-product__section-heading {
	font-family: var(--bedi-font-display);
	font-size: var(--bedi-text-2xl);
	font-weight: var(--bedi-weight-bold);
	margin: 0 0 var(--bedi-space-md);
}

.bedi-product__detail,
.bedi-product__help {
	border-block-start: var(--bedi-border-width) solid var(--bedi-rule);
	padding-block-start: var(--bedi-space-lg);
}

/*
 * Woo's tab headings are hidden, not removed. The specification part below them
 * IS the "additional information" tab's content in a better form, and the
 * section already has its own heading; removing the tab callback instead would
 * take out any tab a plugin registered — a reviews tab, a shipping tab — which
 * a customer may well want.
 */
.bedi-product .woocommerce-tabs ul.tabs {
	display: none;
}

.bedi-product .woocommerce-tabs .panel > h2:first-child {
	display: none;
}

.bedi-product__help-list {
	display: flex;
	flex-direction: column;
	gap: var(--bedi-space-2xs);
}

/*
 * <details>/<summary>, so the disclosure semantics, the keyboard handling and
 * the expanded-state announcement are the browser's. The only thing scripted
 * about this accordion is nothing.
 */
.bedi-product__faq {
	border-block-end: var(--bedi-border-width) solid var(--bedi-rule);
	padding-block-end: var(--bedi-space-2xs);
}

/*
 * BLACK AND BOLD WHILE CLOSED, ACCENT ONCE OPEN.
 *
 * Every question used to be accent blue at medium weight, which made a stack
 * of them read as a list of links — five or six blue lines competing with the
 * actual links on the page — and the thin weight made them look secondary to
 * their own answers. Closed, a question is a heading: ink, bold. Open, it
 * takes the accent, because then the colour is carrying state rather than
 * decorating a list.
 */
.bedi-product__faq-q {
	align-items: center;
	color: var(--bedi-ink);
	column-gap: var(--bedi-space-2xs);
	cursor: pointer;
	display: flex;
	font-family: var(--bedi-font-display);
	font-size: var(--bedi-text-lg);
	font-weight: var(--bedi-weight-bold);
	list-style: none;
	padding-block: var(--bedi-space-3);
	transition: color var(--bedi-dur) var(--bedi-ease-out);
}

.bedi-product__faq[open] > .bedi-product__faq-q {
	color: var(--bedi-accent-strong);
}

/* Safari still draws its own disclosure triangle without this. */
.bedi-product__faq-q::-webkit-details-marker {
	display: none;
}

.bedi-product__faq-q:hover {
	color: var(--bedi-accent-strong);
}

/*
 * A drawn plus/minus rather than a rotated chevron: two 2px bars, one of which
 * scales to zero when the section opens. It reads as "expand / collapse"
 * without the 180-degree spin that every other accordion on the web uses.
 */
.bedi-product__faq-mark {
	block-size: 14px;
	flex: none;
	inline-size: 14px;
	position: relative;
}

.bedi-product__faq-mark::before,
.bedi-product__faq-mark::after {
	background-color: currentColor;
	border-radius: 2px;
	content: "";
	inset-block-start: 50%;
	inset-inline-start: 0;
	block-size: 2px;
	inline-size: 100%;
	position: absolute;
	transition: transform var(--bedi-dur) var(--bedi-ease-out);
}

.bedi-product__faq-mark::before {
	transform: translateY(-50%);
}

.bedi-product__faq-mark::after {
	transform: translateY(-50%) rotate(90deg);
}

.bedi-product__faq[open] .bedi-product__faq-mark::after {
	transform: translateY(-50%) rotate(90deg) scaleX(0);
}

/*
 * The answer slides in. `details` content cannot be transitioned — it is
 * display-toggled — so this is an ANIMATION on the panel, which starts the
 * frame the element is laid out.
 */
.bedi-product__faq[open] .bedi-product__faq-a {
	animation: bedi-faq-in var(--bedi-dur-lg) var(--bedi-ease-out) both;
}

/*
 * THE HEIGHT ITSELF, WHERE THE BROWSER WILL ANIMATE IT.
 *
 * The rule above fades and slides the answer, and that was never the part that
 * felt wrong: the PANEL's height still jumped from nothing to its full size in
 * one frame, so the questions below it snapped down while the text was still
 * fading in. Two different speeds in one gesture is what reads as unfinished.
 *
 * ::details-content is the box <details> lays its content into, and it can be
 * transitioned — which was not true when this accordion was written.
 * `interpolate-size: allow-keywords` is what lets `auto` be an animatable
 * height; without it the transition has no end value to reach and does
 * nothing. `content-visibility` rides along with allow-discrete so the content
 * is not clipped out before the box has finished closing.
 *
 * Behind @supports, so a browser without it keeps exactly what it has now
 * rather than losing the disclosure entirely.
 */
@supports selector(::details-content) {
	.bedi-product__faq {
		interpolate-size: allow-keywords;
	}

	.bedi-product__faq::details-content {
		block-size: 0;
		overflow: hidden;
		transition:
			block-size var(--bedi-dur-lg) var(--bedi-ease-out),
			content-visibility var(--bedi-dur-lg) var(--bedi-ease-out) allow-discrete;
	}

	.bedi-product__faq[open]::details-content {
		block-size: auto;
	}
}

.bedi-product__faq-a {
	color: var(--bedi-ink-muted);
	font-size: var(--bedi-text-base);
	line-height: 1.65;
	padding-block: var(--bedi-space-2xs) var(--bedi-space-sm);
	padding-inline-start: calc(14px + var(--bedi-space-2xs));
}

.bedi-product__faq-a p {
	margin-block: 0 var(--bedi-space-2xs);
}

.bedi-product__faq-a p:last-child,
.bedi-product__faq-a ul:last-child {
	margin-block-end: 0;
}

.bedi-product__faq-a ul {
	margin-block: 0 var(--bedi-space-2xs);
	padding-inline-start: var(--bedi-space-sm);
}

.bedi-product__faq-a li {
	margin-block-end: 6px;
}

@keyframes bedi-faq-in {
	from {
		opacity: 0;
		transform: translateY(-6px);
	}

	to {
		opacity: 1;
		transform: none;
	}
}

/* =========================================================================
 * 5b. RELATED AND UPSELL PRODUCTS — full width, six across
 *
 * Both were unhooked from woocommerce_after_single_product_summary in
 * src/Woo.php and are called by the template below the two columns, because a
 * six-across row does not fit in the left column.
 *
 * THE GRID IS OVERRIDDEN HERE RATHER THAN LEFT TO woo.css. That file steps
 * `ul.products` 1 → 2 → 3 → 4 across its breakpoints, which is right for an
 * archive where each tile is a browsing target. These tiles are a footnote to
 * the product above them, so they go narrower and denser — six of them in the
 * space woo.css would give four.
 *
 * The `.bedi-product__more` ancestor is what makes that safe: it raises the
 * specificity above woo.css's own `.woocommerce ul.products` and scopes the
 * override to this band, so no archive is affected.
 * ====================================================================== */

.bedi-product__more:empty {
	display: none;
}

.bedi-product__more .related,
.bedi-product__more .upsells {
	border-block-start: var(--bedi-border-width) solid var(--bedi-rule);
	margin-block-start: var(--bedi-space-lg);
	padding-block-start: var(--bedi-space-lg);
}

.bedi-product__more > :first-child {
	border-block-start: 0;
	margin-block-start: 0;
	padding-block-start: 0;
}

.bedi-product__more h2 {
	font-family: var(--bedi-font-display);
	font-size: var(--bedi-text-2xl);
	font-weight: var(--bedi-weight-bold);
	margin: 0 0 var(--bedi-space-md);
}

.bedi-product__more .woocommerce ul.products,
.bedi-product__more ul.products {
	display: grid;
	gap: var(--bedi-space-lg) var(--bedi-space-md);
	grid-template-columns: repeat(6, minmax(0, 1fr));
	list-style: none;
	margin: 0;
	padding: 0;
}

/*
 * Six across on a 1280px band is a 190px tile, which is too narrow for the
 * card's price row and its button side by side. The steps below are sized to
 * the tile rather than to the device: 6 → 4 → 3 → 2, and never 1, because a
 * single related product stacked full width reads as the page starting over.
 */
@media (max-width: 71.9375em) {
	.bedi-product__more .woocommerce ul.products,
	.bedi-product__more ul.products {
		grid-template-columns: repeat(4, minmax(0, 1fr));
	}
}

@media (max-width: 55.9375em) {
	.bedi-product__more .woocommerce ul.products,
	.bedi-product__more ul.products {
		grid-template-columns: repeat(3, minmax(0, 1fr));
	}
}

@media (max-width: 35.9375em) {
	.bedi-product__more .woocommerce ul.products,
	.bedi-product__more ul.products {
		gap: var(--bedi-space-md) var(--bedi-space-2xs);
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}
}

/* =========================================================================
 * 6. NARROW, REDUCED MOTION, FORCED COLOURS
 * ====================================================================== */

/*
 * TWO COLUMNS AT TABLET: gallery and rail side by side, description full width
 * beneath. The rail keeps its sticky behaviour — the page is still long — but
 * the description is the thing that needs the width back first.
 */
@media (max-width: 71.9375em) {
	/*
	 * 312, not 290. Between 64em and 72em the quantity row is still side by
	 * side — it only stacks below 64em — and at 290px the content box is 242px,
	 * which is the label's 96px plus the stepper's 146px and NOTHING between
	 * them. 312 gives the row a real gap instead of a collision.
	 */
	.bedi-product__layout {
		grid-template-columns: minmax(0, 1fr) 312px;
	}

	/* The gallery and the description stop sharing a row before the rail
	   drops: two 250px columns is narrower than either of them wants. */
	.bedi-product__top {
		grid-template-columns: minmax(0, 1fr);
	}

}

@media (max-width: 47.9375em) {
	.bedi-product__layout {
		grid-template-columns: minmax(0, 1fr);
	}

	/*
	 * STICKY IS SWITCHED OFF ON A PHONE. A sticky rail in a single-column stack
	 * is just a box that refuses to scroll with its neighbours, and on a short
	 * viewport it would pin the price over the gallery the whole way down the
	 * page.
	 */
	.bedi-product__buy {
		position: static;
	}

	/*
	 * THE PHONE ORDER IS: TITLE, GALLERY, PRICE, THEN THE READING.
	 *
	 * It used to be title, price, gallery — the rail hoisted whole above the
	 * body. The client asked for the picture to come second, and they are
	 * right: on a phone the title names the thing and the photograph confirms
	 * it, and confirming it is what a shopper does before caring what it costs.
	 *
	 * The gallery is nested two levels inside `.bedi-product__body`, so no
	 * amount of `order` on the body could lift it past the rail — the two were
	 * never siblings. `display: contents` dissolves the two wrapper divs at
	 * this width so their children become grid items of the layout itself, and
	 * THEN `order` can sequence all six regions against each other.
	 *
	 * The wrappers are plain divs carrying no semantics, which is the case
	 * where `display: contents` is safe; it is not used on anything that has a
	 * role to lose.
	 *
	 * Those wrappers also supplied their own gaps, which dissolve with them —
	 * `.bedi-product__layout`'s gap takes over for every region, which is why
	 * the rhythm stays even rather than inheriting three different spacings.
	 */
	.bedi-product__body,
	.bedi-product__top {
		display: contents;
	}

	.bedi-product__gallery     { order: 1; }
	.bedi-product__buy         { order: 2; }
	.bedi-product__summary     { order: 3; }
	.bedi-product__description { order: 4; }
	.bedi-product__detail      { order: 5; }
	.bedi-product__help        { order: 6; }

	/*
	 * 16px, down from 24px. These titles are specification strings rather than
	 * names — "– Apacer AH5U32G68C6429BAA-2 DDR5 DIMM 6800-36 2048x8 32GB 1.4V
	 * OC Panther RGB DDR5 w/" — and at 24px one of them fills a phone screen
	 * before the photograph has been reached. At 16px the same string is three
	 * lines instead of six and the product is visible without scrolling.
	 */
	/*
	 * (0,4,1), BECAUSE woo.css IS AT (0,3,1).
	 *
	 * woo.css ships `.woocommerce div.product .product_title` with a fluid
	 * `clamp(1.375rem, 1.1rem + 1.2vw, 1.875rem)`, which resolves to 22.1px at
	 * 375px. The first version of this override was `.bedi-product
	 * .product_title` at (0,2,0) and lost outright — the rule parsed, matched,
	 * and did nothing, which is exactly the failure that is hardest to spot
	 * because the declaration looks right in the file.
	 *
	 * These titles are specification strings rather than names — "– Apacer
	 * AH5U32G68C6429BAA-2 DDR5 DIMM 6800-36 2048x8 32GB 1.4V OC Panther RGB
	 * DDR5 w/" — and at 22px that one fills a phone screen before the
	 * photograph is reached. 16px turns six lines into four and puts the
	 * product in view without scrolling.
	 */
	.woocommerce div.product .bedi-product .product_title,
	.bedi-product.woocommerce div.product .product_title,
	.woocommerce div.product.bedi-product .product_title,
	.bedi-product .product_title {
		font-size: 16px;
		line-height: 1.35;
	}

}

@media (prefers-reduced-motion: reduce) {
	.bedi-product__faq-q,
	.bedi-product__faq-mark::before,
	.bedi-product__faq-mark::after {
		transition-duration: 1ms !important;
	}

	.bedi-product__faq[open] .bedi-product__faq-a {
		animation: none !important;
	}

	/*
	 * The plus/minus still has to change, or an open section looks shut. Only
	 * the transition is removed; the scaleX stays.
	 */
}

@media (forced-colors: active) {
	/*
	 * The rail's own forced-colors contract moved to product-buy.css with the
	 * component it belongs to. What is left here is the page, not the rail.
	 */
	.bedi-product__faq {
		border: 1px solid ButtonText;
	}
}
