/* Buttercup Childcare - shop catalogue layout.
 *
 * The catalogue markup is generated in shop.php rather than by Oxygen, so its
 * styling ships with the plugin instead of the Oxygen stylesheet. Everything
 * here is scoped to the .bc-shop-* / .bc-product classes that shop.php emits.
 * Design tokens come from the Oxygen variables sheet (variables.css).
 */

/* --- INK HEADINGS (W9-INK-HEADINGS, 27 Aug 2026) -----------------------
 *
 * John's call, 27/08: "ink is fine, keep it consistent". Every heading in the
 * commerce flow is now ink, matching the cart and the checkout and matching
 * the rest of the site.
 *
 * WHY THIS WAY ROUND. Measured at 1440 before the change: the page title is
 * 46px centred on every page, but only /book-with-buttercup, the
 * /product-category/ archives and the single product page were
 * rgb(244,136,71) - /creche, /fees, /about-buttercup-childcare, /cart,
 * /checkout and the rest were already ink. Orange was the minority. It is
 * also the failing option: accent on white is 2.48:1, which fails WCAG AA
 * both at 4.5:1 for body text and at 3:1 for large text, while ink on white
 * is 16.13:1.
 *
 * THIS IS A DELIBERATE DEPARTURE FROM LIVE, WHICH SETS ITS SHOP AND PRODUCT
 * TITLES IN ORANGE. It is the one place the like-for-like rule is broken on
 * purpose, and it is John's decision, not an oversight - it needs naming to
 * Georgina rather than leaving for her to spot.
 *
 * What changed here: .bc-archive-title, .bc-product-title, and the shop's own
 * H1 (which is an Oxygen element carrying .bc-heading-accent, overridden
 * below rather than by editing that shared class - .bc-heading-accent is also
 * "Our Services" and "Shop our Services" on the home page, the /fees section
 * heading and the /camps booking heading, none of which are in scope).
 * The single product page's H1 is not here at all: its colour is set on the
 * Woo element's own design properties (build/style-woo-elements.py, node 106
 * of oxygen_template 345), because styling a woo element through its internal
 * classes fights its own generated CSS.
 *
 * NOT CHANGED, ON PURPOSE: .bc-btn stays white on accent orange (2.48:1) -
 * that is a separate open decision for John and this pass is heading text
 * only. The footer's white-on-orange section headings are the same open
 * question and are chrome, not commerce.
 */

/* The shop's own H1, "Purchase and Book".
 *
 * It is an Oxygen text element carrying .bc-heading-accent .bc-page-h1, so it
 * is matched by the grid it sits above rather than by a page id - the same
 * hook the 767 rule below already uses. The extra specificity is needed
 * because shop.css is enqueued ahead of the Oxygen selector sheet;
 * body:has(.bc-shop-grid) h1.bc-page-h1 is (0,2,2) against
 * .bc-heading-accent's (0,1,0), so it wins on either order.
 *
 * :has(.bc-shop-grid) is true on /book-with-buttercup and on the
 * /product-category/ archives, and on nothing else - /camps builds its own
 * .bc-camp markup, and the related-products grid on a product page is
 * WooCommerce's .products. The archives do not carry .bc-page-h1 anyway. */
body:has(.bc-shop-grid) h1.bc-page-h1 {
	color: var(--bc-ink);
}

/* --- section jump nav ------------------------------------------------- */

.bc-shop-nav {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 10px 12px;
	margin: 0 0 46px;
	padding-bottom: 24px;
	border-bottom: 1px solid var(--bc-line);
}

.bc-shop-nav-label {
	font-family: var(--bc-font);
	font-size: 15px;
	font-weight: 500;
	color: var(--bc-muted);
}

.bc-shop-nav-link {
	display: inline-block;
	font-family: var(--bc-font);
	font-size: 15px;
	font-weight: 400;
	line-height: 1;
	color: var(--bc-ink);
	text-decoration: none;
	padding: 10px 17px;
	border: 1px solid var(--bc-line);
	border-radius: 999px;
	transition: background-color 0.2s ease, border-color 0.2s ease, color 0.2s ease;
}

.bc-shop-nav-link:hover,
.bc-shop-nav-link:focus-visible {
	color: var(--bc-white);
	background-color: var(--bc-accent);
	border-color: var(--bc-accent);
}

/* --- one category section --------------------------------------------- */

.bc-shop-cat {
	margin: 0 0 66px;
	scroll-margin-top: 110px;
}

.bc-shop-cat:last-child {
	margin-bottom: 0;
}

.bc-shop-cat-title {
	font-family: var(--bc-font);
	font-size: var(--bc-h3);
	font-weight: 500;
	line-height: 1.2;
	color: var(--bc-ink);
	text-wrap: balance;
	margin: 0 0 12px;
}

.bc-shop-cat-intro {
	font-family: var(--bc-font);
	font-size: var(--bc-body);
	font-weight: 300;
	line-height: 1.6;
	color: var(--bc-muted);
	text-wrap: pretty;
	max-width: 780px;
	margin: 0 0 32px;
}

/* --- a category archive page ------------------------------------------
       Same section markup as the shop, but the category name is the page
       heading rather than one heading among many, so it steps up a size. */

/* The /product-category/ archive heading.
 *
 * G24: this used to be 46px dark, left, line-height 55.2 while the shop's own
 * H1 was 46px orange, centred, line-height 64.4 - so a visitor following a
 * jump-nav pill landed on a page whose title did not match the one they left.
 * Live sets one treatment for both (its 'nested-category-title' measures
 * 46.07px rgb(244,136,71) centred at 1440), so this matches .bc-page-h1.
 *
 * W9-INK-HEADINGS (27 Aug 2026): colour is now ink, not the accent - see the
 * INK HEADINGS note at the head of this file for the decision and the
 * measurements. Everything else about the treatment is unchanged. */

.bc-archive-title {
	font-size: var(--bc-h2);
	line-height: 1.4;
	color: var(--bc-ink);
	text-align: center;
	margin-bottom: 26px;
}

.bc-archive-back {
	margin: 46px 0 0;
}

/* --- a sub-group inside a section (camp weeks, the childcare that goes
       with them, registration deposits, gift vouchers) ------------------- */

.bc-shop-sub {
	margin: 0 0 44px;
}

.bc-shop-sub:last-child {
	margin-bottom: 0;
}

.bc-shop-sub-title {
	font-family: var(--bc-font);
	font-size: var(--bc-h4);
	font-weight: 500;
	line-height: 1.25;
	color: var(--bc-ink);
	text-wrap: balance;
	margin: 0 0 8px;
}

.bc-shop-sub-intro {
	font-family: var(--bc-font);
	font-size: 16px;
	font-weight: 300;
	line-height: 1.6;
	color: var(--bc-muted);
	text-wrap: pretty;
	max-width: 780px;
	margin: 0 0 22px;
}

.bc-shop-sub-title + .bc-shop-grid,
.bc-shop-sub-intro + .bc-shop-grid {
	margin-top: 22px;
}

/* --- the product grid -------------------------------------------------- */

.bc-shop-grid {
	display: grid;
	grid-template-columns: repeat(4, minmax(0, 1fr));
	gap: 30px;
	align-items: stretch;
}

/* The /product-category/ archives run inside the 1015 measure rather than the
   shop's 1354 band. Four columns there would be 231px cells against live's
   316.8, which squeezes the 25.85px title into four ragged lines; three columns
   is 318.3px, so the card is the same object on both pages. Below 1200 the
   breakpoints take over and the two grids behave identically. */

.bc-shop-grid-sm {
	grid-template-columns: repeat(3, minmax(0, 1fr));
}

/* One card.
 *
 * Live has no card chrome at all: the image is flush and fills a 1:1 cell, the
 * title is the orange accent at 25.85px, the price is plain dark body text, and
 * the whole card is a single link. Measured on the live shop at 1440: cell
 * 316.8, image 316.8x316.8 object-fit cover, title 25.85/37.74 rgb(244,136,71),
 * price 17.38/18.08 near-black weight 300 with an 8px gap, and 21.6px (1.5vw)
 * between the image and the title.
 *
 * The rebuild previously wrapped this in a bordered white card with the image
 * inset in a grey well, a navy title, an orange price and a separate
 * "View and book" button. That button is gone on purpose. It duplicated the
 * link the card already is (two links to the same URL in every cell), it is not
 * on live, and the site-wide button scale-up being applied elsewhere would have
 * grown it by another ~40px per card and pushed the grid well past live's
 * height. Removing it makes the click target bigger, not smaller: the whole
 * ~440px card is now the target instead of a 278x44 button.
 */

.bc-product {
	display: flex;
	flex-direction: column;
}

.bc-product-link {
	display: flex;
	flex-direction: column;
	color: inherit;
	text-decoration: none;
}

.bc-product-img {
	display: block;
	aspect-ratio: 1 / 1;
	overflow: hidden;
}

.bc-product-img img {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
	transition: transform 0.35s ease;
}

.bc-product-link:hover .bc-product-img img,
.bc-product-link:focus-visible .bc-product-img img {
	transform: scale(1.04);
}

/* W9-INK-HEADINGS: ink, not the accent. The card title is an <h2>/<h3>/<h4>
   and it is the same object as the related-products card title on the single
   product page, which WooCommerce already renders near-black - so the shop
   grid was the odd one out inside its own flow. The accent is kept as the
   hover/focus colour, which is where it earns its keep: it is the click cue,
   and a transient state is not held to the 4.5:1 bar the resting text is. */
.bc-product-title {
	font-family: var(--bc-font);
	font-size: var(--bc-h4);
	font-weight: 500;
	line-height: 1.46;
	color: var(--bc-ink);
	text-align: left;
	text-wrap: balance;
	/* 1.5vw on live, capped so it stops growing past the 1440 shell. */
	margin: min(1.5vw, 22px) 0 0;
	transition: color 0.2s ease;
}

.bc-product-link:hover .bc-product-title,
.bc-product-link:focus-visible .bc-product-title {
	color: var(--bc-accent-dark);
}

.bc-product-price {
	display: block;
	font-family: var(--bc-font);
	font-size: var(--bc-body);
	font-weight: 300;
	line-height: 1.04;
	color: var(--bc-ink);
	text-align: left;
	margin: 8px 0 0;
}

.bc-product-price .woocommerce-Price-amount {
	white-space: nowrap;
}

/* --- breakpoints ------------------------------------------------------- */

@media (max-width: 1199px) {
	.bc-shop-grid {
		grid-template-columns: repeat(3, minmax(0, 1fr));
		gap: 26px;
	}
}

@media (max-width: 899px) {
	.bc-shop-grid {
		grid-template-columns: repeat(2, minmax(0, 1fr));
		gap: 22px;
	}

	.bc-shop-cat {
		margin-bottom: 50px;
	}

	.bc-shop-sub {
		margin-bottom: 36px;
	}
}

@media (max-width: 767px) {
	/* G16: live left-aligns the shop title below its md breakpoint - measured
	   34.79px orange at x=23.39 against our centred 35px at x=20. The shop
	   heading is an Oxygen element rather than ours, so it is matched by the
	   grid it sits above rather than by a page id, and it needs the extra
	   specificity because shop.css is enqueued ahead of the Oxygen selector
	   sheet. The archive heading follows it, per G24. */
	body:has(.bc-shop-grid) h1.bc-page-h1 {
		text-align: left;
	}

	/* Compound selector: the 559 block below re-sizes .bc-shop-cat-title, which
	   the archive heading also carries, and a bare .bc-archive-title would lose
	   to it on source order. */
	.bc-shop-cat-title.bc-archive-title {
		font-size: 35px;
		text-align: left;
		margin-bottom: 22px;
	}
}

@media (max-width: 559px) {
	.bc-shop-grid {
		grid-template-columns: minmax(0, 1fr);
		gap: 18px;
	}

	.bc-shop-nav {
		margin-bottom: 34px;
		padding-bottom: 20px;
	}

	.bc-shop-cat-title {
		font-size: 30px;
	}

	.bc-shop-sub-title {
		font-size: 22px;
	}

	/* Live keeps the 1:1 crop on one-per-row mobile (measured 343.22 square
	   at 390) and steps the title down to 22.16px. */
	.bc-product-title {
		font-size: 22px;
		line-height: 1.46;
	}
}

/* --- the single product page -------------------------------------------
 *
 * The card-composition fix that landed on the grid never reached the single
 * product template (findings-final-2, S2). Measured on the live product pages
 * (/book-with-buttercup/p/summer-camp, /p/registration-deposit,
 * /p/gift-vouchers-1) on 21 Aug 2026, and identical on all three:
 *
 *              1440                          390
 *   band       1354 (43px page inset)        343 (23.4px inset)
 *   gallery    676.81 x 902.41, cover        343.22 x 457.63, cover
 *   H1         46.07 / 67.26 rgb(244,136,71) 34.79 / 50.80, same orange
 *   price      25.85 / 37.74 rgb(0,0,0)      22.16 / 32.35, black
 *   cart row   [quantity][Add To Cart 490]   [quantity][Add To Cart 208]
 *
 * Ours had the title and price colours INVERTED (dark title, orange price -
 * the exact fault fixed on the grid cards), the gallery letterboxed with
 * object-fit: contain inside a 484 x 400 grey well, and a 146 x 47 WooCommerce
 * default button.
 *
 * The type, colour and button geometry are set on the Oxygen elements
 * themselves (title, price and cart button all expose real design controls,
 * and styling a Woo element through its internal classes fights its own
 * generated CSS). What is left here is the layout the elements cannot express:
 * the column split, the gallery frame, and the cart row.
 *
 * WHY THIS IS IN shop.css AND NOT build/shop-system.css: the Oxygen stylesheet
 * was locked by another agent during this change, so these rules are written
 * as descendant selectors under .bc-product-page (0,2,0 and up) that outrank
 * the single-class rules in shop-system.css. When the lock lifts, the
 * .bc-product-grid / .bc-product-gallery / .bc-product-summary rules in
 * shop-system.css should be reconciled with these and this block dropped.
 *
 * STILL NOT FOLDED IN AS OF 27 AUG 2026 (W9-CART-CHECKOUT), AND THE REASON IS
 * THE SAME LOCK. build/shop-system.css is not a file the site reads: it only
 * reaches staging through build/push-css.py, which is a single call to
 * `oxygen-insert-stylesheet`. That tool is still held. Editing the local file
 * without pushing it would be worse than leaving this here - the repo would
 * then disagree with the site, and the next agent would have no way to tell
 * which of the two was the truth.
 *
 * The fold is three steps and needs the lock, not judgement:
 *   1. in build/shop-system.css, merge each rule below into its single-class
 *      equivalent - .bc-product-grid takes `grid-template-columns:
 *      minmax(0,50%) minmax(0,1fr)` and `gap: 28.8px` (and the 1023 block
 *      takes one column at 30px); .bc-product-gallery takes `aspect-ratio:
 *      3/4`, `background-color: transparent`, `border-radius: 0`;
 *      .bc-product-summary takes `align-items: stretch` in place of
 *      flex-start. Remember the importer REPLACES a selector's rule per
 *      breakpoint, so each must be restated complete.
 *   2. `python build/push-css.py shop-system.css`.
 *   3. delete this whole block from shop.css, keeping ONLY the four rules that
 *      have no single-class home and cannot get one: the .bde-swiper /
 *      .bde-swiper__slide height and object-fit rules, `form.cart >
 *      .bc-child-fields`, `.bde-wooproductprice p.price`, and
 *      `.bde-tabs__panel-content` - all of which target markup WooCommerce
 *      generates rather than a class we set, so they have to stay descendants.
 *      Then re-verify against the live measurements tabulated above.
 *
 * The product page was re-measured on 27 Aug against those figures and had not
 * moved (qa/w9cart/before-measure.txt vs after-measure.txt are byte-identical
 * over the shop and product blocks), so this block is doing its job as it is.
 */

/* Live runs the product page in the same 1354 band as the shop, split 50 / 48.
   The template's shell class is .bc-shell-wide (set on the Oxygen tree); this
   only fixes the split, which shop-system.css has as a 1fr 1fr / 48px grid and
   which would put the gallery 24px under live's 676.81. */
.bc-product-page .bc-product-grid {
	grid-template-columns: minmax(0, 50%) minmax(0, 1fr);
	gap: 28.8px;
}

/* The gallery frame. Live is a flush 3:4 portrait filled with object-fit:
   cover and no chrome at all - no background, no radius, no letterbox. */
.bc-product-page .bc-product-gallery {
	aspect-ratio: 3 / 4;
	background-color: transparent;
	border-radius: 0;
}

.bc-product-page .bc-product-gallery .bde-swiper,
.bc-product-page .bc-product-gallery .swiper,
.bc-product-page .bc-product-gallery .swiper-wrapper,
.bc-product-page .bc-product-gallery .bde-swiper-slide,
.bc-product-page .bc-product-gallery .bde-swiper__slide {
	height: 100%;
}

.bc-product-page .bc-product-gallery .bde-swiper__slide img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	object-position: 50% 50%;
}

/* The summary column stretches its children so the cart row can fill it.
   shop-system.css sets align-items: flex-start, which shrink-wrapped the
   add-to-cart form to 360px inside a 484px column. */
.bc-product-page .bc-product-summary {
	align-items: stretch;
}

/* The cart row, as live composes it: the quantity stepper at its natural
   width, then Add To Cart taking everything that is left. The row itself is
   the cart element's own flex form - width, the 20px gap and the button's
   flex-grow are set on the Oxygen element, not here. All this does is keep the
   child-details fieldset on a line of its own above that row; it is our own
   markup, injected by the buttercup-childcare-fields plugin, so it has no
   flex sizing of its own and would otherwise share the row with the quantity
   stepper once the column grew to live's 648px. */
.bc-product-page form.cart > .bc-child-fields {
	flex: 0 0 100%;
	width: 100%;
}

/* The price element sets its type on the <bdi> inside the amount, so the
   paragraph around it keeps WooCommerce's 1.2 line box and the price block
   comes out 31.02px tall against live's 37.73. Nothing generated sets a
   line-height here, so this is an addition rather than an override. */
.bc-product-page .bde-wooproductprice p.price {
	line-height: 1.46;
}

/* The description and reviews sit below the fold in a 1354 band, which is far
   too long a measure for body copy. 780px is the measure the shop intros use. */
.bc-product-page .bde-tabs__panel-content {
	max-width: 780px;
}

@media (max-width: 1023px) {
	/* shop-system.css already drops the grid to one column here; the gallery
	   keeps live's 3:4 crop full-bleed across the column. */
	.bc-product-page .bc-product-grid {
		grid-template-columns: minmax(0, 1fr);
		gap: 30px;
	}
}

/* --- FLOW-ONLY PRODUCTS (W12-F8 / W12-F6, 1 Sep 2026) -------------------
 *
 * The four camp weeks and the four Full Day Care weeks. Their price is
 * rendered by booking-products.php as one line per rate, each with its unit
 * spelled out, because Full Day Care is charged per ticked day and a bare
 * number reads as a week. Camp has one line, Full Day Care has two.
 *
 * These rules only ever apply where that filter has run, so they cannot reach
 * the deposits, the gift voucher or the jersey.
 */

/* `flex: 0 0 100%` is not decoration. The single product page renders the
   price through Breakdance's WooProductPrice element, whose <p class="price
   price--stackable"> is display:flex / flex-wrap:wrap, so two block spans
   become two flex items on ONE row and Full Day Care read
   "EUR 48.50 per full day, 9 hoursEUR 28.50 per half day, 5 hours".
   Claiming the whole line puts each rate back on its own row there, and is
   ignored where the parent is not a flex container, which is everywhere
   else. */
.bc-price-line {
	display: block;
	flex: 0 0 100%;
	line-height: 1.34;
	/* In a 316px shop cell "EUR 160.00 for the week, Monday to Friday" breaks
	   after "to" and leaves "Friday" alone on the second line. Balancing gives
	   "EUR 160.00 for the week," / "Monday to Friday" instead. */
	text-wrap: balance;
}

.bc-price-line + .bc-price-line {
	margin-top: 3px;
}

.bc-price-unit {
	color: var(--bc-muted);
	font-weight: 300;
}

/* The second rate is the same fact at a smaller size, not a separate price. */
.bc-price-line-alt {
	font-size: 0.88em;
	color: var(--bc-muted);
}

/* The camps listing sets its price inline beside the stock pill; two lines
   need the row to stop being a single baseline. */
.bc-camp-add-price .bc-price-line,
.bc-camp-price .bc-price-line {
	display: block;
}

/* --- the panel that replaces the add-to-cart form ----------------------- */

.bc-flow-only {
	width: 100%;
	max-width: 560px;
	padding: 26px 28px 24px;
	border: 1px solid var(--bc-line);
	border-radius: 2px;
	background-color: var(--bc-paper);
}

.bc-flow-only-title {
	margin: 0 0 10px;
	font-family: var(--bc-font);
	font-size: var(--bc-h4);
	font-weight: 500;
	line-height: 1.2;
	color: var(--bc-ink);
	text-wrap: balance;
}

.bc-flow-only-p {
	margin: 0 0 14px;
	font-family: var(--bc-font);
	font-size: var(--bc-body);
	font-weight: 300;
	line-height: 1.62;
	color: var(--bc-ink);
	text-wrap: pretty;
}

.bc-flow-only-list {
	margin: 0 0 20px;
	padding: 0 0 0 20px;
	font-family: var(--bc-font);
	font-size: var(--bc-body);
	font-weight: 300;
	line-height: 1.62;
	color: var(--bc-muted);
}

.bc-flow-only-list li {
	margin: 0 0 4px;
}

.bc-flow-only-sold {
	font-weight: 500;
	color: var(--bc-accent-dark);
}

.bc-flow-only-actions {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 12px 22px;
	margin: 0;
}

.bc-flow-only-link {
	font-family: var(--bc-font);
	font-size: var(--bc-body);
	font-weight: 300;
	color: var(--bc-accent-dark);
	text-decoration: underline;
	text-underline-offset: 3px;
}

/* The panel is our own markup dropped where WooCommerce's form used to sit, so
   it needs the same full-row behaviour the child-details fieldset already has
   inside the product summary's flex column. */
.bc-product-page .bc-flow-only {
	flex: 0 0 100%;
}

@media (max-width: 767px) {
	.bc-flow-only {
		padding: 22px 20px 20px;
	}
}
