/* ==========================================================================
   Moketal — "plan de pose"

   The subject is modular carpet tile: directional, laid to a pattern, and read
   from above. So the page is built like a laying plan seen at night on a drawing
   board — not a product page with a photo in it.

   Palette is olive-ink rather than neutral black: wool photographed warm dies on
   a cold grey ground. Brass appears only on interactive state, nowhere else.
   Type is geometric to match the wordmark's own letterforms, with a mono for
   anything measured — this product lives on datasheets.
   ========================================================================== */

@font-face {
	font-family: 'Outfit';
	src: url('../fonts/Outfit-latin.woff2') format('woff2');
	font-weight: 300 700;
	font-style: normal;
	font-display: swap;
	unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
		U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193,
		U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
	font-family: 'Outfit';
	src: url('../fonts/Outfit-latin-ext.woff2') format('woff2');
	font-weight: 300 700;
	font-style: normal;
	font-display: swap;
	unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
		U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020,
		U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* Jost, variable 400-500. A geometric sans in the Futura lineage — the
   tradition luxury houses actually set their labels in — replacing IBM Plex
   Mono, which is a developer typeface and read as a terminal on a showroom
   page. Used the same way the mono was: uppercase, letterspaced, small. */
@font-face {
	font-family: 'Jost';
	src: url('../fonts/Jost-latin.woff2') format('woff2');
	font-weight: 400 500; font-style: normal; font-display: swap;
	unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
		U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191,
		U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
	font-family: 'Jost';
	src: url('../fonts/Jost-latin-ext.woff2') format('woff2');
	font-weight: 400 500; font-style: normal; font-display: swap;
	unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
		U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020,
		U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

:root {
	/* Espresso-charcoal, brown-biased with zero green cast: the ground under wool
	   and oak photography, tuned to the taupe wordmark rather than to a screen. */
	--ink: #17120E;
	--board: #1F1914;
	--board-2: #29211A;
	--plaster: #EFE9E1;    /* headings, warm off-white */
	/* Text-safe brand taupe. The wordmark value (#887A6E) measures 3.81:1 on
	   --board-2 and 4.48:1 on --ink, so every one of the ~48 places it was used
	   as text failed AA on a dark ground — which is what made the site read
	   washed out. Lifted within the same warm family to clear AA on the worst
	   ground (5.52:1) while still reading as the brand colour. */
	--taupe: #A69684;
	/* The literal wordmark value, for fills and marks where contrast rules do
	   not apply. */
	--taupe-deep: #887A6E;
	--sand: #BFB3A4;       /* body copy, warm grey-beige — lifted for legibility */
	/* Retired from interactive states at the client's request; kept only for the
	   studio's simulation badge and any future print accent. Never on hover. */
	--brass: #C08A3E;
	--rule: rgba(239, 233, 225, 0.13);
	--rule-hi: rgba(239, 233, 225, 0.28);

	/* One family plus a mono. Display and body are both Outfit — weight and size
	   do the differentiating, which is the restraint a luxury register needs. */
	--display: 'Outfit', system-ui, sans-serif;
	--text: 'Outfit', system-ui, sans-serif;
	/* Still called --mono: the token names the role, the small letterspaced
	   label face, and 40 rules plus the .mono class depend on it. */
	--mono: 'Jost', 'Outfit', system-ui, sans-serif;

	--gutter: clamp(20px, 4.5vw, 68px);
	--max: 1600px;
	--ease: cubic-bezier(0.16, 0.84, 0.44, 1);

	/* Corner radii, taken from the wordmark: its letterforms are monoline with
	   generously rounded terminals, so the interface's surfaces follow. */
	--r-s: 10px;
	--r-m: 16px;
	--r-l: 24px;
}

*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; background: var(--ink); }
@media (prefers-reduced-motion: reduce) {
	html { scroll-behavior: auto; }
	*, *::before, *::after {
		animation-duration: 0.01ms !important;
		animation-iteration-count: 1 !important;
		transition-duration: 0.01ms !important;
		transition-delay: 0ms !important;
	}
}

body {
	margin: 0;
	background: var(--ink);
	color: var(--sand);
	font-family: var(--text);
	font-size: 17px;
	line-height: 1.7;
	-webkit-font-smoothing: antialiased;
}

/* Fine grain over the whole page. A flat dark fill reads as a screen; grain reads
   as a surface, which is the point when you are selling material. */
body::after {
	content: '';
	position: fixed;
	inset: 0;
	z-index: 200;
	pointer-events: none;
	opacity: 0.05;
	background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)'/%3E%3C/svg%3E");
}

img, svg { max-width: 100%; height: auto; display: block; }
a { color: inherit; text-decoration: none; }

h1, h2, h3 {
	font-family: var(--display);
	font-weight: 300;
	line-height: 0.98;
	letter-spacing: -0.035em;
	color: var(--plaster);
	margin: 0;
	text-wrap: balance;
}
h1 { font-size: clamp(2.9rem, 6.4vw, 6.2rem); }
h2 { font-size: clamp(1.9rem, 3.6vw, 3.3rem); }
h3 { font-size: clamp(1.1rem, 1.5vw, 1.4rem); font-weight: 400; letter-spacing: -0.02em; }
p { margin: 0 0 1.05em; text-wrap: pretty; }

.wrap { width: 100%; max-width: var(--max); margin-inline: auto; padding-inline: var(--gutter); }

/* Anything measured, coded or labelled is set in mono. Standards, dimensions,
   counts, decor names in the console. This is the page's connective tissue. */
.mono {
	font-family: var(--mono);
	font-size: 0.8rem;
	font-weight: 400;
	letter-spacing: 0.13em;
	text-transform: uppercase;
	color: var(--sand);
	margin: 0;
}

.lnk {
	display: inline-flex;
	align-items: center;
	gap: 0.65rem;
	font-family: var(--mono);
	font-size: 0.8rem;
	letter-spacing: 0.16em;
	text-transform: uppercase;
	color: var(--plaster);
	padding-bottom: 0.5rem;
	border-bottom: 1px solid var(--rule-hi);
	transition: border-color 0.35s var(--ease), color 0.35s var(--ease);
}
.lnk:hover { border-bottom-color: var(--plaster); color: var(--plaster); }
.lnk i { font-style: normal; transition: transform 0.35s var(--ease); }
.lnk:hover i { transform: translateX(4px); }

/* --- Header ------------------------------------------------------------- */

.hd {
	position: fixed;
	inset: 0 0 auto;
	z-index: 60;
	border-bottom: 1px solid transparent;
	transition: background 0.45s var(--ease), border-color 0.45s var(--ease);
}
.hd.is-stuck {
	background: color-mix(in srgb, var(--ink) 88%, transparent);
	backdrop-filter: blur(16px);
	border-bottom-color: var(--rule);
}
.hd__in {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 2rem;
	min-height: 82px;
}
/* The wordmark is 7.9:1 — a width-based lockup, never a square slot. */
.brand { flex: 0 0 auto; }
.brand svg { width: clamp(120px, 12vw, 158px); }
.brand svg path { fill: var(--plaster); transition: fill 0.35s var(--ease); }
.brand:hover svg path { fill: var(--taupe); }

.nav ul { display: flex; gap: clamp(1rem, 2vw, 2.1rem); list-style: none; margin: 0; padding: 0; }
.nav a {
	font-family: var(--mono);
	font-size: 0.76rem;
	letter-spacing: 0.16em;
	text-transform: uppercase;
	color: var(--sand);
	transition: color 0.3s var(--ease);
}
.nav a:hover, .nav .current-menu-item > a { color: var(--plaster); }

.burger { display: none; }

/* --- The floor (calepinage viewer) ---------------------------------------
   Fills whatever positioned container it is given; the studio section provides
   the stage. */

.floor {
	position: absolute;
	inset: 0;
	display: grid;
	grid-template-columns: repeat(var(--cols, 10), 1fr);
	grid-auto-rows: 1fr;
	gap: 1px;
	background: var(--board);
}
.floor__t {
	position: relative;
	background-size: cover;
	background-position: center;
	background-color: var(--board-2);
	/* Each tile rotates and offsets independently; JS sets --r and --tx per tile
	   and --d staggers them into a diagonal wave when the pattern changes. */
	transform: translateX(var(--tx, 0)) rotate(var(--r, 0deg));
	transition: transform 0.75s var(--ease), background-image 0.5s linear;
	transition-delay: var(--d, 0ms);
	will-change: transform;
}
/* Seam shading so the grid reads as laid tile, not as a CSS grid. */
.floor__t::after {
	content: '';
	position: absolute;
	inset: 0;
	box-shadow: inset 0 0 22px rgba(15, 11, 8, 0.5);
	pointer-events: none;
}
/* Rows shift half a tile in pose décalée, so the grid has to clip. */
.floor { overflow: hidden; }

/* Console: the instrument bar. Reads as drawing-board hardware, not a web form. */
.console {
	position: relative;
	z-index: 2;
	background: var(--board);
	border-top: 1px solid var(--rule);
	padding: 1.4rem var(--gutter) 1.5rem;
	display: grid;
	grid-template-columns: minmax(0, 1fr) minmax(0, 1.15fr);
	gap: 1.6rem clamp(2rem, 5vw, 4.5rem);
	align-items: start;
}
.console fieldset { border: 0; margin: 0; padding: 0; min-width: 0; }
.console legend { padding: 0; margin-bottom: 0.85rem; }

.opts { display: flex; flex-wrap: wrap; gap: 0.5rem; }

/* Pattern buttons draw their own miniature laying diagram — the control shows
   the thing it does rather than naming it and hoping. */
.pat {
	display: inline-flex;
	align-items: center;
	gap: 0.6rem;
	background: none;
	border: 1px solid var(--rule);
	color: var(--sand);
	padding: 0.5rem 0.85rem 0.5rem 0.5rem;
	cursor: pointer;
	font-family: var(--mono);
	font-size: 0.64rem;
	letter-spacing: 0.11em;
	text-transform: uppercase;
	transition: border-color 0.3s var(--ease), color 0.3s var(--ease), background 0.3s var(--ease);
}
.pat:hover { border-color: var(--rule-hi); color: var(--plaster); }
.pat[aria-pressed='true'] { border-color: var(--plaster); color: var(--plaster); background: rgba(239, 233, 225, 0.05); }
.pat svg { width: 22px; height: 22px; flex: 0 0 auto; }
.pat svg rect { fill: none; stroke: currentColor; stroke-width: 1.4; }
.pat svg line { stroke: currentColor; stroke-width: 1.4; opacity: 0.7; }

/* Decor chips: the actual material, small and dense. */
.chips { display: flex; flex-wrap: wrap; gap: 4px; }
.chip {
	width: 30px;
	height: 30px;
	padding: 0;
	border: 1px solid transparent;
	outline-offset: 2px;
	background-size: cover;
	background-position: center;
	cursor: pointer;
	transition: transform 0.3s var(--ease), border-color 0.3s var(--ease);
}
.chip:hover { transform: translateY(-3px); }
.chip[aria-pressed='true'] { border-color: var(--plaster); transform: translateY(-3px); }

.console__read {
	grid-column: 1 / -1;
	display: flex;
	flex-wrap: wrap;
	gap: 0.5rem 1.6rem;
	padding-top: 1rem;
	border-top: 1px solid var(--rule);
	font-family: var(--mono);
	font-size: 0.66rem;
	letter-spacing: 0.1em;
	color: var(--taupe);
	text-transform: uppercase;
}
.console__read b { color: var(--plaster); font-weight: 500; }

/* --- Shop hero ----------------------------------------------------------
   A real room scene, full bleed. The copy sits low-left on a scrim angled at
   the wordmark's 10deg. */

.shopero {
	position: relative;
	min-height: 88svh;
	display: flex;
	align-items: flex-end;
	overflow: hidden;
}
.shopero__img {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	object-fit: cover;
	object-position: center 40%;
}
.shopero__scrim {
	position: absolute;
	inset: 0;
	background:
		/* Top band keeps the fixed header legible over the bright archways. */
		linear-gradient(to bottom, color-mix(in srgb, var(--ink) 78%, transparent), transparent 17%),
		linear-gradient(100deg, color-mix(in srgb, var(--ink) 88%, transparent) 8%, color-mix(in srgb, var(--ink) 45%, transparent) 44%, transparent 72%),
		linear-gradient(to top, var(--ink) 0%, color-mix(in srgb, var(--ink) 55%, transparent) 26%, transparent 55%);
}
.shopero .wrap { position: relative; z-index: 2; }
.shopero__copy {
	padding-block: 0 clamp(3rem, 8vh, 5.5rem);
	max-width: 46rem;
}
.shopero__copy h1 { margin-top: 1.4rem; }
.shopero__lead { margin-top: 1.4rem; max-width: 38ch; font-size: 1.02rem; color: var(--plaster); opacity: 0.85; }
.shopero__cta { display: flex; flex-wrap: wrap; gap: 1rem 2.2rem; margin-top: 2rem; }

/* --- Category tiles ------------------------------------------------------ */

.cats {
	display: grid;
	grid-template-columns: repeat(3, minmax(0, 1fr));
	gap: clamp(0.8rem, 1.6vw, 1.4rem);
}
.cat {
	position: relative;
	display: block;
	overflow: hidden;
}
.cat__img {
	display: block;
	aspect-ratio: 4 / 3;
	background-size: cover;
	background-position: center;
	transition: transform 0.8s var(--ease);
}
.cat:hover .cat__img { transform: scale(1.045); }
.cat__body {
	position: absolute;
	inset: auto 0 0;
	padding: 2.2rem 1.2rem 1rem;
	background: linear-gradient(to top, rgba(23, 18, 14, 0.94), transparent);
}
.cat__body h3 { margin-bottom: 0.2rem; }
.cat__body .mono { font-size: 0.7rem; }

.cats--4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.cats--4 .cat__img { aspect-ratio: 3 / 4; }

.cats-more {
	display: flex;
	flex-wrap: wrap;
	align-items: baseline;
	gap: 0.5rem 1.8rem;
	margin-top: clamp(1.4rem, 2.5vw, 2rem);
	padding-top: 1.2rem;
	border-top: 1px solid var(--rule);
}
.cats-more__g { color: var(--taupe); min-width: 3.2rem; }
.cats-more a {
	font-family: var(--mono);
	font-size: 0.76rem;
	letter-spacing: 0.12em;
	text-transform: uppercase;
	color: var(--taupe);
	transition: color 0.3s var(--ease);
}
.cats-more a:hover { color: var(--plaster); }

/* --- Product cards -------------------------------------------------------
   Frameless, portrait, editorial — the register of a fashion house, not a
   marketplace. No borders, no chips, no coloured hover: the image does the
   work, and where a second image exists the hover crossfades from the room
   scene to the material itself. No price on a card, ever. */

.cards {
	display: grid;
	grid-template-columns: repeat(4, minmax(0, 1fr));
	gap: clamp(1.4rem, 2.4vw, 2rem) clamp(1rem, 1.6vw, 1.5rem);
}
.card { display: block; }
.card__media {
	position: relative;
	display: block;
	aspect-ratio: 4 / 5;
	overflow: hidden;
	background: var(--board);
}
.card__img {
	position: absolute;
	inset: 0;
	background-size: cover;
	background-position: center;
	transition: transform 1.2s var(--ease), opacity 0.6s var(--ease);
}
.card:hover .card__img { transform: scale(1.04); }
.card__img--alt { opacity: 0; }
.card:hover .card__img--alt { opacity: 1; transform: none; }
.card__body { padding: 0.95rem 0 0; }
.card__body .mono { font-size: 0.68rem; }
.card__body h3 { margin: 0.4rem 0 0.3rem; font-size: 1.2rem; font-weight: 400; }
.card__meta {
	display: block;
	font-family: var(--mono);
	font-size: 0.76rem;
	letter-spacing: 0.06em;
	color: var(--sand);
}
.card__cta {
	display: inline-block;
	margin-top: 0.65rem;
	font-family: var(--mono);
	font-size: 0.72rem;
	letter-spacing: 0.16em;
	text-transform: uppercase;
	color: var(--plaster);
	border-bottom: 1px solid var(--rule-hi);
	padding-bottom: 0.25rem;
	opacity: 0;
	transform: translateY(4px);
	transition: opacity 0.35s var(--ease), transform 0.35s var(--ease);
}
.card:hover .card__cta { opacity: 1; transform: none; }
@media (hover: none) { .card__cta { opacity: 1; transform: none; } }

/* Homepage CTA: same quiet-underline register as .card__cta, no filled button —
   the homepage carries exactly one call to action. */
.hero__cta {
	display: inline-block;
	margin-top: 1.6rem;
	font-family: var(--mono);
	font-size: 0.78rem;
	letter-spacing: 0.16em;
	text-transform: uppercase;
	color: var(--plaster);
	border-bottom: 1px solid var(--rule-hi);
	padding-bottom: 0.3rem;
	text-decoration: none;
	transition: border-color 0.3s var(--ease), color 0.3s var(--ease);
}
.hero__cta:hover { color: var(--taupe); border-color: var(--taupe); }

/* Homepage catalogue grid ---------------------------------------------------
   Reuses the .card / .grid product-card language for visual continuity: a
   category tile and a product card are the same kind of object here. */
.home__cats { padding: clamp(2rem, 5vw, 4rem) 0 clamp(4rem, 8vw, 7rem); }
.home__cats h2 { margin: 0 0 1.6rem; }
.card--noimg .card__media { background: var(--board-2); }

/* --- Rail: horizontal product slider -------------------------------------
   Scroll-snap with a partial card peeking at the edge, thin progress line,
   quiet arrows. */

.rail-head {
	display: flex;
	align-items: flex-end;
	justify-content: space-between;
	gap: 2rem;
}
.rail-nav { display: flex; gap: 0.5rem; }
.rail-nav button {
	width: 44px;
	height: 44px;
	display: grid;
	place-items: center;
	background: none;
	border: 1px solid var(--rule);
	color: var(--sand);
	font-family: var(--mono);
	font-size: 0.9rem;
	cursor: pointer;
	transition: border-color 0.3s var(--ease), color 0.3s var(--ease);
}
.rail-nav button:hover { border-color: var(--rule-hi); color: var(--plaster); }
.rail {
	display: grid;
	grid-auto-flow: column;
	grid-auto-columns: calc((100% - 3 * 20px) / 3.6);
	gap: 20px;
	overflow-x: auto;
	scroll-snap-type: x mandatory;
	scrollbar-width: none;
	margin-top: clamp(1.6rem, 3vw, 2.4rem);
}
.rail::-webkit-scrollbar { display: none; }
.rail .card { scroll-snap-align: start; }
.rail-progress {
	position: relative;
	height: 1px;
	background: var(--rule);
	margin-top: clamp(1.4rem, 2.5vw, 2rem);
}
.rail-progress span {
	position: absolute;
	inset: 0 auto 0 0;
	width: var(--p, 25%);
	background: var(--plaster);
	transition: width 0.15s linear;
}
@media (max-width: 1100px) { .rail { grid-auto-columns: calc((100% - 2 * 20px) / 2.4); } }
@media (max-width: 640px) { .rail { grid-auto-columns: calc((100% - 20px) / 1.2); } }

/* --- Material placeholders ----------------------------------------------
   Designed tiles for categories without photography yet: honest colour and
   pattern, not fake photos. Swapped for real shots as they arrive. */

.mat { background-color: var(--board-2); }
.mat--wood {
	background:
		repeating-linear-gradient(90deg,
			rgba(0, 0, 0, 0.22) 0 1px, transparent 1px 23%),
		linear-gradient(90deg, #4A3626, #5C4430 34%, #46331F 67%, #55402B);
}
.mat--wood-light {
	background:
		repeating-linear-gradient(90deg,
			rgba(0, 0, 0, 0.14) 0 1px, transparent 1px 23%),
		linear-gradient(90deg, #8A6F4E, #9C8262 38%, #83694A 70%, #94795A);
}
.mat--wood-chevron {
	background:
		repeating-linear-gradient(45deg,
			#54402B 0 26px, #47351F 26px 52px),
		#4A3626;
}
.mat--slate {
	background:
		repeating-linear-gradient(0deg,
			rgba(255, 255, 255, 0.03) 0 1px, transparent 1px 26%),
		linear-gradient(120deg, #3A4042, #2E3436 55%, #384042);
}
.mat--sport {
	/* Maple sports hall with painted court lines — no green anywhere. */
	background:
		linear-gradient(0deg, transparent 47%, rgba(239, 233, 225, 0.35) 47% 48.6%, transparent 48.6%),
		linear-gradient(90deg, transparent 30%, rgba(239, 233, 225, 0.35) 30% 31.4%, transparent 31.4%),
		repeating-linear-gradient(90deg, rgba(0, 0, 0, 0.08) 0 1px, transparent 1px 12%),
		linear-gradient(140deg, #A98B5F, #97794E 55%, #A5865A);
}
.mat--felt {
	/* Événementiel needle-punch: the classic deep red, fibrous via fine striping. */
	background:
		repeating-linear-gradient(0deg, rgba(0, 0, 0, 0.10) 0 1px, transparent 1px 3px),
		linear-gradient(135deg, #6E1F1E, #571716 58%, #66201E);
}
.mat--weave {
	/* Woven wallpaper: fine crosshatch on warm écru. */
	background:
		repeating-linear-gradient(0deg, rgba(0, 0, 0, 0.05) 0 1px, transparent 1px 5px),
		repeating-linear-gradient(90deg, rgba(0, 0, 0, 0.05) 0 1px, transparent 1px 5px),
		linear-gradient(120deg, #C8B79F, #BCA98F 55%, #C4B29A);
}
.mat--plaster {
	/* Painted cornice profile: light bands and their cast shadows. */
	background:
		linear-gradient(to bottom,
			#DFD8CC 0 18%, #CEC5B7 18% 22%, #E6DFD4 22% 38%, #BFB5A6 38% 41%,
			#DAD2C5 41% 58%, #CBC1B2 58% 61%, #E2DBD0 61% 100%);
}
.mat--steel {
	background:
		repeating-linear-gradient(90deg, rgba(0, 0, 0, 0.28) 0 1px, transparent 1px 25%),
		repeating-linear-gradient(0deg, rgba(0, 0, 0, 0.28) 0 1px, transparent 1px 33%),
		linear-gradient(120deg, #57565028, #3F3E38),
		#4B4A44;
}

/* --- Studio (calepinage viewer) ------------------------------------------
   The stage is a real room photo; the tile engine renders into a perspective
   plane laid over the photographed floor. The plane fades out with distance so
   it never collides with furniture standing on the original floor. */

.studio { border-block: 1px solid var(--rule); }
/* Fixed aspect: with background-size cover, a constant aspect means the photo
   crop is the same at every viewport, so the floor quad can be authored once in
   stage fractions and stays glued to the photographed floor. */
.studio__stage { position: relative; aspect-ratio: 12 / 5; max-height: 660px; overflow: hidden; }
.studio .console { border-top: 1px solid var(--rule); background: var(--board); backdrop-filter: none; }

.mockup { background-size: cover; background-position: center 32%; }

/* The plane fills the stage; the JS pins the tile grid's four corners onto the
   photographed floor with a matrix3d homography, so its vanishing lines are the
   photo's own. The soft top mask (set by JS just above the far edge) hides the
   seam where the swap zone meets the wall line. */
.mockup__plane {
	position: absolute;
	inset: 0;
	overflow: hidden;
}
.mockup__plane .floor {
	position: absolute;
	inset: 0;
	transform-origin: 0 0;
	gap: 2px;
	/* Dark backing: the grid gaps are the seams, and a seam is a shadow — left
	   transparent they let the photo's bright original floor bleed through. */
	background: rgba(18, 13, 10, 0.92);
}
/* In the mockup, tiles keep their own pattern transforms but sit on the tilted
   plane; a slightly stronger seam shadow sells the depth. */
.mockup__plane .floor__t { background-color: transparent; }
.mockup__plane .floor__t::after { box-shadow: inset 0 0 14px rgba(15, 11, 8, 0.55); }

/* Photo lighting re-imposed over the plane: window light falls from the left in
   the room scene, so the plane brightens left and falls into shadow at the
   right foreground corner. Multiply keeps the tile texture underneath. */
.mockup__shade {
	position: absolute;
	inset: 0;
	pointer-events: none;
	background:
		radial-gradient(120% 90% at 18% 30%, rgba(255, 244, 224, 0.14), transparent 55%),
		linear-gradient(105deg, transparent 45%, rgba(15, 11, 8, 0.30) 100%),
		linear-gradient(to top, rgba(15, 11, 8, 0.34), transparent 45%);
	mix-blend-mode: multiply;
}

.mockup__hint {
	position: absolute;
	right: 1rem;
	bottom: 0.9rem;
	z-index: 2;
	padding: 0.35rem 0.6rem;
	background: color-mix(in srgb, var(--ink) 72%, transparent);
	backdrop-filter: blur(8px);
	border: 1px solid var(--rule);
	color: var(--sand);
}

/* --- Nuancier band -------------------------------------------------------- */

.band {
	display: grid;
	grid-auto-flow: column;
	grid-auto-columns: minmax(0, 1fr);
	height: clamp(90px, 12vw, 150px);
	gap: 1px;
	margin: clamp(1.8rem, 3.5vw, 2.8rem) 0;
}
.band span { background-size: cover; background-position: center; }

/* --- Sections ----------------------------------------------------------- */

.sec { padding-block: clamp(4.5rem, 9vw, 8.5rem); }
.sec--board { background: var(--board); }

.head {
	display: grid;
	grid-template-columns: minmax(0, 0.34fr) minmax(0, 1fr);
	gap: 1.4rem clamp(2rem, 5vw, 5rem);
	align-items: baseline;
	padding-bottom: clamp(1.8rem, 3vw, 2.6rem);
	margin-bottom: clamp(2rem, 3.5vw, 3rem);
	border-bottom: 1px solid var(--rule);
}
.head__note { margin: 0.85rem 0 0; max-width: 54ch; }

/* --- Nuancier wall ------------------------------------------------------
   Fixed column counts, not auto-fill: 48 tiles divide evenly by 12/8/6/4 so the
   last row is never ragged. */

.wall { display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); gap: 1px; }
.wall__t {
	position: relative;
	aspect-ratio: 1;
	background-size: cover;
	background-position: center;
	overflow: hidden;
}
.wall__t::after {
	content: '';
	position: absolute;
	inset: 0;
	box-shadow: inset 0 0 18px rgba(15, 11, 8, 0.42);
	transition: box-shadow 0.4s var(--ease);
}
.wall__t:hover::after { box-shadow: inset 0 0 0 1px var(--plaster); }
.wall__m {
	position: absolute;
	inset: auto 0 0;
	z-index: 2;
	padding: 1.5rem 0.75rem 0.7rem;
	background: linear-gradient(to top, rgba(23, 18, 14, 0.94), transparent);
	opacity: 0;
	transform: translateY(6px);
	transition: opacity 0.35s var(--ease), transform 0.35s var(--ease);
}
.wall__t:hover .wall__m, .wall__t:focus-visible .wall__m { opacity: 1; transform: none; }
.wall__n { display: block; font-size: 0.92rem; color: var(--plaster); line-height: 1.3; }
.wall__c { display: block; font-family: var(--mono); font-size: 0.68rem; letter-spacing: 0.1em; text-transform: uppercase; color: var(--taupe); }

/* --- Collection index --------------------------------------------------- */

.idx { border-top: 1px solid var(--rule); }
.idx__r {
	display: grid;
	grid-template-columns: minmax(0, 0.3fr) minmax(0, 0.4fr) minmax(0, 1fr) auto;
	gap: clamp(1rem, 3vw, 3rem);
	align-items: center;
	padding: clamp(1.1rem, 2.2vw, 1.8rem) 0;
	border-bottom: 1px solid var(--rule);
	transition: padding-left 0.4s var(--ease);
}
.idx__r:hover { padding-left: 1rem; }
.idx__r:hover h3 { color: var(--plaster); }
.idx__r h3 { transition: color 0.35s var(--ease); }
.idx__strip {
	display: grid;
	grid-auto-flow: column;
	grid-auto-columns: minmax(0, 1fr);
	height: 42px;
	gap: 1px;
	transform: skewX(-10deg);
}
.idx__strip span { background-size: cover; background-position: center; }
.idx__go { font-family: var(--mono); color: var(--taupe); transition: transform 0.4s var(--ease), color 0.4s var(--ease); }
.idx__r:hover .idx__go { transform: translateX(5px); color: var(--plaster); }

/* --- Specs -------------------------------------------------------------- */

.split { display: grid; grid-template-columns: minmax(0, 0.8fr) minmax(0, 1fr); gap: clamp(2.5rem, 6vw, 6rem); align-items: start; }
.specs table { width: 100%; border-collapse: collapse; }
.specs caption {
	caption-side: top;
	text-align: left;
	padding-bottom: 0.9rem;
	margin-bottom: 0.3rem;
	border-bottom: 1px solid var(--rule-hi);
	font-family: var(--mono);
	font-size: 0.66rem;
	letter-spacing: 0.16em;
	text-transform: uppercase;
	color: var(--taupe);
}
.specs tr { border-bottom: 1px solid var(--rule); }
.specs th { text-align: left; font-weight: 400; color: var(--sand); padding: 0.85rem 1rem 0.85rem 0; width: 50%; font-size: 1rem; }
.specs td { padding: 0.85rem 0; text-align: right; font-family: var(--mono); font-weight: 500; font-size: 0.92rem; color: var(--plaster); }
.specs em { display: block; font-family: var(--mono); font-style: normal; font-size: 0.72rem; letter-spacing: 0.1em; color: var(--taupe); }

/* --- Footer ------------------------------------------------------------- */

.ft { background: var(--board); border-top: 1px solid var(--rule); padding-block: clamp(3.5rem, 7vw, 6rem) 1.8rem; font-size: 0.98rem; }
.ft__g { display: grid; grid-template-columns: minmax(0, 1.5fr) repeat(3, minmax(0, 1fr)); gap: clamp(2rem, 4vw, 4rem); }
.ft h4 { font-family: var(--mono); font-size: 0.74rem; font-weight: 400; letter-spacing: 0.18em; text-transform: uppercase; color: var(--taupe); margin: 0 0 1.1rem; }
.ft ul { list-style: none; margin: 0; padding: 0; }
.ft li { margin-bottom: 0.6rem; }
.ft a { color: var(--sand); transition: color 0.3s var(--ease); }
.ft a:hover { color: var(--plaster); }
.ft .brand svg { width: 146px; }
.ft__b {
	margin-top: clamp(2.5rem, 5vw, 4rem);
	padding-top: 1.5rem;
	border-top: 1px solid var(--rule);
	display: flex;
	flex-wrap: wrap;
	gap: 0.8rem 2rem;
	justify-content: space-between;
	font-family: var(--mono);
	font-size: 0.66rem;
	letter-spacing: 0.08em;
	color: var(--taupe);
}

/* --- Reveal ------------------------------------------------------------- */

.rv { opacity: 0; transform: translateY(16px); animation: rise 0.9s var(--ease) forwards; }
@keyframes rise { to { opacity: 1; transform: none; } }
.rv:nth-child(1) { animation-delay: 0.1s; }
.rv:nth-child(2) { animation-delay: 0.22s; }
.rv:nth-child(3) { animation-delay: 0.34s; }
.rv:nth-child(4) { animation-delay: 0.46s; }

/* --- A11y --------------------------------------------------------------- */

.skip { position: absolute; left: -9999px; top: 0; z-index: 300; padding: 1rem 1.5rem; background: var(--plaster); color: var(--ink); }
.skip:focus { left: 0; }
.screen-reader-text {
	position: absolute !important;
	width: 1px; height: 1px; padding: 0; margin: -1px;
	overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0;
}
:focus-visible { outline: 2px solid var(--plaster); outline-offset: 3px; }

/* --- Responsive --------------------------------------------------------- */

@media (max-width: 1280px) {
	.wall { grid-template-columns: repeat(8, minmax(0, 1fr)); }
	.cards { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

@media (max-width: 1080px) {
	.idx__r { grid-template-columns: minmax(0, 0.5fr) minmax(0, 1fr) auto; }
	.idx__strip { display: none; }
}

@media (max-width: 900px) {
	.wall { grid-template-columns: repeat(6, minmax(0, 1fr)); }
	.head, .split { grid-template-columns: minmax(0, 1fr); }
	.console { grid-template-columns: minmax(0, 1fr); }
	.cats, .cats--4 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
	.cards { grid-template-columns: repeat(2, minmax(0, 1fr)); }
	.shopero { min-height: 74svh; }
	.ft__g { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (max-width: 600px) {
	.wall { grid-template-columns: repeat(4, minmax(0, 1fr)); }
	.cats, .cats--4, .cards { grid-template-columns: minmax(0, 1fr); }
	.nav { display: none; }
	.burger { display: inline-flex; flex-direction: column; gap: 5px; background: none; border: 0; padding: 10px 0; cursor: pointer; }
	.burger span { display: block; width: 25px; height: 1px; background: var(--plaster); }
	.idx__r { grid-template-columns: minmax(0, 1fr) auto; row-gap: 0.3rem; }
	.ft__g { grid-template-columns: minmax(0, 1fr); }
}

/* --- Routed pages: heads, collection nav, forms -------------------------- */

.page-head { padding: clamp(7.5rem, 14vh, 10rem) 0 clamp(2rem, 4vw, 3rem); }
.page-head h1 { font-size: clamp(2.2rem, 4.5vw, 4rem); margin-top: 1.1rem; }
.page-head__note { margin: 1rem 0 0; max-width: 52ch; }

.coll-nav { display: flex; flex-wrap: wrap; gap: 0.5rem 1.6rem; margin-top: 1.8rem; }
.coll-nav a {
	font-family: var(--mono);
	font-size: 0.76rem;
	letter-spacing: 0.14em;
	text-transform: uppercase;
	color: var(--sand);
	padding-bottom: 0.4rem;
	border-bottom: 1px solid transparent;
	transition: color 0.3s var(--ease), border-color 0.3s var(--ease);
}
.coll-nav a:hover { color: var(--plaster); }
.coll-nav a[aria-current='page'] { color: var(--plaster); border-bottom-color: var(--plaster); }

.cards--static .card { scroll-snap-align: unset; }

.lead { display: flex; flex-direction: column; gap: 1.1rem; }
.lead__row { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 1.1rem; }
.lead label { display: flex; flex-direction: column; gap: 0.45rem; }
.lead input,
.lead textarea {
	background: var(--board);
	border: 1px solid var(--rule);
	color: var(--plaster);
	padding: 0.85rem 0.95rem;
	font-family: var(--text);
	font-size: 0.95rem;
	transition: border-color 0.3s var(--ease);
}
.lead input:focus,
.lead textarea:focus { outline: none; border-color: var(--rule-hi); }
.lead__submit {
	align-self: flex-start;
	padding: 1rem 1.8rem;
	background: var(--plaster);
	color: var(--ink);
	border: 0;
	font-family: var(--mono);
	font-size: 0.68rem;
	letter-spacing: 0.16em;
	text-transform: uppercase;
	cursor: pointer;
	transition: opacity 0.3s var(--ease);
}
.lead__submit:hover { opacity: 0.85; }

.form-note { padding: 0.9rem 1.1rem; border: 1px solid var(--rule-hi); margin-bottom: 1.4rem; }
.form-note--ok { color: var(--plaster); }
.form-note--err { color: #C89B8A; border-color: rgba(200, 155, 138, 0.4); }

.contact-list { list-style: none; margin: 1rem 0 0; padding: 0; }
.contact-list li { margin-bottom: 0.6rem; }
.contact-list a { border-bottom: 1px solid var(--rule-hi); padding-bottom: 2px; }

@media (max-width: 640px) {
	.lead__row { grid-template-columns: minmax(0, 1fr); }
}

/* --- Rounded surfaces -----------------------------------------------------
   Radii from the wordmark's letterforms (see :root). Images, tiles, controls
   and form fields all carry them; hairline rules and type stay sharp. */

.card__media { border-radius: var(--r-m); }
.cat { border-radius: var(--r-m); }
.wall__t { border-radius: var(--r-s); }
.wall { margin-inline: var(--gutter); border-radius: var(--r-m); overflow: hidden; }
.band { margin-inline: var(--gutter); border-radius: var(--r-m); overflow: hidden; }

.pat { border-radius: var(--r-s); }
.chip { border-radius: 8px; }
.rail-nav button { border-radius: 50%; }
.lead input,
.lead textarea { border-radius: var(--r-s); }
.lead__submit { border-radius: 999px; }
.form-note { border-radius: var(--r-s); }
.mockup__hint { border-radius: 999px; }
.idx__strip { border-radius: 6px; overflow: hidden; }

/* The simulator becomes a contained, rounded module instead of a full-bleed
   band: stage on top, console below, one soft-cornered box. */
.studio { border-block: 0; }
.studio-box {
	border: 1px solid var(--rule);
	border-radius: var(--r-l);
	overflow: hidden;
}
.studio-box .console { padding-inline: 1.6rem; }

/* --- Designed material tiles (.tex) ---------------------------------------
   Product media without photography: one tint from the product's first finish
   plus a texture family. Honest designed tiles, not fake photos; the global
   grain overlay does the rest. */

.tex { background-color: var(--tint, #4A4238); }
.tex--wood {
	background-image:
		repeating-linear-gradient(90deg, rgba(0, 0, 0, 0.16) 0 1px, transparent 1px 21%),
		linear-gradient(90deg, rgba(0, 0, 0, 0.10), transparent 30% 70%, rgba(0, 0, 0, 0.14));
}
.tex--slats {
	background-image:
		repeating-linear-gradient(90deg, rgba(0, 0, 0, 0.42) 0 6px, transparent 6px 26px);
}
.tex--chevron {
	background-image:
		repeating-linear-gradient(45deg, rgba(0, 0, 0, 0.12) 0 26px, transparent 26px 52px),
		repeating-linear-gradient(-45deg, rgba(255, 255, 255, 0.05) 0 26px, transparent 26px 52px);
}
.tex--stone {
	background-image:
		radial-gradient(90% 60% at 30% 30%, rgba(255, 255, 255, 0.07), transparent 60%),
		radial-gradient(80% 60% at 75% 70%, rgba(0, 0, 0, 0.10), transparent 60%),
		linear-gradient(0deg, transparent 48%, rgba(0, 0, 0, 0.14) 48% 49%, transparent 49%);
}
.tex--felt {
	background-image:
		repeating-linear-gradient(0deg, rgba(0, 0, 0, 0.08) 0 1px, transparent 1px 3px);
}
.tex--carpet {
	background-image:
		repeating-linear-gradient(0deg, rgba(0, 0, 0, 0.07) 0 1px, transparent 1px 3px),
		repeating-linear-gradient(90deg, rgba(255, 255, 255, 0.03) 0 1px, transparent 1px 3px);
}
.tex--plain {
	background-image: radial-gradient(120% 100% at 50% 0%, rgba(255, 255, 255, 0.06), rgba(0, 0, 0, 0.10));
}

/* --- Card additions: badge, finish dots, button CTA ----------------------- */

.card__badge {
	position: absolute;
	top: 0.75rem;
	left: 0.75rem;
	z-index: 2;
	padding: 0.3rem 0.6rem;
	border-radius: 999px;
	background: color-mix(in srgb, var(--ink) 72%, transparent);
	backdrop-filter: blur(8px);
	border: 1px solid var(--rule);
	font-family: var(--mono);
	font-size: 0.66rem;
	letter-spacing: 0.12em;
	text-transform: uppercase;
	color: var(--plaster);
}
.card__dots {
	position: absolute;
	bottom: 0.75rem;
	left: 0.75rem;
	z-index: 2;
	display: inline-flex;
	align-items: center;
	gap: 4px;
}
.card__dots i {
	width: 12px;
	height: 12px;
	border-radius: 50%;
	border: 1px solid rgba(255, 255, 255, 0.35);
}
.card__dots b {
	font-family: var(--mono);
	font-size: 0.58rem;
	font-weight: 400;
	color: var(--plaster);
	margin-left: 2px;
	text-shadow: 0 1px 4px rgba(0, 0, 0, 0.6);
}
button.card__cta { background: none; cursor: pointer; text-align: left; }

/* --- Devis pill ------------------------------------------------------------ */

.devis-pill {
	display: inline-flex;
	align-items: center;
	gap: 0.5rem;
	padding: 0.55rem 1.05rem;
	border-radius: 999px;
	border: 1px solid var(--rule-hi);
	background: none;
	color: var(--plaster);
	font-family: var(--mono);
	font-size: 0.74rem;
	letter-spacing: 0.14em;
	text-transform: uppercase;
	cursor: pointer;
	transition: border-color 0.3s var(--ease), background 0.3s var(--ease);
}
.devis-pill:hover { border-color: var(--plaster); }
.devis-pill b {
	min-width: 18px;
	height: 18px;
	border-radius: 50%;
	background: var(--plaster);
	color: var(--ink);
	font-weight: 500;
	font-size: 0.6rem;
	display: grid;
	place-items: center;
}

/* --- Filters --------------------------------------------------------------- */

.filters {
	display: flex;
	flex-direction: column;
	gap: 1rem;
	padding: 1.2rem 0 1.4rem;
	border-block: 1px solid var(--rule);
	margin-bottom: clamp(1.6rem, 3vw, 2.4rem);
}
.filters__group { display: flex; align-items: baseline; gap: 1.2rem; }
.filters__group > .mono { min-width: 4.5rem; }
.filters__opts { display: flex; flex-wrap: wrap; gap: 0.45rem; }
.fchip {
	display: inline-flex;
	align-items: center;
	gap: 0.45rem;
	padding: 0.4rem 0.8rem;
	border-radius: 999px;
	border: 1px solid var(--rule);
	background: none;
	color: var(--sand);
	font-family: var(--mono);
	font-size: 0.72rem;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	cursor: pointer;
	transition: border-color 0.3s var(--ease), color 0.3s var(--ease);
}
.fchip:hover { color: var(--plaster); border-color: var(--rule-hi); }
.fchip[aria-pressed='true'] { color: var(--ink); background: var(--plaster); border-color: var(--plaster); }
.fchip i { width: 11px; height: 11px; border-radius: 50%; border: 1px solid rgba(255, 255, 255, 0.3); }
.filters__meta { display: flex; justify-content: space-between; align-items: center; gap: 1rem; }
.filters__sort { display: inline-flex; align-items: center; gap: 0.6rem; }
.filters__sort select {
	background: var(--board);
	border: 1px solid var(--rule);
	border-radius: var(--r-s);
	color: var(--plaster);
	font-family: var(--mono);
	font-size: 0.74rem;
	padding: 0.45rem 0.7rem;
}
.filters__empty { padding: 2.5rem 0; max-width: 52ch; }
.card-cell[hidden] { display: none; }

/* --- Product single -------------------------------------------------------- */

.crumbs { display: flex; gap: 0.7rem; }
.crumbs a:hover { color: var(--plaster); }

.produit {
	display: grid;
	grid-template-columns: minmax(0, 1.15fr) minmax(0, 0.85fr);
	gap: clamp(2rem, 5vw, 5rem);
	align-items: start;
}
.produit__media { position: sticky; top: 96px; }
.produit__main { position: relative; border-radius: var(--r-m); overflow: hidden; aspect-ratio: 4 / 3; }
.produit__img { position: absolute; inset: 0; background-size: cover; background-position: center; }
.produit__thumbs { display: flex; flex-wrap: wrap; gap: 0.6rem; margin-top: 0.8rem; }
.pth {
	width: 56px;
	height: 56px;
	border-radius: var(--r-s);
	border: 1px solid var(--rule);
	background-size: cover;
	background-position: center;
	cursor: pointer;
	padding: 0;
	transition: border-color 0.3s var(--ease), transform 0.3s var(--ease);
}
.pth:hover { transform: translateY(-2px); }
.pth[aria-pressed='true'] { border-color: var(--plaster); }

.produit__title { font-size: clamp(1.8rem, 3.2vw, 2.8rem); margin-top: 0.9rem; }
.produit__short { margin-top: 1rem; max-width: 46ch; }
.produit__finishes { margin-top: 1.4rem; }
.produit__finishes .chips { margin-top: 0.7rem; }
.produit__actions { margin-top: 1.8rem; display: flex; flex-direction: column; gap: 0.7rem; align-items: flex-start; }
.produit__note { margin-top: 0.3rem; }

.pbtn {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	padding: 1rem 1.9rem;
	border-radius: 999px;
	border: 1px solid var(--plaster);
	background: var(--plaster);
	color: var(--ink);
	font-family: var(--mono);
	font-size: 0.78rem;
	letter-spacing: 0.16em;
	text-transform: uppercase;
	cursor: pointer;
	transition: opacity 0.3s var(--ease);
}
.pbtn:hover { opacity: 0.85; }
.pbtn--ghost { background: none; color: var(--plaster); border-color: var(--rule-hi); }
.pbtn--ghost:hover { opacity: 1; border-color: var(--plaster); }

/* --- Tabs ------------------------------------------------------------------- */

.tabs__bar { display: flex; gap: 1.8rem; border-bottom: 1px solid var(--rule); }
.tabs__bar [role='tab'] {
	background: none;
	border: 0;
	padding: 0.8rem 0;
	color: var(--sand);
	font-family: var(--mono);
	font-size: 0.78rem;
	letter-spacing: 0.14em;
	text-transform: uppercase;
	cursor: pointer;
	border-bottom: 1px solid transparent;
	margin-bottom: -1px;
	transition: color 0.3s var(--ease), border-color 0.3s var(--ease);
}
.tabs__bar [role='tab']:hover { color: var(--plaster); }
.tabs__bar [role='tab'][aria-selected='true'] { color: var(--plaster); border-bottom-color: var(--plaster); }
.tabs__panel { padding-top: 1.6rem; }

@media (max-width: 900px) {
	.produit { grid-template-columns: minmax(0, 1fr); }
	.produit__media { position: static; }
	.filters__group { flex-direction: column; gap: 0.5rem; }
}

/* Ville combobox -----------------------------------------------------------
   Ported from Proturf, repainted for the dark ground. The list is a shortcut,
   never a constraint: the field stays free text, so a village that is not among
   the 344 still submits. */

.city-combo { position: relative; min-width: 0; }
.city-combo__list {
	position: absolute; z-index: 30; top: calc(100% + 4px); left: 0; right: 0;
	margin: 0; padding: 4px; list-style: none; max-height: 264px; overflow-y: auto;
	background: var(--board-2); border: 1px solid var(--rule-hi);
	border-radius: var(--r-s);
	box-shadow: 0 12px 28px rgba(0, 0, 0, 0.45);
	/* Momentum scrolling, and the list must not swallow the page scroll once it ends. */
	-webkit-overflow-scrolling: touch; overscroll-behavior: contain;
}
.city-combo__list[hidden] { display: none; }
.city-combo__option {
	padding: 10px 12px; border-radius: 6px; font-size: 14.5px; line-height: 1.3;
	color: var(--plaster); cursor: pointer;
	/* 44px minimum touch target: this list is used mostly on phones. */
	min-height: 44px; display: flex; align-items: center;
}
.city-combo__option.is-active,
.city-combo__option:hover { background: var(--taupe); color: var(--ink); }
@media (max-width: 640px) {
	.city-combo__list { max-height: 50vh; }
}

/* Catalogue ----------------------------------------------------------------
   Filter rail plus a card grid. The rail is the feature: 917 wallpapers with no
   way through them is worse than 80 with one. */

.catalogue { padding: 0 var(--gutter); max-width: var(--max); margin: 0 auto; }
.catalogue__head { padding: 4rem 0 2rem; }
.catalogue__body { display: grid; grid-template-columns: 15rem 1fr; gap: 3rem; align-items: start; }

.filters { position: sticky; top: 1.5rem; }
.filters__group { margin-bottom: 2rem; }
.filters__title { color: var(--taupe); margin: 0 0 0.5rem; font-size: 0.75rem; letter-spacing: 0.08em; text-transform: uppercase; }
.filters__list { list-style: none; margin: 0; padding: 0; }
.filters__item {
	display: flex; justify-content: space-between; gap: 0.5rem;
	padding: 0.3rem 0; text-decoration: none; color: var(--sand);
	transition: color 0.18s var(--ease);
}
.filters__item:hover { color: var(--plaster); }
.filters__item.is-on { color: var(--plaster); font-weight: 600; }
.filters__item.is-on::before { content: '×'; margin-right: 0.35rem; }
.filters__n { opacity: 0.45; font-variant-numeric: tabular-nums; }

.chips { display: flex; flex-wrap: wrap; gap: 0.5rem; margin: 0 0 1.5rem; }
.chip {
	border: 1px solid var(--rule-hi); border-radius: 999px;
	padding: 0.25rem 0.75rem; text-decoration: none; color: var(--plaster);
	font-size: 0.85rem;
}
.chip:hover { border-color: var(--taupe); }

.grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr)); gap: 1.5rem; }
.card { display: block; text-decoration: none; color: inherit; }
.card__media {
	position: relative; display: block; overflow: hidden;
	aspect-ratio: 4 / 5; border-radius: var(--r-s); background: var(--board);
}
.card__img { width: 100%; height: 100%; object-fit: cover; display: block; }
.card__img--hover { position: absolute; inset: 0; opacity: 0; transition: opacity 0.35s var(--ease); }
.card--hover:hover .card__img--hover,
.card--hover:focus-visible .card__img--hover { opacity: 1; }
.card__body { display: block; padding: 0.75rem 0.15rem 0; }
.card__name { display: block; color: var(--plaster); }
.card__short { display: block; color: var(--taupe); font-size: 0.85rem; margin-top: 0.15rem; }

.catalogue__empty { color: var(--sand); padding: 3rem 0; }

@media (prefers-reduced-motion: reduce) {
	.card__img--hover { transition: none; }
}

@media (max-width: 60rem) {
	.catalogue__body { grid-template-columns: 1fr; }
	.filters { position: static; }
}

/* Product page -------------------------------------------------------------- */

.product {
	display: grid; grid-template-columns: 1.3fr 1fr; gap: 3rem;
	padding: 3rem var(--gutter); max-width: var(--max); margin: 0 auto;
}
.product__media { display: grid; gap: 1rem; }
.product__img { width: 100%; height: auto; display: block; border-radius: var(--r-s); }
.product__info { position: sticky; top: 1.5rem; align-self: start; }
.product__short { color: var(--taupe); }
.product__long { color: var(--sand); }
.product__attrs { display: grid; grid-template-columns: auto 1fr; gap: 0.4rem 1.5rem; margin-top: 2rem; }
.product__attrs dt { color: var(--taupe); font-size: 0.75rem; letter-spacing: 0.08em; text-transform: uppercase; }
.product__attrs dd { margin: 0; color: var(--sand); }
.product__attrs a { color: inherit; }

.unitform { margin: 2rem 0; }
.unitform__set { border: 1px solid var(--rule); border-radius: var(--r-s); padding: 1rem; margin: 0; }
.unitform__set legend { color: var(--taupe); font-size: 0.75rem; letter-spacing: 0.08em; text-transform: uppercase; padding: 0 0.4rem; }
.unitform__field { display: flex; align-items: center; gap: 0.6rem; margin-top: 0.6rem; }
.unitform__field span:first-child { flex: 1; color: var(--sand); }
.unitform__field input {
	width: 6rem; padding: 0.5rem 0.6rem; background: var(--board-2);
	border: 1px solid var(--rule-hi); border-radius: 6px; color: var(--plaster);
	font: inherit;
}
.unitform__suffix { color: var(--taupe); min-width: 2rem; }
.unitform__add {
	margin-top: 1rem; width: 100%; padding: 0.85rem 1rem; cursor: pointer;
	background: var(--taupe); color: var(--ink); border: 0; border-radius: var(--r-s);
	font: inherit; font-weight: 600;
}
.unitform__add:hover { background: var(--plaster); }

.devis__lines { list-style: none; margin: 0 0 2rem; padding: 0; }
.devis__line {
	display: flex; align-items: baseline; gap: 1rem;
	padding: 0.75rem 0; border-bottom: 1px solid var(--rule);
}
.devis__name { flex: 1; color: var(--plaster); }
.devis__measure { color: var(--taupe); }
.devis__line a { color: var(--taupe); text-decoration: none; font-size: 1.2rem; }
.devis__line a:hover { color: var(--plaster); }
.devis__empty { color: var(--sand); }

@media (max-width: 60rem) {
	.product { grid-template-columns: 1fr; }
	.product__info { position: static; }
}

/* ==========================================================================
   Pass 2 — showroom
   ==========================================================================
   Everything below refines the live surfaces: header and menu, homepage,
   catalogue, product page and the two forms. It is appended
   rather than woven in because several selectors above are inherited from the
   retired static site and still carry the old values; the cascade settles it
   in one place instead of leaving two truths in the file.

   Motif: the wordmark's O is a parallelogram leaning 10deg. That angle is the
   site's signature and appears only where something is active or moving —
   a chosen filter, a hovered link, the panel behind a call to action.
   ========================================================================== */

:root {
	--hd-h: 76px;
	--r-xl: 32px;
	/* One lean, used everywhere the motif appears. */
	--lean: -10deg;
	--wash: rgba(239, 233, 225, 0.045);
	--wash-hi: rgba(239, 233, 225, 0.09);
}

@media (max-width: 900px) {
	:root { --hd-h: 62px; }
}

body { font-size: 16.5px; }

/* Scrollbar, on the surfaces that get one of their own. */
.filters {
	scrollbar-width: thin;
	scrollbar-color: var(--rule-hi) transparent;
}

/* --- Shared -------------------------------------------------------------- */

.mono { color: var(--taupe); }

.lnk {
	position: relative;
	border-bottom: 0;
	padding-bottom: 0.45rem;
	color: var(--plaster);
}
.lnk::after {
	content: '';
	position: absolute;
	inset: auto 0 0;
	height: 1px;
	background: var(--rule-hi);
	transform: skewX(var(--lean));
	transform-origin: left;
	transition: background 0.35s var(--ease), transform 0.35s var(--ease);
}
.lnk:hover::after { background: var(--plaster); }
.lnk--inline { display: inline-flex; vertical-align: baseline; }

/* Filled buttons: actions and forms only. Never navigation. */
.pbtn {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: 0.6rem;
	min-height: 48px;
	padding: 0.9rem 1.9rem;
	border-radius: 999px;
	border: 1px solid var(--plaster);
	background: var(--plaster);
	color: var(--ink);
	font-family: var(--mono);
	font-size: 0.74rem;
	font-weight: 500;
	letter-spacing: 0.14em;
	text-transform: uppercase;
	text-align: center;
	cursor: pointer;
	transition: background 0.3s var(--ease), color 0.3s var(--ease),
		border-color 0.3s var(--ease), transform 0.3s var(--ease);
}
.pbtn:hover { background: var(--taupe); border-color: var(--taupe); color: var(--ink); transform: translateY(-1px); }
.pbtn:active { transform: none; }
.pbtn--ghost { background: none; color: var(--plaster); border-color: var(--rule-hi); }
.pbtn--ghost:hover { background: none; color: var(--plaster); border-color: var(--plaster); }
.pbtn--sm { min-height: 44px; padding: 0.7rem 1.3rem; font-size: 0.68rem; }
.pbtn--full { width: 100%; }

/* --- Header --------------------------------------------------------------- */

.hd { z-index: 60; }
.hd__in { min-height: var(--hd-h); gap: clamp(1rem, 3vw, 2.5rem); }
.hd.is-stuck {
	background: color-mix(in srgb, var(--ink) 92%, transparent);
	backdrop-filter: blur(18px) saturate(120%);
}
.hd__actions { display: flex; align-items: center; gap: 0.6rem; flex: 0 0 auto; }
.brand svg { width: clamp(112px, 11vw, 150px); }

.nav { margin-inline-start: auto; }
/* `.nav ul` up in the retired header block is (0,1,1), so a bare .nav__list
   loses to it on gap and padding. Matched here rather than edited there. */
.nav .nav__list { display: flex; align-items: center; gap: clamp(1.2rem, 2.4vw, 2.4rem); list-style: none; margin: 0; padding: 0; }
.nav__item { position: relative; }
.nav__list > li > a,
.nav__trigger {
	position: relative;
	display: inline-flex;
	align-items: center;
	gap: 0.5rem;
	min-height: 44px;
	padding: 0;
	background: none;
	border: 0;
	color: var(--sand);
	font-family: var(--mono);
	font-size: 0.72rem;
	font-weight: 400;
	letter-spacing: 0.16em;
	text-transform: uppercase;
	cursor: pointer;
	transition: color 0.3s var(--ease);
}
.nav__list > li > a::after,
.nav__trigger::after {
	content: '';
	position: absolute;
	left: 0;
	right: 0;
	bottom: 9px;
	height: 1px;
	background: var(--plaster);
	transform: skewX(var(--lean)) scaleX(0);
	transform-origin: left;
	transition: transform 0.4s var(--ease);
}
.nav__list > li > a:hover,
.nav__trigger:hover,
.nav__list .current-menu-item > a,
.nav__trigger[aria-expanded='true'] { color: var(--plaster); }
.nav__list > li > a:hover::after,
.nav__trigger:hover::after,
.nav__list .current-menu-item > a::after,
.nav__trigger[aria-expanded='true']::after { transform: skewX(var(--lean)) scaleX(1); }

/* The chevron is the wordmark's lean, not a generic arrow. */
.nav__chev {
	width: 7px;
	height: 7px;
	border-right: 1px solid currentColor;
	border-bottom: 1px solid currentColor;
	transform: skewX(var(--lean)) rotate(45deg) translateY(-1px);
	transition: transform 0.35s var(--ease);
}
.nav__trigger[aria-expanded='true'] .nav__chev { transform: skewX(var(--lean)) rotate(225deg) translateY(1px); }

.devis-pill {
	min-height: 44px;
	padding: 0.5rem 1rem;
	border-color: var(--rule-hi);
	font-size: 0.72rem;
	letter-spacing: 0.14em;
	color: var(--plaster);
	background: color-mix(in srgb, var(--board) 60%, transparent);
}
.devis-pill:hover { border-color: var(--plaster); background: var(--board-2); }
.devis-pill b { font-family: var(--mono); font-size: 0.62rem; }
.devis-pill.is-bump { animation: bump 0.5s var(--ease); }
@keyframes bump { 40% { transform: translateY(-3px) scale(1.04); } }

.burger {
	display: none;
	width: 44px;
	height: 44px;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	gap: 5px;
	background: none;
	border: 0;
	padding: 0;
	cursor: pointer;
}
.burger span {
	display: block;
	width: 22px;
	height: 1px;
	background: var(--plaster);
	transition: transform 0.35s var(--ease), opacity 0.25s var(--ease);
}
.burger[aria-expanded='true'] span:nth-child(1) { transform: translateY(6px) rotate(45deg); }
.burger[aria-expanded='true'] span:nth-child(2) { opacity: 0; }
.burger[aria-expanded='true'] span:nth-child(3) { transform: translateY(-6px) rotate(-45deg); }

/* --- Mega menu ------------------------------------------------------------ */

.mega {
	position: absolute;
	inset: 100% 0 auto;
	/* Opaque, not translucent: .hd carries its own backdrop-filter when stuck,
	   which makes it a backdrop root — a blur here would have nothing to blur
	   and the page would read straight through the panel. */
	background: var(--board);
	border-block: 1px solid var(--rule);
	box-shadow: 0 30px 60px rgba(0, 0, 0, 0.45);
}
.mega[hidden] { display: none; }
.mega__in {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(0, 1fr));
	gap: clamp(1.6rem, 4vw, 4rem);
	padding-block: clamp(1.8rem, 3vw, 2.6rem) clamp(2rem, 3.5vw, 3rem);
}
.mega__label { margin-bottom: 1rem; font-size: 0.68rem; }
.mega__list { list-style: none; margin: 0; padding: 0; }
.mega__list li + li { margin-top: 0.15rem; }
.mega__list a {
	display: flex;
	align-items: baseline;
	justify-content: space-between;
	gap: 1rem;
	min-height: 40px;
	padding: 0.35rem 0;
	color: var(--sand);
	font-size: 1.02rem;
	transition: color 0.25s var(--ease), transform 0.35s var(--ease);
}
.mega__list a:hover { color: var(--plaster); transform: translateX(4px); }
.mega__n { font-size: 0.68rem; opacity: 0.55; font-variant-numeric: tabular-nums; }
.mega__col--cta { align-self: start; }
.mega__note { max-width: 30ch; margin-bottom: 1.2rem; font-size: 0.95rem; }

.nav-scrim {
	position: fixed;
	inset: 0;
	z-index: 55;
	background: rgba(10, 8, 6, 0.5);
	opacity: 0;
	pointer-events: none;
	transition: opacity 0.35s var(--ease);
}
body.is-nav-open .nav-scrim { opacity: 1; pointer-events: auto; }
body.is-locked { overflow: hidden; }

/* --- Header, small screens ------------------------------------------------
   One markup, two layouts: the bar becomes a full-height sheet and the mega
   panel drops into it as a plain column. */

@media (max-width: 960px) {
	.burger { display: inline-flex; }
	.hd__in { flex-wrap: wrap; }
	.nav {
		display: none;
		flex: 1 0 100%;
		order: 3;
		/* The sheet is full-bleed inside a gutter-padded wrap. */
		margin: 0 calc(var(--gutter) * -1);
		padding-bottom: 1.5rem;
	}
	.hd.is-open {
		background: var(--ink);
		border-bottom-color: var(--rule);
		height: 100dvh;
		overflow-y: auto;
		overscroll-behavior: contain;
	}
	.hd.is-open .nav { display: block; }
	.nav .nav__list {
		flex-direction: column;
		align-items: stretch;
		gap: 0;
		padding-inline: var(--gutter);
		border-top: 1px solid var(--rule);
	}
	/* Items from a menu assigned in wp-admin carry Woo/WP classes, not .nav__item. */
	.nav .nav__list > li { border-bottom: 1px solid var(--rule); }
	.nav__list > li > a,
	.nav__trigger {
		width: 100%;
		justify-content: space-between;
		min-height: 56px;
		font-size: 0.8rem;
		color: var(--plaster);
	}
	.nav__list > li > a::after,
	.nav__trigger::after { display: none; }

	.mega {
		position: static;
		background: none;
		backdrop-filter: none;
		border: 0;
		box-shadow: none;
	}
	.mega__in {
		grid-template-columns: minmax(0, 1fr);
		gap: 1.8rem;
		padding-block: 1.4rem 2rem;
	}
	.mega__label { margin-bottom: 0.5rem; }
	.mega__list a { min-height: 48px; font-size: 1.05rem; }
	.mega__col--cta .pbtn { width: 100%; }
}

/* --- Homepage: hero -------------------------------------------------------- */

.hero {
	position: relative;
	display: flex;
	flex-direction: column;
	justify-content: center;
	/* The hero photograph is 2.33:1. Forcing it into a 900px-tall box cropped it
	   to a sliver of dark wall — the room, which is the whole point of the shot,
	   fell outside the frame. Height now follows the image's own proportions,
	   floored so the copy still has room to sit. */
	min-height: clamp(560px, 62vw, 760px);
	padding-block: calc(var(--hd-h) + 3rem) clamp(2.5rem, 6vh, 4.5rem);
	overflow: hidden;
}
.hero__img {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	object-fit: cover;
	/* Favour the right of frame: that is where the seating, the floral wall and
	   the carpet are. Dead centre lands on the blank plaster panel. */
	object-position: 62% center;
}
.hero__scrim {
	position: absolute;
	inset: 0;
	/* Directional, not a blanket. The previous three layers together darkened
	   most of the frame, which was survivable on the bright corridor shot and
	   erased this one — a dim interior went to flat black and the room, the
	   entire reason for the photograph, disappeared.
	   Copy sits bottom-left, so that corner is carried; the right half, where
	   the seating and the papered wall are, stays clear. */
	background:
		/* Left column, behind the copy. */
		linear-gradient(to right,
			color-mix(in srgb, var(--ink) 88%, transparent) 0%,
			color-mix(in srgb, var(--ink) 62%, transparent) 26%,
			transparent 58%),
		/* Floor of the frame, so the buttons and the count keep their footing. */
		linear-gradient(to top,
			color-mix(in srgb, var(--ink) 82%, transparent) 0%,
			transparent 38%),
		/* A band under the fixed header. The nav lands on the brightest part of
		   this photograph — the lit ceiling cove — so it needs real cover, not a
		   suggestion of one. */
		linear-gradient(to bottom,
			color-mix(in srgb, var(--ink) 78%, transparent) 0%,
			color-mix(in srgb, var(--ink) 40%, transparent) 9%,
			transparent 18%);
}
.hero__in { position: relative; z-index: 2; }
.hero__eyebrow { display: inline-flex; align-items: center; gap: 0.7rem; }
.hero__eyebrow::before {
	content: '';
	width: 12px;
	height: 12px;
	background: var(--taupe);
	transform: skewX(var(--lean));
}
.hero__title {
	margin-top: 1.3rem;
	max-width: 16ch;
	font-size: clamp(2.6rem, 5.6vw, 5.4rem);
}
.hero__lede {
	margin-top: 1.4rem;
	max-width: 46ch;
	font-size: 1.05rem;
	color: var(--plaster);
	opacity: 0.82;
}
.hero__act { display: flex; flex-wrap: wrap; align-items: center; gap: 1rem 2rem; margin-top: 2.2rem; }
.hero__count {
	position: absolute;
	right: var(--gutter);
	bottom: clamp(2.5rem, 6vh, 4.5rem);
	z-index: 2;
	font-size: 0.68rem;
	color: var(--sand);
	opacity: 0.7;
}
@media (max-width: 900px) {
	.hero { min-height: min(84svh, 720px); }
	.hero__count { display: none; }
	.hero__act { gap: 1.2rem; }
	.hero__act .pbtn { width: 100%; }
	/* Under a full-width button the text link sat flush left and read as a stray. */
	.hero__act .lnk { margin-inline: auto; }
	.hero__title { max-width: none; }
}

/* Phones: the copy sits on the photograph, not under it. Stacking the room as
   its own band pushed the headline to the middle of the screen and the buttons
   off the bottom of it. The portrait crop served here is mostly seating and
   wall, so a bottom-weighted scrim carries the copy without erasing the room. */
@media (max-width: 760px) {
	.hero {
		min-height: min(78svh, 640px);
		padding-block: calc(var(--hd-h) + 1.5rem) clamp(1.6rem, 4vh, 2.4rem);
	}
	.hero__img { object-position: 50% 40%; }
	.hero__scrim {
		background:
			linear-gradient(to top,
				color-mix(in srgb, var(--ink) 94%, transparent) 0%,
				color-mix(in srgb, var(--ink) 74%, transparent) 50%,
				color-mix(in srgb, var(--ink) 30%, transparent) 100%);
	}
	.hero__title { margin-top: 0; }
}

/* --- Homepage: how it works ------------------------------------------------
   One hairline row. Three lines, no headline, no button: the page has its call
   to action above and below, not in every section. */

.steps {
	/* Flush to the hero, but held inside the same container as the hero copy so
	   the numbers line up with the headline above them rather than running off
	   to the viewport edges. */
	margin-top: 0;
	padding-block: 0;
	background: var(--ink);
}
.steps__list {
	display: grid;
	grid-template-columns: repeat(3, minmax(0, 1fr));
	gap: clamp(1.2rem, 3vw, 3rem);
	list-style: none;
	margin: 0;
	padding-block: clamp(1.4rem, 2.5vw, 2rem);
	border-bottom: 1px solid var(--rule);
}
.steps__i { display: grid; grid-template-columns: auto 1fr; gap: 0.2rem 0.9rem; align-items: baseline; }
.steps__n { grid-row: span 2; font-size: 0.7rem; color: var(--taupe); }
.steps__t { color: var(--plaster); font-size: 1.05rem; }
.steps__d { color: var(--sand); font-size: 0.92rem; opacity: 0.8; }
@media (max-width: 760px) {
	.steps__list { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 0.8rem; }
	/* Number above the label rather than beside it: at a third of a phone there
	   is no room for a two-column row inside each step. */
	.steps__i { grid-template-columns: minmax(0, 1fr); gap: 0.15rem; }
	.steps__n { grid-row: auto; }
	.steps__t { font-size: 0.9rem; }
	.steps__d { display: none; }
}

/* --- Homepage: catalogue wall ---------------------------------------------- */

.home__cats { padding-block: clamp(1rem, 2vw, 2rem) clamp(4rem, 8vw, 7rem); scroll-margin-top: var(--hd-h); }
.home__head {
	display: flex;
	flex-wrap: wrap;
	align-items: baseline;
	justify-content: space-between;
	gap: 0.6rem 2rem;
	margin-bottom: clamp(1.6rem, 3vw, 2.4rem);
}
.home__head h2 { font-size: clamp(1.8rem, 3.2vw, 2.9rem); }
.home__head-note { margin: 0; color: var(--taupe); }
/* Phones: the note goes under the title. Spread to the two ends of a narrow
   row, the two read as unrelated. */
@media (max-width: 760px) {
	.home__head { flex-direction: column; align-items: flex-start; gap: 0.3rem; }
}

.home__grid {
	display: grid;
	grid-template-columns: repeat(4, minmax(0, 1fr));
	grid-auto-rows: 1fr;
	gap: clamp(0.8rem, 1.4vw, 1.4rem);
}
.tile {
	position: relative;
	display: flex;
	flex-direction: column;
	height: 100%;
	overflow: hidden;
	border-radius: var(--r-m);
	background: var(--board);
	isolation: isolate;
}
.tile__media { position: relative; display: block; flex: 1 1 auto; aspect-ratio: 4 / 5; overflow: hidden; }
.tile__img {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	object-fit: cover;
	transition: transform 1.1s var(--ease), filter 0.6s var(--ease);
}
.tile:hover .tile__img { transform: scale(1.05); }
.tile::after {
	content: '';
	position: absolute;
	inset: 0;
	z-index: 1;
	pointer-events: none;
	background: linear-gradient(to top, rgba(18, 13, 10, 0.92) 0%, rgba(18, 13, 10, 0.42) 26%, transparent 58%);
}
.tile__body {
	position: absolute;
	inset: auto 0 0;
	z-index: 2;
	display: flex;
	flex-direction: column;
	gap: 0.25rem;
	padding: clamp(1rem, 1.8vw, 1.6rem);
	transition: transform 0.5s var(--ease);
}
.tile:hover .tile__body { transform: translateY(-3px); }
.tile__name {
	font-family: var(--display);
	font-size: clamp(1.1rem, 1.5vw, 1.5rem);
	font-weight: 400;
	letter-spacing: -0.02em;
	color: var(--plaster);
	line-height: 1.15;
}
.tile__n { font-size: 0.66rem; }
.tile--noimg .tile__media { background: var(--board-2); }
.tile:focus-visible { outline-offset: 2px; }

@media (max-width: 1080px) {
	.home__grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
	}
@media (max-width: 760px) {
	.home__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
	.tile--lead { grid-column: span 2; grid-row: span 1; }
	.tile--lead .tile__media { aspect-ratio: 3 / 2; }
}

/* --- Homepage: closing band ------------------------------------------------
   The one place the motif carries real weight: the copy sits on a leaning
   plane, the way a tile sits in the wordmark. */

.band-cta { position: relative; overflow: hidden; isolation: isolate; }
.band-cta__img {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	object-fit: cover;
	object-position: center 70%;
}
.band-cta__scrim {
	position: absolute;
	inset: 0;
	/* Barely anything. The copy sits on its own angled panel, so it needs no
	   help from a scrim, and this photograph is already dark on the left where
	   the panel goes. Anything heavier buried the object the band exists to
	   show — the wordmark's parallelogram built as a real textile piece. */
	background:
		linear-gradient(95deg,
			color-mix(in srgb, var(--ink) 55%, transparent) 0%,
			transparent 34%);
}
.band-cta__in {
	position: relative;
	z-index: 2;
	padding-block: clamp(4rem, 9vw, 8rem);
	max-width: var(--max);
}
.band-cta__in::before {
	content: '';
	position: absolute;
	z-index: -1;
	inset: clamp(2rem, 5vw, 4rem) auto clamp(2rem, 5vw, 4rem) calc(var(--gutter) - clamp(1.5rem, 3vw, 3rem));
	width: min(46rem, 82%);
	background: color-mix(in srgb, var(--board) 55%, transparent);
	backdrop-filter: blur(3px);
	border-left: 1px solid var(--rule-hi);
	transform: skewX(var(--lean));
}
.band-cta__t {
	margin: 1rem 0 1.8rem;
	max-width: 26ch;
	font-family: var(--display);
	font-size: clamp(1.5rem, 2.8vw, 2.5rem);
	font-weight: 300;
	line-height: 1.12;
	letter-spacing: -0.03em;
	color: var(--plaster);
}
@media (max-width: 760px) {
	/* The panel covers the whole band here, so its blur blurred the photograph
	   itself. A plain tint carries the copy and leaves the textile sharp. */
	.band-cta__in::before {
		inset: 0; width: 100%; transform: none; border-left: 0;
		backdrop-filter: none;
		background: color-mix(in srgb, var(--ink) 58%, transparent);
	}
	.band-cta__in .pbtn { width: 100%; }
}

/* --- Catalogue ------------------------------------------------------------- */

.catalogue { padding-inline: var(--gutter); }
/* No rule and no margin under the head: with them the first product sat below
   the fold on a phone and only just inside it on a laptop. */
.catalogue__head {
	padding: calc(var(--hd-h) + clamp(1.2rem, 3vw, 2rem)) 0 clamp(0.9rem, 1.6vw, 1.3rem);
}
.crumbs { display: flex; flex-wrap: wrap; gap: 0.55rem; font-size: 0.68rem; }
.crumbs a { color: var(--taupe); transition: color 0.25s var(--ease); }
.crumbs a:hover { color: var(--plaster); }
.crumbs span { opacity: 0.4; }

.catalogue__title { margin-top: 0.5rem; font-size: clamp(2.2rem, 4.4vw, 3.8rem); }
.catalogue__lede { margin-top: 0.5rem; max-width: 60ch; color: var(--sand); }

.catalogue__body {
	display: grid;
	grid-template-columns: 16rem minmax(0, 1fr);
	gap: clamp(2rem, 4vw, 3.5rem);
	align-items: start;
}

/* The bar exists for the mobile filter button; on desktop the rail is already
   on screen, so the bar only appears when it has a count to show. The count
   used to sit under the title as well, and on a phone the two were a few
   lines apart. */
.catalogue__bar { display: none; }
.catalogue__bar:has(.catalogue__bar-n) { display: flex; margin-bottom: 1rem; }
.catalogue__bar-n { font-size: 0.68rem; }
.filters__open {
	display: none;
	align-items: center;
	gap: 0.55rem;
	min-height: 44px;
	padding: 0.55rem 1.1rem;
	border-radius: 999px;
	border: 1px solid var(--rule-hi);
	background: var(--board);
	color: var(--plaster);
	font-family: var(--mono);
	font-size: 0.72rem;
	letter-spacing: 0.14em;
	text-transform: uppercase;
	cursor: pointer;
}
.filters__open b {
	display: grid;
	place-items: center;
	min-width: 18px;
	height: 18px;
	border-radius: 50%;
	background: var(--plaster);
	color: var(--ink);
	font-size: 0.6rem;
	font-weight: 500;
}

/* Filter rail. Sticky, with its own scroll: six facets is more than a viewport
   and a rail that scrolls the page away is a rail nobody uses. */
.catalogue__rail { position: sticky; top: calc(var(--hd-h) + 1rem); }
.filters {
	position: static;
	display: block;
	gap: 0;
	padding: 0;
	margin: 0;
	border: 0;
	max-height: calc(100dvh - var(--hd-h) - 3rem);
	overflow-y: auto;
	overscroll-behavior: contain;
	padding-right: 0.4rem;
}
.filters__head {
	display: flex;
	align-items: baseline;
	justify-content: space-between;
	gap: 1rem;
	padding-bottom: 0.9rem;
	margin-bottom: 1.2rem;
	border-bottom: 1px solid var(--rule-hi);
}
.filters__lede { color: var(--plaster); font-size: 0.7rem; }
.filters__reset { font-size: 0.64rem; color: var(--taupe); border-bottom: 1px solid var(--rule); transition: color 0.25s var(--ease), border-color 0.25s var(--ease); }
.filters__reset:hover { color: var(--plaster); border-color: var(--plaster); }

.filters__group { margin: 0 0 1.6rem; display: block; }
.filters__title { margin: 0 0 0.5rem; font-size: 0.64rem; letter-spacing: 0.16em; color: var(--taupe); }
.filters__list { display: block; }
.filters__item {
	display: flex;
	align-items: center;
	gap: 0.6rem;
	min-height: 36px;
	padding: 0.25rem 0.5rem 0.25rem 0.35rem;
	margin-inline: -0.35rem;
	border-radius: 8px;
	color: var(--sand);
	font-size: 0.95rem;
	transition: color 0.2s var(--ease), background 0.2s var(--ease);
}
.filters__item:hover { color: var(--plaster); background: var(--wash); }
/* The marker is the wordmark's tile: empty, then filled when the value is on. */
.filters__box {
	flex: 0 0 auto;
	width: 12px;
	height: 12px;
	border: 1px solid var(--rule-hi);
	background: none;
	transform: skewX(var(--lean));
	transition: background 0.25s var(--ease), border-color 0.25s var(--ease);
}
.filters__item:hover .filters__box { border-color: var(--sand); }
.filters__label { flex: 1 1 auto; min-width: 0; }
.filters__item.is-on { color: var(--plaster); font-weight: 500; background: var(--wash); }
.filters__item.is-on::before { content: none; }
.filters__item.is-on .filters__box { background: var(--plaster); border-color: var(--plaster); }
.filters__item.is-on:hover .filters__box {
	background: var(--taupe);
	border-color: var(--taupe);
}
.filters__n { opacity: 0.45; font-family: var(--mono); font-size: 0.72rem; font-variant-numeric: tabular-nums; }

/* Sheet chrome: only ever visible when the rail is a mobile sheet. */
.sheet__head, .sheet__foot { display: none; }

/* Active filters, above the grid. */
.chips { display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem; margin: 0 0 1.4rem; }
.chip {
	display: inline-flex;
	align-items: center;
	gap: 0.5rem;
	/* The decor swatch further up the file fixes .chip at 30x30. */
	width: auto;
	height: auto;
	min-height: 34px;
	padding: 0.3rem 0.85rem;
	border-radius: 999px;
	border: 1px solid var(--rule-hi);
	background: var(--board);
	color: var(--plaster);
	font-size: 0.85rem;
	transform: none;
	transition: border-color 0.25s var(--ease), background 0.25s var(--ease), color 0.25s var(--ease);
}
.chip:hover { transform: none; border-color: var(--plaster); background: var(--board-2); }
.chip span[aria-hidden] { font-family: var(--mono); opacity: 0.6; }
.chip:hover span[aria-hidden] { opacity: 1; }
.chips__reset { margin-left: 0.3rem; font-size: 0.64rem; color: var(--taupe); border-bottom: 1px solid var(--rule); }
.chips__reset:hover { color: var(--plaster); border-color: var(--plaster); }

/* Product grid */
.grid {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(13.5rem, 1fr));
	gap: clamp(1.6rem, 2.4vw, 2.4rem) clamp(1rem, 1.6vw, 1.5rem);
}
.card { position: relative; }
.card__media { border-radius: var(--r-m); background: var(--board); aspect-ratio: 4 / 5; }
.card__img { transition: transform 1s var(--ease); }
.card:hover .card__img { transform: scale(1.04); }
.card__img--hover { transform: none; }
.card--hover:hover .card__img--hover,
.card--hover:focus-visible .card__img--hover { opacity: 1; transform: scale(1.04); }
.card__go {
	position: absolute;
	right: 0.7rem;
	bottom: 0.7rem;
	z-index: 2;
	padding: 0.4rem 0.75rem;
	font-size: 0.6rem;
	letter-spacing: 0.16em;
	color: var(--ink);
	background: var(--plaster);
	transform: skewX(var(--lean)) translateY(8px);
	opacity: 0;
	transition: opacity 0.3s var(--ease), transform 0.35s var(--ease);
}
.card:hover .card__go,
.card:focus-visible .card__go { opacity: 1; transform: skewX(var(--lean)) translateY(0); }
.card__body { padding-top: 0.85rem; }
.card__name {
	font-size: 1rem;
	line-height: 1.3;
	color: var(--plaster);
	transition: color 0.25s var(--ease);
}
.card__short {
	margin-top: 0.25rem;
	font-size: 0.86rem;
	line-height: 1.45;
	color: var(--taupe);
	display: -webkit-box;
	-webkit-line-clamp: 2;
	-webkit-box-orient: vertical;
	overflow: hidden;
}
@media (hover: none) {
	.card__go { opacity: 0; }
}

/* Pagination */
.woocommerce-pagination { margin-top: clamp(2.5rem, 5vw, 4rem); }
.woocommerce-pagination ul.page-numbers {
	display: flex;
	flex-wrap: wrap;
	gap: 0.4rem;
	list-style: none;
	margin: 0;
	padding: 0;
}
.woocommerce-pagination .page-numbers {
	display: grid;
	place-items: center;
	min-width: 44px;
	height: 44px;
	padding-inline: 0.6rem;
	border-radius: 999px;
	border: 1px solid var(--rule);
	color: var(--sand);
	font-family: var(--mono);
	font-size: 0.76rem;
	transition: border-color 0.25s var(--ease), color 0.25s var(--ease), background 0.25s var(--ease);
}
.woocommerce-pagination a.page-numbers:hover { border-color: var(--plaster); color: var(--plaster); }
.woocommerce-pagination .page-numbers.current { background: var(--plaster); border-color: var(--plaster); color: var(--ink); }
.woocommerce-pagination .page-numbers.dots { border-color: transparent; }

.catalogue__empty { padding: clamp(2.5rem, 6vw, 4.5rem) 0; max-width: 46ch; color: var(--sand); }
.catalogue__empty-t { color: var(--plaster); font-size: 1.2rem; }
.catalogue__empty-act { display: flex; flex-wrap: wrap; gap: 0.8rem; margin-top: 1.6rem; }

.catalogue__cta {
	margin-top: clamp(3.5rem, 7vw, 6rem);
	padding: clamp(2rem, 4vw, 3.2rem) 0 clamp(3rem, 6vw, 5rem);
	border-top: 1px solid var(--rule);
}
.catalogue__cta-t {
	margin: 0.9rem 0 1.5rem;
	max-width: 34ch;
	font-family: var(--display);
	font-size: clamp(1.3rem, 2.2vw, 2rem);
	font-weight: 300;
	line-height: 1.15;
	letter-spacing: -0.025em;
	color: var(--plaster);
}

/* Catalogue, small screens: the rail becomes a sheet from the bottom. */
@media (max-width: 60rem) {
	.catalogue__body { grid-template-columns: minmax(0, 1fr); gap: 0; }
	.filters__open { display: inline-flex; }
	.catalogue__bar {
		display: flex;
		align-items: center;
		justify-content: space-between;
		gap: 1rem;
		margin-bottom: 1.2rem;
		position: sticky;
		top: calc(var(--hd-h) - 1px);
		z-index: 40;
		margin-inline: calc(var(--gutter) * -1);
		padding: 0.7rem var(--gutter);
		background: color-mix(in srgb, var(--ink) 92%, transparent);
		backdrop-filter: blur(14px);
		border-bottom: 1px solid var(--rule);
	}

	.catalogue__rail {
		position: fixed;
		inset: auto 0 0;
		z-index: 80;
		display: flex;
		flex-direction: column;
		max-height: 88dvh;
		background: var(--board);
		border-top: 1px solid var(--rule-hi);
		border-radius: var(--r-l) var(--r-l) 0 0;
		box-shadow: 0 -20px 50px rgba(0, 0, 0, 0.5);
		transform: translateY(101%);
		visibility: hidden;
		transition: transform 0.4s var(--ease), visibility 0.4s var(--ease);
	}
	.catalogue__rail.is-open { transform: none; visibility: visible; }

	.sheet__head {
		display: flex;
		align-items: center;
		justify-content: space-between;
		padding: 1rem 1.3rem;
		border-bottom: 1px solid var(--rule);
	}
	.sheet__head .mono { color: var(--plaster); }
	.sheet__close {
		width: 44px;
		height: 44px;
		background: none;
		border: 0;
		color: var(--sand);
		font-size: 1.7rem;
		line-height: 1;
		cursor: pointer;
	}
	.sheet__body { flex: 1 1 auto; min-height: 0; overflow: hidden; display: flex; }
	.filters { max-height: none; flex: 1 1 auto; padding: 1.2rem 1.3rem; }
	.filters__head { display: none; }
	.filters__item { min-height: 44px; font-size: 1rem; }
	.sheet__foot {
		display: block;
		padding: 1rem 1.3rem calc(1rem + env(safe-area-inset-bottom));
		border-top: 1px solid var(--rule);
	}
}

/* --- Product page ---------------------------------------------------------- */

.product {
	display: grid;
	grid-template-columns: minmax(0, 1.05fr) minmax(0, 0.95fr);
	gap: clamp(2rem, 4.5vw, 4.5rem);
	padding: calc(var(--hd-h) + clamp(1.5rem, 4vw, 3rem)) var(--gutter) clamp(3rem, 7vw, 6rem);
	align-items: start;
}
.product__media { position: sticky; top: calc(var(--hd-h) + 1.5rem); display: block; }
.product__info { position: static; }

.pgal__main {
	position: relative;
	margin: 0;
	overflow: hidden;
	border-radius: var(--r-l);
	background: var(--board);
	aspect-ratio: 1 / 1;
}
.pgal__img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }

/* Zoom: the image scales under the pointer; main.js moves the origin. */
.pgal__main { cursor: zoom-in; touch-action: pan-y; }
.pgal__main.is-zoomed { cursor: zoom-out; }
.pgal__main .pgal__img { transition: transform 0.35s var(--ease); will-change: transform; }
.pgal__main.is-zoomed .pgal__img { transform: scale(2.2); }

/* Arrows. They wrap, so both are always live. */
.pgal__nav {
	position: absolute;
	top: 50%;
	z-index: 2;
	display: grid;
	place-items: center;
	width: 44px;
	height: 44px;
	transform: translateY(-50%);
	border: 1px solid color-mix(in srgb, var(--plaster) 20%, transparent);
	border-radius: 50%;
	background: color-mix(in srgb, var(--ink) 62%, transparent);
	color: var(--plaster);
	font-size: 1.1rem;
	line-height: 1;
	cursor: pointer;
	transition: background 0.25s var(--ease), border-color 0.25s var(--ease);
}
.pgal__nav:hover { background: var(--ink); border-color: var(--plaster); }
.pgal__nav--prev { left: 0.7rem; }
.pgal__nav--next { right: 0.7rem; }
.pgal__thumbs {
	display: flex;
	flex-wrap: wrap;
	gap: 0.6rem;
	list-style: none;
	margin: 0.8rem 0 0;
	padding: 0;
}
.pgal__thumb {
	position: relative;
	display: block;
	width: 74px;
	height: 74px;
	padding: 0;
	overflow: hidden;
	border-radius: var(--r-s);
	border: 1px solid var(--rule);
	background: var(--board);
	cursor: pointer;
	transition: border-color 0.25s var(--ease), transform 0.3s var(--ease);
}
.pgal__thumb img { width: 100%; height: 100%; object-fit: cover; }
.pgal__thumb:hover { transform: translateY(-2px); border-color: var(--rule-hi); }
.pgal__thumb.is-on { border-color: var(--plaster); }

.product__title { margin-top: 1rem; font-size: clamp(1.9rem, 3.2vw, 3rem); }
.product__short { margin-top: 1.1rem; max-width: 48ch; color: var(--sand); font-size: 1.05rem; }

/* The conversion moment. The only surface on the page with a fill. */
.buy {
	margin: clamp(1.8rem, 3vw, 2.4rem) 0 0;
	padding: clamp(1.3rem, 2.2vw, 1.8rem);
	border: 1px solid var(--rule-hi);
	border-radius: var(--r-l);
	background: linear-gradient(180deg, var(--board-2), var(--board));
}
.buy__label { font-size: 0.66rem; color: var(--taupe); }
.buy__note { margin: 0.6rem 0 0; color: var(--sand); font-size: 0.95rem; max-width: 40ch; }

.unitform { margin: 1.2rem 0 0; }
.unitform__set { border: 0; border-top: 1px solid var(--rule); border-radius: 0; padding: 1.1rem 0 0; }
.unitform__set legend { padding: 0; font-family: var(--mono); font-size: 0.64rem; letter-spacing: 0.16em; color: var(--taupe); }
.unitform__field {
	display: flex;
	align-items: center;
	gap: 0.8rem;
	min-height: 52px;
	margin-top: 0.5rem;
	padding-bottom: 0.5rem;
	border-bottom: 1px solid var(--rule);
}
.unitform__field:last-of-type { border-bottom: 0; padding-bottom: 0; }
.unitform__field span:first-child { flex: 1 1 auto; color: var(--sand); font-size: 0.98rem; }
.unitform__field input {
	width: 6.5rem;
	min-height: 48px;
	padding: 0.6rem 0.8rem;
	text-align: right;
	background: var(--ink);
	border: 1px solid var(--rule-hi);
	border-radius: var(--r-s);
	color: var(--plaster);
	font-family: var(--mono);
	font-size: 1rem;
	transition: border-color 0.25s var(--ease);
}
.unitform__field input:focus { outline: none; border-color: var(--plaster); }
.unitform__suffix { min-width: 2.2rem; font-size: 0.72rem; color: var(--taupe); }
.unitform__add {
	display: flex;
	align-items: center;
	justify-content: center;
	width: 100%;
	min-height: 54px;
	margin-top: 1.3rem;
	padding: 0.95rem 1.4rem;
	border: 1px solid var(--plaster);
	border-radius: 999px;
	background: var(--plaster);
	color: var(--ink);
	font-family: var(--mono);
	font-size: 0.76rem;
	font-weight: 500;
	letter-spacing: 0.14em;
	text-transform: uppercase;
	cursor: pointer;
	transition: background 0.25s var(--ease), border-color 0.25s var(--ease), transform 0.25s var(--ease);
}
.unitform__add:hover { background: var(--taupe); border-color: var(--taupe); color: var(--ink); transform: translateY(-1px); }
.unitform__add.is-done { background: var(--board-2); border-color: var(--plaster); color: var(--plaster); }

.buy__reassure {
	display: flex;
	flex-wrap: wrap;
	gap: 0.4rem 1.4rem;
	list-style: none;
	margin: 1rem 0 0;
	padding: 0;
	font-size: 0.62rem;
}
.buy__reassure li { display: inline-flex; align-items: center; gap: 0.5rem; }
.buy__reassure li::before {
	content: '';
	width: 8px;
	height: 8px;
	background: var(--taupe);
	transform: skewX(var(--lean));
}

.product__block { margin-top: clamp(2rem, 3.5vw, 3rem); padding-top: clamp(1.4rem, 2.5vw, 2rem); border-top: 1px solid var(--rule); }
.product__h { margin: 0 0 1rem; font-size: 0.64rem; letter-spacing: 0.18em; font-weight: 400; color: var(--taupe); }
.product__long { color: var(--sand); max-width: 62ch; }
.product__long p:last-child { margin-bottom: 0; }

.product__attrs { display: grid; grid-template-columns: minmax(6.5rem, auto) minmax(0, 1fr); gap: 0.1rem 1.5rem; margin: 0; }
.product__attrs dt {
	padding: 0.55rem 0;
	font-family: var(--mono);
	font-size: 0.66rem;
	letter-spacing: 0.12em;
	text-transform: uppercase;
	color: var(--taupe);
	border-top: 1px solid var(--rule);
}
.product__attrs dd { margin: 0; padding: 0.55rem 0; color: var(--sand); border-top: 1px solid var(--rule); }
.product__attrs dt:first-of-type, .product__attrs dd:first-of-type { border-top: 0; }
.product__attrs a { color: var(--sand); border-bottom: 1px solid var(--rule); transition: color 0.25s var(--ease), border-color 0.25s var(--ease); }
.product__attrs a:hover { color: var(--plaster); border-color: var(--plaster); }
.product__sep { padding-inline: 0.45rem; opacity: 0.35; }

.product__help { margin-top: clamp(2rem, 3.5vw, 3rem); display: flex; flex-wrap: wrap; align-items: baseline; gap: 0.4rem 1rem; color: var(--taupe); }

@media (max-width: 60rem) {
	.product { grid-template-columns: minmax(0, 1fr); }
	.product__media { position: static; }
	/* Landscape, not portrait: a 4:5 image at full width was a whole phone
	   screen of material before the name of the product appeared. */
	.pgal__main { aspect-ratio: 4 / 3; }
	.buy { padding-inline: 1.1rem; }
}

/* --- Routed pages: devis, contact ------------------------------------------- */

.page-head { padding: calc(var(--hd-h) + clamp(2.5rem, 6vw, 4.5rem)) 0 clamp(1.6rem, 3vw, 2.4rem); }
.page-head h1 { font-size: clamp(2.1rem, 4.2vw, 3.6rem); }
.page-head__note { color: var(--sand); }

.sec--form { padding-block: 0 clamp(4rem, 8vw, 7rem); }
.split { grid-template-columns: minmax(0, 1fr) minmax(0, 21rem); gap: clamp(1.6rem, 3vw, 3rem); }
.split__main { display: flex; flex-direction: column; gap: clamp(1.2rem, 2vw, 1.6rem); min-width: 0; }
.split__side { display: flex; flex-direction: column; gap: clamp(1.2rem, 2vw, 1.6rem); min-width: 0; }

.panel {
	padding: clamp(1.3rem, 2.4vw, 2rem);
	border: 1px solid var(--rule);
	border-radius: var(--r-l);
	background: var(--board);
}
.panel--form { background: linear-gradient(180deg, var(--board-2), var(--board)); border-color: var(--rule-hi); }
.panel__label { margin-bottom: 1.2rem; font-size: 0.66rem; }
.panel__head { display: flex; align-items: baseline; justify-content: space-between; gap: 1rem; padding-bottom: 0.9rem; border-bottom: 1px solid var(--rule); }
.panel__head .mono { color: var(--plaster); font-size: 0.68rem; }
.panel__n { font-size: 0.64rem; }
.panel__foot { margin: 1rem 0 0; font-size: 0.66rem; }
.panel__foot a { color: var(--taupe); border-bottom: 1px solid var(--rule); }
.panel__foot a:hover { color: var(--plaster); border-color: var(--plaster); }
.panel--side .mono { color: var(--plaster); font-size: 0.68rem; }

.side__steps { margin: 1rem 0 0; padding: 0 0 0 1.1rem; color: var(--sand); font-size: 0.95rem; }
.side__steps li { margin-bottom: 0.5rem; }
.side__steps li::marker { color: var(--taupe); font-family: var(--mono); font-size: 0.75rem; }
.side__note { margin: 0.9rem 0 1.2rem; font-size: 0.95rem; }

.devis__lines { margin: 0; }
.devis__line {
	display: grid;
	grid-template-columns: 64px minmax(0, 1fr) 44px;
	align-items: center;
	gap: 1rem;
	padding: 0.9rem 0;
}
.devis__thumb { display: block; width: 64px; height: 64px; overflow: hidden; border-radius: var(--r-s); background: var(--board-2); }
.devis__thumb img { width: 100%; height: 100%; object-fit: cover; }
.devis__txt { display: flex; flex-direction: column; gap: 0.2rem; min-width: 0; }
.devis__name { color: var(--plaster); line-height: 1.3; border-bottom: 1px solid transparent; align-self: flex-start; }
.devis__name:hover { border-bottom-color: var(--rule-hi); }
.devis__measure { font-size: 0.66rem; }
.devis__rm {
	display: grid;
	place-items: center;
	width: 44px;
	height: 44px;
	border-radius: 50%;
	color: var(--taupe);
	font-size: 1.4rem;
	transition: color 0.25s var(--ease), background 0.25s var(--ease);
}
.devis__rm:hover { color: var(--plaster); background: var(--wash-hi); }
.devis__empty { color: var(--sand); margin-bottom: 1.2rem; }

/* Form fields */
.lead { gap: 1rem; }
.lead label { gap: 0.5rem; }
.lead label > .mono { font-size: 0.62rem; color: var(--taupe); }
.lead input,
.lead textarea {
	min-height: 50px;
	padding: 0.8rem 1rem;
	background: var(--ink);
	border: 1px solid var(--rule-hi);
	border-radius: var(--r-s);
	color: var(--plaster);
	font-size: 1rem;
	transition: border-color 0.25s var(--ease), background 0.25s var(--ease);
}
.lead textarea { min-height: 120px; resize: vertical; }
.lead input:hover, .lead textarea:hover { border-color: var(--sand); }
.lead input:focus,
.lead textarea:focus { outline: none; border-color: var(--plaster); background: var(--ink); }
.lead input::placeholder, .lead textarea::placeholder { color: var(--taupe); opacity: 0.6; }
.lead__submit {
	align-self: flex-start;
	min-height: 54px;
	margin-top: 0.4rem;
	padding: 1rem 2rem;
	background: var(--plaster);
	color: var(--ink);
	border: 1px solid var(--plaster);
	border-radius: 999px;
	font-family: var(--mono);
	font-size: 0.74rem;
	font-weight: 500;
	letter-spacing: 0.14em;
	transition: background 0.25s var(--ease), border-color 0.25s var(--ease), transform 0.25s var(--ease);
}
.lead__submit:hover { opacity: 1; background: var(--taupe); border-color: var(--taupe); transform: translateY(-1px); }

.form-note { border-radius: var(--r-m); padding: 1rem 1.2rem; }
.form-note--ok { border-color: var(--rule-hi); background: var(--wash); }

.contact-list { margin-top: 1rem; }
.contact-list a { color: var(--plaster); border-bottom-color: var(--rule); }
.contact-list a:hover { border-bottom-color: var(--plaster); }

@media (max-width: 900px) {
	.split { grid-template-columns: minmax(0, 1fr); }
	.lead__submit { align-self: stretch; width: 100%; }
	.devis__line { grid-template-columns: 56px minmax(0, 1fr) 44px; gap: 0.8rem; }
	.devis__thumb { width: 56px; height: 56px; }
}

/* --- Footer ----------------------------------------------------------------- */

.ft__g { grid-template-columns: minmax(0, 1.4fr) repeat(3, minmax(0, 1fr)); }
.ft__brand { max-width: 34ch; }
.ft__blurb { margin: 1.2rem 0 1.5rem; color: var(--sand); }
.ft h4 { color: var(--taupe); }
.ft li { margin-bottom: 0.45rem; }
.ft a { border-bottom: 1px solid transparent; transition: color 0.25s var(--ease), border-color 0.25s var(--ease); }
.ft a:hover { border-bottom-color: var(--rule-hi); }
.ft .brand svg { width: 132px; }

@media (max-width: 900px) {
	.ft__g { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 2rem; }
	.ft__brand { grid-column: 1 / -1; }
}

/* --- Motion ------------------------------------------------------------------ */

@media (prefers-reduced-motion: reduce) {
	.tile:hover .tile__img,
	.card:hover .card__img,
	.card--hover:hover .card__img--hover { transform: none; }
	.hd.is-open { transition: none; }
}

/* --- Scrim shared by the menu and the filter sheet -------------------------- */

body.is-sheet-open .nav-scrim { opacity: 1; pointer-events: auto; }

/* --- Menu sheet: the header row wraps, the panel drops in below it ---------- */

@media (max-width: 960px) {
	.hd.is-open .hd__in { padding-bottom: 0; }
	/* Outside the sheet the panel has nowhere to sit: the row is the whole header. */
	.mega { display: none; }
	.hd.is-open .mega { display: block; }
	.hd.is-open .mega[hidden] { display: none; }
	.mega__in { padding-inline: var(--gutter); }
}

/* The hero art is served by <picture>; the wrapper must not become a layout box
   of its own or the absolutely-placed image loses its frame. */
.hero__pic { display: contents; }

/* Phones: two cards a row. One column of 4:5 cards is four screens of scroll
   for eight references, which is not browsing a catalogue of six hundred. */
@media (max-width: 760px) {
	.grid {
		grid-template-columns: repeat(2, minmax(0, 1fr));
		gap: 1.5rem 0.75rem;
	}
	.card__body { padding-top: 0.6rem; }
	.card__name { font-size: 0.92rem; }
	.card__short { font-size: 0.78rem; -webkit-line-clamp: 2; }
	.catalogue__cta-t { max-width: none; }
	.catalogue__cta .pbtn,
	.catalogue__empty-act .pbtn { width: 100%; }
}

/* The city picker wraps its input at runtime; without this the field stops
   filling its column and sits narrower than every other one. */
.lead .city-combo { width: 100%; }
.lead .city-combo input { width: 100%; }

/* --- Small text on the ink ground -------------------------------------------
   The brand taupe read straight from the wordmark is #887A6E, which lands at
   4.49:1 on the ink — just under AA for the sizes this interface sets labels,
   counts and captions at. Lifted here for text only; the taupe itself is
   untouched and still paints every mark, rule and hover. */

/* Kept as an alias: --taupe now clears AA on its own, so there is no longer a
   separate small-text variant to keep in sync. */
:root { --taupe-t: var(--taupe); }

.mono,
.crumbs a,
.filters__title,
.filters__reset,
.card__short,
.product__attrs dt,
.mega__note,
.side__note { color: var(--taupe-t); }

/* Counts carry information; hierarchy comes from the mono face and the size,
   not from dimming them out of legibility. */
.filters__n { opacity: 1; color: var(--taupe-t); }
.mega__n { opacity: 1; color: var(--taupe-t); }

/* These stay plaster: they are the loudest line in their block. */
.filters__lede,
.sheet__head .mono,
.panel__head .mono,
.panel--side .mono { color: var(--plaster); }

/* Catalogue rail (the /shop/ archive) -------------------------------------
   Replaces a two-column text index that pushed every product below the fold.
   One horizontal strip of real photography: shorter, and it shows what is in a
   category instead of only naming it. Scrolls rather than wraps, so its height
   is the same whether there are five categories or fifteen. */

.crail { margin: 0 0 clamp(1rem, 2vw, 1.6rem); }
.crail__list {
	display: flex;
	gap: 0.9rem;
	list-style: none;
	margin: 0;
	padding: 0 0 0.5rem;
	overflow-x: auto;
	scroll-snap-type: x proximity;
	scrollbar-width: thin;
	overscroll-behavior-x: contain;
}
.crail__list li { flex: 0 0 auto; scroll-snap-align: start; }
.crail__item {
	display: flex;
	align-items: center;
	gap: 0.7rem;
	padding: 0.5rem 1rem 0.5rem 0.5rem;
	border: 1px solid var(--rule);
	border-radius: 999px;
	text-decoration: none;
	color: var(--plaster);
	white-space: nowrap;
	transition: border-color 0.25s var(--ease), background 0.25s var(--ease);
}
.crail__item:hover,
.crail__item:focus-visible { border-color: var(--taupe); background: var(--board); }
.crail__media {
	width: 40px;
	height: 40px;
	flex: 0 0 auto;
	overflow: hidden;
	border-radius: 999px;
	background: var(--board-2);
}
.crail__media img { width: 100%; height: 100%; object-fit: cover; display: block; }
.crail__txt { display: flex; align-items: baseline; gap: 0.5rem; }
.crail__n { color: var(--taupe); font-variant-numeric: tabular-nums; font-size: 0.72rem; }

.catalogue__lede--tight { max-width: 46ch; }

@media (max-width: 640px) {
	.crail__list { gap: 0.6rem; }
	.crail__item { padding-right: 0.85rem; }
}

/* Two-group nav ------------------------------------------------------------
   Au sol and Au mur are top-level and each owns its panel, so the panel is a
   child of its <li>. The <li> must stay static or the panel's `inset: 100% 0`
   resolves against the list item and collapses into a narrow column instead of
   spanning the header — .hd is position:fixed and is the intended containing
   block. The <li> being the hover target, panel included, is what lets the
   pointer travel down into the panel without crossing a dead gap. */

.nav__item--panel { position: static; }

.mega__col--wide { grid-column: span 2; }
.mega__col--wide .mega__list {
	columns: 2;
	column-gap: clamp(1.5rem, 3vw, 3rem);
}
.mega__col--wide .mega__list li { break-inside: avoid; }

.nav__item--panel.is-open > .nav__trigger { color: var(--plaster); }
.nav__item--panel.is-open > .nav__trigger .nav__chev { transform: rotate(180deg); }

/* Nav sizing: the bar was set for nine cramped links. With four items it can
   breathe, and the two that open panels should read as the primary route in. */
.nav__list { gap: clamp(1.1rem, 2.2vw, 2.2rem); }
.nav__link,
.nav__trigger {
	font-size: 0.82rem;
	letter-spacing: 0.13em;
}

@media (max-width: 960px) {
	/* In the sheet the panel is inline, so the desktop full-width anchoring and
	   the two-column list both come off. */
	.mega__col--wide { grid-column: auto; }
	.mega__col--wide .mega__list { columns: 1; }
}


/* Header: hairline and scrolled state -------------------------------------
   The bar sits over photography on the homepage, so it needs an edge to sit
   on rather than floating in the image. .hd.is-stuck was styled from the
   start but nothing ever added the class — the toggle now lives in main.js. */

.hd {
	border-bottom: 1px solid var(--rule);
	transition:
		background 0.35s var(--ease),
		border-color 0.35s var(--ease),
		backdrop-filter 0.35s var(--ease);
}
.hd.is-stuck {
	background: color-mix(in srgb, var(--ink) 90%, transparent);
	backdrop-filter: blur(16px) saturate(115%);
	border-bottom-color: var(--rule-hi);
}

/* Simple category dropdown --------------------------------------------------
   Replaces the full-width mega panel. A list of categories is all this needs to
   be: the panel used to carry a second column repeating the devis call that is
   already in the bar, two clicks away from it, and in the footer. */

.drop {
	position: absolute;
	top: calc(100% + 0.4rem);
	left: -0.6rem;
	min-width: 17rem;
	padding: 0.55rem;
	border-radius: var(--r-m);
	/* Frosted glass. The tint is warm rather than neutral so the panel belongs
	   to the same ground as the rest of the site, and the saturation lift keeps
	   the photography behind it from going grey as it blurs. */
	background: color-mix(in srgb, var(--ink) 62%, transparent);
	-webkit-backdrop-filter: blur(26px) saturate(150%);
	backdrop-filter: blur(26px) saturate(150%);
	border: 1px solid color-mix(in srgb, var(--plaster) 14%, transparent);
	box-shadow:
		/* A lit top edge, which is what actually reads as glass rather than a
		   flat translucent rectangle. */
		inset 0 1px 0 color-mix(in srgb, var(--plaster) 16%, transparent),
		0 28px 60px rgba(0, 0, 0, 0.55),
		0 2px 8px rgba(0, 0, 0, 0.35);
}

/* Fallback for engines without backdrop-filter: an opaque panel is better than
   a see-through one nobody can read. */
@supports not (backdrop-filter: blur(1px)) {
	.drop { background: var(--board); }
}
/* The panel floats 0.4rem clear of the bar, and that gap belonged to neither
   the item nor the panel: dragging the pointer down into the list crossed it,
   fired mouseleave on the <li> and shut the panel before it could be reached.
   This bridges the gap with a transparent strip that is part of the panel, so
   the pointer never leaves the item. The visual gap stays. */
.drop::before {
	content: '';
	position: absolute;
	inset: -0.6rem 0 auto 0;
	height: 0.6rem;
}

.drop[hidden] { display: none; }
.drop__list { list-style: none; margin: 0; padding: 0; }
/* The retired static-site block still carries `.nav ul { display: flex }`, which
   outranks a lone .drop__list and laid the categories out in a row. Matched on
   specificity rather than reaching back into that block, which other things
   still depend on. */
.nav .drop__list { display: block; }
.nav .drop__list li { margin: 0; }
.drop__list a {
	display: flex;
	align-items: baseline;
	justify-content: space-between;
	gap: 1.5rem;
	min-height: 40px;
	padding: 0.45rem 0.7rem;
	border-radius: 6px;
	color: var(--sand);
	font-size: 0.95rem;
	text-decoration: none;
	transition: background 0.2s var(--ease), color 0.2s var(--ease);
}
.drop__list a:hover,
.drop__list a:focus-visible {
	background: color-mix(in srgb, var(--plaster) 9%, transparent);
	color: var(--plaster);
}
.drop__n { color: var(--taupe); font-size: 0.7rem; font-variant-numeric: tabular-nums; }

/* The panel now hangs off its own item, so the item is the positioning
   context — the opposite of the full-width panel it replaces. */
.nav__item--panel { position: relative; }

/* Nav sizing, up a step across the bar. */
.nav__list { gap: clamp(1.3rem, 2.4vw, 2.4rem); }
.nav__link,
.nav__trigger { font-size: 0.9rem; letter-spacing: 0.12em; }
.devis-pill { font-size: 0.86rem; }

@media (max-width: 960px) {
	/* In the sheet it is a plain block in the flow, not a floating panel. */
	.nav__item--panel { position: static; }
	.drop {
		position: static;
		min-width: 0;
		padding: 0 0 0.5rem;
		background: none;
		border: 0;
		box-shadow: none;
	}
	.drop__list a { min-height: 48px; font-size: 1.05rem; }
}

/* Nav item sizing --------------------------------------------------------
   The base rule reaches links through `.nav__list > li > a` (0,2,1) and the
   buttons through a bare `.nav__trigger` (0,1,0). Sizing them with `.nav__link`
   therefore lost to the base rule on links and won on triggers, which is why Au
   sol and Au mur came out a step larger than Tout voir and Contact. Matched on
   the same selectors so both move together. */

.nav .nav__list > li > a,
.nav .nav__trigger {
	font-size: 0.86rem;
	letter-spacing: 0.13em;
}

/* Category rail: drag and wheel ------------------------------------------
   Fades mark that the strip continues past both edges — without them a cut-off
   chip just looks like a rendering fault. Each fade hides itself at its end of
   the scroll so there is never a shadow over a hard stop. */

.crail { position: relative; }
.crail::before,
.crail::after {
	content: '';
	position: absolute;
	top: 0;
	bottom: 0.5rem;
	width: clamp(2rem, 6vw, 4.5rem);
	pointer-events: none;
	z-index: 2;
	opacity: 0;
	transition: opacity 0.25s var(--ease);
}
.crail::before {
	left: 0;
	background: linear-gradient(to right, var(--ink), transparent);
}
.crail::after {
	right: 0;
	background: linear-gradient(to left, var(--ink), transparent);
}
.crail.has-before::before,
.crail.has-after::after { opacity: 1; }

.crail__list { cursor: grab; scrollbar-width: none; }
.crail__list::-webkit-scrollbar { display: none; }
.crail.is-dragging .crail__list { cursor: grabbing; scroll-snap-type: none; user-select: none; }
.crail.is-dragging .crail__item { pointer-events: none; }

/* Pagination: no ring around the numbers ---------------------------------- */

.woocommerce-pagination .page-numbers { border-color: transparent; }
.woocommerce-pagination a.page-numbers:hover {
	border-color: transparent;
	background: color-mix(in srgb, var(--plaster) 10%, transparent);
	color: var(--plaster);
}
.woocommerce-pagination .page-numbers.current {
	background: var(--plaster);
	border-color: transparent;
	color: var(--ink);
}

/* Product media, brought back down ----------------------------------------
   The featured image took 1.05fr of the page and ran square, which on a wide
   screen is a ~700px block of material and pushes the measurement block, the
   description and the characteristics below the fold. The material reads at
   half that size; the space belongs to the copy and the devis form, which are
   what the page is for. */
/* Desktop only. Unscoped, these sit after the max-width: 60rem block that
   collapses the product page to one column, and being later they won a
   specificity tie — the page stayed two columns and overflowed the viewport at
   every phone width. The theme's breakpoint is 60rem, not the 900px this
   originally guessed at. */
@media (min-width: 60.01rem) {
	.product { grid-template-columns: minmax(0, 0.82fr) minmax(0, 1.18fr); }
	.product__media { max-width: 400px; }
}

/* The devis pill is a link now, not a button that opened a panel. */
.devis-pill { text-decoration: none; }

/* Adding to the devis has no page change to confirm it, so the button says so
   itself for a couple of seconds, with a check so the change of state is seen
   and not just read. The lead form's submit takes the same two states: sending,
   then done on the page it comes back to. */
.unitform__add.is-done,
.lead__submit.is-done {
	background: var(--taupe);
	border-color: var(--taupe);
	color: var(--ink);
	transform: none;
}
.unitform__add.is-done::before,
.lead__submit.is-done::before {
	content: '✓';
	margin-right: 0.6rem;
	font-weight: 600;
}
.lead__submit.is-sending { opacity: 0.7; cursor: progress; }
.lead__submit.is-sending::before {
	content: '';
	display: inline-block;
	width: 0.85em;
	height: 0.85em;
	margin-right: 0.6rem;
	border-radius: 50%;
	border: 2px solid currentColor;
	border-right-color: transparent;
	vertical-align: -0.1em;
	animation: mk-spin 0.7s linear infinite;
}
@keyframes mk-spin { to { transform: rotate(360deg); } }

/* Outbound links ------------------------------------------------------------
   One link in the catalogue leaves the site: gazon synthétique belongs to the
   sister brand. It sits with the categories because that is where it is looked
   for, and is marked so nobody clicks it expecting to stay here. */
.drop__out { margin-top: 0.35rem; padding-top: 0.35rem; border-top: 1px solid var(--rule); }
.drop__out a { align-items: center; }
.drop__ext {
	display: inline-flex;
	align-items: center;
	gap: 0.35rem;
	color: var(--taupe);
	font-size: 0.62rem;
	letter-spacing: 0.1em;
	text-transform: uppercase;
	white-space: nowrap;
}
.drop__out a:hover .drop__ext { color: var(--plaster); }

.ft .ext { display: inline-flex; align-items: center; gap: 0.4rem; }
.ext__i { flex: none; opacity: 0.75; }
.ext:hover .ext__i,
.drop__out a:hover .ext__i { opacity: 1; }

/* The panel was sized for one-word categories; "Gazon synthétique" plus its
   outbound mark wrapped onto two lines. Desktop only: in the mobile sheet the
   panel is a block in the flow with min-width 0, and an unscoped 20rem here
   overrode that. */
@media (min-width: 60.01rem) {
	.drop { min-width: 20rem; }
	.drop__out .drop__name { white-space: nowrap; }
}

/* Outbound tiles. They sit among the categories because that is where they are
   looked for, and they carry the mark plus a warmer note so the difference is
   visible before the click rather than after it. */
.tile--out .tile__n--out {
	display: inline-flex;
	align-items: center;
	gap: 0.4rem;
	color: var(--taupe);
}
.tile--out:hover .tile__n--out { color: var(--plaster); }
.crail__item--out .crail__n { display: inline-flex; align-items: center; color: var(--taupe); }
.crail__item--out:hover .crail__n { color: var(--plaster); }
