/* =========================================================
   TomatoCat Shop — the only stylesheet the front end loads.
   Forked from TomatoCat Blog; the design tokens below are the
   whole palette, so recolouring the site happens here and in
   the Customizer rather than scattered through the rules.
   ========================================================= */

:root {
	--tc-tomato: #e0503c;
	--tc-tomato-dark: #b93b2a;
	--tc-ink: #1c1b1a;
	--tc-ink-soft: #5a5754;
	--tc-line: #e7e3df;
	--tc-surface: #fff;
	--tc-surface-alt: #faf7f4;

	--tc-accent: var(--tc-tomato);
	--tc-accent-hover: var(--tc-tomato-dark);
	--tc-text: var(--tc-ink);
	--tc-text-muted: var(--tc-ink-soft);
	--tc-bg: var(--tc-surface);
	--tc-bg-alt: var(--tc-surface-alt);
	--tc-border: var(--tc-line);

	--tc-font-body: "Prompt", -apple-system, BlinkMacSystemFont, "Segoe UI", "Noto Sans Thai", "Sarabun", sans-serif;
	--tc-font-heading: var(--tc-font-body);

	/*
	 * Everything from here to --tc-link-line is rewritten by the Customizer's
	 * inline block when the Typography panel has been touched. These are the
	 * shipped values, and they are what the site uses until it is — so the
	 * stylesheet on its own is still a complete design, and a site with the
	 * inline block stripped by a caching plugin degrades to this rather than to
	 * the browser's defaults.
	 */
	--tc-font-h1: var(--tc-font-heading);
	--tc-font-h2: var(--tc-font-heading);
	--tc-font-h3: var(--tc-font-heading);
	--tc-font-h4: var(--tc-font-heading);
	--tc-font-h5: var(--tc-font-heading);
	--tc-fw-h1: 600;
	--tc-fw-h2: 600;
	--tc-fw-h3: 600;
	--tc-fw-h4: 600;
	--tc-fw-h5: 600;
	--tc-font-link: inherit;
	--tc-fw-link: inherit;
	--tc-link-line: underline;

	/* Article text is bigger than a business site's. People read here. */
	--tc-fs-base: 1.0625rem;
	--tc-fs-h1: clamp(1.85rem, 1.3rem + 2.2vw, 2.9rem);
	--tc-fs-h2: clamp(1.4rem, 1.15rem + 1vw, 1.9rem);
	--tc-fs-h3: clamp(1.2rem, 1.1rem + 0.4vw, 1.4rem);
	--tc-fs-h4: clamp(1.0625rem, 1rem + 0.3vw, 1.2rem);
	--tc-fs-h5: clamp(1rem, 0.97rem + 0.15vw, 1.0625rem);
	/* Thai stacks vowels and tone marks above and below the line, so it wants
	   more room between lines than English does at the same size. */
	--tc-lh-body: 1.85;
	--tc-lh-heading: 1.25;

	/* Both are overwritten by the Customizer's inline block; these are the
	   shipped defaults. */
	--tc-container: 1520px;
	--tc-read: 860px;
	--tc-sidebar: 300px;
	--tc-gutter: clamp(1rem, 4vw, 2.25rem);
	--tc-space-sm: 0.75rem;
	--tc-space-md: 1.5rem;
	--tc-space-lg: 3rem;
	--tc-space-xl: clamp(2.5rem, 7vw, 5rem);

	/* Picked from the two the Customizer writes, so everything downstream —
	   the logo itself and the bar's minimum height — follows one name. */
	--tc-logo-height: var(--tc-logo-d, 40px);
	--tc-radius: 10px;
	/* The Customizer writes --tc-header-set; the max() is a floor, because the
	   anchor offsets and the sticky sidebar both key off the height, and a 72px
	   logo in a bar declared 64px tall puts every in-article anchor a centimetre
	   underneath the menu. */
	--tc-header-set: 99px;
	--tc-header-h: max(var(--tc-header-set), calc(var(--tc-logo-height) + 26px));
}

/* ---------- Reset ---------- */

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

html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }

/*
 * clip, not hidden.
 *
 * Both stop a stray wide element dragging the page sideways, but `hidden` turns
 * the body into a scroll container, and the moment it is one every
 * `position: sticky` inside it — the menu, the sidebar — sticks to the body
 * instead of the screen and silently stops working. `clip` refuses the overflow
 * without creating that container.
 *
 * It is a guard, not a diagnosis: something on the page is still wider than the
 * screen, and this only stops the reader feeling it.
 */
body { overflow-x: clip; }

.tc-main { flex: 1 0 auto; }
.tc-footer { flex-shrink: 0; }

/*
 * The admin bar is 32px of chrome WordPress adds above the document, so a body
 * asking for the whole window height ends up 32px taller than the window and
 * gives a logged-in editor a strip of empty page below the footer that no
 * reader ever sees. It is 46px on a narrow screen, where it wraps.
 */
body.admin-bar { min-height: calc(100svh - 32px); }

@media screen and (max-width: 782px) {
	body.admin-bar { min-height: calc(100svh - 46px); }
}
/* Anchors from the contents list must not land under the sticky header. */
:target { scroll-margin-top: calc(var(--tc-header-h) + 1rem); }

/*
 * A column, so the footer is pushed to the bottom of the window on a page with
 * too little in it to reach there — a 404, an empty search, a one-paragraph
 * page. Without it the footer simply stops where the content does and leaves
 * the window's own background showing underneath, which reads as the page
 * having failed to finish loading.
 */
body {
	display: flex;
	flex-direction: column;
	min-height: 100vh;
	min-height: 100svh;
	margin: 0;
	background: var(--tc-bg);
	color: var(--tc-text);
	font-family: var(--tc-font-body);
	font-size: var(--tc-fs-base);
	line-height: var(--tc-lh-body);
	-webkit-font-smoothing: antialiased;
}

img, picture, video, iframe { max-width: 100%; }
img { height: auto; display: block; }

a { color: var(--tc-accent); text-decoration-thickness: 1px; text-underline-offset: 3px; }
a:hover { color: var(--tc-accent-hover); }

h1, h2, h3, h4, h5 {
	font-family: var(--tc-font-heading);
	line-height: var(--tc-lh-heading);
	font-weight: 600;
	margin: 0 0 var(--tc-space-sm);
	overflow-wrap: break-word;
}

/* One rule per level, after the group and at the same weight of specificity,
   so a level that has been given a font of its own takes it and the rest keep
   falling through to the heading font. */
h1 { font-family: var(--tc-font-h1); font-weight: var(--tc-fw-h1); }
h2 { font-family: var(--tc-font-h2); font-weight: var(--tc-fw-h2); }
h3 { font-family: var(--tc-font-h3); font-weight: var(--tc-fw-h3); }
h4 { font-family: var(--tc-font-h4); font-weight: var(--tc-fw-h4); }
h5 { font-family: var(--tc-font-h5); font-weight: var(--tc-fw-h5); }

p, ul, ol, blockquote, figure, table { margin: 0 0 var(--tc-space-md); }

:focus-visible { outline: 2px solid var(--tc-accent); outline-offset: 3px; }

.screen-reader-text {
	position: absolute !important; width: 1px; height: 1px;
	padding: 0; margin: -1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap;
}

.tc-skip {
	position: absolute; left: -9999px; top: 0; z-index: 999;
	background: var(--tc-ink); color: #fff; padding: .75rem 1.25rem;
}
.tc-skip:focus { left: 0; }

/* ---------- Layout ---------- */

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

.tc-main { display: block; min-height: 50vh; padding-block: var(--tc-space-lg) var(--tc-space-xl); }

.tc-layout { display: block; }
.tc-layout__main { min-width: 0; }
.tc-layout__main--narrow { max-width: var(--tc-read); margin-inline: auto; }
.tc-layout__aside { margin-top: var(--tc-space-xl); }

@media (min-width: 1024px) {
	.tc-layout--aside {
		display: grid;
		grid-template-columns: minmax(0, 1fr) var(--tc-sidebar);
		gap: var(--tc-space-xl);
		align-items: start;
	}
	.tc-layout--aside .tc-layout__aside { margin-top: 0; }
	.tc-sticky { position: sticky; top: calc(var(--tc-header-h) + 1rem); }
}

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

.tc-header {
	position: relative;
	z-index: 50;
	background: color-mix(in srgb, var(--tc-surface) 88%, transparent);
	backdrop-filter: saturate(150%) blur(10px);
	border-bottom: 1px solid var(--tc-border);
}

/*
 * Sticky is answered once per screen size, not once for the site. The shadow
 * waits for the page to actually move — printed from the start it would draw a
 * second line under a header that already sits on its own border.
 */
@media (min-width: 900px) {
	.tc-header--sticky { position: sticky; top: 0; }
	.tc-header--sticky.is-scrolled:not(.tc-header--over) { box-shadow: 0 1px 16px rgba(28, 27, 26, .09); }
}

@media (max-width: 899px) {
	:root { --tc-logo-height: var(--tc-logo-m, 32px); }

	.tc-header--sticky-m { position: sticky; top: 0; }
	.tc-header--sticky-m.is-scrolled:not(.tc-header--over) { box-shadow: 0 1px 16px rgba(28, 27, 26, .09); }
}

/*
 * Both logos are in the page from the start and one is hidden. Swapping a src
 * on scroll would leave a hole where the logo was while the second file
 * downloaded, at the exact moment the reader is looking at the bar.
 */
.tc-logo--stuck { display: none; }
.is-scrolled .tc-logo--main { display: none; }
.is-scrolled .tc-logo--stuck { display: block; }

/*
 * Three columns rather than a flex row, so the menu is centred on the page and
 * not on the space left over. With flex it would drift sideways every time the
 * logo or the button changed width — which is exactly when nobody is looking at
 * the other end of the bar.
 */
.tc-header__inner {
	display: grid;
	grid-template-columns: auto minmax(0, 1fr) auto;
	align-items: center;
	gap: var(--tc-space-md);
	min-height: var(--tc-header-h);
}

.tc-brand { grid-column: 1; min-width: 0; }
.tc-brand__link { display: block; text-decoration: none; color: inherit; }
.tc-brand__name { display: block; font-weight: 700; font-size: 1.15rem; line-height: 1.2; }
.tc-brand__tag { display: block; font-size: .75rem; color: var(--tc-text-muted); line-height: 1.4; }

/*
 * object-fit is the guarantee here, not decoration.
 *
 * The logo carries a fixed height, and `max-width: 100%` from the reset. The
 * moment anything squeezes its column narrower than the logo's natural width
 * those two fight: the width gives way, the height does not, and the logo is
 * drawn squashed. `contain` settles the argument — the picture keeps its
 * proportions and simply takes up less of the box — so a logo can no longer be
 * distorted by a layout it knows nothing about.
 */
.custom-logo,
.tc-logo,
.mobile-menu__logo img {
	height: var(--tc-logo-height);
	width: auto;
	max-width: 100%;
	object-fit: contain;
	object-position: left center;
}

/* ---------- Main menu ---------- */

/*
 * The bar stretches the full height of the header so that a dropdown can hang
 * off its bottom edge. Hung off the link instead it would open a few pixels
 * short of the border, and the pointer travelling down to it would cross dead
 * space and close the panel on the way.
 */
.tc-nav { grid-column: 2; align-self: stretch; display: flex; justify-content: center; }

/* The gap gives way before the menu does: seven Thai labels at a fixed 2rem
   apart overflow the middle column somewhere around 1100px. */
.tc-nav__list {
	display: flex; align-items: stretch; height: 100%;
	gap: clamp(.9rem, 2.1vw, 2rem); list-style: none; margin: 0; padding: 0;
}
.tc-nav__list li { position: relative; }
.tc-nav__list > li { display: flex; align-items: center; }

.tc-nav__list a {
	display: flex; align-items: center;
	color: var(--tc-text); text-decoration: none;
	font-size: .95rem; white-space: nowrap;
}
.tc-nav__list > li > a { height: 100%; }
.tc-nav__list a:hover { color: var(--tc-accent); }

/* Where the reader is now. WordPress writes these classes itself; with no rule
   for them a fifteen-item menu tells nobody which section they are in. */
.tc-nav__list .current-menu-item > a,
.tc-nav__list .current-menu-parent > a,
.tc-nav__list .current-menu-ancestor > a,
.tc-nav__list .current_page_item > a { color: var(--tc-accent); }

/* A caret, so an item that opens something says so before it is hovered. */
.tc-nav__list .menu-item-has-children > a::after {
	content: "";
	width: .34em; height: .34em;
	margin-inline-start: .45em;
	border-right: 2px solid currentColor;
	border-bottom: 2px solid currentColor;
	transform: translateY(-.15em) rotate(45deg);
	transition: transform .15s ease;
}
.tc-nav__list .menu-item-has-children:hover > a::after,
.tc-nav__list .menu-item-has-children:focus-within > a::after { transform: translateY(.05em) rotate(225deg); }

/*
 * Opened by flipping visibility, not display: display cannot be transitioned,
 * and visibility — unlike opacity on its own — also takes the links out of the
 * tab order while the panel is shut.
 */
.tc-nav__list .sub-menu {
	position: absolute; top: 100%; left: -.7rem; z-index: 20;
	min-width: var(--tc-sub-w, 210px);
	display: flex; flex-direction: column; gap: .1rem;
	list-style: none; margin: 0; padding: .4rem;
	background: var(--tc-surface);
	border: 1px solid var(--tc-border);
	border-radius: var(--tc-radius);
	box-shadow: 0 14px 34px rgba(28, 27, 26, .13);
	opacity: 0; visibility: hidden; transform: translateY(-6px);
	/*
	 * No delay on the way out. Closing is the state being returned to, so this
	 * is the transition that runs when the pointer leaves, and a panel that
	 * lingers after you have gone is the other half of the same complaint.
	 */
	transition: opacity .18s ease, transform .18s ease, visibility .18s;
	transition-delay: 0s;
}

/*
 * A pause before opening — hover intent, and the fix for a menu that drops a
 * panel over the page before the pointer has arrived anywhere.
 *
 * Crossing a bar of six items to reach the last one passes over every one in
 * between. With no delay each of those is an instruction to open, so panels
 * flash down and cover the page on the way past. A sixth of a second is longer
 * than a pointer in transit spends over any one item and shorter than anybody
 * deliberately reaching for a menu will notice.
 *
 * The delay belongs on the open rule, not the closed one: a transition-delay
 * applies to the change *into* the state its rule describes.
 */
.tc-nav__list li:hover > .sub-menu,
.tc-nav__list li:focus-within > .sub-menu {
	opacity: 1; visibility: visible; transform: none;
	transition-delay: .16s;
}

/*
 * Focus opens it for a keyboard, not for a mouse.
 *
 * Several of these parents are links to "#", so clicking one leaves focus
 * sitting on it — and :focus-within then holds the panel open over the page
 * long after the pointer has gone somewhere else, with nothing the reader can
 * do about it but click elsewhere. :focus-visible is the browser's own answer
 * to "was this focus deliberate", and it says no to a mouse click.
 *
 * Wrapped in @supports and excluding :hover on purpose: where :has() is not
 * understood the rule is skipped and the old behaviour stands, and where it is,
 * it must never win an argument with the pointer actually being there.
 */
@supports selector(:has(*)) {
	.tc-nav__list li:focus-within:not(:hover):not(:has(:focus-visible)) > .sub-menu {
		opacity: 0; visibility: hidden; transform: translateY(-6px);
		transition-delay: 0s;
	}
}

/*
 * Hover opens nothing until the reader has actually moved the pointer.
 *
 * This is the half the delay could not reach. Click a country in a dropdown and
 * the new page loads with the cursor still resting exactly where it was — on a
 * menu item — so the browser applies :hover the moment it paints, and the
 * reader arrives at an article already covered by the menu they just used. No
 * amount of delay helps: the pointer really is there, and waiting longer only
 * means the page is covered a fraction of a second later.
 *
 * Requiring movement separates "the pointer happens to be here" from "the
 * reader is reaching for this", which is the distinction hover was always
 * standing in for.
 *
 * The class is added by the script, never by the markup, so a blocked script
 * leaves the menu behaving exactly as it did before rather than leaving a site
 * whose dropdowns cannot be opened at all.
 */
.tc-nohover .tc-nav__list li:hover > .sub-menu {
	opacity: 0;
	visibility: hidden;
	transition-delay: 0s;
}

.tc-nav__list .sub-menu a {
	display: block;
	padding: .55rem .7rem;
	border-radius: calc(var(--tc-radius) - 4px);
	font-size: var(--tc-sub-fs, 15px); line-height: 1.5; white-space: normal;
	color: var(--tc-text);
	transition: background .15s, color .15s;
}
.tc-nav__list .sub-menu a:hover,
.tc-nav__list .sub-menu a:focus-visible,
.tc-nav__list .sub-menu .current-menu-item > a { background: var(--tc-bg-alt); color: var(--tc-accent); }

/* The caret belongs to the bar, not to the panel. */
.tc-nav__list .sub-menu .menu-item-has-children > a::after { display: none; }

/*
 * The third level stays inside the panel, indented, rather than flying out to
 * the side.
 *
 * A flyout has to decide which side it has room on, re-decide it at every
 * window width, and survive a pointer travelling diagonally across the gap to
 * reach it — three problems, all of them invisible until a reader with a narrow
 * laptop cannot open the menu. Indenting instead costs one rule and reads as
 * what it is: a group and the things in it.
 */
.tc-nav__list .sub-menu .sub-menu {
	position: static;
	opacity: 1; visibility: visible; transform: none;
	min-width: 0;
	margin: .1rem 0 .3rem;
	padding: 0 0 0 .7rem;
	background: none;
	border: 0; border-left: 1px solid var(--tc-border);
	border-radius: 0;
	box-shadow: none;
	transition: none;
}

/* A shade under the level above it, so the two read apart at a glance without
   the owner having to set a second number. */
.tc-nav__list .sub-menu .sub-menu a {
	padding: .4rem .65rem;
	font-size: calc(var(--tc-sub-fs, 15px) * .92);
	color: var(--tc-text-muted);
}
.tc-nav__list .sub-menu .sub-menu a:hover { color: var(--tc-accent); }

/* A group heading is still a link, but it reads as the heading of what is
   under it. */
.tc-nav__list .sub-menu > li.menu-item-has-children > a { font-weight: 600; }

/* A panel on the last item would otherwise run off the right edge. */
.tc-nav__list > li:last-child .sub-menu { left: auto; right: -.7rem; }

@media (prefers-reduced-motion: reduce) {
	/* The movement goes; the pause stays. It is not an animation, it is the
	   difference between a menu that waits to be asked and one that does not. */
	.tc-nav__list .sub-menu { transition-property: visibility; transform: none; }
	.tc-nav__list li:hover > .sub-menu,
	.tc-nav__list li:focus-within > .sub-menu { transform: none; }
	.tc-nav__list .menu-item-has-children > a::after { transition: none; }
}

/* ---------- Language switcher ---------- */

/*
 * Polylang's own menu item is hidden rather than styled.
 *
 * The switcher is a control, and it now lives with the other controls at the
 * right of the bar. Leaving the plugin's copy in the menu as well would show
 * the reader two of them, so the theme takes responsibility for the one it
 * prints and stands the other down. Anyone who would rather have it in the menu
 * can remove it from the header instead — this rule is the only thing holding
 * it back.
 */
.tc-nav__list > li.pll-parent-menu-item,
.mobile-menu__list > li.pll-parent-menu-item { display: none; }

.tc-lang { position: relative; flex: 0 0 auto; }

.tc-lang__toggle {
	display: flex; align-items: center; gap: .45rem;
	padding: .4rem .7rem;
	background: none; cursor: pointer;
	border: 1px solid var(--tc-border); border-radius: 999px;
	color: var(--tc-text);
	font: inherit; font-size: .88rem; line-height: 1.3;
	transition: border-color .15s, background .15s;
}
.tc-lang__toggle:hover { border-color: var(--tc-accent); background: var(--tc-bg-alt); }

/* Polylang writes the flag's size onto the element itself, which is the one
   thing a stylesheet cannot reach any other way. */
.tc-lang img {
	width: 18px !important;
	height: auto !important;
	flex: 0 0 auto;
	border-radius: 2px;
	/* Half the world's flags are white down one edge and vanish without it. */
	box-shadow: 0 0 0 1px rgba(28, 27, 26, .14);
}

.tc-lang__caret {
	width: .34em; height: .34em;
	margin-inline-start: .1em;
	border-right: 2px solid currentColor;
	border-bottom: 2px solid currentColor;
	transform: translateY(-.15em) rotate(45deg);
	transition: transform .15s ease;
}
.tc-lang__toggle[aria-expanded="true"] .tc-lang__caret { transform: translateY(.05em) rotate(225deg); }

.tc-lang__menu {
	position: absolute; top: calc(100% + .5rem); right: 0; z-index: 60;
	min-width: 170px;
	display: flex; flex-direction: column; gap: .1rem;
	list-style: none; margin: 0; padding: .4rem;
	background: var(--tc-surface);
	border: 1px solid var(--tc-border);
	border-radius: var(--tc-radius);
	box-shadow: 0 14px 34px rgba(28, 27, 26, .13);
}
.tc-lang__menu[hidden] { display: none; }

.tc-lang__item {
	display: flex; align-items: center; gap: .5rem;
	padding: .5rem .65rem;
	border-radius: calc(var(--tc-radius) - 4px);
	font-size: .9rem; text-decoration: none; white-space: nowrap;
	color: var(--tc-text);
	transition: background .15s, color .15s;
}
.tc-lang__item:hover { background: var(--tc-bg-alt); color: var(--tc-accent); }
.tc-lang__item.is-on { color: var(--tc-accent); font-weight: 600; }

/* Over a photograph, and back again once the bar turns solid. */
.tc-header--over .tc-lang__toggle { color: #fff; border-color: rgba(255, 255, 255, .5); }
.tc-header--over .tc-lang__toggle:hover { background: rgba(255, 255, 255, .16); border-color: #fff; }
.tc-header--over.is-stuck .tc-lang__toggle { color: var(--tc-text); border-color: var(--tc-border); }
.tc-header--over.is-stuck .tc-lang__toggle:hover { background: var(--tc-bg-alt); border-color: var(--tc-accent); }

/* On a narrow bar the name goes and the flag carries it. */
@media (max-width: 479px) {
	.tc-header__tools .tc-lang__name { display: none; }
	.tc-header__tools .tc-lang__toggle { padding-inline: .55rem; }
}

/* In the full-screen menu it is a full-width row above the button, and its
   list opens downwards with room to do it. */
.tc-lang--block { display: block; margin-bottom: var(--tc-space-sm); }
.tc-lang--block .tc-lang__toggle { width: 100%; justify-content: center; padding-block: .7rem; }
.tc-lang--block .tc-lang__menu { left: 0; right: 0; min-width: 0; }

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

/* Column 3 by name rather than by order: with no menu assigned nothing
   occupies the middle, and auto-placement would slide the tools into it. */
.tc-header__tools { grid-column: 3; display: flex; align-items: center; justify-self: end; gap: .25rem; }

.tc-header__cta {
	flex: 0 0 auto; white-space: nowrap;
	margin-inline-start: .35rem;
	padding: .72rem 1.7rem;
	border-radius: 999px;
}

/* Once the burger appears the bar is brand + burger and nothing else. The
   button is not dropped, only moved: it is repeated at the foot of the
   full-screen menu, which is where a phone reader goes looking for it. */
@media (max-width: 899px) {
	.tc-header__cta { display: none; }
}

.tc-searchtoggle, .tc-burger {
	display: grid; place-items: center;
	width: 40px; height: 40px; padding: 0;
	background: none; border: 0; border-radius: 8px; color: var(--tc-text); cursor: pointer;
}
.tc-searchtoggle:hover, .tc-burger:hover { background: var(--tc-bg-alt); }

.tc-burger { display: none; }
.tc-burger__bar { display: block; width: 20px; height: 2px; margin: 2px 0; background: currentColor; transition: transform .2s, opacity .2s; }
.tc-burger[aria-expanded="true"] .tc-burger__bar:nth-child(1) { transform: translateY(6px) rotate(45deg); }
.tc-burger[aria-expanded="true"] .tc-burger__bar:nth-child(2) { opacity: 0; }
.tc-burger[aria-expanded="true"] .tc-burger__bar:nth-child(3) { transform: translateY(-6px) rotate(-45deg); }

.tc-search { border-top: 1px solid var(--tc-border); padding-block: var(--tc-space-md); background: var(--tc-bg-alt); }
.tc-search[hidden] { display: none; }

/* The inline menu hands over to the full-screen one here. */
@media (max-width: 899px) {
	.tc-burger { display: grid; }
	.tc-nav { display: none; }

	/*
	 * Two columns, because there are two things.
	 *
	 * The bar is a three-column grid so the menu can sit centred between the
	 * logo and the buttons. With the menu gone that middle column is empty and
	 * was still taking a gap on either side of itself — some fifty pixels of
	 * nothing, on the one screen with none to spare. The brand column is allowed
	 * to shrink, so that space came out of the logo rather than out of the
	 * emptiness, which is what made it look squeezed.
	 */
	.tc-header__inner {
		grid-template-columns: auto minmax(0, 1fr);
		gap: var(--tc-space-sm);
	}

	.tc-header__tools { grid-column: 2; }
}

/* ---------- Search form ---------- */

.tc-searchform { display: flex; gap: .5rem; }
.tc-searchform__field {
	flex: 1; min-width: 0;
	padding: .7rem .9rem; font: inherit; font-size: .95rem;
	border: 1px solid var(--tc-border); border-radius: 8px; background: var(--tc-surface); color: inherit;
}
.tc-searchform__field:focus { border-color: var(--tc-accent); outline: none; }
.tc-searchform__btn {
	padding: .7rem 1.1rem; font: inherit; font-size: .95rem; cursor: pointer;
	background: var(--tc-accent); color: #fff; border: 0; border-radius: 8px;
}
.tc-searchform__btn:hover { background: var(--tc-accent-hover); }

/* ---------- Breadcrumbs / archive heading ---------- */

.tc-crumbs { font-size: .82rem; color: var(--tc-text-muted); margin-bottom: var(--tc-space-md); }
.tc-crumbs a { color: inherit; text-decoration: none; }
.tc-crumbs a:hover { color: var(--tc-accent); text-decoration: underline; }
.tc-crumbs__sep { margin-inline: .4rem; opacity: .5; }

.tc-archhead { margin-bottom: var(--tc-space-lg); }
.tc-archhead__title { font-size: var(--tc-fs-h1); margin-bottom: .35rem; }
.tc-archhead__desc, .tc-archhead__count { color: var(--tc-text-muted); margin: 0 0 var(--tc-space-md); max-width: 60ch; }
.tc-404__code { font-size: 4rem; font-weight: 700; line-height: 1; color: var(--tc-accent); margin: 0 0 .5rem; }

/* ---------- Card grid ---------- */

.tc-grid {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(min(100%, 280px), 1fr));
	gap: var(--tc-space-lg) var(--tc-space-md);
}
.tc-grid__full { grid-column: 1 / -1; }

.tc-card { display: flex; flex-direction: column; min-width: 0; }
.tc-card__media { display: block; border-radius: var(--tc-radius); overflow: hidden; background: var(--tc-bg-alt); }
/* The ratio is fixed here as well as in the crop, so the box exists before the
   file does and the grid never reflows as pictures arrive. */
.tc-card__img { width: 100%; aspect-ratio: 16 / 9; object-fit: cover; transition: transform .35s ease; }
.tc-card__media:hover .tc-card__img { transform: scale(1.03); }

.tc-card__body { padding-top: .85rem; }
.tc-card__cat {
	display: inline-block; margin-bottom: .4rem;
	font-size: .72rem; letter-spacing: .06em; text-transform: uppercase;
	color: var(--tc-accent); text-decoration: none; font-weight: 600;
}
.tc-card__title { font-size: 1.08rem; line-height: 1.45; margin: 0 0 .4rem; }
.tc-card__title a { color: var(--tc-text); text-decoration: none; }
.tc-card__title a:hover { color: var(--tc-accent); }
.tc-card__excerpt { font-size: .9rem; line-height: 1.7; color: var(--tc-text-muted); margin: 0 0 .5rem; }
.tc-card__foot { display: flex; gap: .4rem; font-size: .76rem; color: var(--tc-text-muted); }

/* ---------- Article ---------- */

.tc-article { max-width: var(--tc-read); margin-inline: auto; }
.tc-layout--aside .tc-article { margin-inline: 0; }
.tc-article--full { max-width: none; }

.tc-article__title { font-size: var(--tc-fs-h1); margin-bottom: var(--tc-space-sm); }

.tc-meta { display: flex; flex-wrap: wrap; align-items: center; gap: .75rem; font-size: .82rem; color: var(--tc-text-muted); }
.tc-meta__cat {
	color: var(--tc-accent); text-decoration: none; font-weight: 600;
	text-transform: uppercase; letter-spacing: .05em; font-size: .74rem;
}

.tc-article__hero { margin: var(--tc-space-lg) 0; }
.tc-article__hero img { width: 100%; border-radius: var(--tc-radius); }
.tc-article__hero figcaption { margin-top: .5rem; font-size: .8rem; color: var(--tc-text-muted); text-align: center; }

/* ---------- Prose ---------- */

/* The token, not a repeat of its value — this rule used to hard-code the
   shipped 1.0625rem, which meant the body text size in the Customizer changed
   every part of the site except the article you set it for. */
.tc-prose { font-size: var(--tc-fs-base); }
.tc-prose > * { margin-bottom: var(--tc-space-md); }
.tc-prose h1 { font-size: var(--tc-fs-h1); margin-top: var(--tc-space-xl); }
.tc-prose h2 { font-size: var(--tc-fs-h2); margin-top: var(--tc-space-xl); }
.tc-prose h3 { font-size: var(--tc-fs-h3); margin-top: var(--tc-space-lg); }
.tc-prose h4 { font-size: var(--tc-fs-h4); margin-top: var(--tc-space-lg); }
.tc-prose h5 { font-size: var(--tc-fs-h5); margin-top: var(--tc-space-md); }

/*
 * Links in running text, and only there.
 *
 * The same declarations on a bare `a` would reach the menu, the cards and the
 * buttons — all of them links, none of them things anybody means when they say
 * "link text". The underline is on by default because colour on its own does
 * not survive a reader who cannot tell this red from this black.
 */
.tc-prose a {
	font-family: var(--tc-font-link);
	font-weight: var(--tc-fw-link);
	text-decoration-line: var(--tc-link-line);
}
.tc-prose ul, .tc-prose ol { padding-left: 1.3rem; }
.tc-prose li { margin-bottom: .4rem; }
.tc-prose img, .tc-prose .wp-block-image img { border-radius: var(--tc-radius); }
.tc-prose figure { margin-inline: 0; }
.tc-prose figcaption { margin-top: .5rem; font-size: .82rem; color: var(--tc-text-muted); text-align: center; }
.tc-prose blockquote {
	margin-inline: 0; padding: .25rem 0 .25rem 1.25rem;
	border-left: 3px solid var(--tc-accent); color: var(--tc-text-muted); font-style: italic;
}
.tc-prose table { width: 100%; border-collapse: collapse; font-size: .92rem; }
.tc-prose th, .tc-prose td { border: 1px solid var(--tc-border); padding: .6rem .75rem; text-align: left; }
.tc-prose th { background: var(--tc-bg-alt); font-weight: 600; }
.tc-prose code {
	background: var(--tc-bg-alt); padding: .15em .4em; border-radius: 4px; font-size: .9em;
}
.tc-prose pre { background: var(--tc-ink); color: #f5f5f5; padding: 1rem; border-radius: var(--tc-radius); overflow-x: auto; }
.tc-prose pre code { background: none; color: inherit; }
.tc-prose hr { border: 0; border-top: 1px solid var(--tc-border); margin-block: var(--tc-space-lg); }

/* Wide blocks may break the reading column; full-width ones may not break the
   page, because a horizontal scrollbar on a phone is never intentional. */
.tc-prose .alignwide { width: min(100vw - 2rem, calc(var(--tc-read) + 160px)); margin-inline: auto; }
.tc-prose .alignfull { width: 100%; }
.tc-prose .alignleft { float: left; margin: .35rem var(--tc-space-md) var(--tc-space-sm) 0; max-width: 50%; }
.tc-prose .alignright { float: right; margin: .35rem 0 var(--tc-space-sm) var(--tc-space-md); max-width: 50%; }
.tc-prose .aligncenter { margin-inline: auto; }

.wp-block-gallery { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: .6rem; }
.wp-block-gallery figure { margin: 0; }
.wp-block-gallery img { width: 100%; aspect-ratio: 4 / 3; object-fit: cover; }

.wp-block-embed iframe { width: 100%; aspect-ratio: 16 / 9; height: auto; border: 0; border-radius: var(--tc-radius); }

/* ---------- Contents list ---------- */

.tc-toc {
	background: var(--tc-bg-alt);
	border: 1px solid var(--tc-border);
	border-radius: var(--tc-radius);
	padding: 1.1rem 1.35rem;
	margin-bottom: var(--tc-space-lg);
}
.tc-toc__title { font-size: .78rem; letter-spacing: .08em; text-transform: uppercase; color: var(--tc-text-muted); margin-bottom: .6rem; }
.tc-toc__list { list-style: none; margin: 0; padding: 0; counter-reset: toc; }
.tc-toc__item { margin-bottom: .3rem; font-size: .92rem; line-height: 1.55; }
.tc-toc__item--h3 { padding-left: 1rem; font-size: .86rem; }
.tc-toc__item a { color: var(--tc-text); text-decoration: none; }
.tc-toc__item a:hover { color: var(--tc-accent); text-decoration: underline; }
.tc-toc__item.is-current > a { color: var(--tc-accent); font-weight: 600; }

/* ---------- Reading progress ---------- */

.tc-progress { position: fixed; top: 0; left: 0; right: 0; height: 3px; z-index: 60; pointer-events: none; }
.tc-progress__bar { display: block; height: 100%; width: 0; background: var(--tc-accent); transition: width .1s linear; }

/* ---------- Banner slots ---------- */

.tc-adwrap { margin-block: var(--tc-space-lg); }
.tc-adwrap--header { margin-block: var(--tc-space-md) 0; }
.tc-adwrap:empty { display: none; margin: 0; }

/* ---------- Tags, nav, related ---------- */

.tc-tags { display: flex; flex-wrap: wrap; gap: .4rem; align-items: center; margin-top: var(--tc-space-lg); }
.tc-tags__label { font-size: .76rem; text-transform: uppercase; letter-spacing: .06em; color: var(--tc-text-muted); margin-right: .25rem; }
.tc-tags a {
	font-size: .82rem; text-decoration: none; color: var(--tc-text-muted);
	border: 1px solid var(--tc-border); border-radius: 999px; padding: .25rem .7rem;
}
.tc-tags a:hover { border-color: var(--tc-accent); color: var(--tc-accent); }

.tc-postnav {
	display: grid; gap: var(--tc-space-md);
	max-width: var(--tc-read); margin: var(--tc-space-xl) auto 0;
}
.tc-layout--aside .tc-postnav { margin-inline: 0; }
@media (min-width: 640px) { .tc-postnav { grid-template-columns: 1fr 1fr; } }
.tc-postnav__link {
	display: block; padding: 1rem 1.15rem; text-decoration: none; color: var(--tc-text);
	border: 1px solid var(--tc-border); border-radius: var(--tc-radius);
}
.tc-postnav__link:hover { border-color: var(--tc-accent); }
.tc-postnav__link--next { text-align: right; }
.tc-postnav__label { display: block; font-size: .72rem; text-transform: uppercase; letter-spacing: .07em; color: var(--tc-text-muted); margin-bottom: .2rem; }
.tc-postnav__title { display: block; font-size: .95rem; line-height: 1.5; font-weight: 500; }

.tc-related { margin-top: var(--tc-space-xl); }
.tc-related__title { font-size: var(--tc-fs-h3); margin-bottom: var(--tc-space-md); }

/* ---------- Pagination ---------- */

.pagination, .comments-pagination { margin-top: var(--tc-space-xl); }
.pagination .nav-links, .comments-pagination .nav-links { display: flex; flex-wrap: wrap; gap: .4rem; justify-content: center; }
.page-numbers {
	display: grid; place-items: center; min-width: 40px; height: 40px; padding-inline: .7rem;
	border: 1px solid var(--tc-border); border-radius: 8px;
	text-decoration: none; color: var(--tc-text); font-size: .92rem;
}
.page-numbers:hover { border-color: var(--tc-accent); color: var(--tc-accent); }
.page-numbers.current { background: var(--tc-accent); border-color: var(--tc-accent); color: #fff; }
.page-numbers.dots { border-color: transparent; }

/* ---------- Widgets ---------- */

.tc-widget { margin-bottom: var(--tc-space-lg); }
.tc-widget__title { font-size: .8rem; letter-spacing: .08em; text-transform: uppercase; color: var(--tc-text-muted); margin-bottom: .75rem; }
.tc-widget ul { list-style: none; margin: 0; padding: 0; }
.tc-widget li { padding: .45rem 0; border-bottom: 1px solid var(--tc-border); font-size: .92rem; }
.tc-widget li:last-child { border-bottom: 0; }
.tc-widget a { color: var(--tc-text); text-decoration: none; }
.tc-widget a:hover { color: var(--tc-accent); }

/* ---------- Comments ---------- */

.tc-comments { max-width: var(--tc-read); margin: var(--tc-space-xl) auto 0; }
.tc-layout--aside .tc-comments { margin-inline: 0; }
.tc-comments__title { font-size: var(--tc-fs-h3); margin-bottom: var(--tc-space-md); }
.tc-comments__list, .tc-comments__list .children { list-style: none; margin: 0; padding: 0; }
.tc-comments__list .children { padding-left: 1.5rem; border-left: 2px solid var(--tc-border); margin-top: var(--tc-space-md); }
.tc-comments__list li { margin-bottom: var(--tc-space-md); }
.comment-body { border: 1px solid var(--tc-border); border-radius: var(--tc-radius); padding: 1rem 1.15rem; }
.comment-meta { font-size: .8rem; color: var(--tc-text-muted); margin-bottom: .5rem; }
.comment-author img { border-radius: 50%; display: inline-block; vertical-align: middle; margin-right: .5rem; }
.comment-form input[type="text"], .comment-form input[type="email"], .comment-form input[type="url"], .comment-form textarea {
	width: 100%; padding: .65rem .85rem; font: inherit; font-size: .95rem;
	border: 1px solid var(--tc-border); border-radius: 8px; background: var(--tc-surface); color: inherit;
}
.comment-form .submit {
	padding: .7rem 1.4rem; font: inherit; cursor: pointer;
	background: var(--tc-accent); color: #fff; border: 0; border-radius: 8px;
}

/* ---------- Empty state ---------- */

.tc-empty { padding: var(--tc-space-xl) 0; text-align: center; }
.tc-empty__title { font-size: var(--tc-fs-h2); }
.tc-empty .tc-searchform { max-width: 420px; margin-inline: auto; }

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

.tc-footer { background: var(--tc-ink); color: #cfcbc7; padding-block: var(--tc-space-xl) var(--tc-space-md); }
.tc-footer a { color: #fff; }
.tc-footer .tc-widget__title { color: #8d8884; }
.tc-footer .tc-widget li { border-color: rgba(255, 255, 255, .12); }
.tc-footer .tc-widget a { color: #cfcbc7; text-decoration: none; }
.tc-footer .tc-widget a:hover { color: #fff; }

.tc-footer__cols {
	display: grid; gap: var(--tc-space-lg);
	grid-template-columns: repeat(auto-fit, minmax(min(100%, 220px), 1fr));
	margin-bottom: var(--tc-space-lg);
}

.tc-footer__bar {
	display: flex; flex-wrap: wrap; gap: var(--tc-space-sm) var(--tc-space-md);
	align-items: center; justify-content: space-between;
	border-top: 1px solid rgba(255, 255, 255, .12); padding-top: var(--tc-space-md);
	font-size: .85rem;
}
.tc-footer__copy { margin: 0; }
.tc-footer__list { display: flex; flex-wrap: wrap; gap: 1rem; list-style: none; margin: 0; padding: 0; }
.tc-footer__list a { text-decoration: none; color: #cfcbc7; }
.tc-footer__list a:hover { color: #fff; }

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

@media (prefers-reduced-motion: reduce) {
	html { scroll-behavior: auto; }
	*, *::before, *::after { animation-duration: .01ms !important; transition-duration: .01ms !important; }
}

/* =========================================================
   Single article — the wireframe layout.
   ========================================================= */

/*
 * Rails only above 1200px. Below that the 150px columns would have to come
 * out of the article's width, and the article is both what the reader came
 * for and the reason the banners are worth anything.
 */
.tc-single { display: block; }

/*
 * Two columns from 1024px up: the article, then the widgets.
 *
 * What this is really for is the measure. At full container width an article
 * line runs to something like 1100px, which is about 140 characters — the eye
 * loses its place on the way back to the start of the next line, and a reader
 * who keeps re-reading the same line stops reading. The sidebar takes 300px
 * and the gap another 48, which lands the column near the 720px the rest of
 * the theme treats as a reading column.
 */
@media (min-width: 1024px) {
	/*
	 * The article column is capped by the reading width rather than taking
	 * whatever is left over, and the pair is then centred in the container.
	 *
	 * That is the difference between the two widths in the Customizer. Page
	 * width decides how much screen the site uses; it may grow as wide as the
	 * owner likes without the text following it out to a line nobody can track
	 * back. Widening the article is a separate, deliberate decision.
	 */
	.tc-single--aside {
		display: grid;
		grid-template-columns: minmax(0, var(--tc-read)) var(--tc-sidebar);
		gap: var(--tc-space-xl);
		justify-content: center;
		align-items: start;
	}
	.tc-single--aside .tc-layout__aside { margin-top: 0; }
}

/* ---------- Sidebar on the left ---------- */

/*
 * Placed by column number, not by reordering the markup. The main column is
 * still written first and read first; only the painting order changes.
 */
@media (min-width: 1024px) {
	.tc-aside-left .tc-layout--aside { grid-template-columns: var(--tc-sidebar) minmax(0, 1fr); }
	.tc-aside-left .tc-single--aside { grid-template-columns: var(--tc-sidebar) minmax(0, var(--tc-read)); }

	.tc-aside-left .tc-layout--aside > .tc-layout__main,
	.tc-aside-left .tc-single--aside > .tc-single__main { grid-column: 2; grid-row: 1; }

	.tc-aside-left .tc-layout--aside > .tc-layout__aside,
	.tc-aside-left .tc-single--aside > .tc-layout__aside { grid-column: 1; grid-row: 1; }
}

@media (min-width: 1200px) {
	.tc-single--rails {
		display: grid;
		grid-template-columns: 150px minmax(0, 1fr) 150px;
		gap: var(--tc-space-lg);
		align-items: start;
	}
}

.tc-rail { display: none; }

@media (min-width: 1200px) {
	.tc-rail {
		display: grid;
		gap: var(--tc-space-md);
		align-content: start;
		position: sticky;
		top: calc(var(--tc-header-h) + 1rem);
	}
	/* The rail already provides the spacing; the banner's own margin would
	   double it and push the second one out of the sticky area. */
	.tc-rail .tc-ad { margin: 0; }
}

.tc-single__main { min-width: 0; }

/* ---------- Cover ---------- */

/*
 * The cover's own rules are further down, with the full-bleed layout. What
 * stood here was the version from before the cover ran edge to edge: a rounded,
 * boxed picture sitting inside the article column. Only its border-radius still
 * reached the page, and it was putting curved top corners on a band that starts
 * flush against the menu — which reads as a card that has come loose rather
 * than as the top of the page.
 */

.tc-cover__text { padding: var(--tc-space-md) clamp(1rem, 3vw, 1.75rem) clamp(1.1rem, 3vw, 1.6rem); }
.tc-cover__text .tc-crumbs { margin-bottom: .5rem; }

.tc-cover__title {
	font-size: 2rem; /* 32px on desktop, per the wireframe */
	line-height: 1.3;
	margin: 0 0 .6rem;
}

@media (max-width: 781px) {
	.tc-cover__title { font-size: 1.5em; }
}

/* ---------- Date · country · city · tags ---------- */

.tc-placemeta {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: .45rem;
	font-size: 1rem; /* 16px */
	/* Grey, but only a little lighter than the body text — enough to sit back
	   from the headline, not so far that it stops being readable. */
	color: #6b6866;
}

.tc-placemeta__item { color: inherit; text-decoration: none; }
a.tc-placemeta__item:hover { color: var(--tc-accent); text-decoration: underline; }
.tc-placemeta__sep { opacity: .45; }
.tc-placemeta__tags { display: inline-flex; flex-wrap: wrap; gap: .35rem; }
.tc-placemeta__tag {
	font-size: .85rem;
	color: inherit;
	text-decoration: none;
	border: 1px solid var(--tc-border);
	border-radius: 999px;
	padding: .1rem .6rem;
	background: var(--tc-surface);
}
.tc-placemeta__tag:hover { border-color: var(--tc-accent); color: var(--tc-accent); }

/* ---------- Boxed zones ---------- */

.tc-zone {
	border: 1px solid var(--tc-border);
	border-radius: var(--tc-radius);
	padding: clamp(1.1rem, 3vw, 2rem);
	margin-bottom: var(--tc-space-lg);
}

.tc-zone__title { font-size: var(--tc-fs-h3); margin-bottom: .5rem; }
.tc-zone__text { color: var(--tc-text-muted); margin-bottom: var(--tc-space-md); max-width: 60ch; }

.tc-zone__buttons { display: flex; flex-wrap: wrap; gap: .6rem; }

/* ---------- Buttons ---------- */

.tc-btn {
	display: inline-block;
	padding: .6rem 1.15rem;
	border-radius: 8px;
	font-size: .92rem;
	line-height: 1.4;
	text-decoration: none;
	background: var(--tc-bg-alt);
	color: var(--tc-text);
	border: 1px solid var(--tc-border);
	transition: background .15s, border-color .15s, color .15s;
}
.tc-btn:hover { border-color: var(--tc-accent); color: var(--tc-accent); }

/* LINE keeps its own colour, because people look for the green rather than
   reading the label. */
.tc-btn--line { background: #06c755; border-color: #06c755; color: #fff; }
.tc-btn--line:hover { background: #05b34c; border-color: #05b34c; color: #fff; }
.tc-btn--facebook, .tc-btn--facebook2 { background: #1877f2; border-color: #1877f2; color: #fff; }
.tc-btn--facebook:hover, .tc-btn--facebook2:hover { background: #1465d0; border-color: #1465d0; color: #fff; }
.tc-btn--instagram { background: #c13584; border-color: #c13584; color: #fff; }
.tc-btn--instagram:hover { background: #a62d71; border-color: #a62d71; color: #fff; }

.tc-btn--ghost { background: transparent; }

.tc-btn--solid { background: var(--tc-accent); border-color: var(--tc-accent); color: #fff; }
.tc-btn--solid:hover { background: var(--tc-accent-hover); border-color: var(--tc-accent-hover); color: #fff; }

/* ---------- Related ---------- */

.tc-related__head {
	display: flex;
	flex-wrap: wrap;
	gap: var(--tc-space-sm);
	align-items: center;
	justify-content: space-between;
	margin-bottom: var(--tc-space-md);
}
.tc-related__head .tc-related__title { margin: 0; }

/* The article inside a rails layout is already in its own column, so it must
   not also try to centre itself in a narrower one. */
/*
 * Only inside a column that already constrains the measure. The blanket
 * version of this rule was the reason a single post with no sidebar and no
 * rails ran the full width of the page: it removed the article's own reading
 * width and put nothing in its place.
 */
.tc-single--aside .tc-article,
.tc-single--aside .tc-postnav,
.tc-single--aside .tc-comments,
.tc-single--rails .tc-article,
.tc-single--rails .tc-postnav,
.tc-single--rails .tc-comments { max-width: none; margin-inline: 0; }

/* ---------- Loose ends ---------- */

/* The last crumb is where you are, so it is not a link and should not look
   like one. */
.tc-crumbs__here { color: var(--tc-text); }

.tc-article__head { margin-bottom: var(--tc-space-lg); }

/* wp_link_pages, for an article split across several pages. */
.tc-pagelinks {
	display: flex; flex-wrap: wrap; gap: .4rem; align-items: center;
	margin-top: var(--tc-space-lg);
	font-size: .9rem; color: var(--tc-text-muted);
}
.tc-pagelinks a {
	display: inline-grid; place-items: center;
	min-width: 32px; height: 32px; padding-inline: .5rem;
	border: 1px solid var(--tc-border); border-radius: 6px;
	text-decoration: none; color: var(--tc-text);
}
.tc-pagelinks a:hover { border-color: var(--tc-accent); color: var(--tc-accent); }

.tc-comments__closed { color: var(--tc-text-muted); font-size: .9rem; }

/* =========================================================
   Cover, transparent header, preloader, motion, footer columns
   ========================================================= */

/* ---------- Full-bleed cover ---------- */

.tc-main--flush { padding-top: 0; }

/*
 * height, not min-height, and that is the whole difference.
 *
 * A minimum is a floor the content may stand on top of, which is why every
 * cover came out at whatever height its own headline needed: a two-line title
 * gave one answer and a four-line title another, so moving from article to
 * article the top of the site shifted about. A height is a height.
 *
 * What the box cannot fit, the box does not show — which is why the headline is
 * clamped further down. That clamp is not a separate nicety; it is what stops
 * "does not show" from meaning half a word sliced off at the bottom edge.
 */
.tc-cover {
	position: relative;
	/* Edge to edge regardless of what container it was printed inside. */
	width: 100%;
	display: grid;
	align-items: end;
	isolation: isolate;
	overflow: hidden;
	background: var(--tc-ink);
	margin-bottom: var(--tc-space-xl);
	height: calc(var(--tc-cover-vh, 60) * 1vh);
	height: calc(var(--tc-cover-vh, 60) * 1svh);
}

@media (max-width: 767px) {
	.tc-cover {
		height: calc(var(--tc-cover-vh-m, 50) * 1vh);
		height: calc(var(--tc-cover-vh-m, 50) * 1svh);
	}
}

/*
 * Same reasoning as the slider, and the same fix. It has looked right until now
 * only because an article column is narrow enough that most landscape
 * photographs come out shorter than the minimum height anyway; a portrait one
 * would have blown the cover open to its full natural height.
 */
.tc-cover__media,
.tc-cover__scrim {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
}

.tc-cover__media { overflow: hidden; }
.tc-cover__img { width: 100%; height: 100%; object-fit: cover; }

.tc-cover__inner { grid-area: 1 / 1; position: relative; }

/*
 * White type over an arbitrary photograph is unreadable about half the time —
 * a pale sky, a concrete apron, snow. The scrim makes the headline legible on
 * every article rather than on the ones that happened to be dark.
 */
.tc-cover__scrim {
	background: linear-gradient(
		to bottom,
		rgba(0, 0, 0, .45) 0%,
		rgba(0, 0, 0, .05) 32%,
		rgba(0, 0, 0, .55) 72%,
		rgba(0, 0, 0, .82) 100%
	);
}

.tc-cover__inner { display: flex; align-items: flex-end; padding-bottom: clamp(1.5rem, 5vh, 3.5rem); }

/*
 * Three lines, then an ellipsis.
 *
 * This is what makes a fixed height honest. Without it a long headline runs out
 * of the bottom of the box and loses its last line with nothing to say so; with
 * it the reader can see they are being shown a shortened version.
 *
 * Only the drawing is shortened. The whole headline stays in the markup, so a
 * search engine indexes all of it and a screen reader reads all of it —
 * line-clamp hides nothing from either.
 */
.tc-cover__title {
	display: -webkit-box;
	-webkit-box-orient: vertical;
	-webkit-line-clamp: 3;
	overflow: hidden;
}

/* One line fewer on a phone: the box is shorter and the type is not. */
@media (max-width: 767px) {
	.tc-cover__title { -webkit-line-clamp: 2; }
}

.tc-cover__text { color: #fff; width: 100%; }
.tc-cover__text .tc-crumbs { color: rgba(255, 255, 255, .78); margin-bottom: .6rem; }
.tc-cover__text .tc-crumbs a:hover { color: #fff; }
.tc-cover__text .tc-crumbs__here { color: rgba(255, 255, 255, .78); }

.tc-cover__title {
	font-size: 2rem; /* 32px on desktop */
	line-height: 1.28;
	color: #fff;
	max-width: 22ch;
	margin: 0 0 .7rem;
	text-wrap: balance;
	text-shadow: 0 1px 24px rgba(0, 0, 0, .35);
}

@media (min-width: 900px) { .tc-cover__title { max-width: 26ch; } }
@media (max-width: 781px) { .tc-cover__title { font-size: 1.5em; max-width: none; } }

.tc-cover .tc-placemeta { color: rgba(255, 255, 255, .85); }
.tc-cover .tc-placemeta a.tc-placemeta__item:hover { color: #fff; }
.tc-cover .tc-placemeta__tag {
	background: rgba(255, 255, 255, .14);
	border-color: rgba(255, 255, 255, .3);
	color: #fff;
}
.tc-cover .tc-placemeta__tag:hover { background: rgba(255, 255, 255, .26); border-color: #fff; color: #fff; }

/* ---------- Header over the cover ---------- */

.tc-header--over {
	position: absolute;
	top: 0; left: 0; right: 0;
	background: transparent;
	backdrop-filter: none;
	border-bottom-color: transparent;
	color: #fff;
}

.tc-header--over .tc-brand__link,
.tc-header--over .tc-brand__name,
.tc-header--over .tc-nav__list a,
.tc-header--over .tc-searchtoggle,
.tc-header--over .tc-burger { color: #fff; }

.tc-header--over .tc-brand__tag { color: rgba(255, 255, 255, .72); }
.tc-header--over .tc-nav__list a:hover { color: #fff; text-decoration: underline; }
.tc-header--over .tc-searchtoggle:hover,
.tc-header--over .tc-burger:hover { background: rgba(255, 255, 255, .16); }

/* A white logo file is not assumed — a dark mark on a dark photograph simply
   disappears, so it gets the same shadow the headline has. */
.tc-header--over .custom-logo { filter: drop-shadow(0 1px 10px rgba(0, 0, 0, .45)); }

/* Once scrolled, it becomes the ordinary solid header again. */
.tc-header--over.is-stuck {
	position: fixed;
	background: color-mix(in srgb, var(--tc-surface) 92%, transparent);
	backdrop-filter: saturate(150%) blur(10px);
	border-bottom-color: var(--tc-border);
	color: var(--tc-text);
	animation: tc-drop .25s ease both;
}
.tc-header--over.is-stuck .tc-brand__link,
.tc-header--over.is-stuck .tc-brand__name,
.tc-header--over.is-stuck .tc-nav__list a,
.tc-header--over.is-stuck .tc-searchtoggle,
.tc-header--over.is-stuck .tc-burger { color: var(--tc-text); }
.tc-header--over.is-stuck .tc-brand__tag { color: var(--tc-text-muted); }
.tc-header--over.is-stuck .custom-logo { filter: none; }

@keyframes tc-drop { from { transform: translateY(-100%); } to { transform: none; } }

.tc-header--over.is-stuck { box-shadow: 0 1px 16px rgba(28, 27, 26, .09); }

/*
 * The dropdown is its own white surface, so it must not inherit the bar's
 * white-over-photograph text: that rule would paint every item in the panel
 * white on white.
 */
/* Over a photograph the accent red is not reliably legible, so the current
   section is marked by an underline instead — and gets its colour back the
   moment the bar turns solid. */
.tc-header--over .tc-nav__list > li.current-menu-item > a,
.tc-header--over .tc-nav__list > li.current-menu-parent > a,
.tc-header--over .tc-nav__list > li.current-menu-ancestor > a { color: #fff; text-decoration: underline; }

.tc-header--over.is-stuck .tc-nav__list > li.current-menu-item > a,
.tc-header--over.is-stuck .tc-nav__list > li.current-menu-parent > a,
.tc-header--over.is-stuck .tc-nav__list > li.current-menu-ancestor > a { color: var(--tc-accent); text-decoration: none; }

.tc-header--over .tc-nav__list .sub-menu a { color: var(--tc-text); }
.tc-header--over .tc-nav__list .sub-menu a:hover,
.tc-header--over .tc-nav__list .sub-menu a:focus-visible { color: var(--tc-accent); text-decoration: none; }

.tc-header--over .tc-header__cta.tc-btn--ghost { border-color: rgba(255, 255, 255, .6); color: #fff; }
.tc-header--over .tc-header__cta.tc-btn--ghost:hover { background: #fff; border-color: #fff; color: var(--tc-ink); }
.tc-header--over.is-stuck .tc-header__cta.tc-btn--ghost { border-color: var(--tc-border); color: var(--tc-text); }
.tc-header--over.is-stuck .tc-header__cta.tc-btn--ghost:hover { border-color: var(--tc-accent); color: var(--tc-accent); background: transparent; }

/* ---------- Full-screen mobile menu ---------- */

.mobile-menu {
	position: fixed; inset: 0; z-index: 80;
	background: var(--tc-surface);
	overflow-y: auto;
	opacity: 0;
	transition: opacity .2s ease;
}
.mobile-menu[hidden] { display: none; }
.mobile-menu.is-open { opacity: 1; }

.mobile-menu__inner {
	display: flex; flex-direction: column; gap: var(--tc-space-lg);
	min-height: 100%;
	padding: var(--tc-space-md) var(--tc-gutter) var(--tc-space-xl);
}

.mobile-menu__top { display: flex; align-items: center; justify-content: space-between; gap: 1rem; }
/* Sizing for these is with the header's, so the two cannot drift apart. */
.mobile-menu__title { font-weight: 700; font-size: 1.15rem; text-decoration: none; color: var(--tc-text); }

.mobile-menu__close {
	width: 44px; height: 44px; padding: 0; cursor: pointer;
	font-size: 1.9rem; line-height: 1;
	background: none; border: 0; color: var(--tc-text);
}

.mobile-menu__list, .mobile-menu__list .sub-menu { list-style: none; margin: 0; padding: 0; }
.mobile-menu__list > li { border-bottom: 1px solid var(--tc-border); }
/* Every level, not just the first: the fold-away button is positioned against
   its own row, and a third-level row needs to be that row. */
.mobile-menu__list li { position: relative; }
.mobile-menu__list a { display: block; padding: .95rem 0; text-decoration: none; color: var(--tc-text); font-size: 1.1rem; }
.mobile-menu__list a:hover { color: var(--tc-accent); }
.mobile-menu__list .sub-menu { padding: 0 0 .6rem 1rem; }
.mobile-menu__list .sub-menu .sub-menu { padding: 0 0 .4rem .9rem; border-left: 1px solid var(--tc-border); }
.mobile-menu__list .sub-menu .sub-menu a { font-size: .9rem; }
.mobile-menu__list .sub-menu a { font-size: .95rem; padding: .45rem 0; color: var(--tc-text-muted); }
.mobile-menu__list .sub-menu[hidden] { display: none; }

/*
 * A category list with its children permanently unfolded is four screens of
 * scrolling on a phone. The button that folds them is added by the script, and
 * so is the [hidden] that closes them — with the script blocked every submenu
 * stays open and the menu still works, which is the right way round.
 */
.mobile-menu__list .menu-item-has-children > a { padding-inline-end: 52px; }

.mobile-menu__toggle {
	position: absolute; top: .3rem; right: 0;
	display: grid; place-items: center;
	width: 44px; height: 44px; padding: 0; cursor: pointer;
	background: none; border: 0; color: var(--tc-text-muted);
}
.mobile-menu__caret {
	width: .42rem; height: .42rem;
	border-right: 2px solid currentColor;
	border-bottom: 2px solid currentColor;
	transform: translateY(-.1rem) rotate(45deg);
	transition: transform .18s ease;
}
.mobile-menu__toggle[aria-expanded="true"] .mobile-menu__caret { transform: translateY(.1rem) rotate(225deg); }

.mobile-menu__list .current-menu-item > a,
.mobile-menu__list .current-menu-parent > a,
.mobile-menu__list .current-menu-ancestor > a { color: var(--tc-accent); }

.mobile-menu__cta { display: block; text-align: center; margin-bottom: var(--tc-space-md); }

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

.mobile-menu__foot { margin-top: auto; }

/* The overlay is the small-screen menu only; the inline bar takes over above
   this, and both being present at once is how a menu ends up appearing twice. */
@media (min-width: 900px) { .mobile-menu { display: none !important; } }

/* ---------- Preloader ---------- */

.tc-preloader {
	position: fixed; inset: 0; z-index: 9999;
	display: flex; align-items: center; justify-content: center;
	background: #fff;
	opacity: 1;
	transition: opacity 420ms ease, visibility 420ms ease;
	/*
	 * Fail-safe in CSS as well as in JS. main.js clears this on load and again
	 * on a timeout, but both need the script to have run at all — and a fixed,
	 * opaque, z-index 9999 element only JS can remove turns one blocked script
	 * into a permanently white site.
	 *
	 * Six seconds against the script's three, so the script always wins when it
	 * runs at all. At the three it had before, the two fired together and a
	 * reader on a slow connection could watch the cover vanish mid-fade.
	 */
	animation: tc-preloader-bail 0s linear 6s forwards;
}

.tc-preloader.is-done { opacity: 0; visibility: hidden; pointer-events: none; }

@keyframes tc-preloader-bail { to { opacity: 0; visibility: hidden; pointer-events: none; } }

.tc-preloader__inner { display: flex; flex-direction: column; align-items: center; gap: 22px; }

.tc-preloader__logo {
	width: clamp(80px, 15vw, 120px); height: auto;
	animation: tc-pre-logo 1.6s cubic-bezier(.45, 0, .15, 1) infinite;
}

/* A slow heartbeat rather than a spinner — it reads as brand, not as waiting. */
@keyframes tc-pre-logo {
	0%, 100% { transform: scale(1); opacity: 1; }
	50% { transform: scale(.9); opacity: .6; }
}

.tc-preloader__bar {
	position: relative; display: block;
	width: 120px; height: 3px; border-radius: 999px;
	background: rgba(28, 27, 26, .1); overflow: hidden;
}
.tc-preloader__bar i {
	position: absolute; inset: 0; display: block; border-radius: inherit;
	background: var(--tc-accent);
	transform: translateX(-100%);
	animation: tc-pre-bar 1.3s cubic-bezier(.65, 0, .35, 1) infinite;
}
@keyframes tc-pre-bar {
	0% { transform: translateX(-100%); }
	60%, 100% { transform: translateX(100%); }
}

body.tc-loading { overflow: hidden; }

@media (prefers-reduced-motion: reduce) {
	.tc-preloader__logo, .tc-preloader__bar i { animation: none; }
	.tc-preloader__bar i { transform: none; }
}

/* ---------- Front page slider ---------- */

/*
 * No gap under it by default. A full-bleed band that stops short of whatever
 * follows leaves a strip of page doing nothing, and on a front page built in a
 * page builder that strip lands on top of the builder's own top padding and
 * doubles. Anyone who wants air can ask for it in the Customizer.
 */
.tc-hero {
	position: relative;
	display: grid;
	background: var(--tc-ink);
	margin-bottom: var(--tc-hero-gap, 0);
	isolation: isolate;
}

/* The second line wins wherever svh is understood. svh is the screen with the
   browser's own chrome showing, so the slider does not grow and shrink under
   the reader as the address bar hides on scroll. */
.tc-hero {
	min-height: calc(var(--tc-hero-vh, 70) * 1vh);
	min-height: calc(var(--tc-hero-vh, 70) * 1svh);
}

/*
 * Phones get their own figure, because a percentage of the screen is not the
 * same promise on both. Half of a laptop is a band across the top; half of a
 * phone held upright is most of what the reader can see.
 */
@media (max-width: 767px) {
	.tc-hero {
		min-height: calc(var(--tc-hero-vh-m, 60) * 1vh);
		min-height: calc(var(--tc-hero-vh-m, 60) * 1svh);
	}
}

.tc-hero__track { display: grid; grid-template-areas: "slide"; }

/*
 * Every slide occupies the same cell, so the section is as tall as its tallest
 * one and never changes height as they come and go. Hidden slides keep their
 * space rather than being display:none — a slide removed from the box tree
 * cannot be transitioned back in, and the height would jump each time.
 */
.tc-hero__slide {
	grid-area: slide;
	position: relative;
	display: grid;
	align-items: end;
	opacity: 0;
	visibility: hidden;
	transition: opacity .7s ease, visibility .7s;
}

.tc-hero__slide.is-active { opacity: 1; visibility: visible; }

/*
 * The photograph is taken out of the flow, and this is the whole reason the
 * height setting works.
 *
 * Left in the grid an <img> contributes its own natural height. `height: 100%`
 * does nothing about that: a percentage height needs a parent with a definite
 * one, and the parent's height is being decided by this very image, so the
 * percentage is dropped and the browser falls back to the file's own
 * proportions. A 2000 x 1300 photograph across a wide screen is then 1300px
 * tall, the section grows to fit it, and the height asked for in the
 * Customizer is quietly overruled — with the headline pushed off the bottom of
 * the screen along with it.
 *
 * Absolutely positioned, the image is sized by the slide instead of sizing it,
 * and object-fit crops the overflow. The only thing left holding the section
 * open is the text, which is what should be.
 */
.tc-hero__img,
.tc-hero__scrim {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
}

.tc-hero__img { object-fit: cover; }

/* Above the two of them, and in the flow, so the slide is as tall as its words
   and never shorter. */
.tc-hero__inner { grid-area: 1 / 1; position: relative; }

/*
 * Two layers on one element. The gradient — dark at the foot where the words
 * are, and along the top so the menu stays legible over a pale sky — is not a
 * setting, because it is what makes the headline readable at all. The flat
 * tint underneath it is, because that is taste.
 */
.tc-hero__scrim {
	background:
		linear-gradient(
			to bottom,
			rgba(0, 0, 0, .5) 0%,
			rgba(0, 0, 0, .08) 34%,
			rgba(0, 0, 0, .55) 74%,
			rgba(0, 0, 0, .84) 100%
		),
		var(--tc-hero-overlay, rgba(0, 0, 0, .25));
}

.tc-hero__inner {
	display: flex; flex-direction: column; align-items: flex-start;
	justify-content: flex-end;
	padding-block: var(--tc-space-xl) clamp(3rem, 8vh, 5rem);
	color: #fff;
}

.tc-hero__cat {
	margin: 0 0 .6rem;
	font-size: .78rem; font-weight: 600;
	text-transform: uppercase; letter-spacing: .1em;
	color: rgba(255, 255, 255, .82);
}

/*
 * The setting is the top of a clamp, not the size itself. Taking the number
 * literally would put a 46px headline on a 360px phone, where it wraps to five
 * lines and covers the photograph it was supposed to sit on; this way the same
 * one setting gives a sensible answer at both ends.
 */
.tc-hero__title {
	margin: 0;
	max-width: var(--tc-hero-text-w, 640px);
	font-size: clamp(var(--tc-hero-title-m, 26px), 1.1rem + 2.2vw, var(--tc-hero-title, 46px));
	color: #fff;
	text-shadow: 0 2px 18px rgba(0, 0, 0, .4);
}

.tc-hero__title a { color: #fff; text-decoration: none; }

/*
 * One link, stretched over the panel. The z-index keeps it under the dots,
 * which would otherwise be unclickable for sitting inside the same slide.
 */
.tc-hero__link::after { content: ""; position: absolute; inset: 0; z-index: 1; }

.tc-hero__text {
	margin: var(--tc-space-sm) 0 0;
	max-width: var(--tc-hero-text-w, 640px);
	font-size: var(--tc-hero-text, 17px); line-height: 1.7;
	color: rgba(255, 255, 255, .88);
}

.tc-hero__btn {
	margin-top: var(--tc-space-md);
	padding: .72rem 1.7rem; border-radius: 999px;
	background: #fff; border-color: #fff; color: var(--tc-ink);
}
.tc-hero__slide:hover .tc-hero__btn { background: var(--tc-accent); border-color: var(--tc-accent); color: #fff; }

.tc-hero__dots {
	position: absolute; z-index: 2;
	left: 0; right: 0; bottom: clamp(1rem, 3vh, 1.75rem);
	display: flex; justify-content: center; gap: .5rem;
}
.tc-hero__dots[hidden] { display: none; }

.tc-hero__dot {
	width: 11px; height: 11px; padding: 0; cursor: pointer;
	border: 0; border-radius: 50%;
	background: rgba(255, 255, 255, .45);
	transition: background .2s, transform .2s;
}
.tc-hero__dot:hover { background: rgba(255, 255, 255, .75); }
.tc-hero__dot.is-on { background: #fff; transform: scale(1.25); }

@media (prefers-reduced-motion: reduce) {
	.tc-hero__slide { transition: none; }
	.tc-hero__dot { transition: none; }
}

/* ---------- Back to top ---------- */

.tc-totop {
	position: fixed; z-index: 70;
	right: clamp(1rem, 3vw, 2rem);
	bottom: clamp(1rem, 3vw, 2rem);
	display: grid; place-items: center;
	width: 44px; height: 44px; padding: 0; cursor: pointer;
	border: 1px solid var(--tc-border); border-radius: 50%;
	background: color-mix(in srgb, var(--tc-surface) 92%, transparent);
	backdrop-filter: saturate(150%) blur(8px);
	color: var(--tc-text);
	box-shadow: 0 6px 22px rgba(28, 27, 26, .16);
	opacity: 0; transform: translateY(10px);
	transition: opacity .2s ease, transform .2s ease, background .15s, color .15s;
}

.tc-totop[hidden] { display: none; }
.tc-totop.is-in { opacity: 1; transform: none; }
.tc-totop:hover { background: var(--tc-accent); border-color: var(--tc-accent); color: #fff; }

@media (prefers-reduced-motion: reduce) {
	.tc-totop { transition: none; transform: none; }
}

/* ---------- Images arriving ---------- */

/*
 * A photograph that has just finished downloading appears out of focus and
 * settles, the way a lens finds it.
 *
 * As with the reveal, the class is put on by the script and never by the
 * stylesheet: a blocked script must leave every photograph sharp rather than
 * permanently smeared. The slight scale is not decoration — blur() samples
 * past the edges of the box and leaves a soft rim, and 2% over is enough to
 * push that rim outside the frame.
 */
.tc-blur {
	filter: blur(16px);
	transform: scale(1.02);
	transition: filter .55s ease, transform .55s ease;
}

.tc-blur.is-sharp { filter: none; transform: none; }

@media (prefers-reduced-motion: reduce) {
	.tc-blur, .tc-blur.is-sharp { filter: none; transform: none; transition: none; }
}

/* ---------- Scroll reveal ---------- */

/*
 * Nothing is hidden by the stylesheet alone. JS adds .tc-r to each element just
 * before it starts watching it, so a script that never runs leaves the page
 * visible rather than permanently blank. That is the failure mode worth
 * designing around.
 */
.tc-r {
	opacity: 0;
	transition:
		opacity var(--tc-r-ms, 620ms) cubic-bezier(.16, 1, .3, 1) var(--tc-r-delay, 0ms),
		transform var(--tc-r-ms, 620ms) cubic-bezier(.16, 1, .3, 1) var(--tc-r-delay, 0ms);
}

.tc-r-up .tc-r { transform: translateY(26px); }
.tc-r-fade .tc-r { transform: none; }
.tc-r-zoom .tc-r { transform: scale(.95); }
.tc-r-side .tc-r { transform: translateX(-30px); }

.tc-r.is-in { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
	.tc-r, .tc-r.is-in { opacity: 1; transform: none; transition: none; animation: none; }
}

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

.tc-footcols {
	display: grid; gap: var(--tc-space-lg);
	grid-template-columns: repeat(auto-fit, minmax(min(100%, 210px), 1fr));
	margin-bottom: var(--tc-space-lg);
}

.tc-footcol { min-width: 0; }
.tc-footcol--brand .custom-logo { height: calc(var(--tc-logo-height) * 1.1); width: auto; }
.tc-footcol__name { font-weight: 700; font-size: 1.1rem; margin: 0 0 .6rem; }
.tc-footcol__name a { color: #fff; text-decoration: none; }
.tc-footcol__desc { font-size: .88rem; line-height: 1.75; color: #a9a5a1; margin: .8rem 0 0; max-width: 34ch; }

.tc-footcol__title {
	font-size: .78rem; letter-spacing: .1em; text-transform: uppercase;
	color: #8d8884; margin-bottom: .9rem;
}

.tc-footcol__list { list-style: none; margin: 0; padding: 0; }
.tc-footcol__list li { margin-bottom: .5rem; font-size: .9rem; }
.tc-footcol__list a {
	color: #cfcbc7; text-decoration: none;
	display: inline-flex; gap: .5rem; align-items: baseline;
}
.tc-footcol__list a:hover { color: #fff; }
.tc-footcol__count { font-size: .72rem; color: #7e7a76; }

.tc-social { display: flex; flex-wrap: wrap; gap: .5rem; list-style: none; margin: 1rem 0 0; padding: 0; }
.tc-social__item {
	display: grid; place-items: center;
	width: 36px; height: 36px; border-radius: 50%;
	color: #cfcbc7;
	background: rgba(255, 255, 255, .08);
	transition: background .15s, color .15s;
}
.tc-social__item:hover { background: var(--tc-accent); color: #fff; }

/* =========================================================
   WooCommerce
   Overrides, not a rebuild. WooCommerce's own stylesheet
   still loads on shop pages and does the layout; what
   follows repaints it in the theme's tokens so the shop and
   the articles look like one site.
   ========================================================= */

.woocommerce .tc-shop__bar {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: space-between;
	gap: var(--tc-space-sm) var(--tc-space-md);
	margin-bottom: var(--tc-space-lg);
}
.woocommerce .woocommerce-result-count { margin: 0; font-size: .9rem; color: var(--tc-text-muted); }
.woocommerce .woocommerce-ordering { margin: 0; }
.woocommerce .woocommerce-ordering select {
	padding: .55rem .8rem; font: inherit; font-size: .9rem;
	border: 1px solid var(--tc-border); border-radius: 8px;
	background: var(--tc-surface); color: inherit;
}

/* ---------- The grid ---------- */

/*
 * Grid rather than WooCommerce's floats. Its own layout gives every product a
 * percentage width and clears every nth child, which breaks the moment the
 * column count changes and leaves cards of different heights sitting on a
 * ragged baseline.
 *
 * The column count follows the `columns-N` class WooCommerce already puts on
 * the list, so the `loop_shop_columns` filter in inc/woocommerce.php is what
 * decides it and there is one answer rather than two.
 */
.woocommerce ul.products {
	display: grid;
	grid-template-columns: repeat(3, minmax(0, 1fr));
	gap: var(--tc-space-lg) var(--tc-space-md);
	margin: 0;
	padding: 0;
	list-style: none;
}

.woocommerce ul.products.columns-1 { grid-template-columns: minmax(0, 1fr); }
.woocommerce ul.products.columns-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.woocommerce ul.products.columns-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.woocommerce ul.products.columns-5 { grid-template-columns: repeat(5, minmax(0, 1fr)); }
.woocommerce ul.products.columns-6 { grid-template-columns: repeat(6, minmax(0, 1fr)); }

/* Whatever the owner chose, a tablet gets two and a phone gets one. The column
   count is a decision about a wide screen; nobody makes it about a 390px one. */
@media (max-width: 900px) {
	.woocommerce ul.products,
	.woocommerce ul.products[class*="columns-"] { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (max-width: 480px) {
	.woocommerce ul.products,
	.woocommerce ul.products[class*="columns-"] { grid-template-columns: minmax(0, 1fr); }
}

.woocommerce ul.products::before,
.woocommerce ul.products::after { content: none; }

.woocommerce ul.products li.product {
	position: relative;
	width: auto !important;
	margin: 0 !important;
	float: none !important;
	clear: none !important;
	display: flex;
	flex-direction: column;
	text-align: left;
}

/* ---------- One card ---------- */

/*
 * The tile.
 *
 * Its height comes from `aspect-ratio`, and the picture inside it is taken out
 * of the flow — because an <img> left in the flow contributes its own natural
 * height, and then `height: 100%` resolves against a parent whose height
 * depends on the image. The frame has to be decided without asking the
 * picture, or a listing of photographs at four different shapes goes ragged
 * all over again.
 */
.tc-prod__media {
	position: relative;
	display: block;
	aspect-ratio: 1 / 1;
	margin-bottom: .9rem;
	overflow: hidden;
	background: var(--tc-tile, #f2f1ef);
}

.woocommerce ul.products li.product .tc-prod__media img,
.woocommerce ul.products li.product a img {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	display: block;
	margin: 0;
	border-radius: 0;
	object-fit: contain;
	transition: transform .45s ease;
}

/*
 * Crop instead, when the owner has asked for it.
 *
 * `contain` is the default because it is the one that cannot lie: the whole
 * product is in the frame and the tile colour fills what is left over. `cover`
 * is tidier on a shop whose photographs were all shot to the same square, and
 * takes the ends off anything that was not.
 */
.tc-prod-crop .woocommerce ul.products li.product .tc-prod__media img { object-fit: cover; }

@media (hover: hover) {
	.tc-prod__media:hover img { transform: scale(1.04); }
}

@media (prefers-reduced-motion: reduce) {
	.woocommerce ul.products li.product .tc-prod__media img { transition: none; }
	.tc-prod__media:hover img { transform: none; }
}

/* Title, and the control that shares its line. */
.tc-prod__head {
	display: flex;
	align-items: flex-start;
	justify-content: space-between;
	gap: .5rem;
	margin-bottom: .4rem;
}

.woocommerce ul.products li.product .woocommerce-loop-product__title {
	flex: 1 1 auto;
	font-size: 1rem;
	font-weight: 600;
	line-height: 1.55;
	padding: 0;
	margin: 0;
	color: var(--tc-text);
}
.woocommerce ul.products li.product .woocommerce-loop-product__title a { color: inherit; }
.woocommerce ul.products li.product .woocommerce-loop-product__title a:hover { color: var(--tc-accent); }

/*
 * The heart.
 *
 * Printed with `hidden` by PHP and revealed by the script: it is a note kept in
 * one browser's localStorage, and with the script blocked there is nowhere for
 * that note to go.
 */
.tc-fav {
	flex: 0 0 auto;
	display: grid;
	place-items: center;
	width: 32px;
	height: 32px;
	padding: 0;
	border: 0;
	border-radius: 50%;
	background: none;
	color: var(--tc-text-muted);
	cursor: pointer;
	transition: color .15s, background .15s;
}
.tc-fav svg { display: block; }
.tc-fav:hover { color: var(--tc-accent); background: var(--tc-bg-alt); }
.tc-fav:focus-visible { outline: 2px solid var(--tc-accent); outline-offset: 2px; }
.tc-fav[aria-pressed="true"] { color: var(--tc-accent); }
.tc-fav[aria-pressed="true"] svg path { fill: currentColor; }

.woocommerce ul.products li.product .price {
	color: var(--tc-accent);
	font-size: 1.12rem;
	font-weight: 700;
	margin: 0 0 .6rem;
}
.woocommerce ul.products li.product .price del { color: var(--tc-text-muted); font-weight: 400; margin-right: .4rem; }
.woocommerce ul.products li.product .price ins { text-decoration: none; color: var(--tc-accent); }

/* The button goes to the bottom of the card, so a row of cards with titles of
   different lengths still has its buttons on one line. */
.woocommerce ul.products li.product .button { margin-top: auto; align-self: flex-start; }

/*
 * The catalogue plugin's "see details" link, which stands where a buy button
 * would be. Outlined rather than filled: on a page of twelve cards, twelve
 * solid accent pills are the loudest thing on the screen, and the product
 * photographs are meant to be.
 */
.woocommerce ul.products li.product a.button.tc-loop-more {
	padding: .55rem 1.1rem;
	background: transparent;
	color: var(--tc-text);
	border-color: var(--tc-border);
	font-size: .88rem;
	font-weight: 500;
}
.woocommerce ul.products li.product a.button.tc-loop-more:hover {
	background: var(--tc-accent);
	border-color: var(--tc-accent);
	color: #fff;
}

.woocommerce span.onsale {
	top: .6rem; left: .6rem; right: auto;
	min-width: 0; min-height: 0; margin: 0; padding: .25rem .6rem;
	border-radius: 999px;
	background: var(--tc-accent);
	font-size: .72rem; font-weight: 600; line-height: 1.5;
}

/* ---------- Pages of products ---------- */

.woocommerce nav.woocommerce-pagination { margin-top: var(--tc-space-lg); }

.woocommerce nav.woocommerce-pagination ul {
	display: flex;
	flex-wrap: wrap;
	justify-content: center;
	gap: .4rem;
	border: 0;
	margin: 0;
	padding: 0;
}

.woocommerce nav.woocommerce-pagination ul li {
	border: 0;
	margin: 0;
	float: none;
	overflow: visible;
}

.woocommerce nav.woocommerce-pagination ul li a,
.woocommerce nav.woocommerce-pagination ul li span {
	display: grid;
	place-items: center;
	min-width: 42px;
	height: 42px;
	padding: 0 .6rem;
	border: 1px solid var(--tc-border);
	background: var(--tc-surface);
	color: var(--tc-text);
	font-size: .95rem;
	line-height: 1;
	transition: background .15s, border-color .15s, color .15s;
}

.woocommerce nav.woocommerce-pagination ul li a:hover,
.woocommerce nav.woocommerce-pagination ul li a:focus {
	background: var(--tc-bg-alt);
	border-color: var(--tc-text);
	color: var(--tc-text);
}

/* The page you are on is a label, not a link — filled rather than outlined,
   and there is nothing on it to click. */
.woocommerce nav.woocommerce-pagination ul li span.current {
	background: var(--tc-text);
	border-color: var(--tc-text);
	color: var(--tc-bg);
	font-weight: 600;
}

/* ---------- The category column ---------- */

/*
 * The column beside a listing, as nearly every shop draws it: every category,
 * the branch you are standing in already open, the one you are on in bold.
 *
 * Its own rules rather than the generic .tc-widget ones, because those put a
 * rule between every item — right for three recent posts, wrong for forty
 * categories, where forty hairlines read as a table of contents nobody asked
 * for.
 */

.tc-cats .tc-widget__title {
	padding-bottom: .7rem;
	margin-bottom: .2rem;
	border-bottom: 1px solid var(--tc-border);
}

.tc-cats ul { list-style: none; margin: 0; padding: 0; }

.tc-cats .tc-cats__item {
	padding: 0;
	border-bottom: 0;
	font-size: .95rem;
}

.tc-cats__row {
	display: flex;
	align-items: center;
	gap: .35rem;
}

.tc-cats__link {
	flex: 1 1 auto;
	min-width: 0;
	padding: .5rem 0;
	color: var(--tc-text-muted);
	text-decoration: none;
	transition: color .15s;
}
.tc-cats__link:hover { color: var(--tc-accent); }

/* Where you are, said once and plainly. */
.tc-cats__item--on > .tc-cats__row > .tc-cats__link {
	color: var(--tc-text);
	font-weight: 600;
}

.tc-cats__count {
	flex: 0 0 auto;
	font-size: .78rem;
	color: var(--tc-text-muted);
	font-variant-numeric: tabular-nums;
}

.tc-cats__toggle {
	flex: 0 0 auto;
	display: grid;
	place-items: center;
	width: 28px;
	height: 28px;
	padding: 0;
	border: 0;
	border-radius: 50%;
	background: none;
	color: var(--tc-text-muted);
	cursor: pointer;
	transition: color .15s, background .15s;
}
.tc-cats__toggle:hover { color: var(--tc-text); background: var(--tc-bg-alt); }
.tc-cats__toggle:focus-visible { outline: 2px solid var(--tc-accent); outline-offset: 2px; }
.tc-cats__toggle svg { display: block; transition: transform .2s ease; }
.tc-cats__toggle[aria-expanded="true"] svg { transform: rotate(180deg); }

/* Indented by one step at every depth, and a shade smaller — once, not
   compounding, so a category four levels down is still readable. */
.tc-cats__kids > .tc-cats__list { padding-left: 1rem; }
.tc-cats__kids .tc-cats__item { font-size: .9rem; }

@media (prefers-reduced-motion: reduce) {
	.tc-cats__toggle svg { transition: none; }
}

/*
 * Sticky, but with a floor under it.
 *
 * A sticky element taller than the window pins its top and leaves everything
 * past the fold unreachable — which on a shop with forty categories is most of
 * them. Capping the height and letting the overflow scroll is what makes a
 * long list behave; the cap uses the header height the theme already tracks,
 * so it stays right when the header does.
 */
@media (min-width: 1024px) {
	.tc-shop-aside {
		position: sticky;
		top: calc(var(--tc-header-h) + 1rem);
		max-height: calc(100vh - var(--tc-header-h) - 2rem);
		overflow-y: auto;
		overscroll-behavior: contain;
		scrollbar-width: thin;
	}
}

/*
 * Three columns of products is a decision about a full-width page. Beside a
 * 300-pixel sidebar on a 1024-pixel laptop it leaves each product about two
 * hundred pixels wide, which is a thumbnail, not a photograph.
 */
@media (min-width: 1024px) and (max-width: 1250px) {
	.tc-layout--aside .woocommerce ul.products,
	.tc-layout--aside .woocommerce ul.products[class*="columns-"] { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* ---------- Buttons ---------- */

.woocommerce a.button,
.woocommerce button.button,
.woocommerce input.button,
.woocommerce #respond input#submit,
.woocommerce a.button.alt,
.woocommerce button.button.alt {
	padding: .7rem 1.4rem;
	border: 1px solid var(--tc-accent);
	border-radius: 999px;
	background: var(--tc-accent);
	color: #fff;
	font: inherit;
	font-size: .92rem;
	font-weight: 500;
	line-height: 1.4;
	transition: background .15s, border-color .15s;
}
.woocommerce a.button:hover,
.woocommerce button.button:hover,
.woocommerce input.button:hover,
.woocommerce #respond input#submit:hover,
.woocommerce a.button.alt:hover,
.woocommerce button.button.alt:hover {
	background: var(--tc-accent-hover);
	border-color: var(--tc-accent-hover);
	color: #fff;
}

.woocommerce a.added_to_cart { display: inline-block; margin-top: .4rem; font-size: .85rem; }

/* ---------- One product ---------- */

.woocommerce div.product .product_title { font-size: var(--tc-fs-h2); margin-bottom: .5rem; }
.woocommerce div.product p.price,
.woocommerce div.product span.price { color: var(--tc-accent); font-size: 1.5rem; font-weight: 700; }
.woocommerce div.product .woocommerce-product-details__short-description { color: var(--tc-text-muted); line-height: 1.8; }

.woocommerce div.product form.cart { margin-block: var(--tc-space-md); }
.woocommerce div.product form.cart div.quantity input.qty,
.woocommerce .quantity input.qty {
	padding: .6rem .4rem; font: inherit;
	border: 1px solid var(--tc-border); border-radius: 8px;
	background: var(--tc-surface); color: inherit;
}

.woocommerce div.product .woocommerce-tabs ul.tabs { padding: 0; margin-bottom: var(--tc-space-md); }
.woocommerce div.product .woocommerce-tabs ul.tabs::before { border-bottom-color: var(--tc-border); }
.woocommerce div.product .woocommerce-tabs ul.tabs li {
	border-color: var(--tc-border); border-radius: 8px 8px 0 0; background: var(--tc-bg-alt);
}
.woocommerce div.product .woocommerce-tabs ul.tabs li.active { background: var(--tc-surface); }
.woocommerce div.product .woocommerce-tabs ul.tabs li::before,
.woocommerce div.product .woocommerce-tabs ul.tabs li::after { display: none; }

.woocommerce .related > h2,
.woocommerce .upsells > h2,
.woocommerce .cross-sells > h2 { font-size: var(--tc-fs-h3); margin-bottom: var(--tc-space-md); }

/* ---------- Basket ---------- */

.woocommerce table.shop_table {
	border-color: var(--tc-border);
	border-radius: var(--tc-radius);
	font-size: .95rem;
}
.woocommerce table.shop_table th { background: var(--tc-bg-alt); font-weight: 600; }
.woocommerce table.shop_table td { border-top-color: var(--tc-border); }

.woocommerce .cart_totals h2,
.woocommerce-cart .cart-collaterals h2 { font-size: var(--tc-fs-h3); }

.woocommerce #coupon_code,
.woocommerce form .form-row input.input-text,
.woocommerce form .form-row textarea,
.woocommerce form .form-row select {
	padding: .7rem .9rem; font: inherit; font-size: .95rem;
	border: 1px solid var(--tc-border); border-radius: 8px;
	background: var(--tc-surface); color: inherit;
}
.woocommerce form .form-row input.input-text:focus,
.woocommerce form .form-row textarea:focus { border-color: var(--tc-accent); outline: none; }

/* ---------- Messages ---------- */

.woocommerce-message,
.woocommerce-info,
.woocommerce-error {
	border-top-color: var(--tc-accent);
	background: var(--tc-bg-alt);
	border-radius: var(--tc-radius);
	font-size: .95rem;
}
.woocommerce-message::before,
.woocommerce-info::before { color: var(--tc-accent); }
.woocommerce-error { border-top-color: #d63638; }
.woocommerce-error::before { color: #d63638; }
