/* ==========================================================================
   Furniture catalogue and product configurator.
   Landing page catalogue: intro, category chip filter and product bands.
   Product page: gallery slot and the configurator panel. Reuses global
   tokens, .container, .eyebrow--chip, .button, .text-link. Page specific
   styles only; the drawer, badge and chip primitives live in
   components.css because they are global.
   ========================================================================== */

/* --------------------------------------------------------------------------
   Catalogue intro and filter.
   -------------------------------------------------------------------------- */

.section--furniture-catalogue {
	padding-block: clamp(2.4rem, 4vw, 3.6rem) clamp(4rem, 6vw, 6rem);
}

.furniture-catalogue__intro {
	display: flex;
	flex-direction: column;
	gap: var(--space-4);
	border-top: 1px solid var(--color-line);
	padding-top: clamp(1.4rem, 2.5vw, 2rem);
}

.furniture-catalogue__header-row {
	display: grid;
	grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr);
	gap: var(--space-5) clamp(2rem, 5vw, 5rem);
	align-items: end;
}

.furniture-catalogue__header-row h2 {
	font-size: var(--type-section-lg);
	font-weight: 500;
	letter-spacing: -0.015em;
	max-width: 18ch;
}

.furniture-catalogue__note {
	max-width: 34rem;
	font-size: var(--type-body-lg);
	line-height: 1.6;
	color: var(--color-muted);
}

/* --------------------------------------------------------------------------
   Storefront search. The wider door, so it sits above the chips and takes
   the full measure. Same square, mono, line bordered family as everything
   else on this page: a field, not a widget.
   -------------------------------------------------------------------------- */
.furniture-search-bar {
	margin-top: clamp(1.8rem, 3vw, 2.6rem);
}

.furniture-search {
	display: flex;
	flex-wrap: wrap;
	align-items: baseline;
	justify-content: space-between;
	gap: var(--space-3) var(--space-4);
}

.furniture-search__field {
	position: relative;
	display: flex;
	align-items: center;
	gap: 0.7rem;
	flex: 1 1 22rem;
	min-width: 0;
	padding: 0.85rem 1rem;
	border: 1px solid var(--color-line);
	background: transparent;
	transition: border-color 220ms var(--ease-out-soft);
}

/* On a wide screen the field is a field, not a runway: about a fifth
   of the container with a floor that keeps the placeholder on one
   line, left aligned, the product count sitting directly beside it on
   the same baseline. Phones keep the full width. */
@media (min-width: 1024px) {
	.furniture-search {
		justify-content: flex-start;
	}

	.furniture-search__field {
		flex: 0 1 20%;
		min-width: 280px;
	}
}

.furniture-search__field:focus-within {
	border-color: var(--color-accent-deep);
}

.furniture-search__icon {
	flex: none;
	color: var(--color-muted);
	transition: color 220ms var(--ease-out-soft);
}

.furniture-search__field:focus-within .furniture-search__icon {
	color: var(--color-accent-deep);
}

.furniture-search__input {
	flex: 1 1 auto;
	min-width: 0;
	border: 0;
	background: transparent;
	font-family: inherit;
	font-size: var(--type-body-lg);
	line-height: 1.4;
	color: var(--color-ink);
}

.furniture-search__input::placeholder {
	color: var(--color-muted);
}

.furniture-search__input:focus {
	outline: none;
}

/* The field carries the focus ring for the whole control, so the ring is
   never lost when the input itself has no border of its own. */
.furniture-search__field:focus-within {
	outline: 2px solid var(--color-accent-deep);
	outline-offset: 2px;
}

.furniture-search__input::-webkit-search-cancel-button {
	display: none;
}

.furniture-search__clear {
	flex: none;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 1.5rem;
	height: 1.5rem;
	padding: 0;
	border: 0;
	background: transparent;
	font-size: 1.15rem;
	line-height: 1;
	color: var(--color-muted);
	cursor: pointer;
	transition: color 220ms var(--ease-out-soft);
}

.furniture-search__clear:hover,
.furniture-search__clear:focus-visible {
	color: var(--color-ink);
}

.furniture-search__clear[hidden] {
	display: none;
}

.furniture-search__count {
	flex: none;
	font-family: var(--font-mono);
	font-size: var(--type-label);
	letter-spacing: 0.08em;
	text-transform: uppercase;
	color: var(--color-accent-text);
	white-space: nowrap;
}

/* The empty state is never a dead end: shelves that do have something on
   them, then the human route. */
.furniture-search__empty {
	margin-top: clamp(2.4rem, 5vw, 4rem);
	padding-bottom: clamp(1rem, 2vw, 2rem);
	max-width: 46rem;
}

.furniture-search__empty[hidden] {
	display: none;
}

.furniture-search__empty-line {
	font-family: var(--font-heading);
	font-size: var(--type-section-md);
	font-weight: 500;
	letter-spacing: -0.01em;
	color: var(--color-ink);
}

.furniture-search__empty-label {
	margin-top: clamp(1.6rem, 3vw, 2.4rem);
	font-family: var(--font-mono);
	font-size: var(--type-label);
	letter-spacing: 0.08em;
	text-transform: uppercase;
	color: var(--color-muted);
}

.furniture-search__suggestions {
	display: flex;
	flex-wrap: wrap;
	gap: 0.5rem;
	margin-top: 0.9rem;
}

.furniture-search__empty-human {
	margin-top: clamp(1.8rem, 3.4vw, 2.6rem);
	max-width: 38rem;
	font-size: var(--type-body-lg);
	line-height: 1.6;
	color: var(--color-muted);
}

.furniture-search__empty-link {
	display: inline-block;
	margin-top: 0.4rem;
	color: var(--color-accent-deep);
	text-decoration: none;
	border-bottom: 1px solid currentColor;
}

.furniture-search__empty-link:hover,
.furniture-search__empty-link:focus-visible {
	color: var(--color-ink);
}

/* On a phone the grid is long, so the field stays reachable while it
   scrolls. The bar sticks rather than the field, because a sticky element
   only travels inside its own containing block and the bar is a child of
   the section that holds the whole grid. */
@media (max-width: 760px) {
	.furniture-search-bar {
		position: sticky;
		top: 3.6rem;
		z-index: 20;
		padding-block: 0.7rem;
		background: var(--color-bg);
		box-shadow: 0 10px 20px -14px rgba(17, 22, 19, 0.4);
	}

	.furniture-search {
		gap: 0.5rem var(--space-3);
	}

	.furniture-search__field {
		flex: 1 1 100%;
	}
}

.furniture-filter {
	display: flex;
	flex-wrap: wrap;
	gap: 0.5rem;
	margin-top: clamp(1.8rem, 3vw, 2.6rem);
	padding-bottom: clamp(1.4rem, 2.5vw, 2rem);
	border-bottom: 1px solid var(--color-line);
}

.furniture-filter__chip {
	display: inline-flex;
	align-items: center;
	gap: 0.5rem;
	padding: 0.62rem 0.95rem;
	border: 1px solid var(--color-line);
	border-radius: 0;
	background: transparent;
	font-family: var(--font-mono);
	font-size: 0.74rem;
	font-weight: 500;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	color: var(--color-text);
	cursor: pointer;
	transition: border-color 220ms var(--ease-out-soft), color 220ms var(--ease-out-soft), background-color 220ms var(--ease-out-soft);
}

.furniture-filter__chip:hover,
.furniture-filter__chip:focus-visible {
	border-color: var(--color-accent-deep);
	color: var(--color-accent-deep);
	outline: none;
}

.furniture-filter__chip.is-active {
	background: var(--color-ink);
	border-color: var(--color-ink);
	color: var(--color-warm-white);
}

.furniture-filter__count {
	font-size: 0.7rem;
	opacity: 0.6;
}

.furniture-catalogue__empty {
	margin-top: var(--space-6);
	max-width: 36rem;
	color: var(--color-muted);
}

/* --------------------------------------------------------------------------
   Product bands.
   -------------------------------------------------------------------------- */

.furniture-band {
	padding-top: clamp(3rem, 5vw, 4.5rem);
}

.furniture-band__head {
	display: flex;
	align-items: baseline;
	justify-content: space-between;
	gap: var(--space-4);
	margin-bottom: clamp(1.4rem, 2.4vw, 2rem);
}

.furniture-band__title {
	font-family: var(--font-heading);
	font-size: var(--type-section-md);
	font-weight: 500;
	letter-spacing: -0.01em;
	color: var(--color-ink);
}

.furniture-band__count {
	font-family: var(--font-mono);
	font-size: var(--type-label);
	letter-spacing: 0.08em;
	text-transform: uppercase;
	color: var(--color-accent-text);
	white-space: nowrap;
}

.furniture-band__grid {
	display: grid;
	grid-template-columns: repeat(3, minmax(0, 1fr));
	gap: clamp(1.6rem, 2.6vw, 2.4rem) clamp(1.2rem, 2.2vw, 2rem);
}

@media (max-width: 980px) {
	.furniture-band__grid {
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}
}

@media (max-width: 640px) {
	.furniture-band__grid {
		grid-template-columns: 1fr;
	}

	.furniture-catalogue__header-row {
		grid-template-columns: 1fr;
	}
}

/* --------------------------------------------------------------------------
   Product card. Fixed aspect media slot so images never shift layout,
   with a designed tonal placeholder that carries the range name.
   -------------------------------------------------------------------------- */

.product-card {
	display: flex;
	flex-direction: column;
	gap: var(--space-3);
	min-width: 0;
	color: var(--color-text);
}

.product-card__media {
	position: relative;
	display: block;
	aspect-ratio: 4 / 3;
	overflow: hidden;
	background: var(--color-card);
}

.product-card__img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	filter: var(--photo-grade);
	transition: transform 720ms var(--ease-out-soft);
}

.product-card:hover .product-card__img {
	transform: scale(1.04);
}

.product-card__placeholder {
	position: absolute;
	inset: 0;
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	justify-content: flex-end;
	gap: 0.6rem;
	padding: clamp(1rem, 1.6vw, 1.4rem);
	background:
		linear-gradient(160deg, rgba(255, 254, 250, 0.35) 0%, rgba(255, 254, 250, 0) 55%),
		var(--color-card);
}

.product-card__placeholder-mark {
	width: 0.42rem;
	height: 0.42rem;
	transform: rotate(45deg);
	background: var(--color-accent);
}

.product-card__placeholder-name {
	font-family: var(--font-heading);
	font-size: clamp(1.1rem, 1.5vw, 1.4rem);
	font-weight: 500;
	line-height: 1.1;
	letter-spacing: -0.01em;
	color: var(--color-ink);
	opacity: 0.55;
}

.product-card__body {
	display: flex;
	flex-direction: column;
	gap: 0.45rem;
	flex: 1;
}

.product-card__category {
	font-family: var(--font-mono);
	font-size: 0.7rem;
	letter-spacing: 0.1em;
	text-transform: uppercase;
	color: var(--color-accent-text);
}

.product-card__title {
	font-family: var(--font-heading);
	font-size: clamp(1.05rem, 1.3vw, 1.25rem);
	font-weight: 500;
	letter-spacing: -0.01em;
	line-height: 1.15;
}

.product-card__title a {
	color: var(--color-ink);
	text-decoration: none;
	transition: color var(--transition);
}

.product-card:hover .product-card__title a {
	color: var(--color-accent-deep);
}

.product-card__line {
	font-size: 0.9rem;
	line-height: 1.5;
	color: var(--color-muted);
	display: -webkit-box;
	-webkit-line-clamp: 2;
	-webkit-box-orient: vertical;
	overflow: hidden;
}

.product-card__footer {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--space-3);
	margin-top: auto;
	padding-top: var(--space-3);
}

.product-card__price {
	display: flex;
	align-items: baseline;
	gap: 0.35rem;
	flex-wrap: wrap;
}

.product-card__price-label,
.product-card__price-note {
	font-family: var(--font-mono);
	font-size: 0.7rem;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	color: var(--color-muted);
}

.product-card__price-value {
	font-family: var(--font-heading);
	font-size: 1.05rem;
	font-weight: 500;
	color: var(--color-ink);
}

.product-card__cta {
	flex: none;
	min-height: 2.4rem;
	padding: 0.5rem 0.9rem;
	font-size: 0.72rem;
}

/* --------------------------------------------------------------------------
   Product configurator page.
   -------------------------------------------------------------------------- */

.product-configurator {
	padding-block: clamp(1.6rem, 3vw, 2.4rem) clamp(4.5rem, 7vw, 7rem);
	/* A tile tooltip is centred on its tile, so a tile in the last column can
	   push it a few pixels past the page edge and hand the whole page a
	   sideways scrollbar for something nobody can see. This section is already
	   the full width of the viewport, so clipping here trims only what is off
	   screen anyway. Clip and not hidden, so the sticky gallery keeps the
	   viewport as its scrollport. */
	overflow-x: clip;
}

.product-configurator__crumbs {
	display: flex;
	align-items: center;
	gap: 0.6rem;
	margin-bottom: clamp(1.4rem, 2.6vw, 2.2rem);
	font-family: var(--font-mono);
	font-size: var(--type-label);
	letter-spacing: 0.08em;
	text-transform: uppercase;
	color: var(--color-muted);
}

.product-configurator__crumbs a {
	color: var(--color-accent-text);
	text-decoration: none;
}

.product-configurator__crumbs a:hover {
	color: var(--color-ink);
}

.product-configurator__grid {
	display: grid;
	grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr);
	gap: clamp(2rem, 4.5vw, 5rem);
	align-items: start;
}

/* The panel precedes the gallery in the DOM so the H1 leads the
   document outline; the grid still draws the gallery on the left. */
.product-configurator__grid .product-configurator__gallery {
	grid-column: 1;
	grid-row: 1;
}

.product-configurator__grid .product-configurator__panel {
	grid-column: 2;
	grid-row: 1;
}

.product-configurator__gallery {
	position: sticky;
	top: 6rem;
	display: flex;
	flex-direction: column;
	gap: clamp(1.4rem, 2.6vw, 2.2rem);
}

.product-configurator__figure {
	position: relative;
	margin: 0;
	aspect-ratio: 4 / 5;
	overflow: hidden;
	background: var(--color-card);
}

.product-configurator__img {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	object-fit: cover;
	transition: opacity 250ms var(--ease-out-soft);
	filter: var(--photo-grade);
}

/* The resolution floor. A file smaller than the pane sits centred at
   its native size on the pane's own ground, never stretched. The class
   comes from the engine, which compares the pane to the file. */
.product-configurator__img.is-native {
	inset: auto;
	left: 50%;
	top: 50%;
	width: auto;
	height: auto;
	max-width: 100%;
	max-height: 100%;
	transform: translate(-50%, -50%);
	object-fit: contain;
}

.product-configurator__figure--placeholder {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	justify-content: flex-end;
	gap: 0.7rem;
	padding: clamp(1.4rem, 2.6vw, 2.4rem);
	background:
		linear-gradient(160deg, rgba(255, 254, 250, 0.4) 0%, rgba(255, 254, 250, 0) 55%),
		var(--color-card);
}

.product-configurator__placeholder-mark {
	width: 0.5rem;
	height: 0.5rem;
	transform: rotate(45deg);
	background: var(--color-accent);
}

.product-configurator__placeholder-name {
	font-family: var(--font-heading);
	font-size: clamp(1.6rem, 2.6vw, 2.6rem);
	font-weight: 500;
	line-height: 1.05;
	letter-spacing: -0.015em;
	color: var(--color-ink);
	opacity: 0.55;
}

.product-configurator__placeholder-note {
	font-family: var(--font-mono);
	font-size: var(--type-label);
	letter-spacing: 0.1em;
	text-transform: uppercase;
	color: var(--color-muted);
}

.product-configurator__description {
	max-width: 40rem;
	color: var(--color-muted);
	font-size: 0.95rem;
	line-height: 1.66;
}

.product-configurator__description p + p {
	margin-top: var(--space-3);
}

.product-configurator__panel {
	display: flex;
	flex-direction: column;
	gap: clamp(1.6rem, 2.6vw, 2.2rem);
}

.product-configurator__head {
	display: flex;
	flex-direction: column;
	gap: var(--space-3);
}

.product-configurator__title {
	font-size: clamp(2rem, 3.2vw, 3rem);
	font-weight: 500;
	line-height: 1.05;
	letter-spacing: -0.018em;
	color: var(--color-ink);
}

.product-configurator__lead {
	max-width: 32rem;
}

.product-configurator__price {
	display: flex;
	align-items: baseline;
	gap: 0.6rem;
	flex-wrap: wrap;
	padding-block: var(--space-3);
	border-top: 1px solid var(--color-line);
	border-bottom: 1px solid var(--color-line);
}

.product-configurator__price-label,
.product-configurator__price-note {
	font-family: var(--font-mono);
	font-size: var(--type-label);
	letter-spacing: 0.08em;
	text-transform: uppercase;
	color: var(--color-muted);
}

.product-configurator__price-value {
	font-family: var(--font-heading);
	font-size: clamp(1.5rem, 2.2vw, 2rem);
	font-weight: 500;
	color: var(--color-ink);
	transition: color 260ms var(--ease-out-soft);
}

.product-configurator__price-value.is-updating {
	color: var(--color-accent-deep);
}

.product-configurator__options {
	display: flex;
	flex-direction: column;
	gap: clamp(1.3rem, 2.2vw, 1.8rem);
}

/* Option group. */
.config-group {
	margin: 0;
	padding: 0;
	border: 0;
	min-width: 0;
}

.config-group__label {
	display: flex;
	align-items: baseline;
	justify-content: space-between;
	gap: var(--space-3);
	margin-bottom: 0.7rem;
	padding: 0;
	font-family: var(--font-mono);
	font-size: var(--type-label);
	letter-spacing: 0.08em;
	text-transform: uppercase;
	color: var(--color-muted);
}

.config-group__value {
	font-family: var(--font-body);
	font-size: 0.85rem;
	letter-spacing: normal;
	text-transform: none;
	color: var(--color-ink);
	text-align: right;
}

.config-group__chips {
	display: flex;
	flex-wrap: wrap;
	gap: 0.5rem;
}

/* Large touch friendly chip. The radio is visually hidden but keeps
   keyboard and screen reader behaviour. */
.config-chip {
	position: relative;
	display: inline-flex;
	flex-direction: column;
	align-items: flex-start;
	gap: 0.15rem;
	min-height: 2.9rem;
	padding: 0.6rem 2.15rem 0.6rem 0.9rem;
	border: 1px solid var(--color-line);
	background: transparent;
	cursor: pointer;
	transition: border-color 220ms var(--ease-out-soft), background-color 220ms var(--ease-out-soft), color 220ms var(--ease-out-soft);
}

.config-chip input {
	position: absolute;
	width: 1px;
	height: 1px;
	margin: -1px;
	opacity: 0;
	pointer-events: none;
}

.config-chip:hover {
	border-color: var(--color-accent-deep);
}

.config-chip:has(input:focus-visible) {
	outline: 2px solid var(--color-accent-deep);
	outline-offset: 2px;
}

.config-chip.is-selected {
	border-color: var(--color-ink);
	background: var(--color-ink);
	color: var(--color-warm-white);
	outline: 2px solid var(--color-ink);
	outline-offset: 2px;
}

.config-chip__label {
	font-size: 0.9rem;
	font-weight: 500;
	line-height: 1.2;
}

/* The figure on a chip reads as a number, on the same terms as the price line
   under a tile: normal case, normal tracking, and the R closed up against it.
   Letter spacing belongs to the labels above these figures, not to the figures
   themselves. */
.config-chip__price {
	font-family: var(--font-mono);
	font-size: 12px;
	letter-spacing: normal;
	opacity: 0.7;
}

/* Quiet More options reveal. */
.config-more {
	border-top: 1px solid var(--color-line);
	border-bottom: 1px solid var(--color-line);
}

.config-more__summary {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--space-3);
	padding: 0.95rem 0;
	list-style: none;
	cursor: pointer;
	font-family: var(--font-heading);
	font-size: 0.95rem;
	font-weight: 500;
	color: var(--color-ink);
}

.config-more__summary::-webkit-details-marker {
	display: none;
}

.config-more__summary::after {
	content: "+";
	margin-left: auto;
	font-family: var(--font-mono);
	font-size: 1rem;
	color: var(--color-accent);
	transition: transform 260ms var(--ease-out-soft);
}

.config-more[open] .config-more__summary::after {
	transform: rotate(45deg);
}

.config-more__hint {
	font-family: var(--font-mono);
	font-size: 0.7rem;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	color: var(--color-muted);
}

.config-more__body {
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	gap: var(--space-4) var(--space-4);
	padding-bottom: 1.2rem;
}

.config-select select {
	width: 100%;
	padding: 0.8rem 2.6rem 0.8rem 1rem;
	border: 1px solid var(--color-line);
	border-radius: 0;
	background: var(--color-bg);
	color: var(--color-text);
	font-size: 0.9rem;
	line-height: 1.4;
	appearance: none;
	background-image: url("data:image/svg+xml;charset=UTF-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6'%3E%3Cpath d='M1 1l4 4 4-4' fill='none' stroke='%231c1a16' stroke-width='1.4'/%3E%3C/svg%3E");
	background-repeat: no-repeat;
	background-position: right 1rem center;
	transition: border-color 220ms var(--ease-out-soft);
}

.config-select select:focus-visible {
	outline: none;
	border-color: var(--color-accent-deep);
}

/* Quantity stepper. */
.config-qty {
	display: inline-flex;
	align-items: stretch;
	border: 1px solid var(--color-line);
}

.config-qty__btn {
	width: 2.9rem;
	border: 0;
	background: transparent;
	font-size: 1.1rem;
	color: var(--color-ink);
	cursor: pointer;
	transition: background-color 220ms var(--ease-out-soft);
}

.config-qty__btn:hover {
	background: var(--color-card);
}

.config-qty input {
	width: 4rem;
	border: 0;
	border-inline: 1px solid var(--color-line);
	background: transparent;
	text-align: center;
	font-size: 0.95rem;
	color: var(--color-ink);
	-moz-appearance: textfield;
}

.config-qty input::-webkit-outer-spin-button,
.config-qty input::-webkit-inner-spin-button {
	-webkit-appearance: none;
	margin: 0;
}

/* Actions. */
.product-configurator__actions {
	display: flex;
	flex-direction: column;
	gap: 0.8rem;
	align-items: flex-start;
}

.product-configurator__add {
	min-width: 16rem;
	justify-content: space-between;
}

.product-configurator__add.is-added {
	--btn-fill: var(--color-accent-deep);
	--btn-border: var(--color-accent-deep);
	--btn-text: var(--color-accent-deep);
}

.product-configurator__reassure {
	font-size: 0.85rem;
	color: var(--color-muted);
}

/* Below 900 the page reads in buying order: gallery, then the name,
   blurb and price, then the options, then Your build and the add button
   together, and only then About, trust and spec. The strip and the button
   are adjacent here for the same reason they are adjacent on the desktop
   column: About this range between them meant a buyer scrolled past their
   own summary and read a paragraph before reaching the decision. The two
   columns dissolve into one flow and each block takes its place. */
@media (max-width: 900px) {
	.product-configurator__grid {
		display: flex;
		flex-direction: column;
		gap: clamp(1.6rem, 4vw, 2.2rem);
	}

	.product-configurator__gallery,
	.product-configurator__panel {
		display: contents;
	}

	.product-configurator__grid .product-configurator__figure,
	.product-configurator__grid .product-configurator__caption,
	.product-configurator__grid .product-configurator__views {
		order: 1;
	}

	.product-configurator__grid .product-configurator__head {
		order: 2;
	}

	.product-configurator__grid .product-configurator__price {
		order: 3;
	}

	.product-configurator__grid .product-configurator__from {
		order: 4;
	}

	.product-configurator__grid .product-configurator__included {
		order: 5;
	}

	.product-configurator__grid .product-configurator__options {
		order: 6;
	}

	.product-configurator__grid .build-strip {
		order: 7;
	}

	.product-configurator__grid .product-configurator__actions {
		order: 8;
	}

	.product-configurator__grid .product-configurator__description {
		order: 9;
	}

	.product-configurator__grid .trust-strip {
		order: 10;
	}

	.product-configurator__grid .spec-brief {
		order: 11;
	}

	.product-configurator__grid .sticky-add {
		order: 12;
	}

	/* The price sits directly under the head, so the pair reads as one
	   price bar; the tap to floor line closes up under it. */
	.product-configurator__grid .product-configurator__price {
		margin-top: -0.6rem;
	}

	.product-configurator__grid .product-configurator__from {
		margin-top: -1rem;
		align-self: flex-start;
	}

	.config-more__body {
		grid-template-columns: 1fr;
	}
}

@media (max-width: 640px) {
	.product-configurator__add {
		width: 100%;
	}

	.config-chip {
		min-height: 3.2rem;
		padding: 0.7rem 2.2rem 0.7rem 1rem;
	}
}

/* --------------------------------------------------------------------------
   Storefront additions: seating sub filter, hidden matrix chips, spec list.
   -------------------------------------------------------------------------- */
.furniture-subfilter {
	display: flex;
	flex-wrap: wrap;
	gap: 0.4rem;
	margin-top: 0.9rem;
}

/* Inside a band the row tucks up under the heading, half the head gap,
   and opens the full gap again before the product grid. */
.furniture-band .furniture-subfilter {
	margin-top: calc(-0.5 * clamp(1.4rem, 2.4vw, 2rem));
	margin-bottom: clamp(1.4rem, 2.4vw, 2rem);
}

.furniture-subfilter__chip {
	display: inline-flex;
	align-items: center;
	padding: 0.42rem 0.75rem;
	border: 1px solid transparent;
	border-radius: 0;
	background: transparent;
	font-family: var(--font-mono);
	font-size: 0.7rem;
	font-weight: 500;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	color: var(--color-muted);
	cursor: pointer;
	transition: border-color 220ms var(--ease-out-soft), color 220ms var(--ease-out-soft), background-color 220ms var(--ease-out-soft);
}

.furniture-subfilter__chip:hover,
.furniture-subfilter__chip:focus-visible {
	color: var(--color-ink);
	border-color: var(--color-line);
	outline: none;
}

.furniture-subfilter__chip.is-active {
	color: var(--color-ink);
	border-color: var(--color-accent-deep);
	background: var(--color-card);
}

.config-chip[hidden],
.furniture-subfilter[hidden],
.product-card[hidden] {
	display: none;
}

.product-configurator__spec {
	margin-top: var(--space-4);
	padding-top: var(--space-3);
	border-top: 1px solid var(--color-line);
}

.product-configurator__spec-row {
	display: grid;
	grid-template-columns: 6rem minmax(0, 1fr);
	gap: var(--space-3);
	padding: 0.55rem 0;
	border-bottom: 1px solid var(--color-line);
}

.product-configurator__spec-row dt {
	font-family: var(--font-mono);
	font-size: 0.75rem;
	letter-spacing: 0.1em;
	text-transform: uppercase;
	color: var(--color-accent-text);
	padding-top: 0.15rem;
}

.product-configurator__spec-row dd {
	margin: 0;
	font-size: 0.9rem;
	color: var(--color-text);
}

/* Variant aware gallery: the incoming image sits on top and fades in,
   the outgoing one is removed once the fade completes. Opacity only. */
.product-configurator__img.is-incoming {
	opacity: 0;
}

.product-configurator__img.is-incoming.is-visible {
	opacity: 1;
}

@media (prefers-reduced-motion: reduce) {
	.product-configurator__img {
		transition: none;
	}
}

/* Colour and finish swatch chips. The swatch is a fixed square beside
   the label; supplier swatch image on top of a hex fallback. */
.config-chip--swatch {
	display: inline-flex;
	flex-direction: row;
	align-items: center;
	gap: 0.65rem;
	padding-left: 0.5rem;
}

.config-chip__swatch {
	flex: 0 0 auto;
	width: 2rem;
	height: 2rem;
	border: 1px solid rgba(38, 38, 38, 0.12);
	background-color: var(--color-card);
	background-size: cover;
	background-position: center;
}

.config-chip--swatch.is-selected .config-chip__swatch {
	box-shadow: 0 0 0 2px var(--color-ink), 0 0 0 3px var(--color-warm-white);
}

/* --------------------------------------------------------------------------
   Family configurator: colour combination swatches, picture chips, leg
   profile icons, linked lines and horizontal chip rows on mobile.
   -------------------------------------------------------------------------- */
.config-swatches,
.config-pictures {
	display: flex;
	flex-wrap: wrap;
	gap: 0.6rem;
}

.config-swatch {
	position: relative;
	display: inline-flex;
	flex-direction: column;
	align-items: center;
	gap: 0.35rem;
	width: 4rem;
	cursor: pointer;
}

.config-swatch input {
	position: absolute;
	opacity: 0;
	inset: 0;
	pointer-events: none;
}

.config-swatch__tile {
	position: relative;
	display: block;
	width: 3.75rem;
	height: 3.75rem;
	overflow: hidden;
	border: 1px solid rgba(38, 38, 38, 0.14);
	background: var(--color-card);
	transition: box-shadow 220ms var(--ease-out-soft), border-color 220ms var(--ease-out-soft);
}

.config-swatch__a,
.config-swatch__b {
	position: absolute;
	inset: 0;
	background-size: cover;
	background-position: center;
}

.config-swatch--two-tone .config-swatch__b {
	clip-path: polygon(100% 0, 100% 100%, 0 100%);
}

.config-swatch__label {
	max-width: 100%;
	font-size: 0.75rem;
	line-height: 1.25;
	text-align: center;
	color: var(--color-muted);
	transition: color 220ms var(--ease-out-soft);
}

.config-swatch__label em {
	display: block;
	font-style: normal;
	font-family: var(--font-mono);
	font-size: 0.7rem;
	letter-spacing: 0.06em;
	text-transform: uppercase;
	color: var(--color-accent-text);
}

.config-swatch:hover .config-swatch__tile,
.config-swatch:has(input:focus-visible) .config-swatch__tile {
	border-color: var(--color-ink);
}

.config-swatch:hover .config-swatch__label,
.config-swatch.is-selected .config-swatch__label {
	color: var(--color-ink);
}

.config-swatch.is-selected .config-swatch__tile {
	border-color: var(--color-ink);
	box-shadow: 0 0 0 2px var(--color-ink), 0 0 0 3px var(--color-warm-white);
}

.config-swatch[hidden] {
	display: none;
}

.config-more-link {
	margin-top: 0.7rem;
	padding: 0;
	border: 0;
	background: transparent;
	font-family: var(--font-mono);
	font-size: 0.7rem;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	color: var(--color-accent-deep);
	cursor: pointer;
}

.config-more-link:hover,
.config-more-link:focus-visible {
	color: var(--color-ink);
	outline: none;
}

.config-picture {
	position: relative;
	display: inline-flex;
	flex-direction: column;
	gap: 0.4rem;
	width: 7.2rem;
	cursor: pointer;
}

.config-picture input {
	position: absolute;
	opacity: 0;
	inset: 0;
	pointer-events: none;
}

.config-picture__tile {
	display: flex;
	align-items: center;
	justify-content: center;
	aspect-ratio: 1 / 1;
	overflow: hidden;
	border: 1px solid var(--color-line);
	background: #fff;
	transition: border-color 220ms var(--ease-out-soft), box-shadow 220ms var(--ease-out-soft);
}

.config-picture__tile img {
	width: 100%;
	height: 100%;
	object-fit: contain;
}

.config-picture--blank .config-picture__tile {
	background: var(--color-card);
}

.config-picture__mark {
	width: 0.5rem;
	height: 0.5rem;
	transform: rotate(45deg);
	background: var(--color-accent);
}

.config-picture__label {
	font-size: 0.78rem;
	line-height: 1.3;
	color: var(--color-text);
}

.config-picture__price {
	font-family: var(--font-mono);
	font-size: 0.7rem;
	letter-spacing: 0.06em;
	text-transform: uppercase;
	color: var(--color-muted);
}

.config-picture:hover .config-picture__tile,
.config-picture:has(input:focus-visible) .config-picture__tile {
	border-color: var(--color-ink);
}

.config-picture.is-selected .config-picture__tile {
	border-color: var(--color-ink);
	box-shadow: 0 0 0 1px var(--color-ink);
}

.config-picture[hidden] {
	display: none;
}

/* Covering: two tiles, the same pair a chair uses for its own material.
   The quieter one is words rather than a colour, because own material has
   no swatch to show, and the line it opens sits under the row it belongs
   to rather than beside the price. */
.config-group--covering .config-tiles {
	align-items: flex-start;
}

.config-covering__note {
	margin: calc(var(--space-3) * -1) 0 var(--space-4);
}

.config-covering__note .config-fabric__own-line {
	margin: 0;
}

/* What the parent price already covers. Stated once, under the price,
   where it answers the question the price raises, and never drawn as a
   chip a visitor could add and be charged for twice. */
.product-configurator__included {
	margin: calc(var(--space-3) * -1) 0 var(--space-4);
}

.product-configurator__included-label {
	margin: 0 0 0.35rem;
	font-family: var(--font-mono);
	font-size: 0.7rem;
	letter-spacing: 0.1em;
	text-transform: uppercase;
	color: var(--color-muted);
}

.product-configurator__included-list {
	list-style: none;
	margin: 0;
	padding: 0;
	font-size: 0.85rem;
	line-height: 1.6;
	color: var(--color-muted);
}

.product-configurator__included-list li {
	position: relative;
	padding-left: 1.1rem;
}

.product-configurator__included-list li::before {
	content: "";
	position: absolute;
	left: 0;
	top: 0.62em;
	width: 0.45rem;
	height: 0.45rem;
	border: 1px solid var(--color-accent);
	border-radius: 50%;
}

.config-lines {
	list-style: none;
	margin: 0 0 var(--space-4);
	padding: 0;
	border-top: 1px solid var(--color-line);
}

.config-lines[hidden] {
	display: none;
}

.config-lines__item {
	display: flex;
	justify-content: space-between;
	gap: var(--space-3);
	padding: 0.5rem 0;
	border-bottom: 1px solid var(--color-line);
	font-size: 0.85rem;
	color: var(--color-muted);
}

/* The name yields and the price does not. A flex item shrinks by default,
   so in a narrow column R 2 800 broke into "R 2" and "800", which reads as
   two numbers. The name has somewhere to go, a second line; the price has
   not. */
.config-lines__label {
	min-width: 0;
	overflow-wrap: anywhere;
}

.config-lines__price {
	flex: 0 0 auto;
	white-space: nowrap;
	color: var(--color-text);
}

.quote-item__lines {
	list-style: none;
	margin: 0.4rem 0 0;
	padding: 0 0 0 0.75rem;
	border-left: 1px solid var(--color-line);
}

.quote-item__line {
	display: flex;
	justify-content: space-between;
	gap: 0.6rem;
	font-size: 0.78rem;
	line-height: 1.5;
	color: var(--color-muted);
}

/* Same rule as the configurator's own line list, and this is the column it
   was noticed in: at 364 px "+ Top cut out for the power unit x 4" pushed
   R 2 800 into "R 2" and "800". The name takes a second line, the price
   stays whole. */
.quote-item__line > span:first-child {
	min-width: 0;
	overflow-wrap: anywhere;
}

.quote-item__line > span:last-child {
	flex: 0 0 auto;
	white-space: nowrap;
}

.product-spec-list {
	margin: 0;
	padding-left: 1.1rem;
	font-size: 0.9rem;
	line-height: 1.6;
	color: var(--color-muted);
}


/* --------------------------------------------------------------------------
   Family configurator tiles. 64 px on desktop, 56 px on mobile, 8 px gap,
   2 px radius, hairline border, accent ring when selected, 1 px lift on
   hover, label as a hover tip. Sentence case labels with the current
   value beside them, more air between rows.
   -------------------------------------------------------------------------- */
.product-configurator--family .product-configurator__options {
	display: flex;
	flex-direction: column;
	gap: clamp(1.6rem, 2.4vw, 2.2rem);
}

.product-configurator--family .config-group {
	margin: 0;
	padding: 0;
	border: 0;
}

.config-group__label--family {
	display: block;
	margin-bottom: 0.7rem;
	font-family: var(--font-heading);
	font-size: 0.86rem;
	font-weight: 500;
	letter-spacing: 0;
	text-transform: none;
	color: var(--color-muted);
}

.config-group__label--family .config-group__value {
	margin-left: 0;
	font-family: var(--font-heading);
	font-size: 0.86rem;
	letter-spacing: 0;
	text-transform: none;
	color: var(--color-ink);
}

.config-group__label--family .config-group__value:empty + .config-group__sep,
.config-group__label--family .config-group__sep:has(+ .config-group__value:empty) {
	display: none;
}

.config-tiles {
	display: flex;
	flex-wrap: wrap;
	gap: 11px;
}

.config-tile {
	position: relative;
	display: block;
	width: 88px;
	height: 88px;
	cursor: pointer;
}

.config-tile input {
	position: absolute;
	inset: 0;
	opacity: 0;
	pointer-events: none;
}

.config-tile__face {
	position: relative;
	display: flex;
	align-items: center;
	justify-content: center;
	flex-direction: column;
	gap: 0.15rem;
	width: 100%;
	height: 100%;
	overflow: hidden;
	border: 1px solid rgba(38, 38, 38, 0.16);
	border-radius: 2px;
	background: #fff;
	color: var(--color-ink);
	transition: transform 320ms var(--ease-out-soft), box-shadow 320ms var(--ease-out-soft), border-color 220ms var(--ease-out-soft);
}

.config-tile__a,
.config-tile__b {
	position: absolute;
	inset: 0;
	background-size: cover;
	background-position: center;
}

.config-tile__b {
	clip-path: polygon(100% 0, 100% 100%, 0 100%);
}

.config-tile__face img {
	width: 100%;
	height: 100%;
	object-fit: contain;
	padding: 4px;
}

.config-tile__text {
	padding: 0 4px;
	font-size: 0.75rem;
	line-height: 1.2;
	text-align: center;
	color: var(--color-ink);
}

.config-tile:hover .config-tile__face,
.config-tile:has(input:focus-visible) .config-tile__face {
	transform: translateY(-1px);
	border-color: rgba(38, 38, 38, 0.32);
}

.config-tile.is-selected .config-tile__face {
	border-color: transparent;
	box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.7), inset 0 0 6px rgba(38, 38, 38, 0.08);
}

.config-tile__tip {
	position: absolute;
	left: 50%;
	bottom: calc(100% + 6px);
	z-index: 3;
	transform: translate(-50%, 4px);
	max-width: 14rem;
	padding: 0.35rem 0.55rem;
	border-radius: 2px;
	background: var(--color-ink);
	color: var(--color-warm-white);
	font-size: 0.7rem;
	line-height: 1.3;
	white-space: nowrap;
	opacity: 0;
	pointer-events: none;
	transition: opacity 180ms var(--ease-out-soft), transform 180ms var(--ease-out-soft);
}

.config-tile__tip-price {
	display: block;
	opacity: 0.7;
	font-family: var(--font-mono);
	font-size: 0.7rem;
	letter-spacing: normal;
}

.config-tile__tip-price:empty {
	display: none;
}

.config-tile:hover .config-tile__tip,
.config-tile:has(input:focus-visible) .config-tile__tip {
	opacity: 1;
	transform: translate(-50%, 0);
}

.config-tile[hidden] {
	display: none;
}

@media (max-width: 720px) {
	.config-tile {
		width: 76px;
		height: 76px;
	}

	.config-tile__tip {
		display: none;
	}
}

.product-configurator--family .config-more__hint {
	font-family: var(--font-heading);
	font-size: 0.8rem;
	letter-spacing: 0;
	text-transform: none;
}

/* Mobile: chip rows scroll sideways with an edge fade instead of stacking. */
@media (max-width: 720px) {
	.config-group__chips[data-swatch-row] {
		flex-wrap: nowrap;
		overflow-x: auto;
		padding-bottom: 0.4rem;
		scroll-snap-type: x proximity;
		-webkit-overflow-scrolling: touch;
		mask-image: linear-gradient(90deg, #000 88%, transparent);
		-webkit-mask-image: linear-gradient(90deg, #000 88%, transparent);
	}

	.config-group__chips[data-swatch-row] > * {
		flex: 0 0 auto;
		scroll-snap-align: start;
	}

	.config-group__chips[data-swatch-row]::-webkit-scrollbar {
		height: 0;
	}

	/* Tiles wrap into a grid on mobile, never a sideways scroll. */
	.config-tiles[data-swatch-row] {
		flex-wrap: wrap;
		overflow: visible;
	}
}

/* Fieldsets have an intrinsic min width; keep chip rows inside the panel. */
.product-configurator--family .config-group,
.product-configurator--family .product-configurator__panel,
.product-configurator--family .product-configurator__options {
	min-width: 0;
	max-width: 100%;
}

[data-swatch-row] {
	max-width: 100%;
}

.product-configurator--family .config-more-link {
	font-family: var(--font-heading);
	font-size: 0.8rem;
	letter-spacing: 0;
	text-transform: none;
	border-bottom: 1px solid currentColor;
}

/* Master swatch tile: colour name in small caps inside the bottom edge on
   a soft white gradient, grid up to seven per row on desktop. */
.config-tiles {
	max-width: calc(7 * 88px + 6 * 11px);
}

.config-tile__name {
	position: absolute;
	left: 0;
	right: 0;
	bottom: 0;
	padding: 19px 5px 4px;
	font-family: var(--font-heading);
	font-size: 12px;
	font-weight: 500;
	line-height: 1.1;
	letter-spacing: 0.02em;
	font-variant-caps: all-small-caps;
	text-align: center;
	color: var(--color-ink);
	background: linear-gradient(180deg, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.82) 45%, rgba(255, 255, 255, 0.94) 100%);
	white-space: normal;
	overflow: hidden;
	display: -webkit-box;
	-webkit-line-clamp: 2;
	-webkit-box-orient: vertical;
}

.config-tile--two-tone .config-tile__name {
	font-size: 0.7rem;
}

/* A figure steps out of the small capitals and keeps its own size. General
   Sans has no small capital figures, so the browser makes them by scaling the
   label, and at that size a 1 loses its flag and reads as an I: 1D and ID
   become the same tile. The family carries no lining or tabular set either,
   so that declaration is intent rather than effect today, and it will hold if
   the family is ever swapped. */
.config-tile__name .config-tile__fig,
.config-tile__words .config-tile__fig {
	font-variant-caps: normal;
	font-variant-numeric: lining-nums tabular-nums;
	font-size: 0.85em;
}

.config-tile.is-selected .config-tile__face {
	outline: 2px solid var(--color-ink);
	outline-offset: 2px;
	box-shadow: inset 0 0 6px rgba(38, 38, 38, 0.08);
	border-color: rgba(38, 38, 38, 0.16);
}

.config-group--tiles {
	margin-top: 0.4rem;
}

@media (max-width: 720px) {
	.config-tiles {
		max-width: 100%;
	}
}

/* Range and space cross cut bands at the foot of the storefront. */
.section--furniture-crosscuts .container {
	display: flex;
	flex-direction: column;
	gap: clamp(3rem, 6vw, 5rem);
}

.furniture-crosscut__header-row {
	display: grid;
	grid-template-columns: minmax(0, 7fr) minmax(0, 5fr);
	gap: var(--space-4);
	align-items: end;
	margin-bottom: clamp(1.4rem, 2.5vw, 2rem);
}

.furniture-crosscut__note {
	color: var(--color-muted);
	font-size: 0.95rem;
	line-height: 1.6;
}

.furniture-crosscut__grid {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(11rem, 1fr));
	gap: 0.6rem;
}

.furniture-crosscut__tile {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 0.6rem;
	padding: 0.95rem 1rem;
	border: 1px solid var(--color-line);
	background: transparent;
	font-family: var(--font-heading);
	font-size: 0.92rem;
	font-weight: 500;
	color: var(--color-ink);
	text-decoration: none;
	transition: border-color 220ms var(--ease-out-soft), background-color 220ms var(--ease-out-soft), transform 320ms var(--ease-out-soft);
}

.furniture-crosscut__tile:hover,
.furniture-crosscut__tile:focus-visible {
	border-color: var(--color-ink);
	transform: translateY(-1px);
	outline: none;
}

.furniture-crosscut__tile.is-empty {
	display: none;
}

.furniture-crosscut__count {
	font-family: var(--font-mono);
	font-size: 0.7rem;
	color: var(--color-muted);
}

.furniture-crosscut-note {
	display: flex;
	flex-wrap: wrap;
	align-items: baseline;
	gap: 0.6rem;
	margin-top: var(--space-4);
	font-size: 0.9rem;
	color: var(--color-muted);
}

.furniture-crosscut-note[hidden] {
	display: none;
}

.furniture-crosscut-note__clear {
	padding: 0;
	border: 0;
	border-bottom: 1px solid currentColor;
	background: transparent;
	font: inherit;
	color: var(--color-accent-deep);
	cursor: pointer;
}

@media (max-width: 720px) {
	.furniture-crosscut__header-row {
		grid-template-columns: 1fr;
	}

	.furniture-crosscut__grid {
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}
}

/* Render tiles: the supplier picture sits whole in the tile, name inside the
   bottom edge. It used to fill the tile, which meant a crop, and the tile face
   is not the picture's shape: a row of many tiles gives each a face near
   square and a row of one or two gives a wide one, against a picture that is
   104 to 72. Filling a wide face took a third of the height off, which is how
   the CPU holder lost its top plate. The picture is fitted instead, and the
   letterbox is invisible because the face is already white and so is the
   ground every supplier photographs on. */
.config-tile--image .config-tile__face img {
	padding: 0;
	object-fit: contain;
}

.config-tile--text .config-tile__face {
	background: var(--color-card);
}

.config-tile__text {
	font-family: var(--font-heading);
	font-size: 12px;
	font-weight: 500;
	line-height: 1.15;
}

/* Wide picture tiles: leg profile, configuration, modesty and storage
   renders sit in landscape tiles; swatches stay square. */
.config-tiles--wide {
	max-width: none;
}

.config-tiles--wide .config-tile {
	width: 104px;
	height: 72px;
}

.config-tiles--wide .config-tile__name {
	font-size: 9.5px;
	padding-top: 12px;
}

@media (max-width: 720px) {
	.config-tiles--wide .config-tile {
		width: 88px;
		height: 60px;
	}
}

/* --------------------------------------------------------------------------
   Tile previews: floating card on desktop, centred sheet on mobile, and
   the compare sheet. Fixed position, outside the flow, no layout shift.
   -------------------------------------------------------------------------- */
.config-tile__zoom {
	position: absolute;
	top: 3px;
	left: 3px;
	display: none;
	width: 20px;
	height: 20px;
	align-items: center;
	justify-content: center;
	padding: 0;
	border: 0;
	border-radius: 2px;
	background: rgba(255, 255, 255, 0.85);
	color: var(--color-ink);
	pointer-events: auto;
	cursor: pointer;
}

/* The zoom is a real button now; the global button dress, the fill
   panels and the swap glyphs, stands down for this one glyph. */
button.config-tile__zoom::before,
button.config-tile__zoom::after {
	content: none;
}

/* Desktop keeps it out of the way until the tile is hovered or the
   button itself holds keyboard focus. Faded rather than display none,
   because a control removed from layout can never take that focus. */
@media (min-width: 721px) {
	.config-tile__zoom {
		display: inline-flex;
		opacity: 0;
		pointer-events: none;
	}

	.config-tile:hover .config-tile__zoom,
	.config-tile__zoom:focus-visible {
		opacity: 1;
		pointer-events: auto;
	}
}

.config-tile.has-preview {
	cursor: pointer;
}

.tile-preview {
	position: fixed;
	z-index: 400;
	display: flex;
	flex-direction: column;
	gap: 0.3rem;
	padding: 0.5rem 0.5rem 0.65rem;
	border: 1px solid var(--color-line);
	border-radius: 2px;
	background: var(--color-warm-white, #fff);
	box-shadow: 0 12px 32px rgba(38, 38, 38, 0.14);
	opacity: 0;
	transform: translateY(4px);
	transition: opacity 150ms var(--ease-out-soft), transform 150ms var(--ease-out-soft);
	pointer-events: none;
}

.tile-preview.is-visible {
	opacity: 1;
	transform: translateY(0);
}

.tile-preview.no-motion {
	transition: none;
}

.tile-preview[hidden] {
	display: none;
}

.tile-preview__media {
	display: flex;
	align-items: center;
	justify-content: center;
	width: 100%;
	aspect-ratio: 7 / 5;
	overflow: hidden;
	background: #fff;
}

.tile-preview__media img {
	width: 100%;
	height: 100%;
	object-fit: cover;
}

.tile-preview__media img.is-native {
	width: auto;
	height: auto;
	max-width: 100%;
	max-height: 100%;
}

.tile-preview__name {
	font-family: var(--font-heading);
	font-size: 0.86rem;
	font-weight: 500;
	color: var(--color-ink);
}

.tile-preview__spec {
	font-size: 0.74rem;
	line-height: 1.4;
	color: var(--color-muted);
}

.tile-sheet {
	position: fixed;
	inset: 0;
	z-index: 500;
}

.tile-sheet[hidden] {
	display: none;
}

.tile-sheet__scrim {
	position: absolute;
	inset: 0;
	background: rgba(38, 38, 38, 0.36);
	opacity: 0;
	transition: opacity 200ms var(--ease-out-soft);
}

.tile-sheet__panel {
	position: absolute;
	left: 50%;
	top: 50%;
	width: min(40rem, calc(100% - 2rem));
	max-height: calc(100% - 2rem);
	box-sizing: border-box;
	overflow: auto;
	padding: 1.2rem;
	border-radius: 2px;
	background: var(--color-base);
	transform: translate(-50%, -50%) scale(0.98);
	opacity: 0;
	outline: none;
	transition: opacity 200ms var(--ease-out-soft), transform 200ms var(--ease-out-soft);
}

/* Compare sheet: four renders side by side at 220 px each. */
.tile-sheet--compare .tile-sheet__panel {
	width: min(66rem, calc(100% - 2rem));
}

.tile-sheet.is-open .tile-sheet__scrim {
	opacity: 1;
}

.tile-sheet.is-open .tile-sheet__panel {
	opacity: 1;
	transform: translate(-50%, -50%) scale(1);
}

.tile-sheet.no-motion .tile-sheet__scrim,
.tile-sheet.no-motion .tile-sheet__panel {
	transition: none;
}

.tile-sheet__close {
	position: absolute;
	top: 0.6rem;
	right: 0.6rem;
	width: 2.2rem;
	height: 2.2rem;
	border: 1px solid var(--color-line);
	background: transparent;
	font-size: 1.2rem;
	line-height: 1;
	color: var(--color-ink);
	cursor: pointer;
}

.tile-sheet__single img {
	width: 100%;
	height: auto;
	background: #fff;
}

.tile-sheet__title {
	margin: 0 2.6rem 0.9rem 0;
	font-family: var(--font-heading);
	font-size: 1.1rem;
	font-weight: 500;
	color: var(--color-ink);
}

.tile-sheet__name {
	display: block;
	margin-top: 0.6rem;
	font-family: var(--font-heading);
	font-size: 0.92rem;
	font-weight: 500;
	color: var(--color-ink);
}

.tile-sheet__spec {
	display: block;
	margin-top: 0.15rem;
	font-size: 0.78rem;
	line-height: 1.45;
	color: var(--color-muted);
}

.tile-sheet__compare {
	display: grid;
	grid-template-columns: repeat(4, 220px);
	justify-content: center;
	gap: 0.9rem;
}

.tile-sheet__compare-item {
	margin: 0;
}

.tile-sheet__compare-item img {
	width: 100%;
	max-width: 220px;
	height: auto;
	background: #fff;
	border: 1px solid var(--color-line);
}

.config-compare-link {
	margin-left: 1rem;
}

@media (pointer: coarse), (max-width: 720px) {
	.config-tile__zoom {
		display: inline-flex;
	}

	.tile-preview {
		display: none;
	}

	.tile-sheet__panel {
		width: calc(100% - 1.5rem);
	}

	.tile-sheet--compare .tile-sheet__panel {
		width: calc(100% - 1.5rem);
	}

	.tile-sheet__compare {
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}
}

/* Swatch preview card: the colours large, side by side, name and where
   each applies under them. */
.tile-preview__boards {
	display: grid;
	grid-template-columns: 1fr;
	gap: 0.5rem;
}

.tile-preview__boards--two {
	grid-template-columns: 1fr 1fr;
}

.tile-preview__board {
	display: flex;
	flex-direction: column;
	gap: 0.3rem;
	min-width: 0;
}

.tile-preview__fill {
	display: block;
	width: 100%;
	aspect-ratio: 1;
	border: 1px solid var(--color-line);
	border-radius: 2px;
	background-size: cover;
	background-position: center;
}

.tile-preview__boards:not(.tile-preview__boards--two) .tile-preview__fill {
	aspect-ratio: 7 / 5;
}

.tile-preview__where {
	font-size: 0.72rem;
	line-height: 1.35;
	color: var(--color-muted);
}

.tile-sheet__boards {
	display: grid;
	grid-template-columns: 1fr 1fr;
	gap: 0.8rem;
}

.tile-sheet__boards--one {
	grid-template-columns: 1fr;
}

.tile-sheet__boards .tile-preview__fill {
	aspect-ratio: 1;
}

.tile-sheet__boards .tile-preview__name,
.tile-sheet__boards .tile-preview__where {
	display: block;
}

/* --------------------------------------------------------------------------
   Chosen value, readable across a room: a 2 px ink ring at 2 px offset and a
   filled check badge in the top right corner on every selected tile and chip.
   Hovering one tile drops its unselected siblings to 85 percent so the pair
   of ring and badge stays the loudest thing in the row.
   -------------------------------------------------------------------------- */
.config-tile.is-selected::after,
.config-chip.is-selected::after {
	content: "";
	position: absolute;
	z-index: 2;
	width: 16px;
	height: 16px;
	border-radius: 50%;
	background-color: var(--color-ink);
	background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M4 8.4 6.7 11 12 5.2' fill='none' stroke='%23ffffff' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
	background-repeat: no-repeat;
	background-position: center;
	background-size: 12px 12px;
	pointer-events: none;
}

.config-tile.is-selected::after {
	top: -7px;
	right: -7px;
	box-shadow: 0 0 0 2px var(--color-base);
}

/* On the ink filled chip the badge inverts so it reads against the fill. */
.config-chip.is-selected::after {
	top: 6px;
	right: 6px;
	background-color: var(--color-warm-white);
	background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M4 8.4 6.7 11 12 5.2' fill='none' stroke='%23262626' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
}

.config-tiles:hover .config-tile:not(.is-selected):not(:hover) {
	opacity: 0.85;
}

.config-tiles .config-tile {
	transition: opacity 220ms var(--ease-out-soft);
}

/* The current value next to the label carries the weight. */
.config-group__value,
.config-group__label--family .config-group__value {
	font-weight: 500;
	color: var(--color-ink);
}

@media (prefers-reduced-motion: reduce) {
	.config-tiles .config-tile {
		transition: none;
	}
}

/* --------------------------------------------------------------------------
   Sticky add bar, quote page reassurance, talk links, inline field errors.
   -------------------------------------------------------------------------- */
.sticky-add {
	position: fixed;
	left: 0;
	right: 0;
	bottom: 0;
	z-index: 95;
	display: none;
	align-items: center;
	gap: 0.7rem;
	padding: 0.7rem 1rem calc(0.7rem + env(safe-area-inset-bottom));
	border-top: 1px solid var(--color-line);
	background: var(--color-base);
	box-shadow: 0 -8px 24px rgba(38, 38, 38, 0.08);
}

.sticky-add[hidden] {
	display: none;
}

.sticky-add__price {
	display: flex;
	flex-direction: column;
	gap: 0.1rem;
	min-width: 0;
}

.sticky-add__label {
	font-family: var(--font-mono);
	font-size: 0.7rem;
	letter-spacing: 0.1em;
	text-transform: uppercase;
	color: var(--color-muted);
}

.sticky-add__value {
	font-family: var(--font-heading);
	font-size: 2rem;
	line-height: 1.05;
	font-weight: 500;
	color: var(--color-ink);
	white-space: nowrap;
	transition: color 260ms var(--ease-out-soft);
}

/* The same brief emphasis the main figure uses, so cause and effect
   reads even mid page. */
.sticky-add__value.is-updating {
	color: var(--color-accent-deep);
}

/* The product name belongs to the desktop bar only. */
.sticky-add__name {
	display: none;
}

.sticky-add__button {
	flex: 1 1 auto;
	min-height: 2.9rem;
	justify-content: center;
	white-space: nowrap;
}

@media (max-width: 720px) {
	.sticky-add:not([hidden]) {
		display: flex;
	}

	.has-sticky-add body {
		padding-bottom: 5rem;
	}

	/* The floating list button steps aside for the bar. Phones only: the
	   desktop bar sits at the top and never meets the pill. */
	.has-sticky-add .quote-fab {
		display: none;
	}
}

/* --------------------------------------------------------------------------
   Desktop: the same bar, docked under the site header. Full width, a
   hairline below, the same ground as the page, so it reads as structure
   rather than as a floating widget. It parks behind the header and slides
   down once the real price block has scrolled past; visibility waits for
   the slide so a parked bar is never focusable. It overlays, so nothing
   shifts when it mounts.
   -------------------------------------------------------------------------- */
@media (min-width: 721px) {
	.sticky-add.is-docked {
		display: flex;
		align-items: center;
		gap: 1.1rem;
		top: 4.6rem;
		bottom: auto;
		padding: 0.45rem var(--gutter);
		border-top: 0;
		border-bottom: 1px solid var(--color-line);
		background: var(--color-bg);
		box-shadow: none;
		z-index: 40;
		visibility: hidden;
		transform: translateY(-100%);
		transition: transform 250ms var(--ease-out-soft), visibility 0s 250ms;
	}

	.sticky-add.is-docked.is-shown {
		visibility: visible;
		transform: translateY(0);
		transition: transform 250ms var(--ease-out-soft);
	}

	.sticky-add.is-docked .sticky-add__name {
		display: block;
		flex: 0 1 auto;
		min-width: 0;
		overflow: hidden;
		white-space: nowrap;
		text-overflow: ellipsis;
		font-family: var(--font-heading);
		font-size: 1rem;
		font-weight: 500;
		font-variant-caps: all-small-caps;
		letter-spacing: 0.03em;
		color: var(--color-ink);
	}

	/* The figure sits on the right, directly before the button, so the
	   number a buyer watches and the action it leads to read as one unit. */
	.sticky-add.is-docked .sticky-add__price {
		flex-direction: row;
		align-items: baseline;
		gap: 0.55rem;
		margin-left: auto;
	}

	/* A quiet button, never competing with the real one down the page. */
	.sticky-add.is-docked .sticky-add__button {
		flex: 0 0 auto;
		min-height: 2.35rem;
		padding-block: 0.4rem;
		background: transparent;
		border: 1px solid var(--color-ink);
		color: var(--color-ink);
	}

	.sticky-add.is-docked .sticky-add__button:hover,
	.sticky-add.is-docked .sticky-add__button:focus-visible {
		background: var(--color-ink);
		color: var(--color-bg);
	}

}

/* Where the bar tightens, the name is dropped rather than squashed. */
@media (min-width: 721px) and (max-width: 960px) {
	.sticky-add.is-docked .sticky-add__name {
		display: none;
	}
}

@media (prefers-reduced-motion: reduce) {
	.sticky-add.is-docked,
	.sticky-add.is-docked.is-shown {
		transition: none;
	}
}

/* Lead time and pricing, answered before the form is reached. */
.quote-assure {
	margin-bottom: var(--space-3);
	padding: 0.9rem 1.1rem;
	border: 1px solid var(--color-line);
	background: var(--color-card);
}

.quote-assure__row {
	display: flex;
	flex-wrap: wrap;
	gap: 0.2rem 0.7rem;
	margin: 0;
	padding: 0.22rem 0;
	font-size: 0.86rem;
	line-height: 1.5;
	color: var(--color-ink);
}

.quote-assure__label {
	flex: 0 0 8.5rem;
	font-family: var(--font-mono);
	font-size: 0.7rem;
	letter-spacing: 0.1em;
	text-transform: uppercase;
	color: var(--color-muted);
	padding-top: 0.25rem;
}

.quote-assure__value {
	flex: 1 1 12rem;
	min-width: 0;
	color: var(--color-muted);
}

/* For people who would rather talk. */
.quote-talk {
	display: flex;
	flex-wrap: wrap;
	align-items: baseline;
	gap: 0.4rem 1.1rem;
	margin-bottom: var(--space-3);
}

.quote-talk__label {
	font-family: var(--font-mono);
	font-size: 0.7rem;
	letter-spacing: 0.1em;
	text-transform: uppercase;
	color: var(--color-muted);
}

.quote-talk__link {
	font-size: 0.9rem;
	color: var(--color-ink);
	text-decoration: none;
	border-bottom: 1px solid var(--color-line);
	transition: border-color 220ms var(--ease-out-soft), color 220ms var(--ease-out-soft);
}

.quote-talk__link:hover,
.quote-talk__link:focus-visible {
	color: var(--color-accent-deep);
	border-color: var(--color-accent-deep);
}

.quote-form__prefill {
	display: flex;
	flex-wrap: wrap;
	align-items: baseline;
	gap: 0.5rem;
	margin: 0 0 var(--space-2);
	font-size: 0.82rem;
	color: var(--color-muted);
}

.quote-form__prefill-clear {
	padding: 0;
	border: 0;
	border-bottom: 1px solid var(--color-line);
	background: none;
	font: inherit;
	color: var(--color-ink);
	cursor: pointer;
}

.quote-form__prefill-clear:hover,
.quote-form__prefill-clear:focus-visible {
	color: var(--color-accent-deep);
	border-color: var(--color-accent-deep);
}

/* Keep browsing sits beside the request button. */
.quote-drawer__keep {
	display: block;
	width: 100%;
	margin-top: 0.6rem;
	padding: 0.5rem;
	border: 0;
	background: none;
	font-family: var(--font-heading);
	font-size: 0.86rem;
	color: var(--color-muted);
	cursor: pointer;
}

.quote-drawer__keep:hover,
.quote-drawer__keep:focus-visible {
	color: var(--color-ink);
}

/* --------------------------------------------------------------------------
   Preview pictures never render above twice the pixels they hold. The frame
   keeps the card the same size whatever goes in it, and a small picture sits
   centred on the ground rather than being blown up to fill the box.
   -------------------------------------------------------------------------- */
.tile-preview__frame,
.tile-sheet__boards .tile-preview__frame {
	display: flex;
	align-items: center;
	justify-content: center;
	width: 100%;
	aspect-ratio: 7 / 5;
	background: var(--color-card);
	border: 1px solid var(--color-line);
	border-radius: 2px;
	overflow: hidden;
}

.tile-preview__boards--two .tile-preview__frame,
.tile-sheet__boards .tile-preview__frame {
	aspect-ratio: 1;
}

.tile-preview__frame--wide {
	aspect-ratio: 7 / 5;
	background: #fff;
}

.tile-sheet__single .tile-preview__frame {
	aspect-ratio: 7 / 5;
}

.tile-preview__frame .tile-preview__fill {
	width: 100%;
	height: 100%;
	aspect-ratio: auto;
	border: 0;
	border-radius: 0;
	background-size: contain;
	background-repeat: no-repeat;
	background-position: center;
}

/* Price lines under every option tile. The tile grows for its line and the
   face keeps the square, the same shape the fabric and upgrade rows already
   use, now spoken by every row. Later in the cascade on purpose so it wins
   over the fixed tile square above. */
.config-group .config-tile--captioned {
	height: auto;
}

.config-group .config-tile--captioned .config-tile__face {
	height: 88px;
}

/* --------------------------------------------------------------------------
   Composed storefront head. The statement is the eyebrow, one big headline,
   the trust facts as one quiet mono row. Everything above the tiles is
   compact on purpose: at 1440 x 800 the search bar and the full category
   row sit inside the first viewport.
   -------------------------------------------------------------------------- */

.section--furniture-catalogue {
	padding-top: clamp(1.6rem, 2.6vw, 2.4rem);
}

/* Two of the landing's three hairlines go: the rule directly under
   the site header and the rule directly under the trust line. The
   rule above the trust line stays, and the spacing stays as it was. */
.furniture-head {
	display: flex;
	flex-direction: column;
	gap: clamp(0.8rem, 1.5vw, 1.1rem);
	padding-top: clamp(1.2rem, 2vw, 1.6rem);
}

.furniture-head .trust-strip {
	border-bottom: 0;
}

.furniture-head__title {
	margin: 0;
	max-width: 24ch;
	font-family: var(--font-heading);
	font-size: clamp(2rem, 1.3rem + 2.4vw, 3.4rem);
	font-weight: 500;
	line-height: 1.04;
	letter-spacing: -0.015em;
	color: var(--color-ink);
}

.furniture-head__trust {
	display: flex;
	flex-wrap: wrap;
	gap: 0.35rem 1.9rem;
	margin: 0;
	font-family: var(--font-mono);
	font-size: 0.72rem;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	color: var(--color-muted);
}

.furniture-head__trust span {
	position: relative;
	white-space: nowrap;
}

.furniture-head__trust span + span::before {
	content: '\00b7';
	position: absolute;
	left: -1.15rem;
	color: var(--color-accent);
}

/* --------------------------------------------------------------------------
   Category tiles. The categories are the navigation: each carries its
   band's showcase render, the name and a quiet count, and the tiles are
   the filter controls the chips used to be. Same lift and picture zoom
   the option tiles use; selection is a dark frame with the label
   reversed, never a colour splash.
   -------------------------------------------------------------------------- */

.furniture-filter--tiles {
	display: grid;
	grid-template-columns: repeat(var(--tile-count, 8), minmax(0, 1fr));
	gap: clamp(0.6rem, 1vw, 0.9rem);
	margin-top: clamp(1.2rem, 2vw, 1.6rem);
	padding-bottom: 0;
	border-bottom: 0;
}

.furniture-tile {
	display: flex;
	flex-direction: column;
	/* Buttons arrive with centered flex items; the media and label must
	   stretch the full tile or an empty mosaic collapses to nothing. */
	align-items: stretch;
	padding: 0;
	border: 1px solid var(--color-line);
	background: #fff;
	cursor: pointer;
	text-align: left;
	transition: transform 220ms var(--ease-out-soft), border-color 220ms var(--ease-out-soft), box-shadow 220ms var(--ease-out-soft);
}

.furniture-tile:hover,
.furniture-tile:focus-visible {
	transform: translateY(-2px);
	border-color: var(--color-accent-deep);
	box-shadow: 0 12px 22px -16px rgba(17, 22, 19, 0.35);
	outline: none;
}

.furniture-tile__media {
	position: relative;
	aspect-ratio: 4 / 3;
	overflow: hidden;
	background: #fff;
}

.furniture-tile__media img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	transition: transform 360ms var(--ease-out-soft);
}

.furniture-tile:hover .furniture-tile__media img {
	transform: scale(1.05);
}

.furniture-tile__media--mosaic {
	display: grid;
	grid-template-columns: 1fr 1fr;
	grid-template-rows: 1fr 1fr;
}

.furniture-tile__mosaic-cell {
	background-size: cover;
	background-position: center;
	opacity: 0.92;
	transition: transform 360ms var(--ease-out-soft);
}

.furniture-tile:hover .furniture-tile__mosaic-cell {
	transform: scale(1.05);
}

.furniture-tile__label {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 0.5rem;
	padding: 0.5rem 0.6rem;
	border-top: 1px solid var(--color-line);
	font-family: var(--font-mono);
	font-size: 0.7rem;
	font-weight: 500;
	letter-spacing: 0.07em;
	text-transform: uppercase;
	color: var(--color-text);
	transition: background-color 220ms var(--ease-out-soft), color 220ms var(--ease-out-soft);
}

.furniture-tile__name {
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

.furniture-tile__count {
	font-size: 0.7rem;
	color: var(--color-muted);
	transition: color 220ms var(--ease-out-soft);
}

.furniture-tile.is-active {
	border-color: var(--color-ink);
}

.furniture-tile.is-active .furniture-tile__label {
	background: var(--color-ink);
	border-top-color: var(--color-ink);
	color: var(--color-warm-white);
}

.furniture-tile.is-active .furniture-tile__count {
	color: rgba(255, 255, 255, 0.62);
}

@media (prefers-reduced-motion: reduce) {
	.furniture-tile,
	.furniture-tile__media img,
	.furniture-tile__mosaic-cell {
		transition: none;
	}

	.furniture-tile:hover {
		transform: none;
	}

	.furniture-tile:hover .furniture-tile__media img,
	.furniture-tile:hover .furniture-tile__mosaic-cell {
		transform: none;
	}
}

/* Laptop widths: two calm rows of four. */
@media (max-width: 1180px) {
	.furniture-filter--tiles {
		grid-template-columns: repeat(4, minmax(0, 1fr));
	}
}

/* Mobile: one snap scrolling row inside its own gutter, the page never
   scrolls sideways. */
@media (max-width: 640px) {
	.furniture-filter--tiles {
		display: flex;
		flex-wrap: nowrap;
		gap: 0.6rem;
		overflow-x: auto;
		scroll-snap-type: x mandatory;
		scroll-padding-inline: var(--gutter, 1rem);
		-webkit-overflow-scrolling: touch;
		scrollbar-width: none;
		margin-inline: calc(-1 * var(--gutter, 1rem));
		padding-inline: var(--gutter, 1rem);
		padding-bottom: 0.4rem;
	}

	.furniture-filter--tiles::-webkit-scrollbar {
		display: none;
	}

	.furniture-tile {
		flex: 0 0 8.2rem;
		scroll-snap-align: start;
	}
}

/* --------------------------------------------------------------------------
   The range on its own quiet ground: a tone between the hero cream and the
   card colour with one hairline above, so the page reads as composed
   sections instead of one flat wash.
   -------------------------------------------------------------------------- */

.furniture-range {
	margin-top: clamp(1.8rem, 3vw, 2.6rem);
	border-top: 1px solid var(--color-line);
	background: rgba(228, 224, 216, 0.4);
	padding-bottom: clamp(2.4rem, 4vw, 3.6rem);
}

/* --------------------------------------------------------------------------
   The honest picture layer. A quiet caption under the gallery naming what
   the picture shows, printed views as captioned thumbnails, a plain
   pricing explainer beside the price, and notes under add on rows. All of
   it small, muted and factual: honesty as a detail, not a banner.
   -------------------------------------------------------------------------- */

.product-configurator__caption {
	margin: 0.6rem 0 0;
	font-family: var(--font-mono);
	font-size: 0.7rem;
	letter-spacing: 0.05em;
	line-height: 1.5;
	color: var(--color-muted);
}

.product-configurator__views {
	display: flex;
	flex-wrap: wrap;
	gap: 0.7rem;
	margin-top: 0.9rem;
}

.product-configurator__view {
	display: flex;
	flex-direction: column;
	align-items: stretch;
	gap: 0.3rem;
	width: clamp(7rem, 11vw, 9.5rem);
	padding: 0;
	border: 1px solid var(--color-line);
	background: #fff;
	cursor: pointer;
	text-align: left;
	transition: border-color 220ms var(--ease-out-soft), transform 220ms var(--ease-out-soft);
}

.product-configurator__view:hover,
.product-configurator__view:focus-visible {
	border-color: var(--color-accent-deep);
	transform: translateY(-2px);
	outline: none;
}

.product-configurator__view img {
	width: 100%;
	aspect-ratio: 4 / 3;
	object-fit: cover;
}

.product-configurator__view-caption {
	padding: 0 0.45rem 0.4rem;
	font-family: var(--font-mono);
	font-size: 0.7rem;
	letter-spacing: 0.04em;
	line-height: 1.4;
	color: var(--color-muted);
}

/* Your build: one row of equal sized thumbnails between the last option
   and the Add to quote list button, so the summary of what has just been
   chosen is passed over on the way to the button rather than found after
   it. One row at every width: it scrolls sideways where it does not fit,
   because wrapping into two or three rows is what pushes the button off
   the screen this strip is meant to be seen before. */
.build-strip {
	margin: 1.6rem 0 0.4rem;
	/* Below 900 this is a direct flex item of the one column layout, where
	   the horizontal axis is the cross axis and the item is sized to its own
	   content. With a row that does not wrap, that content is every tile
	   added up, so the strip grew wider than the screen and the last tile
	   was clipped away by the section rather than scrolled to. Held to the
	   column it is in, the overflow becomes the sideways scroll it should
	   have been. */
	min-width: 0;
	max-width: 100%;
}

.build-strip[hidden] {
	display: none;
}

.build-strip__label {
	margin: 0 0 0.6rem;
	font-family: var(--font-mono);
	font-size: 0.7rem;
	font-weight: 500;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	color: var(--color-muted);
}

.build-strip__tiles {
	display: flex;
	flex-wrap: nowrap;
	align-items: stretch;
	gap: 0.7rem;
	overflow-x: auto;
	overscroll-behavior-x: contain;
	scrollbar-width: thin;
	/* Room for the hover lift, which an overflow box would otherwise clip. */
	padding: 2px 0;
	/* The row is edge to edge on a phone, so a tile is never cut in half by
	   the container gutter and the peek at the right says it scrolls. */
	scroll-padding-left: 0;
	min-width: 0;
}

.build-strip__tiles::-webkit-scrollbar {
	height: 4px;
}

.build-strip__tiles::-webkit-scrollbar-thumb {
	background: var(--color-line);
}

.build-strip__tile {
	display: flex;
	flex-direction: column;
	align-items: stretch;
	gap: 0.3rem;
	/* Sized off the column it sits in rather than the viewport, because it
	   now lives in the narrower options column. Five tiles, which is what a
	   chair with three upgrade rows and a fabric comes to, fit that column
	   exactly; a sixth scrolls. The floor keeps the label readable. */
	flex: 0 0 auto;
	width: clamp(7rem, 18.5%, 9.5rem);
	padding: 0;
	border: 1px solid var(--color-line);
	background: #fff;
	text-align: left;
}

/* The chair and fabric tiles are the pane's view switch. */
button.build-strip__tile {
	cursor: pointer;
	transition: border-color 220ms var(--ease-out-soft), transform 220ms var(--ease-out-soft);
}

button.build-strip__tile:hover,
button.build-strip__tile:focus-visible {
	border-color: var(--color-accent-deep);
	transform: translateY(-2px);
	outline: none;
}

button.build-strip__tile.is-active {
	border-color: var(--color-ink);
}

/* A row where every tile is Included says it once: one quiet line
   under the legend, no chorus of captions. The captions return the
   moment any tile carries a figure. */
.config-group--all-included .config-tile__caption {
	display: none;
}

.config-group__included-note {
	margin: 0.15rem 0 0.2rem;
	font-family: var(--font-mono);
	font-size: 0.7rem;
	letter-spacing: 0.05em;
	color: var(--color-muted);
}

.config-group__included-note[hidden] {
	display: none;
}

/* Every tile answers a row: the row name sits as a quiet eyebrow
   above the choice, picture tiles and word tiles alike. */
.build-strip__row {
	display: block;
	padding: 0.35rem 0.45rem 0;
	font-family: var(--font-mono);
	font-size: 0.7rem;
	font-weight: 500;
	letter-spacing: 0.07em;
	line-height: 1.35;
	text-transform: uppercase;
	color: var(--color-muted);
	/* One line, always. A heading that wraps pushes the picture down and
	   nothing below it lines up with the tile beside it, which is what made
	   the strip look, in Garth's words, all over the place. */
	white-space: nowrap;
	overflow: hidden;
	text-overflow: ellipsis;
	min-height: calc(0.7rem * 1.35);
}

/* Small option sources sit centred at their native pixels, never
   upscaled; the chair photo and the fabric swatch fill the frame. */
.build-strip__media {
	display: flex;
	align-items: center;
	justify-content: center;
	aspect-ratio: 4 / 3;
	overflow: hidden;
	background: #fff;
	/* Every picture area carries the same hairline, so the areas read as one
	   row of frames and a Super White swatch reads as a white square rather
	   than as nothing at all with its label floating under it. */
	box-shadow: inset 0 0 0 1px var(--color-line);
}

.build-strip__media img {
	width: auto;
	height: auto;
	max-width: 100%;
	max-height: 100%;
}

.build-strip__media--fill img {
	width: 100%;
	height: 100%;
	max-width: none;
	max-height: none;
	object-fit: cover;
}

/* A choice without a picture says so in the picture area, on the same
   footprint as every other tile, in the type the value line uses so a row of
   tiles reads as one set rather than as two kinds of tile. */
.build-strip__media--words {
	padding: 0.4rem 0.45rem;
	text-align: center;
}

.build-strip__words {
	font-family: var(--font-mono);
	font-size: 0.75rem;
	letter-spacing: 0.04em;
	line-height: 1.4;
	color: var(--color-muted);
	overflow: hidden;
	display: -webkit-box;
	-webkit-line-clamp: 3;
	-webkit-box-orient: vertical;
}

/* The value, on the bottom line of every tile, at the same size and colour
   and in the same place. Two lines at most, and the height is held even where
   the value is already in the picture area, so no tile is taller than its
   neighbour. */
.build-strip__name {
	padding: 0 0.45rem 0.4rem;
	font-family: var(--font-mono);
	font-size: 0.75rem;
	letter-spacing: 0.04em;
	line-height: 1.4;
	color: var(--color-muted);
	/* Two lines of room in every tile, filled or not, so no tile is taller
	   than its neighbour and a long name is clipped rather than pushed
	   through the bottom edge. */
	height: calc(0.75rem * 1.4 * 2 + 0.4rem);
	overflow: hidden;
}

/* The clamp sits on an inner span. The name is a flex child of the tile, and
   a flex child cannot be a webkit box, so a clamp written on it is blockified
   away and a three line name runs out through the bottom of the strip. */
.build-strip__value {
	display: -webkit-box;
	overflow: hidden;
	overflow-wrap: anywhere;
	-webkit-line-clamp: 2;
	-webkit-box-orient: vertical;
}

/* The one picture on the site that is a render rather than a photograph says
   so under itself, a step quieter than the name so the choice still leads. */
.build-strip__note {
	display: block;
	padding: 0 0.45rem 0.4rem;
	margin-top: -0.3rem;
	font-family: var(--font-mono);
	font-size: 0.6rem;
	letter-spacing: 0.06em;
	line-height: 1.3;
	color: var(--color-muted);
}

/* A two tone row shows its pair, the top on one half and the legs on the
   other, the same way the option tile above it does. */
.build-strip__media--pair {
	display: grid;
	grid-template-columns: 1fr 1fr;
	gap: 0;
}

.build-strip__half {
	display: block;
	width: 100%;
	height: 100%;
	background-size: cover;
	background-position: center;
}

/* A colour the source gives as a colour and not as a swatch file fills
   the frame with that colour. */
.build-strip__flat {
	display: block;
	width: 100%;
	height: 100%;
	/* Super White on a white tile is invisible without this, so its label
	   floats on nothing. The hairline gives the swatch an edge. */
	box-shadow: inset 0 0 0 1px var(--color-line);
}

/* A counter somebody drew leads with the drawing, at tile size. */
.build-strip__media--plan {
	padding: 0.3rem;
}

.build-strip__media--plan svg {
	width: 100%;
	height: 100%;
	max-height: 100%;
}


/* The fabric view of the main pane: the swatch at its native pixels,
   centred in the same 4 by 5 box and named, never upscaled. */
.product-configurator__img[hidden] {
	display: none;
}

.config-fabric-slide {
	position: absolute;
	inset: 0;
	display: grid;
	place-items: center;
	align-content: center;
	gap: 0.6rem;
	padding: 1rem;
}

.config-fabric-slide[hidden] {
	display: none;
}

.config-fabric-slide img {
	width: auto;
	max-width: 100%;
	border: 1px solid var(--color-line);
}

.config-fabric-slide__name {
	font-family: var(--font-mono);
	font-size: 0.7rem;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	color: var(--color-muted);
}

.product-configurator__pricing-note {
	margin-top: 0.9rem;
	padding: 0.9rem 1rem;
	border: 1px solid var(--color-line);
	background: rgba(228, 224, 216, 0.35);
}

.product-configurator__pricing-note-title {
	margin: 0 0 0.35rem;
	font-family: var(--font-mono);
	font-size: 0.7rem;
	font-weight: 500;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	color: var(--color-ink);
}

.product-configurator__pricing-note-line {
	margin: 0.25rem 0 0;
	font-size: 0.85rem;
	line-height: 1.55;
	color: var(--color-text);
}

.product-configurator__pricing-example {
	margin: 0.55rem 0 0;
	font-family: var(--font-mono);
	font-size: 0.72rem;
	line-height: 1.5;
	color: var(--color-accent-deep);
}

.config-group__note {
	margin: 0.45rem 0 0;
	font-size: 0.78rem;
	line-height: 1.5;
	color: var(--color-muted);
	max-width: 34rem;
}

/* The one note that leads its row rather than qualifying it. It is read
   before the choosing, so it sits above the tiles and takes the space of a
   short paragraph rather than a footnote. */
.config-group__note--lead {
	margin: 0.35rem 0 1rem;
	max-width: 42rem;
	text-wrap: pretty;
}

@media (prefers-reduced-motion: reduce) {
	.product-configurator__view {
		transition: none;
	}

	.product-configurator__view:hover {
		transform: none;
	}
}

/* --------------------------------------------------------------------------
   The reception builder. Quantity stepper tiles build a counter from
   modules while a top down plan drawing redraws live beside them, above
   them on a phone. Thin single weight lines, mono caption labels, a very
   light tint on counter units and dashes for storage, premium and minimal.
   -------------------------------------------------------------------------- */

.builder__layout {
	display: grid;
	grid-template-columns: minmax(0, 1fr);
	gap: clamp(0.9rem, 1.6vw, 1.3rem);
}

@media (min-width: 960px) {
	.builder__layout {
		grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr);
		align-items: start;
	}

	.builder__plan {
		order: 2;
		position: sticky;
		top: calc(var(--space-4, 1.25rem) + 60px);
	}
}

.builder__plan {
	border: 1px solid var(--color-line);
	background: var(--color-warm-white);
	min-height: 340px;
	display: flex;
	align-items: center;
	justify-content: center;
	overflow: hidden;
}

.builder__plan-empty {
	margin: 0;
	padding: 1rem;
	font-family: var(--font-mono);
	font-size: 0.7rem;
	letter-spacing: 0.05em;
	color: var(--color-muted);
	text-align: center;
}

.builder__svg {
	display: block;
	max-width: 100%;
}

/* The architectural plan: three line grades. Heavy for the counter
   footprint with a five percent accent tint so it reads as a surface,
   medium for module divisions, hairline for dimension and extension
   lines, dashed hairline for storage. Ticks, not arrowheads. */
.builder__svg-heavy {
	fill: rgba(162, 151, 130, 0.05);
	stroke: var(--color-ink);
	stroke-width: 2;
	stroke-linejoin: miter;
}

.builder__svg-medium {
	fill: none;
	stroke: var(--color-ink);
	stroke-width: 1.2;
}

.builder__svg-hair {
	fill: none;
	stroke: var(--color-muted);
	stroke-width: 0.75;
}

.builder__svg-tick {
	fill: none;
	stroke: var(--color-ink);
	stroke-width: 1;
}

.builder__svg-storage {
	fill: none;
	stroke: var(--color-muted);
	stroke-width: 0.75;
	stroke-dasharray: 3 2.5;
}

.builder__svg-fig {
	font-family: var(--font-mono);
	fill: var(--color-text);
	letter-spacing: 0.02em;
}

.builder__svg-fig--strong {
	font-weight: 600;
}

.builder__svg-fig--muted {
	fill: var(--color-muted);
}

.builder__svg-caps {
	font-family: var(--font-mono);
	fill: var(--color-muted);
	letter-spacing: 0.16em;
	text-transform: uppercase;
}

.builder__grid {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
	gap: 0.6rem;
	align-content: start;
}

.builder__tile {
	display: flex;
	flex-direction: column;
	gap: 0.45rem;
	padding: 0.7rem 0.6rem 0.6rem;
	border: 1px solid var(--color-line);
	background: #fff;
	text-align: center;
	transition: border-color 200ms var(--ease-out-soft), box-shadow 200ms var(--ease-out-soft);
}

.builder__tile.is-active {
	border-color: var(--color-ink);
	box-shadow: inset 0 0 0 1px var(--color-ink);
}

.builder__tile-media {
	display: block;
	height: 74px;
}

.builder__tile-media img {
	width: auto;
	height: 100%;
	max-width: 100%;
	margin: 0 auto;
	object-fit: contain;
	display: block;
}

.builder__tile-label {
	font-size: 0.78rem;
	line-height: 1.35;
	color: var(--color-text);
	/* The label absorbs the height difference so the price line and the
	   stepper sit aligned at the bottom of every tile in the row. */
	flex-grow: 1;
}

.builder__tile-price {
	font-family: var(--font-mono);
	font-size: 0.7rem;
	letter-spacing: 0.05em;
	color: var(--color-muted);
	min-height: 1em;
}

.builder__stepper {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: 0.4rem;
	margin-top: auto;
}

.builder__step {
	width: 2rem;
	height: 2rem;
	border: 1px solid var(--color-line);
	background: transparent;
	font-size: 1rem;
	line-height: 1;
	cursor: pointer;
	color: var(--color-text);
	transition: border-color 160ms var(--ease-out-soft), background-color 160ms var(--ease-out-soft);
}

.builder__step:hover,
.builder__step:focus-visible {
	border-color: var(--color-ink);
	outline: none;
}

.builder__qty {
	font-family: var(--font-mono);
	font-size: 0.86rem;
	min-width: 1.6rem;
	text-align: center;
	color: var(--color-ink);
}

.builder__maths {
	list-style: none;
	margin: 0.9rem 0 0;
	padding: 0;
	font-family: var(--font-mono);
	font-size: 0.7rem;
	letter-spacing: 0.05em;
	line-height: 1.8;
	color: var(--color-muted);
}

@media (max-width: 640px) {
	.builder__grid {
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}

	.builder__plan {
		min-height: 300px;
	}
}



/* The price floor line under Your build: a quiet tappable control. */
.product-configurator__from {
	display: inline-block;
	margin-top: 6px;
	padding: 0;
	border: 0;
	background: none;
	font-size: 0.85rem;
	color: var(--color-deep);
	text-decoration: underline;
	text-underline-offset: 3px;
	cursor: pointer;
}

.product-configurator__from:hover {
	color: var(--color-accent-deep, #485035);
}

/* A long worded text tile gets room on a phone: two per row, never four
   crushed columns. */
@media (max-width: 480px) {
	.config-tile--text.config-tile--long {
		width: calc(50% - 6px);
	}
}

/* The quiet line under a row that says what the site is doing on the
   customer's behalf, so a price that appears is never a surprise. */
.config-group__help {
	margin: 0.4rem 0 0;
	font-size: 0.78rem;
	line-height: 1.4;
	color: var(--color-muted);
}
