/*
 * The product page.
 *
 * Written to look like a printer's price list rather than a landing page: a
 * type scale that is actually used, one accent, semantic colour kept separate
 * from it, and tabular figures everywhere a digit sits in a column. There are
 * no gradients, no glass, no decorative shadow and no animation that serves
 * nothing, because the product must not look generated.
 *
 * Every rule is scoped under a `ts-` class. This stylesheet loads inside
 * whatever theme the shop runs and it has no business restyling anything of
 * theirs. Since session 09 that theme is usually OURS (`wp-themes/teeshoop`),
 * on the mirror and, from session 14, in production, where Woodmart still runs
 * today. The scoping stays: the plugin has to keep working under a theme it
 * does not own, which is exactly the state production is in until it is
 * deployed.
 *
 * Mobile first: everything below is written for 375 px and widened at 720 px.
 */

/*
 * THE PALETTE IS NOT DECLARED HERE ANY MORE. It lives once, in
 * `assets/tokens.css`, which this stylesheet is enqueued after and which the
 * theme reads as well. It used to be declared on this selector, which meant a
 * shop-wide colour could only be changed by editing a rule that also set a font
 * size on four blocks of the product page.
 */
.ts-buy,
.ts-specs,
.ts-pricing,
.ts-devis {
	color: var(--ts-ink);
	font-size: var(--ts-text);
	line-height: var(--ts-leading);
}

/*
 * Our own controls, reset deliberately.
 *
 * This stylesheet is enqueued from the `wp` action, which runs before the theme
 * enqueues its own, so on a tie of specificity the THEME wins. Twenty
 * Twenty-One styles bare `input[type="number"]` and `input[type="radio"]`
 * heavily, and it showed: the segmented control's hidden radios rendered as
 * large circles above their labels, and the size grid's number inputs came out
 * as empty boxes with the figure pushed out of view. Attribute selectors here
 * are not decoration, they are what wins the tie.
 */
.ts-buy input[type='number'],
.ts-buy input[type='text'] {
	box-sizing: border-box;
	width: 100%;
	min-width: 0;
	height: auto;
	min-height: 0;
	margin: 0;
	padding: 0.375rem 0.5rem;
	border: 1px solid var(--ts-line-strong);
	border-radius: 3px;
	background: #fff;
	color: var(--ts-ink);
	font: inherit;
	font-size: 0.9375rem;
	line-height: 1.3;
	box-shadow: none;
}



/* ------------------------------------------------------------------ price */

.teeshoop-price {
	display: block;
}

.teeshoop-price__ttc {
	color: #5b6470;
}

.teeshoop-price__from {
	display: block;
	color: #5b6470;
	font-size: 0.8125rem;
	font-weight: 400;
}

/* -------------------------------------------------------------- buy box */

.ts-buy {
	margin: 1.25rem 0;
	padding: 1rem;
	border: 1px solid var(--ts-line);
	border-radius: 4px;
	background: #fff;
}

.ts-buy__anchors {
	margin: 0 0 1rem;
	font-size: 1rem;
	line-height: 1.45;
}

.ts-buy__anchors b {
	font-size: 1.125rem;
}

.ts-buy__basis {
	display: block;
	color: var(--ts-muted);
	font-size: 0.8125rem;
}

.ts-field {
	margin: 0 0 1rem;
	padding: 0;
	border: 0;
}

.ts-field__legend {
	margin: 0 0 0.375rem;
	padding: 0;
	color: var(--ts-muted);
	font-size: 0.75rem;
	font-family: var(--ts-font-display);
	font-weight: 600;
	letter-spacing: 0.06em;
	text-transform: uppercase;
}

/* Segmented control: radios that look like a row of choices. */
.ts-seg {
	display: flex;
	flex-wrap: wrap;
	gap: 0;
	border: 1px solid var(--ts-line-strong);
	border-radius: 3px;
	overflow: hidden;
}

.ts-seg__item {
	flex: 1 1 auto;
	margin: 0;
	cursor: pointer;
}

/* The radio is the control; the span is what it looks like. */
.ts-buy .ts-seg__item input[type='radio'] {
	position: absolute;
	width: 1px;
	height: 1px;
	min-width: 0;
	min-height: 0;
	margin: -1px;
	padding: 0;
	overflow: hidden;
	clip: rect(0 0 0 0);
	clip-path: inset(50%);
	white-space: nowrap;
	border: 0;
	opacity: 0;
	appearance: none;
	-webkit-appearance: none;
}

.ts-seg__item span {
	display: block;
	padding: 0.5rem 0.625rem;
	border-left: 1px solid var(--ts-line-strong);
	background: #fff;
	text-align: center;
	font-size: 0.875rem;
	white-space: nowrap;
}

.ts-seg__item:first-child span {
	border-left: 0;
}

.ts-seg__item input[type='radio']:checked + span {
	background: var(--ts-ink);
	color: #fff;
	font-family: var(--ts-font-display);
	font-weight: 600;
}

/* Focus is visible from the start, not retrofitted in session 12. */
.ts-seg__item input[type='radio']:focus-visible + span {
	outline: 2px solid var(--ts-accent);
	outline-offset: -2px;
}

.ts-seg--modes {
	margin-bottom: 0.75rem;
}

.ts-qty__label,
.ts-sizes__intro {
	display: block;
	margin: 0 0 0.375rem;
	color: var(--ts-muted);
	font-size: 0.8125rem;
}

.ts-qty__row {
	display: flex;
	flex-wrap: wrap;
	gap: 0.5rem;
	align-items: end;
}

.ts-qty__field {
	flex: 1 1 7rem;
	min-width: 0;
}

.ts-buy input[type='number'].ts-qty__input {
	width: 100%;
	padding: 0.5rem 0.625rem;
	font-size: 1rem;
}

.ts-qty__select {
	box-sizing: border-box;
	width: 100%;
	padding: 0.5rem 0.625rem;
	border: 1px solid var(--ts-line-strong);
	border-radius: 3px;
	background: #fff;
	color: var(--ts-ink);
	font: inherit;
	/* 16 px for the same reason as the size boxes: below it, iOS zooms. */
	font-size: 1rem;
}

.ts-qty__select:focus-visible {
	outline: 2px solid var(--ts-accent);
	outline-offset: 1px;
}

.ts-table__quote {
	color: var(--ts-accent);
	font-size: 0.8125rem;
	font-family: var(--ts-font-display);
	font-weight: 600;
	white-space: nowrap;
}

.ts-estimate[data-failed='1'] .ts-estimate__unit {
	color: var(--ts-bad);
}

.ts-sizes__grid {
	display: grid;
	grid-template-columns: repeat(3, minmax(0, 1fr));
	gap: 0.375rem;
}

.ts-sizes__cell {
	display: flex;
	align-items: center;
	gap: 0.375rem;
	padding: 0.25rem 0.375rem;
	border: 1px solid var(--ts-line);
	border-radius: 3px;
}

.ts-sizes__name {
	min-width: 2.25rem;
	color: var(--ts-muted);
	font-size: 0.75rem;
	font-family: var(--ts-font-display);
	font-weight: 600;
	letter-spacing: 0.04em;
}

.ts-buy .ts-sizes__cell input[type='number'] {
	padding: 0.25rem 0.375rem;
	border: 0;
	background: transparent;
	text-align: right;
	/*
	 * 16 px, not 15. Mobile Safari zooms the whole viewport when a focused input
	 * computes below 16 px, so tapping each of the six size boxes in turn
	 * re-zoomed the page six times. The cell's width comes from the grid, so
	 * nothing is lost by keeping the type at the base size.
	 */
	font-size: 1rem;
	/*
	 * No native spinner. In a cell about 100 px wide it sits on top of the
	 * figure: at 375 px "10" rendered as "1C". Arrow keys still step the value,
	 * so nothing is lost but the overlap.
	 */
	appearance: textfield;
	-moz-appearance: textfield;
}

.ts-buy .ts-sizes__cell input[type='number']::-webkit-outer-spin-button,
.ts-buy .ts-sizes__cell input[type='number']::-webkit-inner-spin-button {
	-webkit-appearance: none;
	margin: 0;
}

.ts-sizes__total {
	margin: 0.5rem 0 0;
	font-size: 0.875rem;
}

.ts-recalc {
	margin-top: 0.75rem;
	padding: 0.5rem 0.875rem;
	border: 1px solid var(--ts-line-strong);
	border-radius: 3px;
	background: var(--ts-surface);
	/*
	 * SUR CETTE TEINTE, LE GRIS SECONDAIRE EST L'AUTRE.
	 *
	 * `--ts-muted` est le #767676 de l'associé et il vaut 4,54:1 sur du papier,
	 * ce qui passe AA de quatre centièmes. Sur `--ts-surface` il tombe à 4,24:1
	 * et échoue. Redéclarer le jeton ICI plutôt que de changer la couleur de
	 * chaque texte : une propriété personnalisée cascade, donc tout ce qui est
	 * dessiné dans ce bloc et lit `var(--ts-muted)` prend la variante sombre
	 * sans avoir à être listé quelque part, et rien ne rote quand un enfant est
	 * ajouté. Mesuré par `npm run verify:a11y`, qui refusait 13 textes sur la
	 * page catalogue.
	 */
	--ts-muted: var(--ts-muted-strong);
	color: var(--ts-ink);
	font-size: 0.875rem;
	cursor: pointer;
}

/* ------------------------------------------------------------- estimate */

.ts-estimate {
	display: block;
	margin: 0 0 1rem;
	padding: 0.75rem 0.875rem;
	border-left: 3px solid var(--ts-ink);
	background: var(--ts-surface);
	--ts-muted: var(--ts-muted-strong);
}

.ts-estimate__for {
	margin: 0;
	color: var(--ts-muted);
	font-size: 0.8125rem;
}

.ts-estimate__total {
	margin: 0.125rem 0 0;
	font-size: 1rem;
	line-height: 1.3;
}

.ts-estimate__total b {
	font-size: 1.625rem;
	letter-spacing: -0.01em;
}

.ts-estimate__total abbr {
	text-decoration: none;
	font-size: 0.8125rem;
	color: var(--ts-muted);
}

.ts-estimate__ttc {
	display: block;
	color: var(--ts-muted);
	font-size: 0.9375rem;
}

.ts-estimate__unit {
	margin: 0.25rem 0 0;
	color: var(--ts-muted);
	font-size: 0.8125rem;
}

.ts-estimate__unit [data-teeshoop-discount]:not(:empty)::before {
	content: ' · ';
}

.ts-estimate[data-busy='1'] {
	opacity: 0.55;
}

/* -------------------------------------------------------------- actions */

.ts-actions {
	display: flex;
	flex-direction: column;
	gap: 0.5rem;
}

.ts-actions__quote {
	margin: 0 0 0.25rem;
	padding: 0.5rem 0.625rem;
	border-left: 3px solid var(--ts-warn);
	background: #fdf6ec;
	color: #6b4a12;
	font-size: 0.8125rem;
	line-height: 1.45;
}


/* ---------------------------------------------------------------- specs */

.ts-specs {
	margin: 1.5rem 0;
}

.ts-specs__title,
.ts-pricing__title,
.ts-devis__title {
	margin: 1.5rem 0 0.5rem;
	font-size: 1.125rem;
	font-family: var(--ts-font-display);
	font-weight: 700;
	letter-spacing: -0.01em;
}

.ts-specs__title:first-child {
	margin-top: 0;
}

.ts-defs {
	display: grid;
	grid-template-columns: minmax(6.5rem, auto) 1fr;
	gap: 0.25rem 1rem;
	margin: 0 0 0.75rem;
}

.ts-defs dt {
	color: var(--ts-muted);
	font-size: 0.8125rem;
}

.ts-defs dd {
	margin: 0;
}

.ts-swatches {
	display: flex;
	flex-wrap: wrap;
	gap: 0.25rem 0.75rem;
	margin: 0;
	padding: 0;
	list-style: none;
}

.ts-swatches__item {
	display: flex;
	align-items: center;
	gap: 0.3125rem;
	font-size: 0.8125rem;
}

.ts-swatches__chip {
	display: inline-block;
	width: 0.875rem;
	height: 0.875rem;
	border: 1px solid rgba(0, 0, 0, 0.25);
	border-radius: 2px;
	background: var(--ts-chip, #fff);
}


/* ---------------------------------------------------------------- devis */

.ts-devis {
	margin: 2rem 0;
	padding: 1.25rem;
	border: 1px solid var(--ts-line);
	border-radius: 4px;
	background: var(--ts-surface);
	--ts-muted: var(--ts-muted-strong);
}

.ts-devis__lead {
	margin: 0 0 1rem;
	max-width: 60ch;
}


.ts-devis input[type='text'],
.ts-devis input[type='email'],
.ts-devis input[type='tel'],
.ts-devis input[type='date'],
.ts-devis input[type='number'],
.ts-devis textarea {
	width: 100%;
	padding: 0.5rem 0.625rem;
	border: 1px solid var(--ts-line-strong);
	border-radius: 3px;
	background: #fff;
	font-size: 1rem;
	font-family: inherit;
}

.ts-devis input:focus-visible,
.ts-devis textarea:focus-visible,
.ts-buy input:focus-visible {
	outline: 2px solid var(--ts-accent);
	outline-offset: 1px;
}

.ts-devis .ts-cta {
	margin-top: 0.5rem;
	max-width: 18rem;
}



/* --------------------------------------------------------------- studio */

.teeshoop-studio-view {
	margin: 0 0 1.5rem;
}

.teeshoop-studio-view__back {
	margin: 0 0 0.5rem;
	font-size: 0.875rem;
}

/* -------------------------------------------------------------- widened */

@media (min-width: 720px) {
	.ts-sizes__grid {
		grid-template-columns: repeat(6, minmax(0, 1fr));
	}

	.ts-form__row {
		grid-template-columns: 1fr 1fr;
	}

	.ts-actions {
		flex-direction: row;
		/*
		 * The notice asks for a full row, and without `wrap` it never gets one:
		 * the three items shared the line, and inside the theme's summary column
		 * at a 900 px viewport that left the notice 87 px wide.
		 */
		flex-wrap: wrap;
	}

	.ts-actions__quote {
		flex-basis: 100%;
	}

	.ts-cta {
		flex: 1 1 0;
	}

	.ts-devis .ts-cta {
		flex: 0 0 auto;
	}
}

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

/*
 * ─────────────────────────────────────────────────────────────────────────────
 * LE CONTENEUR DE L'ÉDITEUR, ET LA PHRASE QU'IL PORTE AVANT QUE LE SCRIPT
 * ARRIVE.
 *
 * `assets/editeur/editeur.css` habille tout ce qui est DANS l'éditeur, sous
 * `.tshop-ed`. Ces quatre règles habillent le conteneur lui-même et le message
 * de secours que PHP y écrit, parce que ce message doit être lisible même si le
 * paquet de l'éditeur n'est jamais chargé : c'est précisément le cas où il sert.
 */
.teeshoop-editeur {
	margin: var(--ts-space-4) 0 0;
}

.teeshoop-editeur__secours {
	margin: 0;
	padding: var(--ts-space-3);
	background: var(--ts-warn-wash);
	border: 1px solid var(--ts-warn);
	border-radius: var(--ts-radius);
	color: var(--ts-warn-ink);
	font-size: var(--ts-text-sm);
}

/* Le message de secours disparaît dès que l'éditeur a pris la place. */
.teeshoop-editeur.tshop-ed .teeshoop-editeur__secours {
	display: none;
}

/*
 * Le second conteneur, sur un thème qui rend la description deux fois. Marqué
 * plutôt qu'effacé : un administrateur doit pouvoir voir qu'il y en a deux.
 */
.teeshoop-editeur[data-teeshoop-editeur-etat='doublon'] {
	display: none;
}

.ts-actions--devis {
	margin-top: var(--ts-space-4);
}
