/*
Theme Name: Terkina3D
Theme URI:
Description: Child theme of Hello Elementor for Terkina3D, a 3D print-on-demand store. Holds only what the Elementor global kit cannot reach: the internals of legacy widgets inside the Theme Builder header and footer, and everything WooCommerce renders (product loop, single product, cart, Blocks checkout).
Author: TGTV Studio
Author URI:
Template: hello-elementor
Version: 0.6.0
Text Domain: terkina3d
License: GNU General Public License v2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html
Tags: e-commerce, custom-menu, custom-logo
*/

/* ==========================================================================
   TERKINA3D
   --------------------------------------------------------------------------
   Design reference: the Fabrixa layout in assets/inspiration/. Light warm
   ground, generous whitespace, soft rounded surfaces, hairline dividers, one
   accent colour used sparingly. Terkina3D's red replaces Fabrixa's orange.
   Palette and type are the approved system in docs/DESIGN.md.

   Scope. Sections, headings, cards and buttons inside Elementor are the global
   kit's job and are NOT restyled here. This file covers only what the kit
   cannot reach:

     1. the INTERNALS of legacy v3 widgets sitting inside the Theme Builder
        header (194) and footer (195). The shells, the 1240 wrap, the grounds
        and the hairlines are global classes (tk-header, tk-footer, ...) and
        live in the kit, not here. What is here is the markup those widgets
        generate themselves: Elementor's Nav Menu list, and its burger toggle.
     2. everything WooCommerce renders from its own templates: the product
        loop, the single product, and the Blocks cart and checkout
     3. markup printed by the sandbox plugin, which the kit never sees:
        .tk-defs, .tk-faq, .tk-list, .tk-note, .tk-product-sections

   Cascade note, two directions. The kit emits `.elementor .tk-x` at (0,2,0)
   from a stylesheet that loads AFTER this one, so nothing here targets a tk-*
   global class: fix kit-owned things in the kit. In the other direction the
   WooCommerce Blocks stylesheets also load after this file, so the Blocks
   rules in sections 12 to 14 have to win on specificity rather than order.
   Where a selector below doubles a class, that is why, and the rule it
   outranks is named in the comment above it.
   ========================================================================== */

:root {
	/* Approved palette, mirrored from docs/DESIGN.md because theme chrome and
	   WooCommerce templates cannot read Elementor kit tokens. */
	--tk-ink: #0A0A0A;
	--tk-red: #E90211;
	--tk-red-text: #D9020F;
	--tk-paper: #FAF8F7;
	--tk-surface: #FFFFFF;
	--tk-surface-2: #F2EFEE;
	--tk-line: #E3DEDD;
	--tk-line-2: #CFC8C6;
	--tk-muted: #5C5452;

	/* Three families, same three the Elementor kit uses. The kit reaches its own
	   surfaces through the PoliceDisplay / PoliceTexte / PoliceMono variables;
	   theme chrome and WooCommerce templates cannot read those, so they are
	   mirrored here. Keep the two in step. */
	--tk-body-font: "Inter", system-ui, -apple-system, sans-serif;
	--tk-display-font: "Archivo", var(--tk-body-font);
	--tk-mono-font: "Roboto Mono", ui-monospace, SFMono-Regular, monospace;

	--tk-radius: 12px;
	--tk-ease: cubic-bezier(0.2, 0.7, 0.2, 1);
}

/* WooCommerce's own tokens, re-pointed at the brand so nothing it renders can
   leak a colour nobody chose. --wc-primary was #720eec (Woo purple) and
   --wc-highlight was #958E09, the olive that measured 3.4:1 on the product
   price and failed WCAG AA. Both are declared on :root in woocommerce.css;
   :root:root outranks that on specificity, so this holds whatever order the
   stylesheets end up enqueued in. */
:root:root {
	--wc-primary: var(--tk-red);
	--wc-primary-text: var(--tk-surface);
	--wc-highlight: var(--tk-red-text);
	--wc-highlight-text: var(--tk-surface);
}

/* --------------------------------------------------------------------------
   0. ELEMENTOR'S 10px BOX, NEUTRALISED ON THE STRUCTURAL WRAPPERS
   -------------------------------------------------------------------------
   Elementor v4 ships `.elementor .e-flexbox-base { padding: 10px }` in
   base-desktop.css. Every atomic flexbox gets it, at every width, whether or
   not the design asked for one.

   Our layout nests those wrappers: section > wrap > head, and often
   > stack or > grid inside that. Each level added its own 10px, so the indent
   COMPOUNDED with nesting depth and every page ended up on a different left
   edge. Measured before this rule, at 390px: legal 34px, contact 40px, FAQ
   50px. At 1440 the same fault produced the four different left edges recorded
   in BUILD-PLAN section 16, product 100, header logo 124, home content 140.

   These wrappers are meant to be transparent boxes: their padding belongs to
   tk-section (96/24) and tk-card (24), which set it explicitly. So the fix is
   to say so, once.

   This is the one place in this file that targets tk-* classes, against the
   note at the top. It is deliberate: what is being overridden is an ELEMENTOR
   BASE default, not a value the kit chose. The kit never sets padding on any
   of these, so there is nothing here to fight, and the same specificity (0,2,0)
   resolves in this file's favour because it loads after base-desktop.css.
   -------------------------------------------------------------------------- */

.elementor .tk-wrap,
.elementor .tk-head,
.elementor .tk-stack,
.elementor .tk-row,
.elementor .tk-grid-2,
.elementor .tk-grid-3,
.elementor .tk-grid-4,
.elementor .tk-header-inner > .tk-nav-wrap,
.elementor .tk-footer-cols,
.elementor .tk-footer-col,
.elementor .tk-footer-bottom {
	padding: 0;
}

/* --------------------------------------------------------------------------
   0b. MOBILE MENU
   -------------------------------------------------------------------------
   The button is created by terkina3d_mobile_nav_script(), which also adds
   `tk-nav-js` to the header. Everything below is gated on that class, so with
   JavaScript off the header keeps today's behaviour, wrapped but complete,
   instead of collapsing into a logo with no navigation.
   -------------------------------------------------------------------------- */

/* Scoped to .tk-header, at (0,2,0), because the Elementor kit styles every
   `button` on the site as a brand-red call to action through
   `.elementor-kit-6 button` at (0,1,1). Unqualified `.tk-nav-burger` lost to
   it, and the menu control rendered as a solid red square. Hover and focus are
   restated for the same reason: the kit paints those too. */
.tk-header .tk-nav-burger,
.tk-header .tk-nav-burger:hover,
.tk-header .tk-nav-burger:focus,
.tk-header .tk-nav-burger:active {
	display: none;   /* shown only on phones, below */
	appearance: none;
	background-color: transparent;
	color: var(--tk-ink);
	border: 1px solid var(--tk-line-2);
	border-radius: 8px;
	width: 46px;
	height: 46px;
	padding: 0;
	margin-inline-start: auto;
	cursor: pointer;
	align-items: center;
	justify-content: center;
	flex: 0 0 auto;
	box-shadow: none;
}

/* Three bars from one element: the middle is the box, the outer two are its
   shadows, so the button carries no icon font and no SVG. */
.tk-nav-burger-bars,
.tk-nav-burger-bars::before,
.tk-nav-burger-bars::after {
	display: block;
	width: 20px;
	height: 2px;
	background-color: var(--tk-ink);
	transition: transform 0.25s var(--tk-ease), opacity 0.2s var(--tk-ease);
}

.tk-nav-burger-bars {
	position: relative;
}

.tk-nav-burger-bars::before,
.tk-nav-burger-bars::after {
	content: "";
	position: absolute;
	inset-inline-start: 0;
}

.tk-nav-burger-bars::before { top: -6px; }
.tk-nav-burger-bars::after { top: 6px; }

/* Open state: the bars become a cross. */
.tk-header.tk-nav-open .tk-nav-burger-bars { background-color: transparent; }
.tk-header.tk-nav-open .tk-nav-burger-bars::before { transform: translateY(6px) rotate(45deg); }
.tk-header.tk-nav-open .tk-nav-burger-bars::after { transform: translateY(-6px) rotate(-45deg); }

.tk-nav-burger:focus-visible {
	outline: 2px solid var(--tk-red);
	outline-offset: 2px;
}

@media (max-width: 767px) {
	.tk-header .tk-nav-burger { display: inline-flex; }

	.tk-header .tk-header-inner {
		flex-wrap: wrap;
		row-gap: 0;
	}

	/* Elementor lays the menu out as a right-aligned horizontal row and sizes
	   the list to its content. As a vertical panel it has to fill the width,
	   or the links sit in a ~106px column against the left edge with the
	   dividers stopping short. Selectors carry the element name to clear
	   Elementor's own (0,3,x) nav rules. */
	.tk-header.tk-nav-js nav.elementor-nav-menu--main,
	.tk-header.tk-nav-js ul.elementor-nav-menu,
	.tk-header.tk-nav-js ul.elementor-nav-menu > li,
	.tk-header.tk-nav-js ul.elementor-nav-menu > li > a {
		width: 100%;
	}

	.tk-header.tk-nav-js ul.elementor-nav-menu {
		justify-content: flex-start;
		align-items: stretch;
	}

	.tk-header.tk-nav-js ul.elementor-nav-menu > li > a {
		justify-content: flex-start;
	}

	/* The panel takes the full row under the bar, and scrolls if the menu ever
	   outgrows the screen. */
	.tk-header.tk-nav-js .elementor-widget-nav-menu {
		flex-basis: 100%;
		display: none;
		max-height: calc(100vh - 140px);
		overflow-y: auto;
	}

	.tk-header.tk-nav-js.tk-nav-open .elementor-widget-nav-menu {
		display: block;
	}

	/* One link per row, each a real 48px tap target. Before this the links were
	   30 to 32px, under the 44px minimum, and the only navigation on the site.

	   Gated on .tk-nav-js with everything else here. Ungated, this turned the
	   no-JavaScript fallback into a 430px narrow column stacked beside the
	   logo, which is worse than the wrapped rows it was meant to replace. The
	   fallback has to stay untouched: it is the state a visitor gets when the
	   script fails, and it is the only navigation on the site. */
	.tk-header.tk-nav-js .elementor-nav-menu {
		flex-direction: column;
		align-items: stretch;
		gap: 0;
		padding-block-end: 8px;
	}

	.tk-header.tk-nav-js .elementor-nav-menu > li > a {
		display: flex;
		align-items: center;
		min-height: 48px;
		padding-inline: 2px;
		border-block-start: 1px solid var(--tk-line);
	}

	.tk-footer .elementor-nav-menu > li > a {
		display: flex;
		align-items: center;
		min-height: 40px;
	}
}

/* --------------------------------------------------------------------------
   1. THEME BUILDER HEADER AND FOOTER: THE LEGACY WIDGETS INSIDE THEM
   -------------------------------------------------------------------------
   Batch 2 replaced Hello Elementor's header and footer with Theme Builder
   templates 194 and 195, so Hello's own .site-header / .site-footer markup no
   longer renders on any route and the ~130 lines that styled it were deleted
   rather than left to fight the new system. If either template is ever
   unpublished, Hello's chrome comes back UNSTYLED: re-publish the template, do
   not re-add the old CSS.

   The shells are global classes and live in the kit, not here:
     tk-header / tk-header-inner  sticky, paper, hairline, 1240 wrap
     tk-footer / tk-footer-inner  surface-2 ground, hairline, 1240 wrap
     tk-footer-cols / -col / -title / -note / -bottom
     tk-logo-header / tk-logo-footer

   What is left below is only what those global classes cannot reach: the list
   markup Elementor's Nav Menu widget generates for itself, and its burger.
   -------------------------------------------------------------------------- */

/* Elementor's Nav Menu ships its own list chrome. Nothing here sets a colour or
   a font: the widget is bound to the kit's "Navigation" typography preset and
   to the Encre / Rouge texte global colours in template 194 and 195, which is
   where the client changes them. */
.tk-header .elementor-nav-menu,
.tk-footer .elementor-nav-menu {
	margin: 0;
	padding: 0;
	list-style: none;
}

.tk-header .elementor-nav-menu a,
.tk-footer .elementor-nav-menu a {
	text-decoration: none;
	transition: color 0.2s var(--tk-ease);
}

/* Elementor draws its own focus ring on menu links; this keeps the site's. */
.tk-header .elementor-nav-menu a:focus-visible,
.tk-footer .elementor-nav-menu a:focus-visible {
	outline: 2px solid var(--tk-red);
	outline-offset: 3px;
	border-radius: 4px;
}

/* Cart link, injected into the primary menu by terkina3d_menu_cart_link().
   It rides the menu's own styling, so the count is the only declaration it
   needs, and that count is the only red in the header: it reads as a state
   rather than a seventh navigation item. */
.tk-cart-count {
	color: var(--tk-red-text);
	font-variant-numeric: tabular-nums;
}

.tk-header .elementor-nav-menu li.tk-cart-item > a {
	white-space: nowrap;
}

/* The logo is a flex item next to a nav that wraps onto three rows on a phone.
   With nothing stopping it the image was compressed to 22 x 34 from a 390 x 281
   source, which is illegible: the brand became a smudge on exactly the devices
   most of this store's traffic will use. Doubling the class clears the kit's
   own `.elementor .tk-logo-header` at (0,2,0), which loads after this file. */
.tk-header .tk-logo-header.tk-logo-header {
	flex: 0 0 auto;   /* the crush was flex-shrink, so this is the actual fix */
	width: auto;
	height: 40px;
	max-height: 40px;
	object-fit: contain;
}

@media (max-width: 767px) {
	/* Six links plus the cart wrap under the logo rather than collapsing into a
	   burger, which is deliberate: see the note above. Left-aligning the rows
	   and tightening the gaps makes the wrap read as a two-row menu instead of
	   ragged right-aligned text. */
	.tk-header .elementor-nav-menu {
		justify-content: flex-start;
		gap: 2px 18px;
	}

	.tk-header .elementor-nav-menu > li > a {
		padding-inline: 0;
	}

	.tk-header .tk-logo-header.tk-logo-header {
		height: 34px;
		max-height: 34px;
	}
}

/* NO BURGER, ON PURPOSE. The Nav Menu widget in template 194 is set to
   dropdown: none, so the menu never collapses and there is no toggle to style.

   Why: with the widget's own mobile dropdown enabled, the panel would not open.
   Measured after tapping the burger, three times, with the CSS deployed and
   re-measured each time: the toggle carried .elementor-active, aria-expanded
   was "true", the inline --menu-height was set, the panel held all 7 items and
   285px of real content (ul.offsetHeight), the open selector was confirmed to
   match the element with Element.matches(), and the declaration was confirmed
   present in the served stylesheet, and the computed max-height stayed 0px.
   Restating Elementor's open rule did not fix it, and neither did the same rule
   with !important, which is not a cascade outcome that has an ordinary
   explanation.

   Rather than ship the only navigation control on mobile depending on a widget
   state that could not be made to work or explained, the collapse was removed.
   Six short links plus the cart wrap onto a second row under the logo, which
   needs no JavaScript and no state class, and is verifiable by measurement.
   If a burger is wanted later it should be built and tested by `tester` in a
   real browser, not in this headless pane. */
.tk-header .elementor-nav-menu {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: flex-end;
}

/* The logo is an atomic image sitting in a flex row. Without a shrink guard the
   row squashed the 1200px lockup to 21px wide at 375. Note the guard goes on
   the LINK, not the image: e-image wraps its img in an <a class="e-image-link-
   base">, so the anchor is the flex child and a rule on the img itself does
   nothing (measured: still 21px). The heights live on the tk-logo-header /
   tk-logo-footer global classes in the kit; only the guard is here, because the
   global-class edit ability takes no `variants` argument and rewriting the
   class through it would drop tk-logo-header's mobile height variant. */
.tk-header .e-image-link-base,
.tk-footer .e-image-link-base {
	flex: 0 0 auto;
}

/* The footer's contact column is a .tk-defs list inside an HTML widget, which
   the kit never sees. Section 7 styles .tk-defs globally; on the footer's
   narrower column the label/value pair reads better stacked. */
.tk-footer .tk-defs {
	border-top: 0;
}

.tk-footer .tk-defs > div {
	flex-direction: column;
	align-items: flex-start;
	gap: 2px;
	padding: 10px 0;
	border-block-end-color: var(--tk-line);
}

.tk-footer .tk-defs dd {
	text-align: start;
	font-weight: 500;
}

/* --------------------------------------------------------------------------
   3. WOOCOMMERCE PRODUCT LOOP
   Woo renders its own templates, outside Elementor, so the kit never reaches
   them. Without this the catalogue is default WooCommerce and matches nothing
   else on the site. Soft rounded tiles, per the reference.
   -------------------------------------------------------------------------- */

.woocommerce ul.products {
	display: grid;
	gap: 24px;
	margin: 0;
	padding: 0;
}

.woocommerce ul.products::before,
.woocommerce ul.products::after {
	content: none;
}

.woocommerce ul.products.columns-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.woocommerce ul.products.columns-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.woocommerce ul.products.columns-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }

.woocommerce ul.products li.product {
	width: 100% !important;   /* Woo ships percentage widths with !important */
	margin: 0 !important;
	float: none !important;
	clear: none !important;
	display: flex;
	flex-direction: column;
	gap: 6px;
	padding: 14px 14px 20px;
	background: var(--tk-surface-2);
	border-radius: var(--tk-radius);
	transition:
		transform 0.3s var(--tk-ease),
		box-shadow 0.3s var(--tk-ease);
}

/* The catalogue is an Elementor Products widget, and Pro's own grid CSS carries
   `.elementor-products-grid ul.products.elementor-grid li.product` at (0,4,2),
   which outranks the (0,3,2) rule above and sets
   `display: var(--button-align-display)`. That variable is only defined when
   the widget's "Align buttons" control is set, so it resolved to nothing, the
   declaration was invalid at computed-value time, and the card fell back to
   `display: block`. The column layout died with it, so "Ajouter au panier"
   could no longer be pushed to the bottom and the buttons sat at a different
   height in every card of a row.

   Matching that selector rather than raising specificity blindly, so the fix
   is aimed at the exact rule it has to beat. */
.woocommerce ul.products li.product,
.elementor-products-grid ul.products.elementor-grid li.product {
	display: flex;
	flex-direction: column;
}

.woocommerce ul.products li.product:hover {
	transform: translateY(-3px);
	box-shadow: 0 12px 28px rgba(10, 10, 10, 0.08);
}

.woocommerce ul.products li.product a img {
	margin: 0 0 14px;
	aspect-ratio: 1 / 1;
	object-fit: cover;
	border-radius: 8px;
	background-color: var(--tk-surface);
}

.woocommerce ul.products li.product .woocommerce-loop-product__title {
	font-family: var(--tk-body-font);
	font-weight: 700;
	font-size: 15px;
	line-height: 1.3;
	color: var(--tk-ink);
	padding: 0;
	margin: 0;
}

/* Injected by terkina3d_loop_made_to_order(). Nothing here is in stock, and a
   shopper who does not learn that before checkout learns it from a five day
   wait, which is the most expensive place to find out. */
.woocommerce ul.products li.product .tk-made {
	font-family: var(--tk-body-font);
	font-size: 13px;
	line-height: 1.45;
	color: var(--tk-muted);
	margin: 0;
}

.woocommerce ul.products li.product .price {
	font-family: var(--tk-body-font);
	font-size: 15px;
	font-weight: 700;
	color: var(--tk-ink);
	margin: 4px 0 0;
}

.woocommerce ul.products li.product .price del { color: var(--tk-muted); font-weight: 400; }
.woocommerce ul.products li.product .price ins { text-decoration: none; color: var(--tk-red-text); }

/* `auto` rather than a fixed gap, so every button in a row sits on the same
   line whatever the title wraps to. The container's 6px gap is the minimum
   spacing, so a tall card never crushes the button against the price. */
.woocommerce ul.products li.product .button,
.woocommerce ul.products li.product .added_to_cart {
	margin-block-start: auto;
	align-self: flex-start;
	background-color: var(--tk-red);
	color: var(--tk-surface);
	font-family: var(--tk-body-font);
	font-weight: 600;
	font-size: 13px;
	border-radius: 999px;
	padding: 10px 20px;
	transition: background-color 0.25s var(--tk-ease);
}

.woocommerce ul.products li.product .button:hover,
.woocommerce ul.products li.product .added_to_cart:hover {
	background-color: #B4000B;
	color: var(--tk-surface);
}

.woocommerce span.onsale {
	background-color: var(--tk-red);
	color: var(--tk-surface);
	font-family: var(--tk-body-font);
	font-size: 12px;
	font-weight: 600;
	border-radius: 999px;
	min-height: 0;
	min-width: 0;
	line-height: 1;
	padding: 8px 14px;
}

/* Woo's own buttons elsewhere: cart, checkout, single product. */
.woocommerce #respond input#submit,
.woocommerce a.button,
.woocommerce button.button,
.woocommerce input.button,
.woocommerce a.button.alt,
.woocommerce button.button.alt {
	background-color: var(--tk-red);
	color: var(--tk-surface);
	border-radius: 999px;
	font-family: var(--tk-body-font);
	font-weight: 600;
}

.woocommerce #respond input#submit:hover,
.woocommerce a.button:hover,
.woocommerce button.button:hover,
.woocommerce input.button:hover,
.woocommerce a.button.alt:hover,
.woocommerce button.button.alt:hover {
	background-color: #B4000B;
	color: var(--tk-surface);
}

/* --------------------------------------------------------------------------
   4. FAQ ACCORDION
   Native <details>/<summary>, so it works with no JavaScript and screen
   readers announce the state for free. Elementor's accordion widget would
   have brought its own markup and its own styling to fight.

   Rendered through an Elementor "html" widget, which is why these are plain
   classes and not tk-* global classes: the kit never sees this markup.
   -------------------------------------------------------------------------- */

.tk-faq {
	border-top: 1px solid var(--tk-line);
	width: 100%;
	/* The jump nav targets this container, but the group's eyebrow and heading
	   sit ABOVE it. Clearing only the sticky header would land the reader on a
	   list of questions with no idea which group they are in, so this clears
	   the header and the heading block together. */
	scroll-margin-top: 210px;
}

.tk-faq details {
	border-bottom: 1px solid var(--tk-line);
}

.tk-faq summary {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 24px;
	padding: 22px 4px;
	cursor: pointer;
	list-style: none;
	font-family: var(--tk-body-font);
	font-size: 17px;
	font-weight: 600;
	line-height: 1.4;
	color: var(--tk-ink);
	transition: color 0.2s var(--tk-ease);
}

/* Safari and Chrome each need their own opt-out of the default triangle. */
.tk-faq summary::-webkit-details-marker { display: none; }
.tk-faq summary::marker { content: ""; }

.tk-faq summary:hover { color: var(--tk-red-text); }

/* A plus that rotates into a close cross. Two gradients, no icon font. */
.tk-faq summary::after {
	content: "";
	flex: 0 0 auto;
	width: 14px;
	height: 14px;
	background-image:
		linear-gradient(var(--tk-ink), var(--tk-ink)),
		linear-gradient(var(--tk-ink), var(--tk-ink));
	background-size: 14px 2px, 2px 14px;
	background-position: center, center;
	background-repeat: no-repeat;
	transition: transform 0.3s var(--tk-ease), background-image 0.2s var(--tk-ease);
}

.tk-faq details[open] > summary { color: var(--tk-red-text); }

.tk-faq details[open] > summary::after {
	transform: rotate(45deg);
	background-image:
		linear-gradient(var(--tk-red), var(--tk-red)),
		linear-gradient(var(--tk-red), var(--tk-red));
}

.tk-faq .tk-faq-a {
	margin: 0;
	padding: 0 4px 24px;
	max-width: 68ch;
	font-family: var(--tk-body-font);
	font-size: 16px;
	line-height: 1.65;
	color: var(--tk-muted);
}

/* Progressive enhancement: browsers that can interpolate to auto get a real
   open/close transition. Everywhere else the panel just appears. */
@supports (interpolate-size: allow-keywords) {
	:root { interpolate-size: allow-keywords; }

	.tk-faq details::details-content {
		height: 0;
		overflow: hidden;
		content-visibility: hidden;
		transition:
			height 0.3s var(--tk-ease),
			content-visibility 0.3s allow-discrete;
	}

	.tk-faq details[open]::details-content {
		height: auto;
		content-visibility: visible;
	}
}

/* Jump nav. 15 questions is too many to scroll blind. */
.tk-faq-nav {
	display: flex;
	flex-wrap: wrap;
	gap: 10px;
	padding: 0;
	margin: 0;
	list-style: none;
}

.tk-faq-nav a {
	display: inline-block;
	padding: 9px 18px;
	border: 1px solid var(--tk-line-2);
	border-radius: 999px;
	font-family: var(--tk-body-font);
	font-size: 13px;
	font-weight: 500;
	color: var(--tk-ink);
	text-decoration: none;
	transition:
		background-color 0.2s var(--tk-ease),
		border-color 0.2s var(--tk-ease),
		color 0.2s var(--tk-ease);
}

.tk-faq-nav a:hover {
	background-color: var(--tk-ink);
	border-color: var(--tk-ink);
	color: var(--tk-surface);
}

@media (max-width: 767px) {
	.tk-faq summary { font-size: 16px; gap: 16px; }
	.tk-faq .tk-faq-a { font-size: 15px; }

	/* Label above value, so a long value is not squeezed into a column. */
	.tk-defs > div {
		flex-direction: column;
		align-items: flex-start;
		gap: 4px;
	}

	.tk-defs dd { text-align: start; }

	.tk-list li { font-size: 16px; gap: 14px; }
	.tk-list li::before { width: 38px; }
}

/* --------------------------------------------------------------------------
   5. NUMBERED ROWS
   The "(01) ... " divided rows from the Fabrixa reference. Used only where the
   content really is an enumerated set, so the numbers carry information rather
   than decorate. Rendered through an "html" widget, hence plain classes.
   -------------------------------------------------------------------------- */

.tk-list {
	width: 100%;
	margin: 0;
	padding: 0;
	list-style: none;
	counter-reset: tk-li;
	border-top: 1px solid var(--tk-line);
}

.tk-list li {
	counter-increment: tk-li;
	display: flex;
	align-items: baseline;
	gap: 20px;
	padding: 20px 4px;
	border-bottom: 1px solid var(--tk-line);
	font-family: var(--tk-body-font);
	font-size: 17px;
	line-height: 1.5;
	color: var(--tk-ink);
}

.tk-list li::before {
	content: "(" counter(tk-li, decimal-leading-zero) ")";
	flex: 0 0 auto;
	width: 48px;
	font-size: 14px;
	font-weight: 500;
	color: var(--tk-muted);
	font-variant-numeric: tabular-nums;
}

/* --------------------------------------------------------------------------
   6. NOTE CALLOUT
   For content the client has not confirmed yet. Deliberately neutral: these
   are honest "not decided yet" statements shown to visitors, not errors, so
   they must not read as a warning.
   -------------------------------------------------------------------------- */

.tk-note {
	width: 100%;
	margin: 0;
	padding: 18px 22px;
	border-inline-start: 3px solid var(--tk-line-2);
	border-radius: 0 8px 8px 0;
	background-color: var(--tk-surface);
	font-family: var(--tk-body-font);
	font-size: 15px;
	line-height: 1.6;
	color: var(--tk-muted);
}

/* --------------------------------------------------------------------------
   7. DEFINITION ROWS
   Label and value pairs: contact channels, delivery times, specifications.
   -------------------------------------------------------------------------- */

.tk-defs {
	width: 100%;
	margin: 0;
	padding: 0;
	border-top: 1px solid var(--tk-line);
}

.tk-defs > div {
	display: flex;
	align-items: baseline;
	justify-content: space-between;
	gap: 24px;
	padding: 16px 4px;
	border-bottom: 1px solid var(--tk-line);
}

.tk-defs dt {
	font-family: var(--tk-body-font);
	font-size: 14px;
	font-weight: 500;
	color: var(--tk-muted);
	margin: 0;
}

.tk-defs dd {
	font-family: var(--tk-body-font);
	font-size: 15px;
	font-weight: 600;
	color: var(--tk-ink);
	margin: 0;
	text-align: end;
}

.tk-defs dd a { color: var(--tk-red-text); text-decoration: none; }
.tk-defs dd a:hover { text-decoration: underline; }

/* An in-page jump target. Sits where the anchor should land, and clears the
   sticky header plus the heading above it. */
.tk-anchor {
	display: block;
	height: 0;
	scroll-margin-top: 160px;
}

/* --------------------------------------------------------------------------
   8. ELEMENTOR PRO FORMS
   The form widget is legacy v3, so the kit's global classes never touch it.
   -------------------------------------------------------------------------- */

.elementor-form .elementor-field-group > label.elementor-field-label {
	font-family: var(--tk-body-font);
	font-size: 13px;
	font-weight: 600;
	color: var(--tk-ink);
	margin-block-end: 8px;
}

.elementor-form .elementor-field-textual {
	font-family: var(--tk-body-font);
	font-size: 15px;
	color: var(--tk-ink);
	background-color: var(--tk-surface);
	border: 1px solid var(--tk-line-2);
	border-radius: 8px;
	padding: 13px 16px;
	transition: border-color 0.2s var(--tk-ease), box-shadow 0.2s var(--tk-ease);
}

.elementor-form .elementor-field-textual:focus {
	border-color: var(--tk-ink);
	box-shadow: 0 0 0 3px rgba(10, 10, 10, 0.06);
	outline: none;
}

.elementor-form .elementor-field-textual::placeholder { color: #9C9391; }

.elementor-form .elementor-field-type-upload input[type="file"] {
	font-family: var(--tk-body-font);
	font-size: 14px;
	color: var(--tk-muted);
	padding: 12px 0;
}

.elementor-form .elementor-field-type-acceptance .elementor-field-option label {
	font-family: var(--tk-body-font);
	font-size: 14px;
	line-height: 1.55;
	color: var(--tk-muted);
}

.elementor-form .elementor-field-type-acceptance a { color: var(--tk-red-text); }

.elementor-form .elementor-button[type="submit"] {
	background-color: var(--tk-red);
	color: var(--tk-surface);
	font-family: var(--tk-body-font);
	font-size: 15px;
	font-weight: 700;
	border: 0;
	border-radius: 999px;
	padding: 15px 30px;
	transition: background-color 0.25s var(--tk-ease);
}

.elementor-form .elementor-button[type="submit"]:hover { background-color: #B4000B; }

.elementor-message.elementor-message-success { color: #1B7A3D; }
.elementor-message.elementor-message-danger { color: var(--tk-red-text); }

.elementor-field-required .elementor-field-label:after { color: var(--tk-red-text); }

/* --------------------------------------------------------------------------
   9. PROSE PAGES
   Any page NOT built in Elementor: the legal pages, and anything the client
   writes themselves after handoff. Without this they render as raw Gutenberg
   and look like a different website. Scoped to Hello's .page-content wrapper,
   and excluded when Elementor owns the page.
   -------------------------------------------------------------------------- */

.page-content > *:not(.elementor) {
	max-width: 760px;
	margin-inline: auto;
	font-family: var(--tk-body-font);
}

.page-content:not(:has(.elementor)) {
	padding: 8px 24px 96px;
	background-color: var(--tk-paper);
}

/* Hello prints the page title itself, in .page-header. Elementor pages carry
   hide_title so this only ever shows on prose pages. */
.page-header:not(:has(.elementor)) {
	background-color: var(--tk-paper);
	padding: 72px 24px 0;
}

.page-header .entry-title {
	max-width: 760px;
	margin: 0 auto 24px;
	font-family: var(--tk-display-font);
	font-size: clamp(2rem, 5vw, 3rem);
	font-weight: 900;
	text-transform: uppercase;
	letter-spacing: -0.02em;
	line-height: 1.05;
	color: var(--tk-ink);
}

.page-content > h2 {
	font-size: 1.4rem;
	font-weight: 800;
	line-height: 1.25;
	color: var(--tk-ink);
	margin: 48px auto 14px;
	padding-block-start: 28px;
	border-top: 1px solid var(--tk-line);
}

.page-content > h3 {
	font-size: 1.1rem;
	font-weight: 700;
	color: var(--tk-ink);
	margin: 28px auto 10px;
}

.page-content > p,
.page-content > ul,
.page-content > ol {
	font-size: 16px;
	line-height: 1.7;
	color: var(--tk-muted);
	margin: 0 auto 16px;
}

.page-content > ul,
.page-content > ol { padding-inline-start: 22px; }
.page-content > ul li,
.page-content > ol li { margin-block-end: 8px; }

.page-content > p a { color: var(--tk-red-text); }
.page-content > p strong,
.page-content > ul strong { color: var(--tk-ink); }

.page-content > .wp-block-separator { display: none; }  /* the h2 rule replaces it */

@media (max-width: 767px) {
	/* Hello Elementor adds `padding-inline: 10px` to .site-main and to
	   .page-header .entry-title below 575px, which stacked with the 24px here
	   and pushed the legal pages to a 34px gutter while every other page sat at
	   20px. Zeroed, and the gutter stated once. */
	.site-main {
		padding-inline: 0;
	}

	.page-header .entry-title {
		padding-inline: 0;
	}

	.page-header:not(:has(.elementor)),
	.page-content:not(:has(.elementor)) {
		padding-inline: 20px;
	}
}

/* --------------------------------------------------------------------------
   10. ACCESSIBILITY
   -------------------------------------------------------------------------- */

.tk-header a:focus-visible,
.tk-footer a:focus-visible,
.woocommerce a:focus-visible,
.woocommerce button:focus-visible {
	outline: 2px solid var(--tk-red);
	outline-offset: 3px;
	border-radius: 4px;
}

@media (prefers-reduced-motion: reduce) {
	.woocommerce ul.products li.product:hover {
		transform: none;
	}

	*,
	*::before,
	*::after {
		transition-duration: 0.01ms !important;
	}
}

/* --------------------------------------------------------------------------
   11. RESPONSIVE
   -------------------------------------------------------------------------- */

@media (max-width: 1024px) {
	.woocommerce ul.products.columns-4 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

@media (max-width: 767px) {
	.woocommerce ul.products.columns-4,
	.woocommerce ul.products.columns-3,
	.woocommerce ul.products.columns-2 {
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}

	/* Header and footer padding, logo heights and the single-column footer are
	   mobile variants on the tk-header-inner / tk-footer-inner / tk-footer-cols
	   / tk-logo-header global classes, set in the kit. Nothing to do here. */
}

/* --------------------------------------------------------------------------
   12. WOOCOMMERCE, SHARED
   Everything WooCommerce renders outside Elementor: the shop, the single
   product, cart, checkout, account. The kit never reaches any of it.

   Cascade note. The child theme is enqueued after woocommerce.css but BEFORE
   the WooCommerce Blocks stylesheets, so Blocks rules have to be beaten on
   specificity, not on order. Where a selector below looks over-qualified or
   doubles a class, that is why, and the Blocks rule it outranks is named.
   -------------------------------------------------------------------------- */

/* Every Elementor page sits on paper; every WooCommerce page sat on white. */
body.woocommerce,
body.woocommerce-page,
body.tax-product_cat,
body.tax-product_tag,
body.post-type-archive-product,
body.single-product {
	background-color: var(--tk-paper);
}

/* Links WooCommerce renders carry no colour of their own. Measured before this
   rule, a bare <a> on this site computed to rgb(204, 51, 102) in Chrome and
   nothing in any enqueued stylesheet set it: that is the BROWSER's default,
   so the colour was not merely off-brand, it was undefined and varied by
   browser. Every Elementor surface sets its own colour, which is why the gap
   only ever showed where WooCommerce rendered. */
.woocommerce a,
.wc-block-checkout a,
.wp-block-woocommerce-cart a,
.woocommerce-notices-wrapper a {
	color: var(--tk-red-text);
}

/* Product names are titles, not text links: ink, with red kept for the action.
   Doubled scope class because a two-class Blocks rule loading after this one
   sets the summary item title to #333, so a (0,2,0) tie loses on order. */
.woocommerce ul.products li.product > a,
.wc-block-checkout.wc-block-checkout .wc-block-components-product-name,
.wp-block-woocommerce-cart.wp-block-woocommerce-cart .wc-block-components-product-name {
	color: var(--tk-ink);
	text-decoration: none;
}

.wc-block-checkout.wc-block-checkout .wc-block-components-product-name:hover,
.wp-block-woocommerce-cart.wp-block-woocommerce-cart .wc-block-components-product-name:hover {
	color: var(--tk-red-text);
}

/* Notices. Woo ships these with an olive-green, blue and maroon accent and the
   system font stack. Keeping Woo's layout and icon, correcting the palette. */
.woocommerce-message,
.woocommerce-info,
.woocommerce-error {
	font-family: var(--tk-body-font);
	font-size: 15px;
	line-height: 1.6;
	color: var(--tk-ink);
	background-color: var(--tk-surface-2);
	border-radius: 0 0 8px 8px;
}

.woocommerce-message { border-top-color: var(--tk-red); }
.woocommerce-message::before { color: var(--tk-red); }
.woocommerce-info { border-top-color: var(--tk-ink); }
.woocommerce-info::before { color: var(--tk-ink); }
.woocommerce-error { border-top-color: var(--tk-red-text); }
.woocommerce-error::before { color: var(--tk-red-text); }

/* --------------------------------------------------------------------------
   13. WOOCOMMERCE BLOCKS: CART AND CHECKOUT
   /panier/ and /commander/ are the Blocks versions, which render from React
   and share nothing with Woo's classic templates. Values below are the tokens
   already in use elsewhere on the site. No new ones were introduced.
   -------------------------------------------------------------------------- */

/* The place-order button is the most important control on the site and shipped
   as a transparent 3px-radius outline. Beats
   `.wc-block-components-button:not(.is-link).contained` (0,3,0). */
.wc-block-checkout .wc-block-components-checkout-place-order-button.wc-block-components-button:not(.is-link),
.wp-block-woocommerce-cart .wc-block-cart__submit-button.wc-block-components-button:not(.is-link) {
	background-color: var(--tk-red);
	color: var(--tk-surface);
	font-family: var(--tk-body-font);
	font-size: 15px;
	font-weight: 700;
	border: 0;
	border-radius: 999px;
	padding: 15px 30px;
	transition: background-color 0.25s var(--tk-ease);
}

.wc-block-checkout .wc-block-components-checkout-place-order-button.wc-block-components-button:not(.is-link):hover,
.wc-block-checkout .wc-block-components-checkout-place-order-button.wc-block-components-button:not(.is-link):focus,
.wc-block-checkout .wc-block-components-checkout-place-order-button.wc-block-components-button:not(.is-link):active,
.wp-block-woocommerce-cart .wc-block-cart__submit-button.wc-block-components-button:not(.is-link):hover,
.wp-block-woocommerce-cart .wc-block-cart__submit-button.wc-block-components-button:not(.is-link):focus,
.wp-block-woocommerce-cart .wc-block-cart__submit-button.wc-block-components-button:not(.is-link):active {
	background-color: #B4000B;
	color: var(--tk-surface);
	opacity: 1;
}

/* Fields, to the same 8px and --tk-line-2 as .elementor-form. The rule these
   have to beat is
   `.wc-block-components-form .wc-block-components-text-input input[type=text]`
   at (0,3,1), which loads after this stylesheet, so a tie loses. Doubling the
   scope class plus the [type] attribute puts these at (0,4,1). */
.wc-block-checkout.wc-block-checkout .wc-block-components-text-input input[type],
.wc-block-checkout.wc-block-checkout .wc-block-components-textarea,
.wc-block-checkout.wc-block-checkout .wc-blocks-components-select__select,
.wp-block-woocommerce-cart.wp-block-woocommerce-cart .wc-block-components-text-input input[type],
.wp-block-woocommerce-cart.wp-block-woocommerce-cart .wc-blocks-components-select__select {
	font-family: var(--tk-body-font);
	color: var(--tk-ink);
	background-color: var(--tk-surface);
	border: 1px solid var(--tk-line-2);
	border-radius: 8px;
	transition: border-color 0.2s var(--tk-ease), box-shadow 0.2s var(--tk-ease);
}

/* Same focus treatment as .elementor-form .elementor-field-textual:focus. The
   border width is restated because Woo's focus rule jumps to 1.5px, which
   nudges the field 1px as you tab through it. */
.wc-block-checkout.wc-block-checkout .wc-block-components-text-input input[type]:focus,
.wc-block-checkout.wc-block-checkout .wc-block-components-textarea:focus,
.wc-block-checkout.wc-block-checkout .wc-blocks-components-select__select:focus,
.wp-block-woocommerce-cart.wp-block-woocommerce-cart .wc-block-components-text-input input[type]:focus,
.wp-block-woocommerce-cart.wp-block-woocommerce-cart .wc-blocks-components-select__select:focus {
	border: 1px solid var(--tk-ink);
	box-shadow: 0 0 0 3px rgba(10, 10, 10, 0.06);
	outline: none;
}

/* The lead time, restated in the order summary. Same .tk-note as the rest of
   the site, tightened for a 247px sidebar. */
.wc-block-checkout .tk-note--summary {
	margin-block-start: 16px;
	padding: 14px 16px;
	font-size: 14px;
}

/* --------------------------------------------------------------------------
   14. SINGLE PRODUCT
   The page where the customer decides. It was still stock Hello Elementor.
   -------------------------------------------------------------------------- */

/* Beats `.woocommerce div.product .product_title` and Hello's h1 defaults,
   which rendered it at -apple-system 40px weight 500 on #333. */
.woocommerce div.product .summary h1.product_title {
	font-family: var(--tk-display-font);
	font-size: clamp(2rem, 4vw, 2.75rem);
	font-weight: 900;
	line-height: 1.05;
	letter-spacing: -0.02em;
	text-transform: uppercase;
	color: var(--tk-ink);
	margin-block-end: 14px;
}

/* Beats `.woocommerce:where(...) div.product p.price` (0,3,2), which set the
   olive --wc-highlight at weight 400. */
.woocommerce div.product .summary p.price,
.woocommerce div.product .summary span.price {
	font-family: var(--tk-body-font);
	font-size: 22px;
	font-weight: 700;
	color: var(--tk-ink);
	margin-block-end: 14px;
}

.woocommerce div.product .summary p.price del { color: var(--tk-muted); font-weight: 400; }
.woocommerce div.product .summary p.price ins { text-decoration: none; color: var(--tk-red-text); }

/* Printed by terkina3d_single_lead_time() at woocommerce_single_product_summary
   priority 11, immediately under the price. Mirrors the tk-badge global class,
   which cannot be used here: the kit only emits `.elementor .tk-badge`, and
   nothing WooCommerce renders is inside .elementor. */
.woocommerce div.product .summary .tk-lead-time {
	display: inline-block;
	margin: 0 0 20px;
	padding: 7px 16px;
	background-color: var(--tk-surface-2);
	border: 1px solid var(--tk-line-2);
	border-radius: 999px;
	font-family: var(--tk-body-font);
	font-size: 13px;
	line-height: 1.4;
	color: var(--tk-muted);
}

.woocommerce div.product .summary .woocommerce-product-details__short-description {
	font-family: var(--tk-body-font);
	font-size: 16px;
	line-height: 1.65;
	color: var(--tk-muted);
}

/* The single product page was the only route with no side gutter: between
   768px and about 1340px its content sat flush against both viewport edges,
   because the 1240 centring only engages above that. Every other page,
   including cart and checkout, already had one.

   Applied only BELOW the width where the 1240 centring engages. Adding the
   gutter at every width instead cost 48px of content and left the product page
   1192 wide against a 1240 header, which is a misalignment rather than a fix. */
@media (max-width: 1339px) {
	body.single-product .site-main {
		padding-inline: 24px;
	}
}

@media (max-width: 767px) {
	body.single-product .site-main {
		padding-inline: 20px;
	}
}

/* ---- Square product gallery ----------------------------------------------
   Every product photo renders 1:1, cropped to fill, whatever shape it was
   uploaded in. The catalogue already did this; the product page did not, so a
   1600x2400 portrait ran to 893px tall while a 1600x1600 square sat at 595,
   and the page changed shape from one product to the next. Source images in
   the library today are 1600x2400, 1600x2408, 1600x1067 and 1600x1600.

   `cover`, not `contain`: contain would letterbox a portrait inside the square
   and leave dead bands, which looks like a mistake rather than a crop. The
   client should still frame their real photos square, because cover crops the
   top and bottom off a tall image.

   overflow:hidden on the link is load-bearing. WooCommerce's magnifier injects
   an absolutely positioned img.zoomImg at the source image's own aspect ratio,
   which would otherwise spill out of the square on hover. Clipping it to the
   link keeps the zoom inside the frame the customer is looking at. */
.woocommerce div.product div.images .woocommerce-product-gallery__image,
.woocommerce div.product div.images .woocommerce-product-gallery__image > a {
	display: block;
	position: relative;
	width: 100%;
	aspect-ratio: 1 / 1;
	overflow: hidden;
	border-radius: var(--tk-radius);
	background-color: var(--tk-surface-2);
}

.woocommerce div.product div.images .woocommerce-product-gallery__image img,
.woocommerce div.product div.images .woocommerce-product-gallery__image > a img {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
	object-position: center;
	border-radius: inherit;
}

/* The gallery thumbnail strip, for when the client adds second and third
   photos. No product has one today, so this is styled ahead of the content
   rather than after someone finds it broken. */
.woocommerce div.product div.images .flex-control-thumbs li img {
	aspect-ratio: 1 / 1;
	object-fit: cover;
	border-radius: 8px;
	opacity: 0.65;
	transition: opacity 0.2s var(--tk-ease);
}

.woocommerce div.product div.images .flex-control-thumbs li img:hover,
.woocommerce div.product div.images .flex-control-thumbs li img.flex-active {
	opacity: 1;
}

/* Woo's zoom hint sits over the top-right corner; keep it clear of the radius. */
.woocommerce div.product div.images .woocommerce-product-gallery__trigger {
	top: 14px;
	right: 14px;
	z-index: 2;
}

.woocommerce div.product .product_meta {
	font-family: var(--tk-body-font);
	font-size: 13px;
	color: var(--tk-muted);
}

@media (max-width: 767px) {
	.wc-block-checkout .wc-block-components-checkout-place-order-button.wc-block-components-button:not(.is-link),
	.wp-block-woocommerce-cart .wc-block-cart__submit-button.wc-block-components-button:not(.is-link) {
		width: 100%;
	}
}

/* --------------------------------------------------------------------------
   15. SHOP ARCHIVE
   /boutique/ and every /categorie-produit/... page render from Theme Builder
   template 197. The hero, the 1240 wrap and the paper ground are global
   classes; what is below is the markup WooCommerce and the sandbox plugin
   generate inside it.
   -------------------------------------------------------------------------- */

/* THE CATALOGUE TILE, INSIDE ELEMENTOR'S ARCHIVE PRODUCTS WIDGET.
   Section 3 styles the tile for the loop WooCommerce renders itself, which is
   what /boutique/ used before batch 2 and what the homepage [products]
   shortcode still uses. Elementor's widget re-wraps the same loop in
   .elementor-products-grid and then flattens it with
   `.elementor-products-grid ul.products.elementor-grid li.product` at (0,4,1),
   from a stylesheet that loads AFTER this file, so section 3's (0,3,1) rules
   lose on specificity AND on order. Measured symptoms before this block: tile
   padding 0, and the product title and price rendering Archivo 28/800 (the
   kit's h2 scale) instead of Inter 15/700, which also pushed the price out of
   its tile and gave the page 49px of horizontal scroll at 375.
   Doubling .product takes these to (0,5,1). */
.elementor-products-grid ul.products.elementor-grid li.product.product {
	padding: 14px 14px 20px;
}

.elementor-products-grid ul.products.elementor-grid li.product.product .woocommerce-loop-product__title,
.elementor-products-grid ul.products.elementor-grid li.product.product .price {
	font-family: var(--tk-body-font);
	font-size: 15px;
	font-weight: 700;
	line-height: 1.3;
	color: var(--tk-ink);
	overflow-wrap: anywhere;
}

.elementor-products-grid ul.products.elementor-grid li.product.product .price {
	margin: 4px 0 0;
}

.elementor-products-grid ul.products.elementor-grid li.product.product .tk-made {
	font-size: 13px;
	font-weight: 400;
	color: var(--tk-muted);
}

.elementor-products-grid ul.products.elementor-grid li.product.product .button,
.elementor-products-grid ul.products.elementor-grid li.product.product .added_to_cart {
	font-size: 13px;
}

/* The category filter row, printed by [terkina3d_product_categories]. It reuses
   the .tk-faq-nav pill treatment from section 4 wholesale, so only the current
   state is new: before this the five categories were reachable from nothing. */
.tk-shop-nav a.is-current {
	background-color: var(--tk-ink);
	border-color: var(--tk-ink);
	color: var(--tk-surface);
}

/* ---- The catalogue toolbar -----------------------------------------------
   Filters left, count and sort right, on one line closed by a hairline.

   All three are controls for narrowing the catalogue, so they read as one
   strip. They could not be brought together with CSS: WooCommerce prints the
   count and the sort from `woocommerce_before_shop_loop`, which fires inside
   the Elementor Products widget, while the filters are a separate shortcode
   widget earlier in the template. Two subtrees, no shared flex parent.
   terkina3d_product_categories_shortcode() now renders all three, and unhooks
   the WooCommerce pair so they are not printed twice. */
.tk-shop-toolbar {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: space-between;
	gap: 14px 24px;
	margin-block: 4px 8px;
	padding-block-end: 18px;
	border-block-end: 1px solid var(--tk-line);
}

/* Grows to take the row, but is allowed to wrap its own pills before it forces
   the sort control onto a second line. */
.tk-shop-toolbar .tk-shop-nav {
	flex: 1 1 420px;
	margin: 0;
}

.tk-shop-tools {
	display: flex;
	align-items: center;
	gap: 18px;
	flex: 0 0 auto;
	margin-inline-start: auto;
}

.tk-shop-tools .woocommerce-result-count,
.tk-shop-tools .woocommerce-ordering {
	float: none;   /* Woo floats both */
	margin: 0;
	font-family: var(--tk-body-font);
	font-size: 14px;
	line-height: 1.4;
	color: var(--tk-muted);
	white-space: nowrap;
}

/* Woo's select is width:100% in woocommerce.css, which is what stretched it to
   the full 1240px content width on its own row. `auto` lets it size to its
   widest option instead, and the cap stops that overflowing a narrow screen:
   "Tri du plus récent au plus ancien" is 266px wide, which ran off the right
   edge of a 390px phone. */
.tk-shop-tools .woocommerce-ordering select {
	width: auto;
	max-width: 100%;
	font-family: var(--tk-body-font);
	font-size: 14px;
	color: var(--tk-ink);
	background-color: var(--tk-surface);
	border: 1px solid var(--tk-line-2);
	border-radius: 999px;
	padding: 9px 18px;
	cursor: pointer;
}

.tk-shop-tools .woocommerce-ordering select:focus-visible {
	outline: 2px solid var(--tk-red);
	outline-offset: 2px;
}

.elementor-widget-woocommerce-archive-products .woocommerce > .woocommerce-notices-wrapper:first-child:empty {
	display: none;
}

.elementor-widget-woocommerce-archive-products .woocommerce {
	display: flex;
	flex-direction: column;
	gap: 20px;
}

@media (max-width: 767px) {
	/* On a phone the pills already use two or three rows, so the count and the
	   sort drop to their own line and spread rather than crowding the pills. */
	.tk-shop-tools {
		margin-inline-start: 0;
		width: 100%;
		justify-content: space-between;
		gap: 12px;
	}

	/* min-width:0 so the form is allowed to shrink below the select's intrinsic
	   width, which is what a flex item refuses to do by default. */
	.tk-shop-tools .woocommerce-ordering {
		flex: 1 1 auto;
		min-width: 0;
	}

	.tk-shop-tools .woocommerce-result-count {
		flex: 0 0 auto;
	}

	.tk-shop-tools .woocommerce-ordering select {
		width: 100%;
		padding: 8px 14px;
		text-overflow: ellipsis;
	}
}

.elementor-widget-woocommerce-archive-products .woocommerce-pagination ul.page-numbers {
	border: 0;
	display: flex;
	flex-wrap: wrap;
	gap: 8px;
	padding: 0;
	margin-block-start: 12px;
}

.elementor-widget-woocommerce-archive-products .woocommerce-pagination ul.page-numbers li {
	border: 0;
	margin: 0;
}

.elementor-widget-woocommerce-archive-products .woocommerce-pagination .page-numbers {
	font-family: var(--tk-body-font);
	font-size: 14px;
	font-weight: 500;
	color: var(--tk-ink);
	border: 1px solid var(--tk-line-2);
	border-radius: 999px;
	padding: 8px 16px;
	min-width: 40px;
	text-align: center;
}

.elementor-widget-woocommerce-archive-products .woocommerce-pagination .page-numbers.current,
.elementor-widget-woocommerce-archive-products .woocommerce-pagination .page-numbers:hover {
	background-color: var(--tk-ink);
	border-color: var(--tk-ink);
	color: var(--tk-surface);
}

@media (max-width: 767px) {
	.elementor-widget-woocommerce-archive-products .woocommerce-ordering select { width: 100%; }
}

/* --------------------------------------------------------------------------
   16. SINGLE PRODUCT: STACKED SECTIONS
   Printed by terkina3d_product_sections() in place of WooCommerce's three-tab
   strip. These are plain classes, not tk-* global classes, because the kit
   never sees markup a plugin echoes into a WooCommerce template.
   -------------------------------------------------------------------------- */

/* ---- Quick Order ---------------------------------------------------------
   Printed by terkina3d_quick_order_form(). Given a surface and a border so it
   reads as a thing you do, not a paragraph you read, and so it is clearly
   separate from the Description below it. */
.tk-quickorder {
	/* Rendered at woocommerce_after_single_product_summary, so it is a sibling
	   of WooCommerce's floated gallery and summary and lands beside them unless
	   it clears. Exactly the fault that put the description in a 50px column;
	   the same trap catches every block added after the product summary. */
	clear: both;
	width: 100%;
	background-color: var(--tk-surface-2);
	border-radius: var(--tk-radius);
	padding: 28px 28px 32px;
	margin-block-start: 56px;
	scroll-margin-top: 110px;   /* clears the sticky header on the #anchor jump */
}

.tk-quickorder-lead {
	max-width: 62ch;
	margin: 0 0 22px;
	font-family: var(--tk-body-font);
	font-size: 16px;
	line-height: 1.6;
	color: var(--tk-muted);
}

.tk-quickorder-error {
	margin: 0 0 20px;
	padding: 12px 16px;
	border-inline-start: 3px solid var(--tk-red);
	border-radius: 0 8px 8px 0;
	background-color: var(--tk-surface);
	font-family: var(--tk-body-font);
	font-size: 15px;
	color: var(--tk-ink);
}

/* Form on the left, order summary on the right. The right column was empty
   before, on the most decision-heavy block on the site. */
.tk-quickorder-grid {
	display: grid;
	grid-template-columns: minmax(0, 760px) minmax(0, 1fr);
	align-items: start;
	gap: 40px 56px;
}

.tk-qo-main {
	display: flex;
	flex-direction: column;
	gap: 28px;
	min-width: 0;
}

.tk-quickorder-form {
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	gap: 16px 20px;
}

/* ---- The order summary column -------------------------------------------- */

.tk-qo-aside {
	display: flex;
	flex-direction: column;
	gap: 16px;
}

.tk-qo-card {
	background-color: var(--tk-surface);
	border-radius: 10px;
	padding: 20px 22px;
}

.tk-qo-card-title {
	margin: 0 0 14px;
	font-family: var(--tk-body-font);
	font-size: 13px;
	font-weight: 700;
	letter-spacing: 0.06em;
	text-transform: uppercase;
	color: var(--tk-ink);
}

.tk-qo-card .tk-defs {
	border-top: 0;
}

.tk-qo-card .tk-defs > div {
	padding-block: 10px;
}

.tk-qo-card .tk-defs > div:first-child {
	padding-block-start: 0;
}

/* The line the customer actually hands money against, so it is the only one
   given weight. */
.tk-qo-card .tk-defs .tk-qo-total {
	border-block-end: 0;
	padding-block-end: 0;
	margin-block-start: 2px;
	border-block-start: 2px solid var(--tk-ink);
	padding-block-start: 12px;
}

.tk-qo-card .tk-defs .tk-qo-total dt {
	color: var(--tk-ink);
	font-weight: 600;
}

.tk-qo-card .tk-defs .tk-qo-total dd {
	font-size: 19px;
	font-weight: 700;
}

.tk-qo-card-note {
	margin: 14px 0 0;
	font-family: var(--tk-body-font);
	font-size: 13px;
	line-height: 1.5;
	color: var(--tk-muted);
}

/* Reuse the (01)(02)(03) rows from section 5, tightened for a narrow card. */
.tk-qo-steps.tk-list li {
	font-size: 14px;
	line-height: 1.55;
	padding-block: 12px;
	gap: 12px;
}

.tk-qo-steps.tk-list li::before {
	width: 32px;
	font-size: 12px;
}

.tk-qo-steps.tk-list li:last-child {
	border-block-end: 0;
	padding-block-end: 0;
}

.tk-qo-tips {
	margin: 0;
	padding: 0;
	list-style: none;
	display: flex;
	flex-direction: column;
	gap: 12px;
}

.tk-qo-tips li {
	font-family: var(--tk-body-font);
	font-size: 14px;
	line-height: 1.55;
	color: var(--tk-muted);
	padding-inline-start: 18px;
	position: relative;
}

.tk-qo-tips li::before {
	content: "";
	position: absolute;
	inset-inline-start: 0;
	top: 8px;
	width: 6px;
	height: 6px;
	border-radius: 50%;
	background-color: var(--tk-red);
}

.tk-qo-tips strong {
	color: var(--tk-ink);
	font-weight: 600;
}

.tk-qo-aside-help {
	margin: 2px 0 0;
	font-family: var(--tk-body-font);
	font-size: 13px;
	line-height: 1.55;
	color: var(--tk-muted);
}

.tk-qo-aside-help a {
	color: var(--tk-red-text);
}

@media (max-width: 1024px) {
	/* Summary above the form once they stack: what it costs and what happens
	   next is the thing that decides whether the form gets filled at all. */
	.tk-quickorder-grid {
		grid-template-columns: minmax(0, 1fr);
		gap: 28px;
	}

	.tk-qo-aside {
		order: -1;
	}
}

.tk-qo-field {
	display: flex;
	flex-direction: column;
	gap: 7px;
	margin: 0;
	grid-column: 1 / -1;
}

.tk-qo-field.tk-qo-half {
	grid-column: auto;
}

.tk-qo-field label {
	font-family: var(--tk-body-font);
	font-size: 13px;
	font-weight: 600;
	color: var(--tk-ink);
}

.tk-qo-field label span {
	color: var(--tk-red-text);
}

.tk-qo-field input,
.tk-qo-field textarea {
	width: 100%;
	font-family: var(--tk-body-font);
	font-size: 15px;
	color: var(--tk-ink);
	background-color: var(--tk-surface);
	border: 1px solid var(--tk-line-2);
	border-radius: 8px;
	padding: 12px 14px;
	transition: border-color 0.2s var(--tk-ease), box-shadow 0.2s var(--tk-ease);
}

.tk-qo-field textarea {
	resize: vertical;
	min-height: 62px;
}

.tk-qo-field input:focus,
.tk-qo-field textarea:focus {
	border-color: var(--tk-ink);
	box-shadow: 0 0 0 3px rgba(10, 10, 10, 0.06);
	outline: none;
}

/* The honeypot. Off-screen rather than display:none, because some bots skip
   fields they can tell are hidden. Kept out of the tab order in the markup. */
.tk-qo-hp {
	position: absolute;
	left: -9999px;
	width: 1px;
	height: 1px;
	overflow: hidden;
}

.tk-qo-submit {
	grid-column: 1 / -1;
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 10px 20px;
	margin-block-start: 4px;
}

.tk-qo-terms {
	font-family: var(--tk-body-font);
	font-size: 13px;
	line-height: 1.5;
	color: var(--tk-muted);
	max-width: 46ch;
}

/* Link from the summary down to the form. */
.tk-qo-jump {
	margin: 12px 0 0;
	font-family: var(--tk-body-font);
	font-size: 14px;
}

.tk-qo-jump a {
	color: var(--tk-red-text);
	text-decoration: underline;
	text-underline-offset: 3px;
}

.tk-quickorder-done .tk-list {
	max-width: 68ch;
	margin-block-end: 20px;
}

.tk-quickorder-done .tk-note {
	background-color: var(--tk-surface);
}

@media (max-width: 767px) {
	.tk-quickorder {
		padding: 22px 18px 26px;
	}

	/* One column: two fields side by side on a phone makes both too narrow to
	   type an address into. */
	.tk-quickorder-form {
		grid-template-columns: minmax(0, 1fr);
	}

	.tk-qo-field.tk-qo-half {
		grid-column: 1 / -1;
	}
}

.tk-product-sections {
	/* WooCommerce floats div.images left and .summary right, and this block is
	   their next sibling. Without a clear it lays out in the ~50px gutter
	   BETWEEN the two floats: the description rendered one character per line,
	   2807px tall, overlapping the product title. Reproduced at 1440 and 1920.
	   Nothing else in this file can substitute: the floats are Woo's own. */
	clear: both;
	width: 100%;
	display: flex;
	flex-direction: column;
	gap: 48px;
	margin-block-start: 64px;
}

/* Description and Fiche technique side by side, when both exist. The modifier
   is set in PHP: a product with only one of the two keeps the block above and
   fills the width, rather than sitting in a half-width column with dead space
   beside it.

   Not 1fr 1fr. The description is prose and the spec list is short label/value
   rows, so an even split leaves the right column half empty while crowding the
   left. align-items:start stops the shorter column stretching to match. */
.tk-product-sections--pair {
	display: grid;
	grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr);
	align-items: start;
	gap: 48px 56px;
}

/* The prose cap exists to keep a readable measure on a full-width block. In
   the pair layout the column already provides it, and the cap would only push
   the text away from its own column edge. */
.tk-product-sections--pair .tk-product-prose {
	max-width: none;
}

@media (max-width: 1024px) {
	/* Two columns at tablet width squeezes the spec values onto three lines
	   each. Stacked is more readable than narrow. */
	.tk-product-sections--pair {
		grid-template-columns: minmax(0, 1fr);
		gap: 44px;
	}
}

.tk-product-section {
	display: flex;
	flex-direction: column;
	gap: 18px;
}

/* Mirrors the tk-h2 global class, which cannot be used here: the kit only
   emits `.elementor .tk-h2`, and nothing WooCommerce renders sits inside
   .elementor. Keep the two in step. */
.tk-product-h2 {
	font-family: var(--tk-display-font);
	font-size: clamp(1.5rem, 2.4vw, 1.875rem);
	font-weight: 800;
	text-transform: uppercase;
	letter-spacing: -0.015em;
	line-height: 1.15;
	color: var(--tk-ink);
	margin: 0;
	padding-block-start: 28px;
	border-block-start: 1px solid var(--tk-line);
}

.tk-product-prose {
	max-width: 68ch;
	font-family: var(--tk-body-font);
	font-size: 16px;
	line-height: 1.7;
	color: var(--tk-muted);
}

.tk-product-prose p { margin: 0 0 14px; }
.tk-product-prose p:last-child { margin-block-end: 0; }
.tk-product-prose a { color: var(--tk-red-text); }
.tk-product-prose strong { color: var(--tk-ink); }

/* The specification list replaces Woo's shop_attributes table. .tk-defs from
   section 7 does the work; it only needs a width cap so long values do not
   stretch to the full page. */
.tk-product-sections .tk-defs {
	max-width: 760px;
}

/* Colour is a display-only attribute on this store, not a variation, so the
   product page states how the colour is actually chosen. .tk-note carries the
   neutral callout treatment; this only tightens it for the summary column. */
.woocommerce div.product .summary .tk-colour-note {
	margin-block: 4px 20px;
	padding: 14px 18px;
	font-size: 14px;
}

/* Related products, relabelled "Vous aimerez aussi" and topped up to four. */
.woocommerce .related > h2,
.woocommerce .upsells > h2 {
	font-family: var(--tk-display-font);
	font-size: clamp(1.5rem, 2.4vw, 1.875rem);
	font-weight: 800;
	text-transform: uppercase;
	letter-spacing: -0.015em;
	color: var(--tk-ink);
	margin: 0 0 24px;
	padding-block-start: 28px;
	border-block-start: 1px solid var(--tk-line);
}

.woocommerce .related,
.woocommerce .upsells {
	margin-block-start: 48px;
}

/* --------------------------------------------------------------------------
   17. CONTAINER WIDTH, EVERYWHERE
   The kit's container width is 1240 and every Elementor section wraps at 1240.
   Hello Elementor caps its own content area at 1140, which is why the shop, the
   product page, the cart and the checkout sat 50px narrower on each side than
   the header directly above them. WooCommerce pages that render a Theme Builder
   template are already 1240 through tk-wrap; this covers the ones that do not.
   -------------------------------------------------------------------------- */

body.woocommerce .site-main,
body.woocommerce-page .site-main,
body.single-product .site-main,
body.error404 .site-main {
	max-width: 1240px;
	margin-inline: auto;
}

/* Paper ground on every route, not only the WooCommerce ones batch 1 covered.
   Section 12 lists the WooCommerce bodies; these are the rest. */
body.error404,
body.search,
body.search-results,
body.search-no-results {
	background-color: var(--tk-paper);
}

/* --------------------------------------------------------------------------
   THE "NOUVEAU DANS LA BOUTIQUE" GRID ON THE EMPTY CART
   -------------------------------------------------------------------------
   WooCommerce's Blocks cart puts a product grid under an empty basket, and
   ships it at 12px, which cascades to the titles and the prices. That is the
   smallest text anywhere on the site, on the page whose whole job is to send
   somebody back to the catalogue.

   Doubled selectors: wc-blocks.css loads AFTER this file, so these have to win
   on specificity rather than order.
   -------------------------------------------------------------------------- */

/* Doubled to (0,3,0): wc-blocks.css sets the tile font-size at (0,2,0) and
   loads later, so a single-class rule here lost. Everything inside the tile
   that is sized in `em` resolves from this. */
.wc-block-grid.wc-block-grid .wc-block-grid__product {
	font-size: 15px;
}

.wc-block-grid .wc-block-grid__product-title {
	font-family: var(--tk-body-font);
	font-size: 15px;
	font-weight: 700;
	line-height: 1.3;
	color: var(--tk-ink);
}

.wc-block-grid .wc-block-grid__product-price {
	font-family: var(--tk-body-font);
	font-size: 15px;
	font-weight: 700;
	color: var(--tk-ink);
}

.wc-block-grid .wc-block-grid__product-image img {
	border-radius: 8px;
}

/* Its add-to-cart buttons came out at 12px, the smallest text on the site, on
   controls people are meant to tap. Matched to the catalogue buttons.

   The selector mirrors wc-blocks' own
   `.wc-block-grid__product-add-to-cart.wp-block-button .wp-block-button__link`
   at (0,3,1), which sets `font-size: 1em`, plus one class to outrank it. */
.wc-block-grid .wc-block-grid__product-add-to-cart.wp-block-button .wp-block-button__link,
.wc-block-grid .wp-block-button__link {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-height: 42px;
	padding: 10px 20px;
	font-family: var(--tk-body-font);
	font-size: 13px;
	font-weight: 600;
	line-height: 1.2;
	color: var(--tk-surface);
	background-color: var(--tk-red);
	border: 0;
	border-radius: 999px;
}

.wc-block-grid .wp-block-button__link:hover,
.wc-block-grid .wp-block-button__link:focus {
	background-color: #B4000B;
	color: var(--tk-surface);
}

/* --------------------------------------------------------------------------
   LAST: PHONES, TEXT INPUTS AND THE ZOOM THEY CAUSE
   MUST REMAIN THE FINAL BLOCK IN THIS FILE.
   -------------------------------------------------------------------------
   iOS Safari zooms the whole page in when a field with a font-size under 16px
   receives focus, and does not zoom back out afterwards. The customer is left
   pinching to see the rest of the form.

   Every field on this site was under that line: Quick Order at 15px, the
   Elementor forms at 15px, the catalogue sort and the file upload at 14px, the
   cart quantity stepper at 13px. 16px is the whole fix, and it only applies on
   phones so the desktop type scale is untouched.

   These rules match the same selectors used earlier in the file, at the same
   specificity, so ONLY their position decides the outcome. Placed mid-file this
   block silently lost to the catalogue toolbar 400 lines below it and the sort
   control stayed at 14px. Anything appended after this will win instead.
   -------------------------------------------------------------------------- */

@media (max-width: 767px) {
	.tk-qo-field input,
	.tk-qo-field textarea,
	.elementor-form .elementor-field-textual,
	.elementor-form .elementor-field-type-upload input[type="file"],
	.tk-shop-tools .woocommerce-ordering select,
	.woocommerce .quantity input.qty,
	.woocommerce form .form-row input.input-text,
	.woocommerce form .form-row textarea,
	.woocommerce form .form-row select,
	.wc-block-components-text-input input,
	.wc-block-components-textarea {
		font-size: 16px;
	}

	/* 12px uppercase with letter-spacing is legible on a desktop monitor and
	   marginal on a phone held at arm's length. */
	.elementor .tk-eyebrow {
		font-size: 13px;
	}

	/* The catalogue sort is a control, not a caption. */
	.tk-shop-tools .woocommerce-ordering select {
		min-height: 44px;
	}

	/* Two standalone links measured 17px and 19px tall: the Quick Order jump
	   under the add-to-cart button, and the e-mail and Instagram links in the
	   footer. Both are things a customer taps on purpose, unlike the breadcrumb
	   and the inline links inside sentences, which are left alone.

	   The footer pair grows its hit area with a pseudo-element rather than
	   padding, so five rows of contact details do not each gain 26px of height
	   on the page where the footer is already longest. */
	.tk-qo-jump a {
		display: inline-block;
		padding-block: 13px;
	}

	.tk-footer .tk-defs dd a {
		position: relative;
	}

	.tk-footer .tk-defs dd a::after {
		content: "";
		position: absolute;
		inset: -13px 0;
	}
}
