/*
Theme Name: Neve FSE Child
Theme URI: https://github.com/DTLA-Print/neve-fse-child
Description: Shop Titan child theme for Neve FSE. Holds the converted block patterns (formerly ACF Flexible-Content blocks) rebuilt as native FSE patterns that consume the parent theme's theme.json design tokens (color / typography / spacing presets).
Author: The Comet Companies
Author URI: https://thecometcompany.com
Template: neve-fse
Version: 1.24.0
Requires at least: 6.5
Tested up to: 6.7
Requires PHP: 7.4
Text Domain: neve-fse-child
*/

/*
 * Styling lives in theme.json / Global Styles, not here.
 * Add only genuinely-custom CSS that presets cannot express.
 */

/* ── LEGACY · Custom-HTML logo marquee ──────────────────────────────────────
   st-trusted-by used to ship its marquee as a Custom HTML block with the logo
   set pasted in twice. It is now ordinary blocks driven by assets/marquee.js
   (see "Block marquee" below), but pages that inserted the old version still
   hold that raw HTML, so these rules stay until those pages are re-inserted.
   Do not use .st-logo-marquee in new work.                                   */
.st-logo-marquee {
	width: 100%;
	overflow: hidden;
	-webkit-mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
	        mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
}
.st-logo-marquee__track {
	display: flex;
	flex-wrap: nowrap;
	width: max-content;
	align-items: center;
	gap: 3.5rem;
	animation: st-marquee 32s linear infinite;
}
.st-logo-marquee:hover .st-logo-marquee__track {
	animation-play-state: paused;
}
.st-logo-marquee__item {
	flex: 0 0 auto;
	margin: 0;
	white-space: nowrap;
	font-weight: 600;
	letter-spacing: 0.06em;
	text-transform: uppercase;
	opacity: 0.7;
}
@keyframes st-marquee {
	from { transform: translateX(0); }
	to   { transform: translateX(-50%); }
}
@media (prefers-reduced-motion: reduce) {
	.st-logo-marquee__track {
		animation: none;
		flex-wrap: wrap;
		justify-content: center;
		width: 100%;
	}
}

/* ── Shop Titan · Receipt spec card (pattern: st-receipt) ───────────────────
   Frame + dashed itemized rules that give the "printed receipt" look. Colours
   come from theme.json presets (ti-fg / ti-line); only the frame lives here.  */
.st-receipt {
	max-width: 460px;
	margin-inline: auto;
	border: 1px solid var(--wp--preset--color--ti-fg);
}
.st-receipt-hd {
	border-bottom: 1px dashed var(--wp--preset--color--ti-line);
	padding-bottom: 0.85rem;
	margin-bottom: 0.35rem;
}
.st-receipt-row {
	gap: 1rem;
	padding-top: 0.55rem;
	padding-bottom: 0.55rem;
	border-bottom: 1px dashed var(--wp--preset--color--ti-line);
}
.st-receipt-row:last-child {
	border-bottom: 0;
}
.st-receipt-row p {
	margin: 0;
}

/* ── Shop Titan · Accordion (patterns: st-process-steps, st-faq) ────────────
   Hairline-ruled core/details list. Colour comes from theme.json presets on
   the blocks; only the rules, the marker swap and the step counter live here.
   Add the class `st-accordion` to the group wrapping the details blocks —
   add `st-steps` as well to get automatic 01/02/03 numbering.               */
.st-accordion > .wp-block-details {
	border-top: 1px solid var(--wp--preset--color--ti-line);
	padding: 1.15rem 0;
	margin: 0;
}
.st-accordion > .wp-block-details:last-child {
	border-bottom: 1px solid var(--wp--preset--color--ti-line);
}
.st-accordion > .wp-block-details > summary {
	display: flex;
	align-items: baseline;
	gap: 0.9rem;
	cursor: pointer;
	list-style: none;
	font-weight: 700;
	line-height: 1.35;
}
.st-accordion > .wp-block-details > summary::-webkit-details-marker {
	display: none;
}
.st-accordion > .wp-block-details > summary::after {
	content: "+";
	margin-left: auto;
	flex: 0 0 auto;
	font-family: var(--wp--preset--font-family--space-mono);
	font-weight: 400;
	color: var(--wp--preset--color--ti-accent-secondary);
}
.st-accordion > .wp-block-details[open] > summary::after {
	content: "\2013"; /* en dash */
}
.st-accordion > .wp-block-details > summary:focus-visible {
	outline: 2px solid var(--wp--preset--color--ti-fg);
	outline-offset: 3px;
}
.st-accordion > .wp-block-details > *:not(summary) {
	margin-top: 0.85rem;
	/* Keep a reading measure, but not so tight that answers look left-clipped
	   against a full-width question. 62ch filled barely half the 860px column
	   and read as a layout bug; 90ch is the upper bound of a comfortable measure
	   and sits at roughly three-quarters. */
	max-width: 90ch;
}

/* Auto-numbering — renumbers itself when steps are added, moved or removed. */
.st-steps {
	counter-reset: st-step;
}
.st-steps > .wp-block-details {
	counter-increment: st-step;
}
.st-steps > .wp-block-details > summary::before {
	content: counter(st-step, decimal-leading-zero);
	flex: 0 0 auto;
	font-family: var(--wp--preset--font-family--space-mono);
	font-size: var(--wp--preset--font-size--small);
	font-weight: 400;
	letter-spacing: 0.06em;
	color: var(--wp--preset--color--ti-accent-secondary);
}
.st-steps > .wp-block-details > *:not(summary) {
	padding-left: 3.1rem;
}

/* ── Shop Titan · Why-us differentiators (pattern: st-why-us) ───────────────
   Numbered, rule-topped points. Counter numbering matches the accordion so a
   reordered point renumbers itself.                                         */
.st-why-list {
	counter-reset: st-why;
}
.st-why-item {
	counter-increment: st-why;
	position: relative;
	padding-top: 1.5rem;
	padding-left: 3.1rem;
	border-top: 1px solid var(--wp--preset--color--ti-line);
}
.st-why-item::before {
	content: counter(st-why, decimal-leading-zero);
	position: absolute;
	top: 1.5rem;
	left: 0;
	font-family: var(--wp--preset--font-family--space-mono);
	font-size: var(--wp--preset--font-size--small);
	letter-spacing: 0.06em;
	line-height: 1.6;
	color: var(--wp--preset--color--ti-accent-secondary);
}
@media (max-width: 781px) {
	.st-why-item {
		padding-left: 0;
	}
	.st-why-item::before {
		position: static;
		display: block;
		margin-bottom: 0.35rem;
	}
}

/* ── Shop Titan · How-it-works step cards (pattern: st-how-it-works) ────────
   Framed cards with an oversized outlined "ghost" numeral, counter-driven so
   adding or reordering a card renumbers the set.                            */
.st-hiw-grid {
	counter-reset: st-hiw;
}
.st-hiw-card {
	counter-increment: st-hiw;
	position: relative;
	overflow: hidden;
	padding: 2.25rem 1.75rem 1.75rem;
	border: 1px solid var(--wp--preset--color--ti-line);
}
.st-hiw-card::before {
	content: counter(st-hiw, decimal-leading-zero);
	position: absolute;
	top: -0.3em;
	right: 0.08em;
	font-size: 7rem;
	font-weight: 800;
	line-height: 1;
	letter-spacing: -0.04em;
	color: transparent;
	-webkit-text-stroke: 1px var(--wp--preset--color--ti-line);
	opacity: 0.4;
	pointer-events: none;
}
.st-hiw-card > * {
	position: relative;
}
.st-hiw-detail {
	margin-top: 1.25rem;
	padding-top: 0.9rem;
	border-top: 1px dashed var(--wp--preset--color--ti-line);
	letter-spacing: 0.04em;
}

/* Scroll-triggered rise, CSS-only. Gated on @supports so unsupporting
   browsers simply show the cards, and skipped inside the editor canvas
   (body.editor-styles-wrapper) where the scroll container is the iframe. */
@supports (animation-timeline: view()) {
	@media (prefers-reduced-motion: no-preference) {
		body:not(.editor-styles-wrapper) .st-hiw-card {
			animation: st-hiw-rise linear both;
			animation-timeline: view();
			animation-range: entry 8% cover 26%;
		}
	}
}
@keyframes st-hiw-rise {
	from {
		opacity: 0;
		transform: translateY(14px);
	}
	to {
		opacity: 1;
		transform: none;
	}
}

/* ── Shop Titan · Full-height column panels ─────────────────────────────────
   The columns stretch to the tallest panel, but a cover or group nested
   inside one does not inherit that height — it sits at its own content
   height and leaves a gap under the shorter side. Make each column a flex
   column so its panel fills it, and both sides end level whatever the copy
   length. Used by st-dual-cta and st-feature-media-full; add st-fill-columns
   to any Columns block that needs the same. (.st-dual-cta is kept as its own
   selector because pages inserted before st-fill-columns existed carry it.) */
.st-dual-cta > .wp-block-column,
.st-fill-columns > .wp-block-column {
	display: flex;
	flex-direction: column;
}
.st-dual-cta > .wp-block-column > .wp-block-cover,
.st-fill-columns > .wp-block-column > .wp-block-cover,
.st-fill-columns > .wp-block-column > .wp-block-group {
	flex: 1 0 auto;
}

/* ── Shop Titan · Logo wall (pattern: st-logo-wall) ─────────────────────────
   Grid cells hold logos at a common height; mono treatment keeps a wall of
   mismatched client files looking like one set.                             */
.st-logo-wall .wp-block-image {
	margin: 0;
	display: flex;
	align-items: center;
	justify-content: center;
}
.st-logo-wall .wp-block-image img {
	max-height: 3rem;
	width: auto;
	object-fit: contain;
	filter: grayscale(1);
	opacity: 0.6;
	transition: opacity 0.2s ease, filter 0.2s ease;
}
.st-logo-wall .wp-block-image img:hover {
	filter: grayscale(0);
	opacity: 1;
}

/* ── Shop Titan · Production standards (pattern: st-production-standards) ───
   Faint press-registration rules behind the section, and spec cards with a
   heavy top accent. Card framing lives here so the block attributes stay
   editable without fighting an inline style block.                          */
.st-prod-std {
	position: relative;
	overflow: hidden;
}
.st-prod-std::before {
	content: "";
	position: absolute;
	inset: 0;
	pointer-events: none;
	background: repeating-linear-gradient(
		90deg,
		transparent,
		transparent calc(25% - 0.5px),
		rgba(0, 0, 0, 0.05) calc(25% - 0.5px),
		rgba(0, 0, 0, 0.05) calc(25% + 0.5px)
	);
}
.st-prod-std > * {
	position: relative;
}
.st-prod-card {
	padding: 1.75rem 1.5rem;
	background: var(--wp--preset--color--ti-bg-alt);
	border: 1px solid var(--wp--preset--color--ti-line);
	border-top: 3px solid var(--wp--preset--color--ti-fg);
}
.st-prod-method {
	margin-bottom: 0.85rem;
}
.st-prod-label {
	margin-top: 1.25rem;
	padding-top: 0.9rem;
	border-top: 1px dashed var(--wp--preset--color--ti-line);
	margin-bottom: 0.35rem;
}

/* ── Shop Titan · Durability proof (pattern: st-durability-proof) ───────────
   Method chips, then staggered test cards with an oversized counter number
   set in the left margin. Stagger is decorative and drops away on mobile.  */
/* .st-method-chip is styled with .st-chip further down. */
.st-dur-tests {
	counter-reset: st-dur;
}
.st-dur-test {
	counter-increment: st-dur;
	position: relative;
	padding-left: 5.5rem;
	padding-top: 1.75rem;
	border-top: 1px solid var(--wp--preset--color--ti-accent-secondary);
	max-width: 46rem;
}
.st-dur-test::before {
	content: counter(st-dur, decimal-leading-zero);
	position: absolute;
	left: 0;
	top: 1.25rem;
	font-size: 3rem;
	font-weight: 800;
	line-height: 1;
	letter-spacing: -0.04em;
	color: transparent;
	-webkit-text-stroke: 1px var(--wp--preset--color--ti-accent-secondary);
}
@media (min-width: 782px) {
	.st-dur-test:nth-child(2) {
		margin-left: 6rem;
	}
	.st-dur-test:nth-child(3) {
		margin-left: 12rem;
	}
}
@media (max-width: 781px) {
	.st-dur-test {
		padding-left: 0;
		padding-top: 3.75rem;
	}
	.st-dur-test::before {
		top: 1.25rem;
	}
}

/* ── Shop Titan · Block marquee (patterns: st-trust-strip, st-trusted-by) ───
   The items are ordinary blocks. assets/marquee.js clones them until the
   track is two identical halves each at least as wide as the frame, then
   sets --st-marquee-duration from --st-marquee-speed (px per second), so a
   short strip and a long one travel at the same rate. Until that runs — no
   JS, or reduced motion — the track is just a wrapped, centred flex row,
   which is also how it appears in the editor.                              */
.st-marquee__viewport {
	width: 100%;
	overflow: hidden;
}
.st-marquee__track.is-animated {
	flex-wrap: nowrap;
	justify-content: flex-start;
	width: max-content;
	animation: st-marquee-scroll var(--st-marquee-duration, 30s) linear infinite;
}
.st-marquee:hover .st-marquee__track.is-animated {
	animation-play-state: paused;
}
.st-marquee__item {
	flex: 0 0 auto;
	margin: 0;
	white-space: nowrap;
}
@keyframes st-marquee-scroll {
	from { transform: translateX(0); }
	to   { transform: translateX(-50%); }
}
@media (prefers-reduced-motion: reduce) {
	.st-marquee__track {
		animation: none;
	}
	.st-marquee__viewport {
		-webkit-mask-image: none;
		        mask-image: none;
	}
}

/* Trust strip — hairline-divided claims on a dark band. */
.st-trust-strip .st-marquee__viewport {
	-webkit-mask-image: linear-gradient(90deg, transparent, #000 6%, #000 94%, transparent);
	        mask-image: linear-gradient(90deg, transparent, #000 6%, #000 94%, transparent);
}
.st-trust-strip .st-marquee__track {
	--st-marquee-speed: 90;
	row-gap: 0.5rem;
}
.st-trust-strip .st-marquee__item {
	padding: 0 1.75rem;
	letter-spacing: 0.04em;
	border-left: 1px solid var(--wp--preset--color--ti-accent-secondary);
}

/* Trusted-by — spaced uppercase wordmarks, no dividers. */
.st-logo-strip .st-marquee__viewport {
	-webkit-mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
	        mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
}
.st-logo-strip .st-marquee__track {
	--st-marquee-speed: 70;
	row-gap: 1rem;
}
.st-logo-strip .st-marquee__item {
	padding: 0 1.75rem;
	font-weight: 600;
	letter-spacing: 0.06em;
	text-transform: uppercase;
	opacity: 0.7;
}
.st-logo-strip .st-marquee__item img {
	max-height: 2.5rem;
	width: auto;
}

/* ── Shop Titan · Use-case cards (pattern: st-use-cases) ────────────────────
   Framed text cards that sit alongside the image panel in the same grid.   */
.st-use-card {
	display: flex;
	flex-direction: column;
	padding: 1.5rem;
	background: var(--wp--preset--color--ti-bg-alt);
	border: 1px solid var(--wp--preset--color--ti-line);
}
.st-use-cta {
	margin-top: auto;
	padding-top: 1rem;
	letter-spacing: 0.04em;
}
.st-use-cta a {
	text-decoration: none;
}
.st-use-cta a:hover {
	text-decoration: underline;
}

/* ── Shop Titan · Use-case rail (pattern: st-use-cases-slider) ──────────────
   Every use case is the same card with its own photograph, laid on a
   scroll-snapping rail instead of one big panel plus three small text boxes.
   Pure CSS until assets/carousel.js adds arrows: with no JS it is still a
   swipeable, keyboard-scrollable row, and in the editor every card stays
   directly editable rather than being buried behind a control.
   --st-rail-cols is how many cards a full-width rail shows.                 */
.st-rail {
	--st-rail-cols: 3;
	--st-rail-gap: 1.25rem;
	position: relative;
}
.st-rail__track {
	display: flex;
	gap: var(--st-rail-gap);
	overflow-x: auto;
	scroll-snap-type: x mandatory;
	scroll-behavior: smooth;
	scrollbar-width: none;
	/* Room for the card border and focus ring, which a clipped rail would
	   otherwise shave off the first and last card. */
	padding: 2px 2px 1rem;
	margin: -2px -2px 0;
}
.st-rail__track::-webkit-scrollbar {
	display: none;
}
.st-rail__card {
	flex: 0 0
		calc(
			(100% - (var(--st-rail-cols) - 1) * var(--st-rail-gap)) /
				var(--st-rail-cols)
		);
	scroll-snap-align: start;
	/* The stretched heading link resolves against this, not against .st-rail —
	   without it one card's link would cover the whole rail. */
	position: relative;
	display: flex;
	flex-direction: column;
	overflow: hidden;
	background: var(--wp--preset--color--ti-bg-alt);
	border: 1px solid var(--wp--preset--color--ti-line);
	transition: border-color 0.2s ease;
}
.st-rail__card:hover {
	border-color: var(--wp--preset--color--ti-fg);
}
.st-rail__card > .wp-block-image {
	margin: 0;
	overflow: hidden;
}
.st-rail__card > .wp-block-image img {
	display: block;
	width: 100%;
	height: auto;
	object-fit: cover;
	transition: transform 0.6s cubic-bezier(0.2, 0.6, 0.2, 1);
}
.st-rail__card:hover > .wp-block-image img {
	transform: scale(1.05);
}
.st-rail__body {
	display: flex;
	flex-direction: column;
	flex: 1 1 auto;
	padding: 1.5rem;
}
.st-rail__card .st-use-cta {
	position: relative;
	z-index: 2;
}
/* Same stretched-heading-link contract as the decoration cards. */
.st-rail__card h3 a {
	text-decoration: none;
	color: inherit;
}
.st-rail__card h3 a::after {
	content: "";
	position: absolute;
	inset: 0;
	z-index: 1;
}
.st-rail__card:hover h3 a {
	text-decoration: underline;
	text-underline-offset: 3px;
}
.st-rail__card h3 a:focus-visible::after {
	outline: 2px solid var(--wp--preset--color--ti-fg);
	outline-offset: -3px;
}
/* Arrows are generated by assets/carousel.js, so they only appear when the
   rail actually overflows — a three-card rail on a wide screen shows none. */
.st-rail__nav {
	display: flex;
	justify-content: flex-end;
	gap: 0.5rem;
	margin-top: 0.75rem;
}
.st-rail__arrow {
	cursor: pointer;
	display: flex;
	align-items: center;
	justify-content: center;
	width: 2.5rem;
	height: 2.5rem;
	padding: 0;
	background: transparent;
	color: var(--wp--preset--color--ti-fg);
	border: 1px solid var(--wp--preset--color--ti-fg);
	border-radius: 2px;
	font-family: var(--wp--preset--font-family--space-mono);
	font-size: 1.25rem;
	line-height: 1;
	transition: background-color 0.2s ease, color 0.2s ease, opacity 0.2s ease;
}
.st-rail__arrow:hover {
	background: var(--wp--preset--color--ti-fg);
	color: var(--wp--preset--color--ti-fg-alt);
}
.st-rail__arrow[disabled] {
	opacity: 0.3;
	cursor: default;
}
.st-rail__arrow[disabled]:hover {
	background: transparent;
	color: var(--wp--preset--color--ti-fg);
}
.st-rail__arrow:focus-visible {
	outline: 2px solid var(--wp--preset--color--ti-fg);
	outline-offset: 3px;
}
@media (max-width: 1023px) {
	.st-rail {
		--st-rail-cols: 2;
	}
}
@media (max-width: 599px) {
	.st-rail {
		/* A sliver of the next card is the only affordance that reads as
		   "this scrolls" without an arrow to point at. */
		--st-rail-cols: 1.15;
	}
}
@media (prefers-reduced-motion: reduce) {
	.st-rail__track {
		scroll-behavior: auto;
	}
	.st-rail__card:hover > .wp-block-image img {
		transform: none;
	}
}

/* ── Shop Titan · Manifesto with images (pattern: st-manifesto-media) ───────
   Each promise links to the page that backs it up, so the section is a way
   into the site rather than a dead band of copy. Image and heading are one
   link; the section's own CTA sits below the three columns.                 */
.st-manifesto-media__col {
	position: relative;
}
.st-manifesto-media__col h3 a {
	text-decoration: none;
	color: inherit;
}
.st-manifesto-media__col h3 a::after {
	content: "";
	position: absolute;
	inset: 0;
}
.st-manifesto-media__col:hover h3 a {
	text-decoration: underline;
	text-underline-offset: 3px;
}
.st-manifesto-media__col h3 a:focus-visible::after {
	outline: 2px solid var(--wp--preset--color--ti-fg);
	outline-offset: 4px;
}
.st-manifesto-media__col:hover .st-manifesto-media__img img {
	transform: scale(1.05);
}
@media (prefers-reduced-motion: reduce) {
	.st-manifesto-media__col:hover .st-manifesto-media__img img {
		transform: none;
	}
}

/* ── Shop Titan · SEO content sections (pattern: st-seo-content) ────────────
   Hairline-separated long-form sections and a rule-framed pull quote.      */
.st-seo-card {
	padding-top: 3rem;
	padding-bottom: 3rem;
	border-bottom: 1px solid var(--wp--preset--color--ti-line);
}
.st-seo-card:first-child {
	padding-top: 0;
}
.st-seo-quote {
	max-width: 46rem;
	margin: 3rem auto 0;
	padding: 0 0 0 1.75rem;
	border-left: 3px solid var(--wp--preset--color--ti-fg);
}
.st-seo-quote cite {
	display: block;
	margin-top: 0.85rem;
	font-family: var(--wp--preset--font-family--space-mono);
	font-size: var(--wp--preset--font-size--small);
	font-style: normal;
	letter-spacing: 0.06em;
	text-transform: uppercase;
	color: var(--wp--preset--color--ti-accent-secondary);
}

/* Marquee strip — bold statement band, phrases divided by a middot. */
.st-marquee-strip .st-marquee__track {
	--st-marquee-speed: 80;
	row-gap: 0.5rem;
}
.st-marquee-strip .st-marquee__item {
	padding: 0 1.5rem;
	font-weight: 800;
	letter-spacing: -0.01em;
}
.st-marquee-strip .st-marquee__item::after {
	content: "\00B7"; /* · */
	margin-left: 3rem;
	opacity: 0.5;
}

/* ── Shop Titan · Media band panel (pattern: st-feature-media-full) ─────────
   The text panel centres its content inside whatever height the image half
   sets, so a short heading does not float at the top of a tall band.       */
.st-media-panel {
	display: flex;
	flex-direction: column;
	justify-content: center;
}

/* ── Shop Titan · Material lab (pattern: st-material-lab) ───────────────────
   Collapsed-border spec table: the wrapper draws the top and left rules,
   each card draws its own right and bottom, so the grid reads as one table
   however many columns it reflows to.                                      */
.st-mat-grid {
	border-top: 1px solid var(--wp--preset--color--ti-line);
	border-left: 1px solid var(--wp--preset--color--ti-line);
}
.st-mat-card {
	padding: 1.5rem;
	border-right: 1px solid var(--wp--preset--color--ti-line);
	border-bottom: 1px solid var(--wp--preset--color--ti-line);
}
.st-mat-spec {
	margin-bottom: 0.75rem;
	padding-bottom: 0.75rem;
	border-bottom: 1px dashed var(--wp--preset--color--ti-line);
	letter-spacing: 0.04em;
}
.st-aside-card {
	padding: 1.75rem 1.5rem;
}
.st-aside-note {
	margin-top: 1.25rem;
	padding-top: 0.9rem;
	border-top: 1px dashed var(--wp--preset--color--ti-accent-secondary);
	letter-spacing: 0.04em;
}

/* ── Shop Titan · Attribute chips (pattern: st-brand-story) ─────────────────
   Shares its look with the durability-proof method chips.                  */
.st-chip,
.st-method-chip {
	margin: 0;
	padding: 0.3rem 0.7rem;
	border: 1px solid var(--wp--preset--color--ti-line);
	letter-spacing: 0.04em;
}
.st-method-chip {
	border-color: var(--wp--preset--color--ti-accent-secondary);
}

/* ── Shop Titan · Decoration zones (pattern: st-decoration-zones) ───────────
   Ruled reference rows, plus a framed guidance note beneath them.          */
.st-zone {
	padding: 1.25rem 0;
	border-bottom: 1px solid var(--wp--preset--color--ti-line);
}
.st-zone:first-child {
	padding-top: 0;
}
.st-zone-spec {
	margin-top: 0.25rem;
	margin-bottom: 0.5rem;
	letter-spacing: 0.04em;
}
.st-zone-note {
	padding: 1.25rem 1.5rem;
	border-left: 3px solid var(--wp--preset--color--ti-fg);
	background: var(--wp--preset--color--ti-bg);
}

/* Collection story — attribute chips on a slow ticker. The chips already
   carry .st-chip, so only spacing and pace are set here. */
.st-attr-strip .st-marquee__track {
	--st-marquee-speed: 45;
	row-gap: 0.6rem;
}
.st-attr-strip .st-marquee__item {
	margin: 0 0.35rem;
}

/* ── Shop Titan · Decoration methods (pattern: st-decoration-methods) ───────
   Framed link cards. The CTA is pinned to the foot so cards with a one-line
   tagline and cards with three lines still align along the bottom.         */
.st-method-card {
	position: relative;
	display: flex;
	flex-direction: column;
	overflow: hidden;
	padding: 1.5rem;
	background: var(--wp--preset--color--ti-bg-alt);
	border: 1px solid var(--wp--preset--color--ti-line);
	transition: border-color 0.2s ease;
}
.st-method-card:hover {
	border-color: var(--wp--preset--color--ti-fg);
}

/* The whole card is the link. The heading anchor carries a stretched ::after
   so image, copy and whitespace all navigate, while the thing announced to a
   screen reader is still "Screen printing, link" rather than an unnamed box.
   The "Explore →" anchor is lifted above that overlay so it keeps its own
   hover state; both point at the same page, which is fine and is why the
   heading link is the one that stretches. */
.st-method-card h3 a {
	text-decoration: none;
	color: inherit;
}
.st-method-card h3 a::after {
	content: "";
	position: absolute;
	inset: 0;
	z-index: 1;
}
.st-method-card:hover h3 a {
	text-decoration: underline;
	text-underline-offset: 3px;
}
.st-method-card h3 a:focus-visible::after {
	outline: 2px solid var(--wp--preset--color--ti-fg);
	outline-offset: -3px;
}
.st-method-card .st-method-link {
	position: relative;
	z-index: 2;
}
.st-method-card.is-featured {
	border-top: 3px solid var(--wp--preset--color--ti-fg);
}
.st-method-link {
	margin-top: auto;
	padding-top: 1rem;
	letter-spacing: 0.04em;
}
.st-method-link a {
	text-decoration: none;
}
.st-method-link a:hover {
	text-decoration: underline;
}

/* ── Shop Titan · Print longevity (pattern: st-print-longevity) ─────────────
   A stamped guarantee seal drawn in CSS, so the wording inside stays real
   editable text rather than baked into an image.                           */
.st-seal {
	display: flex;
	flex-direction: column;
	justify-content: center;
	width: 15rem;
	height: 15rem;
	margin-inline: auto;
	padding: 1.5rem;
	border: 2px solid var(--wp--preset--color--ti-fg-alt);
	border-radius: 50%;
	box-shadow: 0 0 0 6px var(--wp--preset--color--ti-bg-inv), 0 0 0 7px var(--wp--preset--color--ti-accent-secondary);
}
.st-seal > * {
	margin: 0;
}
.st-seal__figure {
	line-height: 1;
	margin-block: 0.35rem;
}
.st-proof {
	padding-top: 1.1rem;
	border-top: 1px solid var(--wp--preset--color--ti-accent-secondary);
}
.st-proof__label {
	margin-bottom: 0.5rem;
	letter-spacing: 0.12em;
}

/* ── Shop Titan · Block carousel (pattern: st-hero-editorial) ───────────────
   Slides are ordinary blocks. assets/carousel.js adds .is-enhanced plus the
   arrows and dots once there are two or more; until then — no JS, one slide,
   or the editor canvas — they stay stacked full-bleed sections with nothing
   hidden. Enhanced, the slides share one grid cell so the carousel is as tall
   as its tallest slide without any absolute positioning.                    */
.st-carousel.is-enhanced {
	position: relative;
	display: grid;
}
.st-carousel.is-enhanced > .st-carousel__slide {
	grid-area: 1 / 1;
	opacity: 0;
	visibility: hidden;
	/* Delay the visibility flip until the fade finishes when hiding, so the
	   outgoing slide can still be seen on its way out — and drop out of the
	   tab order the moment it is gone. */
	transition: opacity 0.6s ease, visibility 0s linear 0.6s;
}
.st-carousel.is-enhanced > .st-carousel__slide.is-active {
	opacity: 1;
	visibility: visible;
	transition: opacity 0.6s ease, visibility 0s;
}
.st-carousel__nav {
	position: absolute;
	z-index: 2;
	left: 0;
	right: 0;
	bottom: 2rem;
	display: flex;
	align-items: center;
	justify-content: center;
	gap: 1.25rem;
}
.st-carousel__arrow,
.st-carousel__dot {
	cursor: pointer;
	background: transparent;
	color: var(--wp--preset--color--ti-fg-alt);
	border: 1px solid var(--wp--preset--color--ti-fg-alt);
	transition: background-color 0.2s ease, opacity 0.2s ease;
}
.st-carousel__arrow {
	display: flex;
	align-items: center;
	justify-content: center;
	width: 2.5rem;
	height: 2.5rem;
	padding: 0;
	font-family: var(--wp--preset--font-family--space-mono);
	font-size: 1.25rem;
	line-height: 1;
}
.st-carousel__arrow:hover,
.st-carousel__dot:hover {
	background: var(--wp--preset--color--ti-fg-alt);
	color: var(--wp--preset--color--ti-fg);
}
.st-carousel__dots {
	display: flex;
	align-items: center;
	gap: 0.5rem;
}
.st-carousel__dot {
	width: 0.75rem;
	height: 0.75rem;
	padding: 0;
	opacity: 0.6;
}
.st-carousel__dot.is-active {
	background: var(--wp--preset--color--ti-fg-alt);
	opacity: 1;
}
.st-carousel__arrow:focus-visible,
.st-carousel__dot:focus-visible {
	outline: 2px solid var(--wp--preset--color--ti-fg-alt);
	outline-offset: 3px;
}
@media (prefers-reduced-motion: reduce) {
	.st-carousel.is-enhanced > .st-carousel__slide {
		transition: none;
	}
}

/* Editorial hero — auto-advance in seconds. Set to 0 for manual only.
   Auto-advance is skipped anyway under prefers-reduced-motion, and pauses
   while the pointer or keyboard focus is inside the hero. */
.st-hero-carousel {
	--st-carousel-autoplay: 7;
}
.st-hero-carousel em {
	font-style: italic;
	color: var(--wp--preset--color--ti-line);
}

/* ── Shop Titan · Sticky showcase (pattern: st-sticky-showcase) ─────────────
   Each panel pins at the top and the next scrolls over it. Pure CSS — no
   scroll listener. The panels must stay opaque or they will show through
   each other, which is why every one carries an overlay.                   */
.st-sticky-panel {
	position: sticky;
	top: 0;
}
/* The last panel should release rather than pin under the following section. */
.st-sticky-showcase > .st-sticky-panel:last-child {
	position: relative;
}
@media (max-width: 781px) {
	.st-sticky-panel {
		position: relative;
	}
}

/* ── Shop Titan · Generic framed card ───────────────────────────────────────
   The plain version of the card treatment used across the patterns, for
   sections that need the frame without a pinned CTA or a ghost numeral.    */
.st-card {
	display: flex;
	flex-direction: column;
	height: 100%;
	padding: 1.5rem;
	background: var(--wp--preset--color--ti-bg-alt);
	border: 1px solid var(--wp--preset--color--ti-line);
}

/* ── Shop Titan · Branch connector (pattern: st-custom-merch) ───────────────
   Drawn on a Spacer block with gradients rather than three inline SVGs: one
   stem down from the headline, a bar across, and a descender into each of
   the three columns. Decorative — Spacer is already aria-hidden. Hidden once
   the columns stack, where it would point at nothing.                      */
@media (min-width: 782px) {
	.st-branch {
		background-image:
			linear-gradient(var(--wp--preset--color--ti-line), var(--wp--preset--color--ti-line)),
			linear-gradient(var(--wp--preset--color--ti-line), var(--wp--preset--color--ti-line)),
			linear-gradient(var(--wp--preset--color--ti-line), var(--wp--preset--color--ti-line)),
			linear-gradient(var(--wp--preset--color--ti-line), var(--wp--preset--color--ti-line)),
			linear-gradient(var(--wp--preset--color--ti-line), var(--wp--preset--color--ti-line));
		background-repeat: no-repeat;
		background-size:
			66.67% 1px,  /* bar across */
			1px 50%,     /* stem down from the headline */
			1px 50%,     /* descender, left column */
			1px 50%,     /* descender, middle column */
			1px 50%;     /* descender, right column */
		background-position:
			center 50%,
			center top,
			16.67% bottom,
			center bottom,
			83.33% bottom;
	}
}

/* ── Shop Titan · Category cards (pattern: st-hero-section) ─────────────────
   The label link is stretched over the whole card so the entire tile is the
   target, not just the few words of text.                                  */
/* A centred flex row rather than a grid: with `1fr` grid columns a row of
   five always stretches edge to edge, and a wrapped orphan sits hard left.
   Flex basis + justify-content keeps the row — and any wrapped remainder —
   centred under the hero copy at every width. */
/* Grid, not flex. As a wrapping flex row the last card on a short row grows to
   fill it — 11 categories at five up left "Bags" stretched across the full
   width, which read as a layout bug. auto-fill keeps every tile the same size
   and lets the orphan sit at one column. */
.st-cat-cards {
	display: grid !important;
	grid-template-columns: repeat(auto-fill, minmax(13rem, 1fr));
	gap: 1rem;
	max-width: 1360px;
	margin-inline: auto;
}
.st-cat-card {
	position: relative;
	flex: none;
	overflow: hidden;
}

/* Nothing washes over the photo at rest. Cover ships a flat 60% black dim
   (`has-background-dim-60` plus an inline background-color) which turned every
   tile grey; both are overridden here rather than in the page content, so a
   store cannot lose the fix by re-saving the page.
   No scrim either — these tiles are product shots on white, and a gradient
   dark enough to hold white text greys the bottom half of the garment, which
   is the same complaint one step quieter. The label gets its own chip instead:
   it reads on a white tee and on a black hoodie, and it covers only itself.
   Hover dims and pushes in on the image, which is where the affordance is. */
.st-cat-card .wp-block-cover__background {
	background-color: transparent !important;
	opacity: 1 !important;
	background-image: none;
}
.st-cat-card .wp-block-cover__image-background {
	transition: transform 0.6s cubic-bezier(0.2, 0.6, 0.2, 1), filter 0.3s ease;
}
.st-cat-card:hover .wp-block-cover__image-background,
.st-cat-card:focus-within .wp-block-cover__image-background {
	transform: scale(1.06);
	filter: brightness(0.88);
}
@media (prefers-reduced-motion: reduce) {
	.st-cat-card .wp-block-cover__image-background {
		transition: filter 0.3s ease;
	}
	.st-cat-card:hover .wp-block-cover__image-background,
	.st-cat-card:focus-within .wp-block-cover__image-background {
		transform: none;
	}
}
.st-cat-card__label {
	margin: 0;
}
/* The chip. inline-block so it hugs the words rather than banding the tile,
   and the ink colour is forced past the block's own has-ti-fg-alt-color —
   white text on a near-white chip was the previous version's failure mode. */
.st-cat-card__label a {
	display: inline-block;
	padding: 0.4rem 0.65rem;
	background: rgba(250, 250, 247, 0.94);
	color: var(--wp--preset--color--ti-fg);
	text-decoration: none;
}
.st-cat-card__label a::after {
	content: "";
	position: absolute;
	inset: 0;
}
.st-cat-card:hover .st-cat-card__label a {
	background: var(--wp--preset--color--ti-fg);
	color: var(--wp--preset--color--ti-fg-alt);
}
.st-cat-card__label a:focus-visible::after {
	outline: 2px solid var(--wp--preset--color--ti-fg);
	outline-offset: -4px;
}

/* ── Shop Titan · Scoped product loop (st-best-sellers, st-product-grid) ────
   The [products] shortcode renders woocommerce/content-product.php — the
   store's own card — which is Tailwind-classed. functions.php loads the
   .dtla-legacy-scope-prefixed copy of the legacy bundle on these pages, so
   the card styles itself without the unscoped bundle reaching Global Styles.
   Only the grid frame lives here; the card's own look comes from that sheet. */
.st-product-loop .products {
	margin: 0;
	padding: 0;
	list-style: none;
}
.st-product-loop .woocommerce-result-count,
.st-product-loop .woocommerce-ordering {
	display: none;
}

/* ── Shop Titan · Block tabs (pattern: st-best-sellers) ─────────────────────
   assets/tabs.js builds the strip from each panel's first heading and adds
   .is-enhanced. Until then every panel is visible with its heading, which is
   what the editor and a no-JS visitor see.                                  */
.st-tabs__list {
	display: flex;
	flex-wrap: wrap;
	justify-content: center;
	gap: 0.5rem;
	margin-bottom: 2rem;
}
.st-tabs__tab {
	cursor: pointer;
	padding: 0.6rem 1.25rem;
	font-family: var(--wp--preset--font-family--space-mono);
	font-size: var(--wp--preset--font-size--small);
	letter-spacing: 0.06em;
	text-transform: uppercase;
	color: var(--wp--preset--color--ti-fg);
	background: transparent;
	border: 1px solid var(--wp--preset--color--ti-line);
	transition: background-color 0.15s ease, color 0.15s ease;
}
.st-tabs__tab:hover {
	border-color: var(--wp--preset--color--ti-fg);
}
.st-tabs__tab.is-active {
	color: var(--wp--preset--color--ti-fg-alt);
	background: var(--wp--preset--color--ti-fg);
	border-color: var(--wp--preset--color--ti-fg);
}
.st-tabs__tab:focus-visible {
	outline: 2px solid var(--wp--preset--color--ti-fg);
	outline-offset: 3px;
}
.st-tabs.is-enhanced > .st-tabs__panel:focus {
	outline: none;
}

/* ── Shop Titan · Product track (pattern: st-best-sellers) ──────────────────
   The scrolling is CSS scroll-snap, so swipe works with no JS at all;
   assets/track.js only adds the arrows and dots. The .is-track class is added
   by that script, so the grid stays a plain grid when it does not run.      */
.st-track .products.is-track {
	display: flex;
	flex-wrap: nowrap;
	gap: 1rem;
	margin: 0;
	padding: 0 0 0.5rem;
	list-style: none;
	overflow-x: auto;
	scroll-snap-type: x mandatory;
	scrollbar-width: none;
}
.st-track .products.is-track::-webkit-scrollbar {
	display: none;
}
.st-track .products.is-track > li {
	flex: 0 0 calc((100% - 4rem) / 5);
	margin: 0;
	scroll-snap-align: start;
}
@media (max-width: 1023px) {
	.st-track .products.is-track > li {
		flex-basis: calc((100% - 2rem) / 3);
	}
}
@media (max-width: 781px) {
	.st-track .products.is-track > li {
		flex-basis: calc((100% - 1rem) / 2);
	}
}
@media (max-width: 559px) {
	.st-track .products.is-track > li {
		flex-basis: 78%;
	}
}
.st-track__nav {
	display: flex;
	align-items: center;
	justify-content: center;
	gap: 1.25rem;
	margin-top: 1.5rem;
}
.st-track__arrow,
.st-track__dot {
	cursor: pointer;
	background: transparent;
	color: var(--wp--preset--color--ti-fg);
	border: 1px solid var(--wp--preset--color--ti-line);
	transition: background-color 0.15s ease, opacity 0.15s ease;
}
.st-track__arrow {
	display: flex;
	align-items: center;
	justify-content: center;
	width: 2.5rem;
	height: 2.5rem;
	padding: 0;
	font-family: var(--wp--preset--font-family--space-mono);
	font-size: 1.25rem;
	line-height: 1;
}
.st-track__arrow:hover:not(:disabled),
.st-track__dot:hover {
	background: var(--wp--preset--color--ti-fg);
	color: var(--wp--preset--color--ti-fg-alt);
}
.st-track__arrow:disabled {
	opacity: 0.35;
	cursor: default;
}
.st-track__dots {
	display: flex;
	align-items: center;
	gap: 0.5rem;
}
.st-track__dot {
	width: 0.6rem;
	height: 0.6rem;
	padding: 0;
	border-radius: 50%;
}
.st-track__dot.is-active {
	background: var(--wp--preset--color--ti-fg);
	border-color: var(--wp--preset--color--ti-fg);
}
.st-track__arrow:focus-visible,
.st-track__dot:focus-visible {
	outline: 2px solid var(--wp--preset--color--ti-fg);
	outline-offset: 3px;
}
@media (prefers-reduced-motion: reduce) {
	.st-track .products.is-track {
		scroll-behavior: auto;
	}
}

/* ── Shop Titan · Category gallery (pattern: st-category-gallery) ───────────
   Title always readable; the supporting line is revealed on hover and on
   keyboard focus, so it is reachable without a pointer.                     */
.st-gallery-card__desc {
	margin-top: 0.35rem;
	max-height: 0;
	opacity: 0;
	overflow: hidden;
	transition: max-height 0.25s ease, opacity 0.25s ease;
}
.st-gallery-card:hover .st-gallery-card__desc,
.st-gallery-card:focus-within .st-gallery-card__desc {
	max-height: 6rem;
	opacity: 1;
}
.st-gallery-card h3 a {
	text-decoration: none;
}
.st-gallery-card h3 a::after {
	content: "";
	position: absolute;
	inset: 0;
}
.st-gallery-card {
	position: relative;
}
@media (prefers-reduced-motion: reduce) {
	.st-gallery-card__desc {
		transition: none;
	}
}

/* ── Shop Titan · Category hero media (pattern: st-category-hero) ───────────
   Product shots are usually transparent PNGs that should sit whole rather
   than fill the column, so cap the height and centre it.                   */
.st-cat-hero-media .wp-block-image {
	margin: 0;
	display: flex;
	justify-content: center;
}
.st-cat-hero-media .wp-block-image img {
	max-height: 26rem;
	width: auto;
	object-fit: contain;
}

/* ── Shop Titan · Newsletter form (pattern: st-newsletter) ──────────────────
   A real form, so it is a Custom HTML block rather than blocks — the field
   and button are styled here to match the theme.json button element.       */
.st-subscribe {
	display: flex;
	flex-wrap: wrap;
	gap: 0.75rem;
	max-width: 34rem;
	margin-inline: auto;
}
.st-subscribe__field {
	flex: 1 1 16rem;
	min-width: 0;
	padding: 0.85rem 1rem;
	font-family: var(--wp--preset--font-family--helvetica);
	font-size: var(--wp--preset--font-size--small);
	color: var(--wp--preset--color--ti-fg);
	background: var(--wp--preset--color--ti-bg-alt);
	border: 1px solid var(--wp--preset--color--ti-bg-alt);
	border-radius: 2px;
}
.st-subscribe__field:focus-visible {
	outline: 2px solid var(--wp--preset--color--ti-fg-alt);
	outline-offset: 2px;
}
.st-subscribe__submit {
	flex: 0 0 auto;
	cursor: pointer;
	padding: 0.85rem 1.5rem;
	font-family: var(--wp--preset--font-family--space-mono);
	font-size: var(--wp--preset--font-size--small);
	font-weight: 700;
	text-transform: uppercase;
	letter-spacing: 0.06em;
	color: var(--wp--preset--color--ti-fg);
	background: var(--wp--preset--color--ti-bg-alt);
	border: 1px solid var(--wp--preset--color--ti-bg-alt);
	border-radius: 2px;
}
.st-subscribe__submit:disabled {
	opacity: 0.6;
	cursor: wait;
}
.st-form__status {
	flex: 1 0 100%;
	margin: 0;
	min-height: 1.4em;
	font-family: var(--wp--preset--font-family--space-mono);
	font-size: var(--wp--preset--font-size--small);
	color: var(--wp--preset--color--ti-accent-secondary);
}
.st-form__status.is-success {
	color: var(--wp--preset--color--ti-fg-alt);
}
.st-form__status.is-error {
	color: var(--wp--preset--color--ti-line);
}
/* Honeypot — off-screen rather than display:none, so a bot that checks
   computed styles still fills it in. Never shown, never focusable. */
.st-form__hp {
	position: absolute;
	left: -9999px;
	width: 1px;
	height: 1px;
	opacity: 0;
	pointer-events: none;
}

/* ── Shop Titan · Coupon cards (pattern: st-flash-deals) ────────────────────
   Perforated ticket edge on the code, to read as a voucher stub.          */
.st-coupon {
	height: 100%;
	padding: 2rem 1.5rem;
	border: 1px solid var(--wp--preset--color--ti-accent-secondary);
}
.st-coupon__amount {
	margin-bottom: 0.5rem;
	font-weight: 800;
	letter-spacing: -0.02em;
}
.st-coupon__code {
	margin-top: 1.25rem;
	padding: 0.6rem 1rem;
	border: 1px dashed var(--wp--preset--color--ti-fg-alt);
	letter-spacing: 0.16em;
	text-transform: uppercase;
}

/* ── Shop Titan · Woo reviews (pattern: st-reviews) ─────────────────────────
   The All Reviews block ships its own layout; only the surrounding rules
   are set here so it sits in the theme's hairline idiom.                   */
.st-reviews .wc-block-review-list-item__item {
	padding: 1.5rem 0;
	border-bottom: 1px solid var(--wp--preset--color--ti-line);
}
.st-reviews .wc-block-review-list-item__product {
	font-family: var(--wp--preset--font-family--space-mono);
	font-size: var(--wp--preset--font-size--small);
}
.st-reviews .wc-block-review-list-item__author,
.st-reviews .wc-block-review-list-item__published-date {
	font-family: var(--wp--preset--font-family--space-mono);
	font-size: var(--wp--preset--font-size--small);
	color: var(--wp--preset--color--ti-accent-secondary);
}

/* ── Shop Titan · Assurance list (pattern: st-premium-services) ─────────────*/
.st-assurances {
	margin: 0;
	padding-left: 1.1rem;
}
.st-assurances li {
	margin-bottom: 0.5rem;
}

/* ── Shop Titan · Link list (pattern: st-link-list) ─────────────────────────
   Hairline-ruled rows with a trailing arrow, in place of bullets.           */
.st-link-list {
	list-style: none;
	margin: 0;
	padding: 0;
}
.st-link-list li {
	border-bottom: 1px solid var(--wp--preset--color--ti-line);
}
.st-link-list li:first-child {
	border-top: 1px solid var(--wp--preset--color--ti-line);
}
.st-link-list li a {
	display: flex;
	align-items: baseline;
	gap: 1rem;
	padding: 0.9rem 0;
	text-decoration: none;
}
.st-link-list li a::after {
	content: "\2192"; /* → */
	margin-left: auto;
	color: var(--wp--preset--color--ti-accent-secondary);
	transition: transform 0.2s ease;
}
.st-link-list li a:hover {
	text-decoration: underline;
}
.st-link-list li a:hover::after {
	transform: translateX(3px);
}

/* ── DTLA · Site header (block: neve-fse-child/dtla-header) ─────────────────
   Port of the hello-elementor-child header (parts/blocks/header/header.php).
   Structure and behaviour follow the original; the styling is rebuilt on
   theme.json presets rather than the old Tailwind bundle, which is gated to
   the ported cart/checkout/product pages — see inc/header.php for why.

   Layout is one grid whose columns swap at the tablet breakpoint:
     desktop  [wide logo] [nav] [actions]
     mobile   [burger] [square logo] [actions]  + nav as a slide-in panel     */

/* The sticky header does not work without this. neve-fse ships
   `body,html{height:100%}` and `.wp-site-blocks{display:flex;height:100%}`, so
   the sticky header's containing block is exactly ONE VIEWPORT tall no matter
   how long the page is. The bar pins correctly for the first (100vh - header)
   pixels and then scrolls away for good — which reads as "sticky is broken"
   rather than "the parent box ended", and no rule on the header itself can fix
   it. Measured 2026-08-09 on a 10380px home page: .wp-site-blocks computed to
   900px, and the header unstuck at 799px.
   min-height keeps neve-fse's short-page footer-at-the-bottom behaviour. */
html,
body {
	height: auto;
}
.wp-site-blocks {
	height: auto;
	min-height: 100vh;
}

/* Sticky has to be applied to the template-part wrapper, not just the cover:
   templates render this part as <header class="wp-block-template-part">, and a
   sticky element only travels within its own parent's box — which here is
   exactly the height of the header, so it would unstick immediately. */
.wp-block-template-part:has(> .dtla-header-cover) {
	position: sticky;
	top: 0;
	z-index: 110;
}
.dtla-header-cover {
	position: sticky;
	top: 0;
	z-index: 110;
	background: var(--wp--preset--color--ti-bg);
	transition: transform 0.35s ease-in-out;
	margin-left: calc(var(--wp--custom--spacing--outer)*-1) !important;
	margin-right: calc(var(--wp--custom--spacing--outer)*-1) !important;
	width: unset;
	border-bottom: 1px solid var(--wp--preset--color--ti-line);
}
.dtla-header-cover.is-stuck {
	box-shadow: 0 1px 0 var(--wp--preset--color--ti-line);
}
/* Scrolling down past the fold hides the bar; scrolling up brings it back. */
.dtla-header-cover.is-hidden {
	transform: translateY(-100%);
}

/* ── Admin bar ──────────────────────────────────────────────────────────────
   The admin bar is position:fixed across the top of the viewport, so anything
   pinned at top:0 ends up underneath it. Offsets are WordPress's own: 32px
   above 782px, 46px at or below it, and at 600px and under the bar stops being
   fixed and scrolls away with the page — so the offset goes back to 0.
   Both the wrapper and the cover are listed because whichever of the two is
   actually doing the sticking depends on :has() support; the inner one clamps
   to its container, so setting both is safe.                                 */
.admin-bar .wp-block-template-part:has(> .dtla-header-cover),
.admin-bar .dtla-header-cover {
	top: 32px;
}
@media screen and (max-width: 782px) {
	.admin-bar .wp-block-template-part:has(> .dtla-header-cover),
	.admin-bar .dtla-header-cover {
		top: 46px;
	}
}
@media screen and (max-width: 600px) {
	.admin-bar .wp-block-template-part:has(> .dtla-header-cover),
	.admin-bar .dtla-header-cover {
		top: 0;
	}
}

/* ── Announcement bar ───────────────────────────────────────────────────────*/
.dtla-topbar {
	background: var(--wp--preset--color--ti-bg-inv);
	color: var(--wp--preset--color--ti-fg-alt);
	padding: 0.55rem 1.5rem;
	text-align: center;
}
.dtla-topbar__text {
	margin: 0;
	font-family: var(--wp--preset--font-family--space-mono);
	font-size: 0.75rem;
	line-height: 1.4;
	letter-spacing: 0.04em;
}
.dtla-topbar__code {
	appearance: none;
	background: none;
	border: 0;
	padding: 0 0 0 0.35rem;
	font: inherit;
	font-weight: 700;
	color: inherit;
	text-decoration: underline;
	text-underline-offset: 2px;
	cursor: pointer;
}
.dtla-topbar__code.is-copied {
	text-decoration: none;
	opacity: 0.7;
}

/* ── Header row ─────────────────────────────────────────────────────────────*/
.dtla-header {
	display: grid;
	grid-template-columns: auto 1fr auto;
	align-items: center;
	gap: 2rem;
	max-width: 1400px;
	margin-inline: auto;
	padding: 0.9rem 1.5rem;	
}
.dtla-header__logo {
	display: flex;
	align-items: center;
	text-decoration: none;
}
.dtla-header__logo img {
	display: block;
	width: auto;
	height: 26px;
}
.dtla-header__logo--square,
.dtla-header__burger {
	display: none;
}
/* Shown when no logo is configured — see dtla_header_logo(). Sized to sit in
   the same slot as the image so the header height does not jump. */
.dtla-header__wordmark {
	font-family: var(--wp--preset--font-family--helvetica);
	font-size: 1.25rem;
	font-weight: 800;
	letter-spacing: -0.03em;
	line-height: 26px;
	white-space: nowrap;
	color: var(--wp--preset--color--ti-fg);
}

/* ── Navigation ─────────────────────────────────────────────────────────────*/
.dtla-header__nav-head {
	display: none;
}
.dtla-header__nav-list {
	display: flex;
	align-items: center;
	gap: 1.75rem;
	list-style: none;
	margin: 0;
	padding: 0;
}
.dtla-header__nav-item {
	position: relative;
}
.dtla-header__nav-item > a {
	display: inline-flex;
	align-items: center;
	gap: 0.35rem;
	font-family: var(--wp--preset--font-family--space-mono);
	font-size: var(--wp--preset--font-size--small);
	text-transform: uppercase;
	letter-spacing: 0.05em;
	text-decoration: none;
	white-space: nowrap;
}
.dtla-header__nav-item > a:hover {
	color: var(--wp--preset--color--ti-accent-secondary);
}
/* Chevron for items with children. A CSS caret rather than the icon font, so
   the submenu still reads correctly if icons-style.css ever stops loading.   */
.dtla-header__nav-toggle {
	appearance: none;
	background: none;
	border: 0;
	padding: 0.25rem;
	margin-left: 0.15rem;
	cursor: pointer;
	line-height: 0;
	color: inherit;
}
.dtla-header__nav-toggle::after {
	content: "";
	display: block;
	width: 6px;
	height: 6px;
	border-right: 1.5px solid currentColor;
	border-bottom: 1.5px solid currentColor;
	transform: translateY(-2px) rotate(45deg);
	transition: transform 0.2s ease;
}
.dtla-header__nav-item.is-open > .dtla-header__nav-toggle::after {
	transform: translateY(1px) rotate(225deg);
}
.dtla-header__submenu {
	list-style: none;
	margin: 0;
	padding: 0.6rem 0;
	min-width: 13rem;
}
.dtla-header__submenu a {
	display: block;
	padding: 0.45rem 1.1rem;
	font-size: var(--wp--preset--font-size--small);
	text-decoration: none;
	white-space: nowrap;
}
.dtla-header__submenu a:hover {
	background: var(--wp--preset--color--ti-bg-alt);
}

/* ── Actions ────────────────────────────────────────────────────────────────*/
.dtla-header__actions {
	display: flex;
	align-items: center;
	gap: 0.35rem;
}
.dtla-header__action {
	position: relative;
	display: inline-flex;
	align-items: center;
	gap: 0.4rem;
	appearance: none;
	background: none;
	border: 0;
	padding: 0.45rem 0.6rem;
	font-family: var(--wp--preset--font-family--space-mono);
	font-size: var(--wp--preset--font-size--small);
	color: inherit;
	text-decoration: none;
	white-space: nowrap;
	cursor: pointer;
	transition: color 0.2s ease;
}
.dtla-header__action:hover {
	color: var(--wp--preset--color--ti-accent-secondary);
}
.dtla-header__action [class*="icon-"] {
	font-size: 20px;
	line-height: 1;
}
.dtla-header__cart-count::before {
	content: "(";
}
.dtla-header__cart-count::after {
	content: ")";
}

/* ── Tablet and below ───────────────────────────────────────────────────────*/
@media (max-width: 1024px) {
	.dtla-header {
		gap: 0.75rem;
		padding: 0.7rem 1rem;
	}
	.dtla-header__logo--wide {
		display: none;
	}
	.dtla-header__logo--square {
		display: flex;
		justify-self: center;
	}
	.dtla-header__logo--square img {
		height: 40px;
	}

	/* Burger takes the first column; the nav leaves the grid entirely. */
	.dtla-header__burger {
		display: flex;
		flex-direction: column;
		justify-content: center;
		gap: 4.5px;
		appearance: none;
		background: none;
		border: 0;
		padding: 0.4rem;
		cursor: pointer;
		color: inherit;
	}
	.dtla-header__burger span {
		display: block;
		width: 20px;
		height: 1.5px;
		background: currentColor;
		transition: transform 0.2s ease, opacity 0.15s ease;
	}
	.dtla-header-cover.is-open .dtla-header__burger span:nth-child(1) {
		transform: translateY(6px) rotate(45deg);
	}
	.dtla-header-cover.is-open .dtla-header__burger span:nth-child(2) {
		opacity: 0;
	}
	.dtla-header-cover.is-open .dtla-header__burger span:nth-child(3) {
		transform: translateY(-6px) rotate(-45deg);
	}

	/* Slide-in panel. Off-canvas rather than display:none so it animates and so
	   the links stay focusable in source order.                               */
	.dtla-header__nav {
		position: fixed;
		top: 0;
		left: 0;
		bottom: 0;
		width: min(20rem, 85vw);
		z-index: 120;
		background: var(--wp--preset--color--ti-bg);
		border-right: 1px solid var(--wp--preset--color--ti-line);
		overflow-y: auto;
		transform: translateX(-100%);
		transition: transform 0.3s ease;
	}
	.dtla-header-cover.is-open .dtla-header__nav {
		transform: translateX(0);
	}
	/* The off-canvas panel is fixed too, so it needs the same clearance. */
	.admin-bar .dtla-header__nav {
		top: 32px;
	}
	@media screen and (max-width: 782px) {
		.admin-bar .dtla-header__nav {
			top: 46px;
		}
	}
	@media screen and (max-width: 600px) {
		.admin-bar .dtla-header__nav {
			top: 0;
		}
	}
	.dtla-header__nav-head {
		display: flex;
		align-items: center;
		justify-content: space-between;
		padding: 1rem 1.25rem;
		border-bottom: 1px solid var(--wp--preset--color--ti-line);
		font-family: var(--wp--preset--font-family--space-mono);
		font-size: var(--wp--preset--font-size--small);
		text-transform: uppercase;
		letter-spacing: 0.08em;
	}
	.dtla-header__nav-close {
		appearance: none;
		background: none;
		border: 0;
		padding: 0 0.25rem;
		font-size: 1.5rem;
		line-height: 1;
		cursor: pointer;
		color: inherit;
	}
	.dtla-header__nav-list {
		flex-direction: column;
		align-items: stretch;
		gap: 0;
		padding: 0.5rem 0;
	}
	.dtla-header__nav-item {
		display: flex;
		flex-wrap: wrap;
		align-items: center;
	}
	.dtla-header__nav-item > a {
		flex: 1;
		padding: 0.75rem 1.25rem;
	}
	.dtla-header__nav-toggle {
		padding: 0.75rem 1.25rem;
	}
	.dtla-header__submenu {
		flex: 1 0 100%;
		padding: 0 0 0.5rem 1.25rem;
	}

	.dtla-header__overlay {
		position: fixed;
		inset: 0;
		z-index: 115;
		background: rgba(10, 10, 10, 0.45);
	}
	.dtla-no-scroll,
	.dtla-no-scroll body {
		overflow: hidden;
	}

	/* Labels give way to icons; the cart count keeps its parentheses. */
	.dtla-header__action-label {
		position: absolute;
		width: 1px;
		height: 1px;
		margin: -1px;
		padding: 0;
		overflow: hidden;
		clip-path: inset(50%);
		white-space: nowrap;
	}
	.dtla-header__action [class*="icon-"] {
		font-size: 22px;
	}
}

@media (max-width: 600px) {
	.dtla-header__logo--square img {
		height: 34px;
	}
	.dtla-header__actions {
		gap: 0;
	}
	.dtla-header__action {
		padding: 0.45rem 0.4rem;
	}
}

/* ── Desktop submenu ────────────────────────────────────────────────────────
   Above the tablet breakpoint the submenu is a hover/focus dropdown. Kept out
   of the block above so the mobile panel is not fighting absolute positioning.*/
@media (min-width: 1025px) {
	.dtla-header__submenu {
		position: absolute;
		top: 100%;
		left: -1.1rem;
		background: var(--wp--preset--color--ti-bg);
		border: 1px solid var(--wp--preset--color--ti-line);
		opacity: 0;
		visibility: hidden;
		transform: translateY(4px);
		transition: opacity 0.18s ease, transform 0.18s ease, visibility 0.18s;
	}
	.dtla-header__nav-item:hover > .dtla-header__submenu,
	.dtla-header__nav-item:focus-within > .dtla-header__submenu,
	.dtla-header__nav-item.is-open > .dtla-header__submenu {
		opacity: 1;
		visibility: visible;
		transform: translateY(0);
	}
}

/* ── Lazily-loaded legacy popups ────────────────────────────────────────────
   assets/header.js drops the ported contact / search popups into this
   container along with build/css/*.scoped.css, whose selectors are all
   confined to it (tasks/scope-legacy-css.mjs).                               */
.dtla-legacy-scope .popups.hidden {
	display: none;
}

/* The container must generate NO box.
   tasks/scope-legacy-css.mjs rewrites the old theme's `body` / `html` / `:root`
   rules onto .dtla-legacy-scope so body-anchored popup rules keep working. That
   also hands this wrapper <div> body's own background and min-height — which
   rendered as a full viewport of painted empty space at the bottom of every
   page. `display: contents` keeps the scope and the custom properties (both
   inherit fine) while removing the box entirely. The popups and the mega menu
   cover are position:fixed, so they are unaffected by having no parent box.
   !important because the generated sheet is injected after style.css and its
   :not() selectors out-specify a bare class. */
.dtla-legacy-scope {
	display: contents !important;
}

/* ── DTLA · Product archive — room, hierarchy and polish ────────────────────
   ⚠️ The archive MARKUP is Diego's: inc/woocommerce/archive.php builds the
   shell, woocommerce/content-product.php builds the card, and
   src/scss/woocommerce/archive.scss + src/scss/kit/cards/product.scss size
   both. Nothing here edits any of those files. This block re-sizes and
   re-orders from our own stylesheet, so his layer stays the single source of
   the DOM and deleting this block restores his design exactly.

   ── WHY EVERY SELECTOR CARRIES `body#dtla_body_id.dtla__body` ──
   Both of his stylesheets are nested under `#dtla_body_id.dtla__body`, which
   `body_class` and the `wp_body_open` script put on the <body> of a product
   archive (functions.php:652 and :680). An id cannot be out-ranked by any
   number of classes, so the first version of this block — plain class
   selectors — lost every layout declaration silently and only its hover
   states survived. These rules repeat his anchor and add the `body` element
   on top: (1,3,1) against his (1,3,0). Won on specificity, not on
   !important and not on load order, so it stays legible in devtools.

   What it overrides, so it can be found and undone:
     archive.scss:70        ul.products             grid-template-columns
     archive.scss:89        .has-filter-widget      grid-template-columns 20% 1fr
     container-width.scss:2 :root                   --container-max-width
     product.scss:10        .dtla_product           flex order of the card
     product.scss:110       .size-woocommerce_thumbnail / .kover2  fit + ratio

   Measured before (1512px viewport, /custom/t-shirts/): content 1337,
   sidebar 267, loop 1046, card 246, product image 244x291. On a blanks
   catalog the photograph IS the product, and 246px of it was not selling. */

/* A 20% sidebar is 267px of a 1337px row. The widget inside it is a handful
   of checkboxes at any width — it does not need a fifth of the page, and
   every pixel it gives back goes into the photograph. */
@media (min-width: 1024px) {
	body#dtla_body_id.dtla__body .dtla-shop-archive__content.has-filter-widget {
		grid-template-columns: 210px minmax(0, 1fr);
		column-gap: 2.5rem;
	}
}

/* Above 1600px the 1548 cap leaves the catalog floating in margin. The var is
   declared on :root, so setting it on <body> re-inherits into `.container`
   without touching the rule that reads it. */
@media (min-width: 1600px) {
	body#dtla_body_id.dtla__body.post-type-archive-product,
	body#dtla_body_id.dtla__body.tax-product_cat,
	body#dtla_body_id.dtla__body.tax-product_tag {
		--container-max-width: 1680px;
	}
}

/* Cards get WIDER, not more numerous. Four across is the right density for a
   garment judged by eye; auto-fill would have spent the new width on a fifth
   column and handed the gain straight back. */
@media (min-width: 1280px) {
	body#dtla_body_id.dtla__body .dtla-shop-archive__loop-shell ul.products {
		gap: 1.75rem 1.5rem;
	}
}

/* ── The image well ──────────────────────────────────────────────────────
   His card crops to `object-fit: cover` at 0.84/1. On flat garment shots
   photographed on white that quietly clips sleeves and hems, and it clipped
   them differently on every product because the source crops are not
   consistent. `contain` inside a fixed 4/5 well cannot crop a garment, and
   the letterboxing is invisible because the well is the same white the
   photographs were shot on. The padding is what makes it read as a catalog
   plate rather than a thumbnail. */
body#dtla_body_id.dtla__body .dtla-shop-archive__loop-shell li.product .product_thumbnail_wrapper__container {
	width: 100%;
	background: #fff;
}
body#dtla_body_id.dtla__body .dtla-shop-archive__loop-shell li.product .product_thumbnail_wrapper__container img,
body#dtla_body_id.dtla__body .dtla-shop-archive__loop-shell li.product .kover2 {
	width: 100%;
	max-height: none;
	aspect-ratio: 1 / 1;
	object-fit: contain;
	padding: 6%;
}

/* .kover1 is the alternate shot that fades in on hover. It is absolutely
   positioned, so it has to track the well it sits in rather than carry its
   own 1/1.3 ratio, or the two images swap at different sizes. */
body#dtla_body_id.dtla__body .dtla-shop-archive__loop-shell li.product .kover1 {
	aspect-ratio: auto;
	transition: opacity 0.45s ease;
}

/* ── Reading order ───────────────────────────────────────────────────────
   The card renders swatches, then "SKU: 5001", then the product name. That is
   the order the WooCommerce hooks fire in (inc/woocommerce/product.php:137
   and :146 both hang off woocommerce_shop_loop_item_title, at priorities 6
   and 7, ahead of the title at 10) — it is inventory order, not shopping
   order, and it buried the name of the product under a part number.

   `order` on the flex children fixes the presentation without touching a
   hook or a template. Name first, then the style number as a quiet caption,
   then colors, then price on the baseline. Only one element in the card is
   focusable, so tab order is unaffected by this. */
body#dtla_body_id.dtla__body .dtla-shop-archive__loop-shell li.product > a.woocommerce-loop-product__link {
	order: 1;
}
body#dtla_body_id.dtla__body .dtla-shop-archive__loop-shell li.product > .woocommerce-loop-product__title {
	order: 2;
}
body#dtla_body_id.dtla__body .dtla-shop-archive__loop-shell li.product > .dtla-meta-box {
	order: 3;
}
body#dtla_body_id.dtla__body .dtla-shop-archive__loop-shell li.product > .dtla-color-box {
	order: 4;
}
body#dtla_body_id.dtla__body .dtla-shop-archive__loop-shell li.product > .price {
	order: 5;
}
body#dtla_body_id.dtla__body .dtla-shop-archive__loop-shell li.product > .add_to_cart_button,
body#dtla_body_id.dtla__body .dtla-shop-archive__loop-shell li.product > .added_to_cart {
	order: 6;
}

/* ── Type hierarchy ──────────────────────────────────────────────────────
   Name, style number and price all rendered at 14px, so nothing led. */
body#dtla_body_id.dtla__body .dtla-shop-archive__loop-shell li.product .woocommerce-loop-product__title {
	margin: 1.1rem 0 0.15rem;
	font-size: 0.95rem;
	font-weight: 500;
	line-height: 1.4;
	min-height: 2.8em;
	color: #181f30;
}

/* The style number is how a buyer who already knows AS Colour searches, so it
   stays on the card — as a caption, in the mono face the rest of the site
   uses for specs, not as the first thing they read. */
body#dtla_body_id.dtla__body .dtla-shop-archive__loop-shell li.product .dtla-meta-box {
	margin: 0 0 0.75rem;
}
body#dtla_body_id.dtla__body .dtla-shop-archive__loop-shell li.product .dtla-sku-box {
	font-family: var(--wp--preset--font-family--space-mono, ui-monospace, monospace);
	font-size: 0.68rem;
	letter-spacing: 0.08em;
	line-height: 1.2;
	color: #8f8d85;
}

/* Price is the second thing a buyer looks for and it was set at the weight of
   body copy. */
body#dtla_body_id.dtla__body .dtla-shop-archive__loop-shell li.product .price > span {
	font-size: 1rem;
	font-weight: 700;
	line-height: 1.3;
}

/* Swatches: 24px circles with a 2px ring wrapped to a second row on any
   product carrying more than about eight colors, which made the price sit at
   a different height on every card in the row. Smaller circles fit the common
   case on one line; the row is capped so a 20-color style cannot push the
   price out of alignment, and the "+N" the card already prints is what tells
   the buyer there is more. */
body#dtla_body_id.dtla__body .dtla-shop-archive__loop-shell li.product .dtla-color-box {
	margin: 0 0 1rem;
	gap: 0.15rem;
	max-height: 1.5rem;
	overflow: hidden;
}
body#dtla_body_id.dtla__body .dtla-shop-archive__loop-shell li.product .dtla-color-box .kcolor_box__wrapper {
	width: 1.25rem;
	height: 1.25rem;
}

/* ── Card behaviour ──────────────────────────────────────────────────────
   Lift the card and push into the photograph. `transition: all` is already on
   li.product from the legacy bundle, so only the new properties are stated. */
body#dtla_body_id.dtla__body .dtla-shop-archive__loop-shell li.product {
	overflow: hidden;
	transition: transform 0.28s ease, box-shadow 0.28s ease;
}
body#dtla_body_id.dtla__body .dtla-shop-archive__loop-shell li.product:hover {
	transform: translateY(-4px);
	box-shadow: 0 16px 34px -20px rgba(10, 10, 10, 0.5);
}
body#dtla_body_id.dtla__body .dtla-shop-archive__loop-shell li.product .product_thumbnail_wrapper {
	overflow: hidden;
}
body#dtla_body_id.dtla__body .dtla-shop-archive__loop-shell li.product .product_thumbnail_wrapper__container img {
	transition: transform 0.6s cubic-bezier(0.2, 0.6, 0.2, 1);
}
body#dtla_body_id.dtla__body .dtla-shop-archive__loop-shell li.product:hover .product_thumbnail_wrapper__container img {
	transform: scale(1.04);
}

/* The card's one focusable element is the image link, and its focus ring was
   being clipped by the overflow:hidden above. Put a visible ring on the card
   itself instead — WCAG 2.4.11, and it is the only way to see where you are
   tabbing through a 4-across grid. */
body#dtla_body_id.dtla__body .dtla-shop-archive__loop-shell li.product:focus-within {
	outline: 2px solid #181f30;
	outline-offset: 3px;
}

@media (prefers-reduced-motion: reduce) {
	body#dtla_body_id.dtla__body .dtla-shop-archive__loop-shell li.product,
	body#dtla_body_id.dtla__body .dtla-shop-archive__loop-shell li.product .product_thumbnail_wrapper__container img,
	body#dtla_body_id.dtla__body .dtla-shop-archive__loop-shell li.product .kover1 {
		transition: none;
	}
	body#dtla_body_id.dtla__body .dtla-shop-archive__loop-shell li.product:hover {
		transform: none;
	}
	body#dtla_body_id.dtla__body .dtla-shop-archive__loop-shell li.product:hover .product_thumbnail_wrapper__container img {
		transform: none;
	}
}

/* ── Catalog grid variations — the rules WordPress cannot carry ─────────────
   The six looks live in styles/catalog-*.json as block style variations, and
   each is a `styles.css` string that WP re-emits scoped to the block instance
   (`:root :where(.wp-block-woocommerce-product-collection.is-style-catalog-
   editorial--1 …)`).

   ⚠️ That processor only understands FLAT, SINGLE-SELECTOR rules. Two things
   it does silently, both caught in the generated CSS on /grid-styles/:

     @media(…){ & .a{…} }   the @media wrapper is DROPPED and the rules inside
                            are emitted UNCONDITIONALLY. A prefers-reduced-
                            motion block therefore disables the animation for
                            everybody — the exact inverse of its purpose, and
                            invisible unless you read the generated CSS.
     & .a,& .b{…}           mangled to `:root :where(scope){.a,}` — garbage,
                            and it takes the following rule down with it.

   So anything conditional belongs here instead. `:root :where(…)` scores
   (0,1,0), so a two-class selector out-specifies it; the !important is only
   needed because the variation declarations carry !important themselves. */

/* One focusable card in a grid of four is impossible to track without a ring. */
.st-catalog-grid .wc-block-product-template > li:focus-within {
	outline: 2px solid var(--wp--preset--color--ti-fg, #0a0a0a);
	outline-offset: 3px;
}

@media (prefers-reduced-motion: reduce) {
	.st-catalog-grid .wc-block-product-template > li,
	.st-catalog-grid .wc-block-components-product-image,
	.st-catalog-grid .wc-block-components-product-image img,
	.st-catalog-grid .wc-block-components-product-button .wp-block-button__link,
	.st-catalog-grid .st-catalog-grid__btn,
	.st-catalog-grid .wp-block-post-title a {
		transition: none !important;
	}
	.st-catalog-grid .wc-block-product-template > li:hover {
		transform: none !important;
	}
	.st-catalog-grid .wc-block-product-template > li:hover .wc-block-components-product-image img {
		transform: none !important;
	}
}

/* A coarse pointer never fires :hover, so any state parked behind it is
   unreachable on a phone. Nothing here is load-bearing — the hover states are
   emphasis, not information — but the image must not sit mid-zoom. */
@media (hover: none) {
	.st-catalog-grid .wc-block-product-template > li:hover {
		transform: none !important;
	}
	.st-catalog-grid .wc-block-product-template > li:hover .wc-block-components-product-image img {
		transform: none !important;
	}
}

/* ── Category archives: the WooCommerce header block ────────────────────────
   `<header class="woocommerce-products-header">` carries the H1 and, on page 1
   of a term archive, `.term-description` — WooCommerce's own output, rendered
   above the loop. Nothing in either stylesheet styled it, so ~1,600 characters
   of prose landed at the full container width in the default face, and the
   products started below it.

   Half of that was fixed as data: the seven-method list and the closing
   promise were byte-identical across all 11 category descriptions, so they
   moved into templates/taxonomy-product_cat.html and now render once, below
   the loop. Each description is roughly half the length and entirely unique
   to its category.

   The rest is measure. Prose set across 1,680px is unreadable regardless of
   how good it is. */
.woocommerce-products-header {
	margin-bottom: 2rem;
}

.woocommerce-products-header .term-description {
	max-width: 68ch;
	margin-top: 0.9rem;
	font-size: 0.95rem;
	line-height: 1.65;
	color: var(--wp--preset--color--ti-accent-secondary, #55554f);
}

/* WooCommerce runs the description through wpautop, which turns the single
   blank-line breaks into one <p> full of <br>. Paragraphs therefore have to be
   spaced off the line break rather than off a margin that is not there. */
.woocommerce-products-header .term-description p {
	margin: 0 0 0.9rem;
}
.woocommerce-products-header .term-description p:last-child {
	margin-bottom: 0;
}
.woocommerce-products-header .term-description br {
	content: "";
	display: block;
	height: 0.9rem;
}

.woocommerce-products-header .term-description a {
	color: inherit;
	text-decoration: underline;
	text-underline-offset: 0.2em;
}
.woocommerce-products-header .term-description a:hover {
	color: var(--wp--preset--color--ti-fg, #0a0a0a);
}


/* ── Archive width: the padding stacks twice ────────────────────────────────
   Measured at 1512px on /custom/t-shirts/: 1497 viewport, and the products
   row was 1087 of it. The chain that ate the difference is

     .wp-site-blocks   48px each side   (parent theme root gutter)
     main.container    32px each side   (this theme's own gutter)

   which is 160px of horizontal padding before a single product is drawn, for
   one gutter's worth of visual effect. Handing the sidebar 57px back bought
   the card only 5px because of it.

   ⚠️ Do NOT fix this by shrinking `.wp-site-blocks` padding. Every full-bleed
   element on the page derives its negative margin from that value
   (`_global.scss:278` computes `calc(((100vw - var(--container-max-width)) / -2)
   - var(--container-padding-x))`). Dropping it 48 → 16 pushed `.dtla-header-cover`,
   `.dtla-topbar` and every alignfull group 32px past the viewport on both
   sides and put a horizontal scrollbar on the page. Measured, not guessed.

   Pull the grid out instead. Only this one section moves, the full-bleed maths
   everywhere else is untouched, and the page keeps a 32px gutter. */
@media (min-width: 1024px) {
	body#dtla_body_id.dtla__body .prod-archive-grid.dtla-shop-archive {
		margin-left: -32px;
		margin-right: -32px;
	}
}

/* ── The category description was the whole first screen ────────────────────
   At 1512 the description ran 301px tall in a 575px column with the entire
   right half of the page empty beside it, and the first row of products
   started below 640px. Two columns use the dead space and halve the height,
   which is the difference between seeing one row of products on open and
   seeing none. Single column below 1024 where there is no space to give. */
@media (min-width: 1024px) {
	.woocommerce-products-header .term-description {
		max-width: 1180px;
		column-count: 2;
		column-gap: 3.5rem;
	}
	.woocommerce-products-header .term-description p {
		margin-top: 0;
	}
}
