/*
 * Home: "Les packs" (template-parts/home/packs.php, .packs) and "Composez votre installation"
 * (template-parts/home/configurator.php, .config; script assets/js/home-configurator.js).
 * Built on design-system/MASTER.md tokens; every class is namespaced .packs__ or .config__.
 */

/* =====================================================================================================
 * Les packs
 * ≥1280: the lead banner on the left over both rows, the two others stacked on the right; the text sits over the image.
 * 768–1279: the lead across (text left, image right), the two others side by side (image on top, text under it).
 * Phones: stacked cards, the image 4:5 on top, the text under it.
 * The image layer (.packs__inner) is wiped in by a scrubbed clip-path and drifts at 0.96x (home-configurator.js);
 * --over is its overscan, set by the script (0 without it).
 * ===================================================================================================== */
.packs__grid {
	display: grid; gap: var(--s-5);
	grid-template-columns: minmax(0, 1.06fr) minmax(0, 1fr);
	/* rows never shorter than their card's copy (at 1280 the small cards' text outgrew a fixed 298 px row) */
	grid-template-rows: repeat(2, minmax(min-content, 1fr));
	min-height: clamp(620px, 47vw, 680px);
}
.packs__card {
	position: relative; isolation: isolate; overflow: hidden;
	display: flex; flex-direction: column; min-width: 0; min-height: 0;
	border-radius: var(--r-lg); background: var(--mist);
}
.packs__card--lead { grid-row: 1 / 3; }
/* the card's own edge: a hairline ring above the image, so every card reads as a card on the white page */
.packs__card::after {
	content: ""; position: absolute; inset: 0; z-index: 3; pointer-events: none;
	border-radius: inherit; box-shadow: inset 0 0 0 1px rgb(16 24 40 / 0.07);
}

/* ---------- The image: the photograph, or the cut-outs on plinths in a soft studio ---------- */
.packs__media {
	position: absolute; inset: 0; z-index: 0; overflow: hidden; border-radius: inherit;
	container-type: size; container-name: packs-media;
}
.packs__inner { position: absolute; inset: calc(-1 * var(--over, 0px)) 0; }
.packs__photo, .packs__photo img { position: absolute; inset: 0; display: block; width: 100%; height: 100%; }
.packs__photo img { object-fit: cover; object-position: var(--focus, 70% 50%); }
@media (max-width: 1279px) { .packs__photo img { object-position: var(--focus-tablet, var(--focus, 70% 50%)); } }
.packs__studio {
	position: absolute; inset: 0;
	background:
		radial-gradient(58% 48% at 70% 26%, rgb(255 255 255 / 0.85) 0%, rgb(255 255 255 / 0) 100%),
		linear-gradient(180deg, #EFF1F4 0%, #EAEDF1 56%, #E1E5EA 100%);
}
.packs__set { position: absolute; bottom: var(--over, 0px); aspect-ratio: 1 / 1; height: auto; }
.packs__set--tall { display: none; }
.packs__card--lead .packs__set { right: -1cqw; width: min(100cqh, 80cqw); }
.packs__card:not(.packs__card--lead) .packs__set { right: 2.5cqw; width: min(100cqh, 48cqw); }

/* a white plinth: the top face catches the light, the front face falls off toward the floor, a soft contact shadow */
.packs__plinth {
	--depth: calc((var(--f) - var(--t)) / (var(--pb) - var(--t)) * 100%);
	position: absolute; z-index: 0;
	left: calc(var(--l) * 1%); width: calc((var(--r) - var(--l)) * 1%);
	top: calc(var(--t) * 1%); height: calc((var(--pb) - var(--t)) * 1%);
}
.packs__plinth::before, .packs__plinth::after { content: ""; position: absolute; left: 0; right: 0; }
.packs__plinth::before {
	top: 0; height: var(--depth); z-index: 1; border-radius: 3px 3px 0 0;
	background: linear-gradient(180deg, #FDFDFE 0%, #FFFFFF 100%);
	box-shadow: inset 0 1px 0 rgb(255 255 255 / 1), 0 1px 0 rgb(16 24 40 / 0.06);
}
.packs__plinth::after {
	top: var(--depth); bottom: 0; border-radius: 0 0 2px 2px;
	background:
		linear-gradient(90deg, rgb(255 255 255 / 0.55) 0%, rgb(255 255 255 / 0) 38%, rgb(16 24 40 / 0) 72%, rgb(16 24 40 / 0.035) 100%),
		linear-gradient(180deg, #F7F8FA 0%, #EEF0F3 45%, #E3E7EC 100%);
	box-shadow: 0 2px 2px rgb(16 24 40 / 0.06), 0 22px 26px -16px rgb(16 24 40 / 0.32);
}
.packs__piece {
	position: absolute; max-width: none;
	left: calc(var(--x) * 1%); top: calc(var(--b) * 1%); width: calc(var(--w) * 1%); height: auto;
	translate: -50% -100%;
	filter: drop-shadow(0 6px 5px rgb(16 24 40 / 0.16));
}

/* the photograph's copy space: a soft mist veil under the text column only (light photos; the products stand clear of
 * it, from about 52 % of the card), or an ink veil (dark ones). Mist, not paper: the card keeps its ground on white. */
.packs__card--photo .packs__media::after {
	content: ""; position: absolute; inset: 0; z-index: 1; pointer-events: none;
	background: linear-gradient(90deg, rgb(244 245 247 / 0.72) 0%, rgb(244 245 247 / 0.6) 30%, rgb(244 245 247 / 0) 52%);
	/* gone under the copy's end, so a product low in the frame (the lead's cable reel) keeps its colour */
	-webkit-mask-image: linear-gradient(180deg, #000 0%, #000 62%, transparent 86%);
	mask-image: linear-gradient(180deg, #000 0%, #000 62%, transparent 86%);
}
.packs__card--dark .packs__media::after { background: linear-gradient(90deg, rgb(0 0 0 / 0.62) 0%, rgb(0 0 0 / 0.38) 36%, rgb(0 0 0 / 0) 62%); }
.packs__card--dark { background: var(--ink); color: var(--on-ink); }
.packs__card--dark .packs__title, .packs__card--dark .packs__qty, .packs__card--dark .packs__price { color: var(--on-ink); }
.packs__card--dark .packs__line, .packs__card--dark .price__tax { color: var(--on-ink-2); }

/* ---------- The copy ---------- */
.packs__body {
	position: relative; z-index: 2;
	display: flex; flex-direction: column; align-items: flex-start;
	/* the floor keeps "Ajouter le pack" and the round WhatsApp button on one row at 1280 */
	width: max(54%, 320px); padding: clamp(24px, 2.4vw, 36px);
}
.packs__card--lead .packs__body { width: min(48%, 440px); padding: clamp(32px, 3.2vw, 48px); }
.packs__title { margin: 0; font-size: var(--text-lg); line-height: var(--leading-snug); letter-spacing: var(--tracking-display); text-wrap: balance; }
.packs__card--lead .packs__title { font-size: var(--text-xl); line-height: 1.1; }
.packs__lines { list-style: none; margin: var(--s-3) 0 0; padding: 0; display: grid; gap: 5px; }
.packs__card--lead .packs__lines { margin-top: var(--s-4); gap: 6px; }
.packs__line {
	display: grid; grid-template-columns: 2.1em minmax(0, 1fr); align-items: baseline;
	font-size: 0.9375rem; line-height: 1.35; color: var(--ink-2); text-wrap: pretty;
}
.packs__qty { font-weight: 600; color: var(--ink); white-space: nowrap; }
.packs__name { padding-block: 3px; color: inherit; text-decoration: none; border-radius: 4px; /* padding: a 24 px hit band, the line stays put */ transition: color var(--dur-1) var(--ease-out); }
@media (hover: hover) { .packs__name:hover { color: var(--action); text-decoration: underline; text-underline-offset: 0.2em; text-decoration-thickness: 1px; } }
.packs__card--dark .packs__name:hover { color: var(--on-ink); }
.packs__name:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.packs__price { margin: var(--s-4) 0 0; font-size: var(--text-lg); line-height: 1.1; white-space: nowrap; }
.packs__card--lead .packs__price { margin-top: var(--s-5); font-size: var(--text-xl); }
.packs__actions { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-2); margin-top: var(--s-4); }
.packs__card--lead .packs__actions { margin-top: var(--s-5); }
.packs__add { position: relative; overflow: hidden; }
.packs__add .icon { width: 20px; height: 20px; }
.packs__add-label, .packs__add-done { display: inline-flex; align-items: center; gap: 0.5em; transition: transform var(--dur-2) var(--ease-out), opacity var(--dur-1) var(--ease-out); }
.packs__add-done { position: absolute; inset: 0; justify-content: center; opacity: 0; transform: translateY(70%); }
.packs__add.is-added .packs__add-label { opacity: 0; transform: translateY(-70%); }
.packs__add.is-added .packs__add-done { opacity: 1; transform: none; }
.packs__wa { background: var(--paper); }
.packs__card--dark .packs__wa { background: transparent; }
.packs__card:not(.packs__card--lead) .packs__wa { width: var(--btn-h); padding: 0; flex: none; }
.packs__card:not(.packs__card--lead) .packs__wa .icon { width: 22px; height: 22px; }
.packs__card:not(.packs__card--lead) .packs__wa-label { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }

/* ---------- 768–1279: the lead across, the two others side by side ---------- */
@media (max-width: 1279px) {
	.packs__grid { height: auto; grid-template-columns: repeat(2, minmax(0, 1fr)); grid-template-rows: auto auto; }
	.packs__card--lead { grid-column: 1 / -1; grid-row: auto; min-height: clamp(420px, 44vw, 520px); }
	.packs__card--lead .packs__body { width: min(50%, 440px); }
	.packs__card--lead .packs__set { right: 0; width: min(100cqh, 56cqw); }
	.packs__card:not(.packs__card--lead) .packs__media { position: relative; inset: auto; flex: none; aspect-ratio: 4 / 3; border-radius: 0; }
	.packs__card:not(.packs__card--lead) .packs__set { right: auto; left: 50%; translate: -50% 0; width: min(100cqh, 94cqw); }
	.packs__card:not(.packs__card--lead) .packs__body { width: auto; flex: 1 1 auto; padding: var(--s-5) clamp(20px, 2.6vw, 28px) clamp(20px, 2.6vw, 28px); }
	.packs__card:not(.packs__card--lead) .packs__actions { margin-top: auto; padding-top: var(--s-4); }
	.packs__card--photo:not(.packs__card--lead) .packs__media::after { content: none; }
}

/* ---------- Phones: stacked cards, the image 4:5, the text under it ---------- */
@media (max-width: 767px) {
	.packs__grid { grid-template-columns: minmax(0, 1fr); gap: var(--s-4); }
	.packs__card--lead { grid-column: auto; min-height: 0; }
	.packs .packs__card .packs__media { position: relative; inset: auto; flex: none; aspect-ratio: 4 / 5; border-radius: 0; }
	.packs__card--photo .packs__media::after { content: none; }
	.packs__photo img { object-position: var(--focus-phone, var(--focus, 50% 50%)); }
	.packs__card .packs__set--square { display: none; }
	.packs__card .packs__set.packs__set--tall { display: block; left: 0; right: auto; width: 100cqw; aspect-ratio: 4 / 5; translate: none; }
	.packs__card .packs__body, .packs__card--lead .packs__body { width: auto; padding: var(--s-5) var(--s-5) var(--s-5); }
	.packs__title, .packs__card--lead .packs__title { font-size: var(--text-xl); }
	.packs__line { font-size: var(--text-base); }
	.packs__price, .packs__card--lead .packs__price { margin-top: var(--s-4); font-size: var(--text-xl); }
	.packs__actions, .packs__card--lead .packs__actions { width: 100%; flex-wrap: nowrap; margin-top: var(--s-4); padding-top: 0; }
	.packs__add { flex: 1 1 auto; min-width: 0; }
	.packs__card--lead .packs__wa { width: var(--btn-h); padding: 0; flex: none; }
	.packs__card--lead .packs__wa .icon { width: 22px; height: 22px; }
	.packs__card--lead .packs__wa-label { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
}

/* =====================================================================================================
 * Composez votre installation
 * Desktop: the stage (a plain mist floor, the real cut-outs with their contact shadows) on the left, the controls and the bill on the right.
 * Tablet: the stage across, then controls | bill, then the total bar. Phones: controls first, the stage, a compact
 * bill, and the total with both actions in a bar that sticks inside the section while it is on screen.
 * ===================================================================================================== */
.config__grid {
	display: grid;
	grid-template-columns: minmax(0, 1fr) minmax(360px, 432px);
	grid-template-areas:
		"stage controls"
		"stage summary"
		"stage bar"
		"stage notes";
	grid-template-rows: auto auto auto 1fr;
	column-gap: clamp(32px, 4.4vw, 72px);
	align-items: start;
}

/* ---------- Controls ---------- */
.config__controls { grid-area: controls; display: grid; gap: var(--s-5); padding-bottom: var(--s-5); border-bottom: 1px solid var(--hairline); }
.config__field { display: grid; gap: var(--s-2); min-width: 0; }
.config__label { margin: 0; font-size: var(--text-sm); font-weight: 800; color: var(--ink); letter-spacing: 0.01em; }
.config__places { display: flex; width: 100%; }
.config__places .segmented__opt { flex: 1 1 0; min-height: 44px; padding-inline: 0.6em; font-size: var(--text-base); }
.config__places .segmented__opt:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

.config__stepper {
	display: flex; align-items: center; justify-content: space-between; gap: var(--s-2);
	padding: 4px; border-radius: var(--r-pill); background: var(--mist);
}
.config__step {
	position: relative; width: 44px; height: 44px; flex: none; display: grid; place-items: center;
	border: 0; border-radius: 50%; background: var(--paper); color: var(--ink);
	box-shadow: 0 1px 2px rgb(16 24 40 / 0.08), 0 0 0 1px var(--hairline);
	transition: background-color var(--dur-1) var(--ease-out), color var(--dur-1) var(--ease-out), transform var(--dur-2) var(--ease-spring), opacity var(--dur-1) var(--ease-out);
}
.config__step .icon { width: 20px; height: 20px; }
@media (hover: hover) { .config__step:hover { background: var(--ink); color: var(--on-ink); } }
.config__step:active { transform: scale(0.9); }
.config__step:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.config__step[aria-disabled="true"] { opacity: 0.4; cursor: not-allowed; transform: none; }
@media (hover: hover) { .config__step[aria-disabled="true"]:hover { background: var(--paper); color: var(--ink); } }
.config__count { display: inline-flex; align-items: baseline; gap: 0.4em; min-width: 0; }
.config__count .num { font-weight: 600; font-size: var(--text-xl); line-height: 1; letter-spacing: var(--tracking-tight); min-width: 1.3ch; text-align: right; display: inline-block; }
.config__count-unit { font-weight: 700; color: var(--ink-2); }
.config__hint { margin: 0; font-size: var(--text-sm); color: var(--muted); }

/* ---------- The stage ---------- */
.config__stage {
	grid-area: stage; align-self: stretch;
	position: relative; isolation: isolate; overflow: hidden;
	min-height: 560px;
	border-radius: var(--r-lg);
	background:
		radial-gradient(70% 46% at 50% 54%, rgb(255 255 255 / 0.9) 0%, rgb(255 255 255 / 0) 100%),
		linear-gradient(180deg, var(--mist) 0%, #EDEFF2 100%);
	container-type: inline-size; container-name: config-stage;
	user-select: none; -webkit-user-select: none;
}
/* the floor: plain mist, a touch deeper toward the viewer, with a soft pool of daylight under the arc; no lines, no grid */
.config__ground {
	position: absolute; left: 0; right: 0; top: 30%; bottom: 0; z-index: 0; pointer-events: none;
	background:
		radial-gradient(54% 40% at 50% 46%, rgb(255 255 255 / 0.8) 0%, rgb(255 255 255 / 0) 100%),
		linear-gradient(180deg, rgb(232 235 239 / 0) 0%, rgb(232 235 239 / 0.7) 40%, #E5E8ED 100%);
}
.config__floor { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; z-index: 0; }
.config__ring { fill: rgb(255 255 255 / 0.5); stroke: rgb(16 24 40 / 0.14); stroke-width: 1.25; }
.config__ring--inner { fill: rgb(255 255 255 / 0.4); }
.config__cable { fill: none; stroke: var(--accent); stroke-opacity: 0.62; stroke-width: 1.75; stroke-linecap: round; }

.config__cams { position: absolute; inset: 0; z-index: 1; }
.config__cam {
	position: absolute;
	left: calc(var(--x) * 1%); top: calc(var(--y) * 1%); width: calc(var(--w) * 1%);
	translate: -50% -100%;
	transform-origin: 50% 100%;
	will-change: transform;
}
/* each camera stands on the floor at its port: a tight contact core where it touches, a soft penumbra around it */
.config__cam img { width: 100%; height: auto; translate: 0 -3%; filter: drop-shadow(0 2px 2px rgb(16 24 40 / 0.1)); }
.config__cam::before, .config__cam::after { content: ""; position: absolute; z-index: -1; pointer-events: none; }
/* the cut-outs keep about 5 % of transparent margin under the product: the shadows sit at the product's own base */
.config__cam::after {
	left: 6%; right: 6%; bottom: -2%; height: 20%;
	background: radial-gradient(closest-side, rgb(16 24 40 / 0.17), rgb(16 24 40 / 0.06) 60%, rgb(16 24 40 / 0));
}
.config__cam::before {
	left: 22%; right: 22%; bottom: 5%; height: 7%;
	background: radial-gradient(closest-side, rgb(16 24 40 / 0.34), rgb(16 24 40 / 0));
}
/* the bullet rests on its housing (left), the mount stands back from the floor */
.config__cam--bullet::after { left: 0; right: 16%; }
.config__cam--bullet::before { left: 7%; right: 55%; bottom: 5.5%; }

.config__nvr {
	position: absolute; left: 50%; top: 73%; width: 50%; z-index: 900;
	translate: -50% -50%;
}
.config__nvr img { width: 100%; height: auto; filter: drop-shadow(0 3px 3px rgb(16 24 40 / 0.14)); }
.config__nvr::before, .config__nvr::after { content: ""; position: absolute; z-index: -1; pointer-events: none; }
.config__nvr::after {
	left: -2%; right: -2%; bottom: -14%; height: 40%;
	background: radial-gradient(closest-side, rgb(16 24 40 / 0.16), rgb(16 24 40 / 0.05) 62%, rgb(16 24 40 / 0));
}
.config__nvr::before {
	left: 6%; right: 6%; bottom: -3%; height: 14%;
	background: radial-gradient(closest-side, rgb(16 24 40 / 0.34), rgb(16 24 40 / 0));
}

.config__reel {
	position: absolute; left: 87%; top: 66%; width: 14%; z-index: 850;
	translate: -50% -50%;
	transform-origin: 50% 80%;
	transition: opacity var(--dur-3) var(--ease-out), transform var(--dur-4) var(--ease-out-expo);
}
.config__reel img { width: 100%; height: auto; filter: drop-shadow(0 2px 2px rgb(16 24 40 / 0.12)); }
/* the reel stands on its two flanges: the contact under them, the cable end lying on the floor in front */
.config__reel::before, .config__reel::after { content: ""; position: absolute; z-index: -1; pointer-events: none; }
.config__reel::after {
	left: 2%; right: -6%; bottom: 14%; height: 22%;
	background: radial-gradient(closest-side, rgb(16 24 40 / 0.16), rgb(16 24 40 / 0.05) 60%, rgb(16 24 40 / 0));
}
.config__reel::before {
	left: 16%; right: 6%; bottom: 20%; height: 9%;
	background: radial-gradient(closest-side, rgb(16 24 40 / 0.3), rgb(16 24 40 / 0));
}
.config__reel-qty {
	position: absolute; top: -4%; right: -18%;
	min-width: 30px; height: 26px; padding: 0 8px; display: grid; place-items: center;
	border-radius: var(--r-pill); background: var(--ink); color: var(--on-ink);
	font-size: 0.8125rem; font-weight: 600; line-height: 1; white-space: nowrap;
}
.config__stage.is-no-reel .config__reel { opacity: 0; transform: translateY(12px) scale(0.88); transition-duration: var(--dur-2); transition-timing-function: var(--ease-in); }

.config__caption { position: absolute; left: clamp(16px, 4cqw, 32px); top: clamp(16px, 4cqw, 32px); right: 40%; z-index: 1000; display: grid; gap: 2px; }
.config__caption p { margin: 0; }
.config__caption-name { font-family: var(--font-display); font-weight: 600; font-size: clamp(1rem, 0.6rem + 1.6cqw, 1.25rem); line-height: var(--leading-snug); letter-spacing: var(--tracking-tight); color: var(--ink); text-wrap: balance; }
.config__caption-maker { font-size: var(--text-sm); font-weight: 700; color: var(--muted); }
.config__facts { list-style: none; margin: var(--s-2) 0 0; padding: 0; display: flex; flex-wrap: wrap; gap: 6px; }
.config__facts li {
	display: inline-flex; align-items: center; min-height: 26px; padding: 0 10px;
	border-radius: var(--r-pill); background: rgb(255 255 255 / 0.85); border: 1px solid var(--hairline);
	font-size: 0.75rem; font-weight: 700; color: var(--ink-2); white-space: nowrap;
}

.config__ports {
	position: absolute; left: 50%; top: calc(100% + clamp(10px, 2.4cqw, 20px)); z-index: 1000;
	translate: -50% 0; width: max-content; max-width: 180%;
	display: grid; justify-items: center; gap: 6px; text-align: center;
}
.config__ports p { margin: 0; }
.config__ports-name { font-size: 0.8125rem; font-weight: 800; color: var(--ink); line-height: 1.25; }
.config__ports-row { display: inline-flex; align-items: center; gap: 8px; font-size: 0.75rem; font-weight: 700; color: var(--muted); }
.config__dots { display: inline-flex; flex-wrap: wrap; justify-content: center; gap: 4px; max-width: 168px; }
.config__dots i {
	width: 8px; height: 8px; border-radius: 2px; background: var(--hairline-strong);
	position: relative; overflow: hidden;
}
.config__dots i::after {
	content: ""; position: absolute; inset: 0; background: var(--accent);
	transform: scale(0); opacity: 0;
	transition: transform var(--dur-2) var(--ease-spring), opacity var(--dur-1) var(--ease-out);
	transition-delay: calc(var(--i, 0) * 18ms);
}
.config__dots i.is-on::after { transform: none; opacity: 1; }
.config__ports-used { color: var(--ink); font-weight: 600; font-size: 0.8125rem; }

/* ---------- The bill ---------- */
.config__summary { grid-area: summary; padding-top: var(--s-5); min-width: 0; }
/* the pill keeps its own row whatever its text ("Vidéosurveillance 4 caméras" or "Bureau · 1 caméra"): composing never changes the page height */
.config__sum-head { display: grid; justify-items: start; gap: var(--s-2); margin-bottom: var(--s-2); }
.config__title { margin: 0; font-size: var(--text-lg); }
.config__match {
	margin: 0; display: inline-flex; align-items: center; gap: 6px; min-height: 30px; padding: 0 12px;
	border-radius: var(--r-pill); background: var(--mist); color: var(--ink-2);
	font-size: var(--text-sm); font-weight: 800; white-space: nowrap;
	transition: background-color var(--dur-2) var(--ease-out), color var(--dur-2) var(--ease-out), padding var(--dur-2) var(--ease-out);
}
.config__match .icon { width: 18px; height: 18px; color: var(--action); display: none; }
.config__match.is-pack { padding-left: 8px; background: var(--accent-soft); color: var(--action-press); }
.config__match.is-pack .icon { display: block; }

/* Every line keeps one height, so composing never moves the page (and the sections below). */
.config__lines { list-style: none; margin: 0; padding: 0; position: relative; z-index: 0; }
.config__line {
	position: relative;
	display: grid; grid-template-columns: 56px minmax(0, 1fr) auto 36px; align-items: center; column-gap: var(--s-3);
	height: 88px; padding: 0; border-bottom: 1px solid var(--hairline);
}
.config__line::before { /* the change flash: opacity only */
	content: ""; position: absolute; inset: 4px -10px; border-radius: var(--r-sm); background: var(--accent-soft);
	opacity: 0; z-index: -1; pointer-events: none;
}
.config__line.is-changed::before { animation: config-flash 900ms var(--ease-out) both; }
@keyframes config-flash { 0% { opacity: 0; } 18% { opacity: 1; } 100% { opacity: 0; } }
.config__thumb { width: 56px; height: 56px; display: grid; place-items: center; border-radius: var(--r-xs); background: var(--mist); overflow: hidden; transition: opacity var(--dur-2) var(--ease-out); }
.config__thumb img { max-width: 84%; max-height: 84%; width: auto; height: auto; object-fit: contain; }
.config__what { display: grid; gap: 3px; min-width: 0; }
.config__name {
	font-family: var(--font-display); font-weight: 500; font-size: 0.9375rem; line-height: 1.3; color: var(--ink); text-decoration: none; padding-block: 2px;
	display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; line-clamp: 2; overflow: hidden;
	transition: color var(--dur-2) var(--ease-out);
}
@media (hover: hover) { .config__name:hover { color: var(--action); text-decoration: underline; text-decoration-color: currentColor; text-underline-offset: 0.2em; } }
.config__name:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 4px; }
.config__meta { display: flex; align-items: center; gap: 8px; min-width: 0; font-size: 0.8125rem; font-weight: 600; color: var(--muted); }
.config__maker { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.config__tag {
	flex: none; display: inline-flex; align-items: center; min-height: 22px; padding: 0 8px;
	border-radius: var(--r-pill); border: 1px solid var(--accent-line); color: var(--action);
	font-size: 0.75rem; font-weight: 800;
}
.config__money { display: grid; justify-items: end; gap: 2px; text-align: right; transition: opacity var(--dur-2) var(--ease-out); }
.config__sum { font-weight: 600; font-size: 0.9375rem; line-height: 1.2; white-space: nowrap; color: var(--ink); }
.config__unit { font-size: 0.8125rem; font-weight: 600; color: var(--muted); white-space: nowrap; }
.config__unit .num { font-family: var(--font-display); }
.config__act { position: relative; align-self: stretch; display: flex; align-items: center; justify-content: flex-end; }
.config__remove {
	width: 44px; height: 44px; flex: none; display: grid; place-items: center; margin-right: -6px;
	border: 0; border-radius: 50%; background: transparent; color: var(--muted);
	transition: background-color var(--dur-1) var(--ease-out), color var(--dur-1) var(--ease-out), transform var(--dur-2) var(--ease-spring);
}
.config__remove .icon { width: 18px; height: 18px; }
@media (hover: hover) { .config__remove:hover { background: var(--mist); color: var(--ink); } }
.config__remove:active { transform: scale(0.9); }
.config__remove:focus-visible { outline: 2px solid var(--accent); outline-offset: 0; }
.config__remove[hidden], .config__restore-btn[hidden] { display: none; }

/* The removed reel stays in its place, quiet, with "Remettre" over its price. */
.config__line--reel.is-off .config__thumb { opacity: 0.45; }
.config__line--reel.is-off .config__name { color: var(--muted); }
.config__line--reel.is-off .config__tag { border-color: var(--hairline-strong); color: var(--muted); }
.config__line--reel.is-off .config__money { opacity: 0; visibility: hidden; }
.config__restore-btn {
	position: absolute; right: -6px; top: 50%; translate: 0 -50%;
	display: inline-flex; align-items: center; gap: 6px; min-height: 44px; padding: 0 14px 0 10px;
	border: 1.5px solid var(--ink); border-radius: var(--r-pill); background: var(--paper); color: var(--ink);
	font-weight: 700; font-size: var(--text-sm); white-space: nowrap;
	transition: background-color var(--dur-1) var(--ease-out), color var(--dur-1) var(--ease-out), transform var(--dur-2) var(--ease-spring);
}
.config__restore-btn .icon { width: 18px; height: 18px; flex: none; }
@media (hover: hover) { .config__restore-btn:hover { background: var(--ink); color: var(--on-ink); } }
.config__restore-btn:active { transform: scale(0.96); }
.config__restore-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* ---------- Total and actions ---------- */
.config__bar { grid-area: bar; display: grid; gap: var(--s-4); padding-top: var(--s-5); }
.config__total { margin: 0; display: flex; align-items: baseline; justify-content: space-between; gap: var(--s-3); }
.config__total-label { font-weight: 800; font-size: var(--text-sm); color: var(--ink-2); }
.config__total-label abbr { text-decoration: none; }
.config__total-value { font-size: clamp(1.75rem, 1.2rem + 1.5vw, 2.5rem); }
.config__actions { display: grid; gap: var(--s-2); }
.config__actions .btn { width: 100%; }
.config__add { overflow: hidden; }
.config__add-label, .config__add-done { display: inline-flex; align-items: center; gap: 0.5em; transition: transform var(--dur-2) var(--ease-out), opacity var(--dur-1) var(--ease-out); }
.config__add-done { position: absolute; inset: 0; justify-content: center; opacity: 0; transform: translateY(70%); }
.config__add.is-added .config__add-label { opacity: 0; transform: translateY(-70%); }
.config__add.is-added .config__add-done { opacity: 1; transform: none; }
.config__add .icon { width: 20px; height: 20px; }
.config__notes { grid-area: notes; margin: 0; padding-top: var(--s-4); display: flex; flex-wrap: wrap; gap: var(--s-2) var(--s-4); font-size: var(--text-sm); font-weight: 700; color: var(--ink-2); }
.config__notes span { display: inline-flex; align-items: center; gap: 6px; }
.config__notes .icon { width: 18px; height: 18px; color: var(--accent); }

/* The rolling total: one column per digit (tabular Rubik), the strip of 0–9 slides to its digit. */
.config__odo { display: inline-flex; align-items: flex-start; line-height: 1.1; }
.odo__col { display: inline-block; height: 1.1em; overflow: hidden; }
.odo__strip { display: flex; flex-direction: column; transform: translateY(calc(var(--d, 0) * -10%)); transition: transform 640ms var(--ease-out); transition-delay: calc(var(--p, 0) * 28ms); }
.odo__strip > span { display: block; height: 1.1em; }
.odo__sep { display: inline-block; width: 0.22em; }
.odo__unit { margin-left: 0.22em; }
.odo__col.is-new { animation: config-odo-in 420ms var(--ease-out) both; }
@keyframes config-odo-in { from { opacity: 0; transform: translateY(-30%); } to { opacity: 1; transform: none; } }

/* ---------- 1024–1279: the stage stays square-ish and holds its place while the bill scrolls by ---------- */
@media (min-width: 1024px) and (max-width: 1279px) {
	.config__stage { align-self: start; aspect-ratio: 1 / 1.1; min-height: 0; max-height: 720px; position: sticky; top: calc(var(--header-tight) + var(--s-4)); }
}

/* ---------- Tablet: the stage across, the controls side by side, the bill and the bar across ---------- */
@media (max-width: 1023px) {
	.config__grid {
		grid-template-columns: minmax(0, 1fr);
		grid-template-areas:
			"stage"
			"controls"
			"summary"
			"bar"
			"notes";
		grid-template-rows: auto auto auto auto auto;
	}
	.config__stage { aspect-ratio: 4 / 3; max-height: 620px; min-height: 0; margin-bottom: var(--s-6); }
	.config__controls { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); column-gap: var(--s-6); align-items: start; }
	.config__summary { padding-top: var(--s-5); }
	.config__bar { grid-template-columns: auto minmax(0, 1fr); align-items: center; gap: var(--s-5); margin-top: var(--s-5); padding: var(--s-5) 0 0; border-top: 1px solid var(--hairline); }
	.config__total { display: grid; gap: 4px; }
	.config__actions { grid-template-columns: 1fr 1fr; }
	.config__nvr { width: 40%; top: 75%; }
}

/* ---------- Phones: controls first, compact bill, the sticky bar ---------- */
@media (max-width: 767px) {
	/* stretch: the desktop grid's align-items: start would size the bar to its content (407 px at 390) */
	.config__grid { display: flex; flex-direction: column; align-items: stretch; gap: 0; }
	.config__controls { order: 1; gap: var(--s-4); grid-template-columns: minmax(0, 1fr); }
	.config__stage { order: 2; aspect-ratio: 1 / 1; min-height: 0; margin: var(--s-5) 0 0; border-radius: var(--r-md); }
	.config__summary { order: 3; padding-top: var(--s-5); }
	.config__notes { order: 4; padding-top: var(--s-4); padding-bottom: var(--s-4); }
	.config__bar {
		order: 5;
		position: sticky; bottom: calc(var(--bottom-bar-h) + env(safe-area-inset-bottom) + 8px); z-index: 30;
		display: flex; align-items: center; gap: var(--s-2);
		margin: var(--s-2) calc(-1 * var(--s-2)) 0; padding: 8px 8px 8px 16px;
		border: 1px solid var(--hairline); border-radius: var(--r-lg);
		background: var(--paper);
		box-shadow: var(--shadow-pop);
	}
	/* With the script, the site's bottom bar steps aside while this one is on screen (html.is-config-bar), so it
	   takes the bottom of the screen alone. */
	html.has-config-bar .config__bar { bottom: calc(env(safe-area-inset-bottom) + 8px); }
	.config__total { flex: 1 1 auto; min-width: 0; display: grid; gap: 2px; }
	.config__total-label { font-size: 0.75rem; }
	.config__total-value { font-size: 1.375rem; }
	.config__actions { display: flex; flex: none; min-width: 0; gap: var(--s-2); }
	.config__actions .btn { width: auto; }
	.config__add { padding-inline: 1.1em; }
	.config__wa { width: 48px !important; padding: 0; }
	.config__wa-label { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
	.config__wa .icon { width: 22px; height: 22px; }
	.config__line {
		grid-template-columns: 48px minmax(0, 1fr) 36px;
		grid-template-areas: "thumb what act" "thumb money act";
		align-content: center; row-gap: 4px; height: 104px;
	}
	.config__thumb { grid-area: thumb; width: 48px; height: 48px; }
	.config__what { grid-area: what; }
	.config__money { grid-area: money; display: flex; flex-direction: row-reverse; justify-content: space-between; align-items: baseline; gap: var(--s-2); }
	.config__act { grid-area: act; }
	.config__maker { display: none; }
	.config__meta:not(:has(.config__tag)) { display: none; }
	/* the reel's tag goes under its name, so the name keeps its two lines ("… · bobine 305 m") */
	.config__line--reel .config__meta { min-height: 22px; }
	.config__name { font-size: 0.9375rem; -webkit-line-clamp: 2; line-clamp: 2; }
	.config__ports-name { display: none; }
	.config__caption { right: 30%; }
	.config__nvr { width: 54%; top: 76%; }
	.config__reel { width: 15%; left: 88%; top: 64%; }
}
/* "Ajouter au panier" needs about 75 px more than "Ajouter": it fits from 440 px with a five-figure total. */
@media (max-width: 439px) {
	.config__long { display: none; }
}
/* One action bar at a time: the configurator's bar replaces the site's bottom bar while it is on screen. */
@media (max-width: 767px) {
	html.is-config-bar .bottom-bar { transform: translateY(110%); }
}
@container config-stage (max-width: 760px) {
	.config__facts { display: none; }
}
@container config-stage (max-width: 460px) {
	.config__caption-maker { font-size: 0.75rem; }
	.config__reel-qty { height: 22px; min-width: 26px; font-size: 0.75rem; }
}

@media (prefers-reduced-motion: reduce) {
	.odo__strip { transition: none; }
	.config__line.is-changed::before { animation: none; }
}
