/**
 * Single-product layout — un-toolkit.
 *
 * Two desktop layouts from ONE Elementor template, switched by the body signal
 * class `un-no-wheel` (added in includes/color-meta.php when the ChromaLab block
 * renders nothing). A single CSS-grid container reflows its children via named
 * grid-areas; no widget is duplicated.
 *
 * Target Elementor structure — the "Données produits" container gets the class
 * `un-product-grid` and holds these children (each an Elementor widget or a
 * sub-container), tagged with an area class:
 *
 *   .un-area-media   left block: gallery + price + add-to-cart
 *   .un-wheel-col    the "UN ChromaLab — Product" widget (wheel + swatches)
 *   .un-area-req     the "UN - Produit requis" widget
 *   .un-area-tabs    the product data tabs (The7 / UN product content)
 *   .un-spec-col     the "UN - Fiche technique" widget
 *
 * The page title / breadcrumb stay in their own block ABOVE the grid.
 *
 * BOXED vs FULL-WIDTH — the container works EITHER way, so it can match the
 * category-archive template (boxed) without special settings. Elementor wraps a
 * *boxed* container's children in an extra `.e-con-inner`; a *full-width* one
 * has none. The real grid host is therefore:
 *     boxed      → `.un-product-grid > .e-con-inner`  (Elementor centers this
 *                  at the site content width for free — NO max-width needed)
 *     full-width → `.un-product-grid` itself          (spans its parent)
 * Every rule below addresses the host through this token:
 *     :is(.un-product-grid:not(:has(> .e-con-inner)), .un-product-grid > .e-con-inner)
 * The `:not(:has(> .e-con-inner))` guard keeps the grid OFF the outer element in
 * boxed mode — putting it there collapses the lone `.e-con-inner` into column 1
 * (the classic "everything squished on the left" break). The area children sit
 * one level under whichever host matched, so `HOST > .un-area-*` resolves in
 * both modes. (`:has()`/`:is()` support already assumed — used throughout.)
 *
 * See custom-classes-helpers.md for the full build recipe.
 */

/* We own this host's layout outright. Elementor generates flex rules for
 * `.e-con.e-flex` (specificity 0,2,0) that would otherwise force its own
 * direction; `!important` lets our grid/flex win deterministically, so the
 * container's own "Disposition / Direction" settings never matter. */
body :is(.un-product-grid:not(:has(> .e-con-inner)), .un-product-grid > .e-con-inner) {
	/* Tunables (override per-placement in Elementor custom CSS if needed). */
	--unpl-gap: 40px;
	--unpl-col-mid: minmax(260px, 0.9fr); /* ChromaLab wheel column */
	--unpl-col-side: minmax(280px, 1fr);  /* media / spec columns     */

	display: grid !important;
	gap: var(--unpl-gap);
	align-items: start;
}

/* Three breakpoints, each isolated in its own media query so they never fight
 * on specificity: desktop (>1024) grid, tablet (768–1024) 2-col grid, mobile
 * (≤767) single column. Drawers are active ≤1024 (tablet + mobile).
 *
 * Line-based placement (not grid-template-areas) lets the stacked side column
 * AUTO-FLOW: when "Produit requis" is absent, the block below rises to the top
 * instead of leaving an empty reserved row. */

/* DEFAULT = a SINGLE content row + a full-width row below, so the gap between
 * the content and the description is never doubled (the old 2-row span left an
 * empty middle row when "Produit requis" was absent, stacking two row-gaps).
 * When a real Produit requis IS rendered (the widget outputs `.un-req`), `:has()`
 * switches to a 2-row layout stacking req over the fiche, media/wheel spanning. */

/* ============================ DESKTOP (>1024) ============================ */
@media (min-width: 1025px) {
	/* ---- WITH wheel: media | wheel(+swatches) | fiche ; tabs full width ---- */
	body:not(.un-no-wheel) :is(.un-product-grid:not(:has(> .e-con-inner)), .un-product-grid > .e-con-inner) {
		grid-template-columns: var(--unpl-col-side) var(--unpl-col-mid) var(--unpl-col-side);
	}
	body:not(.un-no-wheel) :is(.un-product-grid:not(:has(> .e-con-inner)), .un-product-grid > .e-con-inner) > .un-area-media { grid-column: 1; grid-row: 1; }
	body:not(.un-no-wheel) :is(.un-product-grid:not(:has(> .e-con-inner)), .un-product-grid > .e-con-inner) > .un-wheel-col  { grid-column: 2; grid-row: 1; min-width: 0; }
	body:not(.un-no-wheel) :is(.un-product-grid:not(:has(> .e-con-inner)), .un-product-grid > .e-con-inner) > .un-area-req   { grid-column: 3; grid-row: 1; }
	body:not(.un-no-wheel) :is(.un-product-grid:not(:has(> .e-con-inner)), .un-product-grid > .e-con-inner) > .un-spec-col   { grid-column: 3; grid-row: 1; }
	body:not(.un-no-wheel) :is(.un-product-grid:not(:has(> .e-con-inner)), .un-product-grid > .e-con-inner) > .un-area-tabs  { grid-column: 1 / -1; grid-row: 2; min-width: 0; }

	/* req present → 2 rows: req over fiche, media/wheel span both, tabs row 3 */
	body:not(.un-no-wheel) :is(.un-product-grid:not(:has(> .e-con-inner)), .un-product-grid > .e-con-inner):has(> .un-area-req .un-req) > .un-area-media { grid-row: 1 / 3; }
	body:not(.un-no-wheel) :is(.un-product-grid:not(:has(> .e-con-inner)), .un-product-grid > .e-con-inner):has(> .un-area-req .un-req) > .un-wheel-col  { grid-row: 1 / 3; }
	body:not(.un-no-wheel) :is(.un-product-grid:not(:has(> .e-con-inner)), .un-product-grid > .e-con-inner):has(> .un-area-req .un-req) > .un-area-req   { grid-row: 1; }
	body:not(.un-no-wheel) :is(.un-product-grid:not(:has(> .e-con-inner)), .un-product-grid > .e-con-inner):has(> .un-area-req .un-req) > .un-spec-col   { grid-row: 2; }
	body:not(.un-no-wheel) :is(.un-product-grid:not(:has(> .e-con-inner)), .un-product-grid > .e-con-inner):has(> .un-area-req .un-req) > .un-area-tabs  { grid-row: 3; }

	/* ---- WITHOUT wheel: media | fiche ; description (tabs) full width ------ */
	body.un-no-wheel :is(.un-product-grid:not(:has(> .e-con-inner)), .un-product-grid > .e-con-inner) {
		grid-template-columns: var(--unpl-col-side) var(--unpl-col-side);
	}
	body.un-no-wheel :is(.un-product-grid:not(:has(> .e-con-inner)), .un-product-grid > .e-con-inner) > .un-wheel-col  { display: none; }
	body.un-no-wheel :is(.un-product-grid:not(:has(> .e-con-inner)), .un-product-grid > .e-con-inner) > .un-area-media { grid-column: 1; grid-row: 1; }
	body.un-no-wheel :is(.un-product-grid:not(:has(> .e-con-inner)), .un-product-grid > .e-con-inner) > .un-area-req   { grid-column: 2; grid-row: 1; }
	body.un-no-wheel :is(.un-product-grid:not(:has(> .e-con-inner)), .un-product-grid > .e-con-inner) > .un-area-tabs  { grid-column: 2; grid-row: 1; min-width: 0; }
	body.un-no-wheel :is(.un-product-grid:not(:has(> .e-con-inner)), .un-product-grid > .e-con-inner) > .un-spec-col   { grid-column: 1 / -1; grid-row: 2; }

	/* req present → media spans, req over tabs in col 2, fiche full width row 3 */
	body.un-no-wheel :is(.un-product-grid:not(:has(> .e-con-inner)), .un-product-grid > .e-con-inner):has(> .un-area-req .un-req) > .un-area-media { grid-row: 1 / 3; }
	body.un-no-wheel :is(.un-product-grid:not(:has(> .e-con-inner)), .un-product-grid > .e-con-inner):has(> .un-area-req .un-req) > .un-area-req   { grid-row: 1; }
	body.un-no-wheel :is(.un-product-grid:not(:has(> .e-con-inner)), .un-product-grid > .e-con-inner):has(> .un-area-req .un-req) > .un-area-tabs  { grid-row: 2; }
	body.un-no-wheel :is(.un-product-grid:not(:has(> .e-con-inner)), .un-product-grid > .e-con-inner):has(> .un-area-req .un-req) > .un-spec-col   { grid-row: 3; }
}

/* ============================ TABLET (768–1024) ========================= *
 * 2 columns: media | second block (wheel + swatches if wheel, else Produit
 * requis), everything else full width below. The wheel renders INLINE here —
 * only the Fiche technique uses its drawer on tablet. */
@media (min-width: 768px) and (max-width: 1024px) {
	body :is(.un-product-grid:not(:has(> .e-con-inner)), .un-product-grid > .e-con-inner) {
		grid-template-columns: 1fr 1fr;
	}

	/* WITH wheel: media | swatches ; the ChromaLab button tucks under the swatches
	 * (col 2), the rest is full width. The chroma trigger is the one right after
	 * the wheel column in the DOM. */
	body:not(.un-no-wheel) :is(.un-product-grid:not(:has(> .e-con-inner)), .un-product-grid > .e-con-inner) > .un-area-media { grid-column: 1; grid-row: 1; }
	body:not(.un-no-wheel) :is(.un-product-grid:not(:has(> .e-con-inner)), .un-product-grid > .e-con-inner) > .un-wheel-col  { grid-column: 2; grid-row: 1; min-width: 0; }
	body:not(.un-no-wheel) :is(.un-product-grid:not(:has(> .e-con-inner)), .un-product-grid > .e-con-inner) > .un-area-req,
	body:not(.un-no-wheel) :is(.un-product-grid:not(:has(> .e-con-inner)), .un-product-grid > .e-con-inner) > .un-area-tabs,
	body:not(.un-no-wheel) :is(.un-product-grid:not(:has(> .e-con-inner)), .un-product-grid > .e-con-inner) > .un-spec-col,
	body:not(.un-no-wheel) :is(.un-product-grid:not(:has(> .e-con-inner)), .un-product-grid > .e-con-inner) > .un-drawer-trigger { grid-column: 1 / -1; }
	/* Wheel renders inline on tablet, so its ChromaLab reveal button isn't needed. */
	body :is(.un-product-grid:not(:has(> .e-con-inner)), .un-product-grid > .e-con-inner) > .un-wheel-col + .un-drawer-trigger { display: none; }

	/* WITHOUT wheel: media | Produit requis */
	body.un-no-wheel :is(.un-product-grid:not(:has(> .e-con-inner)), .un-product-grid > .e-con-inner) > .un-wheel-col  { display: none; }
	body.un-no-wheel :is(.un-product-grid:not(:has(> .e-con-inner)), .un-product-grid > .e-con-inner) > .un-area-media { grid-column: 1; grid-row: 1; }
	body.un-no-wheel :is(.un-product-grid:not(:has(> .e-con-inner)), .un-product-grid > .e-con-inner) > .un-area-req   { grid-column: 2; grid-row: 1; }
	body.un-no-wheel :is(.un-product-grid:not(:has(> .e-con-inner)), .un-product-grid > .e-con-inner) > .un-area-tabs,
	body.un-no-wheel :is(.un-product-grid:not(:has(> .e-con-inner)), .un-product-grid > .e-con-inner) > .un-spec-col,
	body.un-no-wheel :is(.un-product-grid:not(:has(> .e-con-inner)), .un-product-grid > .e-con-inner) > .un-drawer-trigger { grid-column: 1 / -1; }
}

/* ============================ MOBILE (≤767) ============================= *
 * Single column. Order follows the Elementor navigator order of the grid's
 * direct children — arrange them as you want them read on phones. */
@media (max-width: 767px) {
	body :is(.un-product-grid:not(:has(> .e-con-inner)), .un-product-grid > .e-con-inner) {
		display: flex !important;
		flex-direction: column !important;
		gap: var(--unpl-gap);
	}

	/* Wheel UI lives in its drawer on phones; the swatches stay inline. Gated on a
	 * wired drawer (body class from un-product-layout.js) so a page without a
	 * ChromaLab drawer keeps its wheel inline. */
	body.un-drawer-ready--chromalab .un-product-grid .chromalab-product .chromalab {
		display: none;
	}
}

/* ===== Fiche drawer: tablet + mobile (≤1024). Wheel drawer: mobile only ==== */
@media (max-width: 1024px) {
	/* Show the wheel column again (for its swatches) even when un-no-wheel hides
	 * it on desktop — but only if it actually has a block. */
	body.un-no-wheel :is(.un-product-grid:not(:has(> .e-con-inner)), .un-product-grid > .e-con-inner) > .un-wheel-col:not(:empty) {
		display: block;
	}

	/* Fiche technique inline preview: show only the FIRST section (clean, no
	 * fade-out); the full fiche opens in its drawer via the button. */
	:is(.un-product-grid:not(:has(> .e-con-inner)), .un-product-grid > .e-con-inner) > .un-spec-col[data-unpl-clamp] .un-ontology-details__group:not(:first-child) {
		display: none;
	}
}

/* --- Drawer triggers (reveal buttons) ------------------------------------ *
 * Buttons with class `un-drawer-trigger`. Hidden on desktop; shown ≤1024px. */
.un-drawer-trigger {
	display: none;
}

@media (max-width: 1024px) {
	.un-drawer-trigger {
		display: block;
	}
}

/* No wheel on this product → nothing for the ChromaLab reveal button to open.
 * Hide that button specifically (it's the sibling right after the wheel column);
 * the Fiche technique trigger, a different sibling, stays visible. */
body.un-no-wheel :is(.un-product-grid:not(:has(> .e-con-inner)), .un-product-grid > .e-con-inner) > .un-wheel-col + .un-drawer-trigger {
	display: none;
}

/* Off-Canvas slots: empty containers the user places inside each Off-Canvas
 * widget. un-product-layout.js moves the wheel UI / clones the full fiche into
 * the matching slot on mobile and adds `is-filled`. The relocated wheel UI is
 * outside `.un-product-grid`, so the inline-hide rule no longer applies to it;
 * this `!important` is belt-and-braces in case of cascade surprises. */
.un-drawer-slot.is-filled .chromalab,
.un-drawer-slot.is-filled .un-ontology-details {
	display: block !important;
}
.un-drawer-slot {
	min-width: 0;
}

/* Drawer content framing. The slot is a direct child of Elementor's block-level
 * `.e-off-canvas__content`; we own the gutter here so it's guaranteed symmetric
 * on every side (no stray margin on the side the panel opens from, whatever the
 * slot's own padding). Column flex + margin:auto centers short content (wheel +
 * a few swatches) yet keeps a long swatch grid scrollable from the top instead
 * of clipping it (as justify/align-center would). Scoped via :has() so only our
 * two drawers are touched; a close button, if enabled on the Off-Canvas widget,
 * is positioned separately and is unaffected. */
.e-off-canvas__content:has(> .un-drawer-slot--chromalab),
.e-off-canvas__content:has(> .un-drawer-slot--fiche) {
	display: flex;
	flex-direction: column;
	padding: clamp(16px, 4vw, 28px);
	box-sizing: border-box;
}

.e-off-canvas__content > .un-drawer-slot--chromalab,
.e-off-canvas__content > .un-drawer-slot--fiche {
	margin: auto;             /* center when it fits; auto-margins collapse when tall → scrollable */
	width: 100%;
	padding: 0 !important;    /* gutter is owned by the panel body above — no double/asymmetric padding */
}
