/* =========================================================
   TomatoCat Core — Elementor widget styles
   Colours and spacing are driven by each widget's Style tab;
   this carries structure plus sensible defaults so the widgets
   look right the moment they are dropped on a page.
   ========================================================= */

.tc-section {
	position: relative;
	background: #0d0d0d;
	color: #fff;
	--tc-w-transition: 220ms cubic-bezier(0.2, 0.8, 0.2, 1);
	--tc-w-lift: cubic-bezier(0.16, 1, 0.3, 1);
	--tc-i: 0;
}

/* Break out of a boxed Elementor container so the colour band reaches both
   edges of the viewport.
   `100vw` includes the scrollbar, so the band would sit a few pixels wide and
   cause a horizontal scroll. Measuring against the root element's width
   instead — set by the theme — keeps it exact; the vw values are only a
   fallback for when that variable is missing. */
.tc-section.is-bleed {
	--tc-vw: var(--tc-viewport, 100vw);

	margin-inline: calc(50% - var(--tc-vw) / 2);
	padding-inline: max(var(--tc-gutter, 24px), calc(var(--tc-vw) / 2 - 50%));
	max-width: var(--tc-vw);
}

@supports not (width: max(1px, 2px)) {
	.tc-section.is-bleed {
		padding-inline: calc(var(--tc-vw) / 2 - 50%);
	}
}

.tc-section__inner {
	width: 100%;
	max-width: var(--tc-container, 1200px);
	margin-inline: auto;
}

.tc-section__head { margin-bottom: clamp(2rem, 5vw, 3.5rem); }

.tc-section__eyebrow {
	margin: 0 0 0.5rem;
	color: #e9c46a;
	font-size: 0.875rem;
	font-weight: 600;
	letter-spacing: 0.35em;
	text-transform: uppercase;
}

.tc-section__title {
	margin: 0;
	color: #fff;
	font-size: clamp(2rem, 1.2rem + 3vw, 3.5rem);
	line-height: 1.15;
	font-weight: 800;
}

.tc-section__title .tc-hl { color: #e9c46a; }

.tc-hl-underline .tc-section__title {
	text-decoration: underline;
	text-decoration-thickness: 3px;
	text-underline-offset: 0.14em;
}

/* ---------- Course grid ---------- */

.tc-course-grid {
	display: grid;
	grid-template-columns: repeat(3, minmax(0, 1fr));
	gap: 24px;
}

.tc-course-card {
	position: relative;
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: 0.6rem;
	padding: 28px;
	border-radius: 16px;
	background: #e9f2fb;
	color: #1c1b1a;
	overflow: hidden;
	isolation: isolate;
	transition:
		transform 320ms var(--tc-w-lift),
		box-shadow 320ms var(--tc-w-lift);
}

/* ---------- Course card image ---------- */

/*
 * align-self: stretch is what makes this full width — the card is a flex column
 * with align-items: flex-start, so without it the image would shrink to its own
 * intrinsic width and sit in a corner. The negative side margins that push it
 * out through the card padding are written by the padding control itself, so the
 * two can never drift apart.
 */
.tc-course-card__media {
	align-self: stretch;
	position: relative;
	overflow: hidden;
	aspect-ratio: 4 / 3;
	background: rgba(28, 27, 26, 0.06);
}

.tc-course-card__img {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
	transition: transform 520ms var(--tc-w-lift);
}

/* Inset variant keeps its own rounded corners; the bleeding variant inherits
   the card's, and the card already has overflow: hidden to clip it. */
.tc-course-card:not(.tc-course-card--bleed) .tc-course-card__media {
	border-radius: 10px;
}

.tc-course-card--zoom:hover .tc-course-card__img,
.tc-course-card--zoom:focus-within .tc-course-card__img { transform: scale(1.06); }

@media (prefers-reduced-motion: reduce) {
	.tc-course-card__img,
	.tc-course-card--zoom:hover .tc-course-card__img { transition: none; transform: none; }
}

/* ---------- Card alignment ---------- */

/*
 * The grid already makes every card the same height. What breaks the row is the
 * *inside* of the card: a short description lets the button float up while its
 * neighbour's sits low. Pushing the button down with an auto margin puts every
 * one of them on the same line.
 */
.tc-course-card--equal .tc-course-card__btn { margin-top: auto; }

/*
 * Clamping by lines rather than by words, because Thai has no spaces —
 * wp_trim_words() counts one enormous "word" and trims nothing, so a word limit
 * alone leaves the cards ragged. The custom property is only printed when a
 * limit is set, so the fallback of `none` means "no clamp".
 *
 * Deliberately only the description, never the title. The title carries the
 * anchor whose ::after covers the whole card, and putting overflow: hidden on
 * an element in that chain is exactly the sort of change that made the cards
 * unclickable once before. Lining the buttons up already equalises the row, so
 * clamping the title would be risk for no gain.
 */
.tc-course-card__text {
	display: -webkit-box;
	-webkit-box-orient: vertical;
	-webkit-line-clamp: var(--tc-cc-text-lines, none);
	overflow: hidden;
}

/* Soft sheen that sweeps across on hover. */
.tc-course-card::after {
	content: "";
	position: absolute;
	inset: 0;
	z-index: 0;
	background: linear-gradient( 115deg, transparent 30%, rgba(255, 255, 255, 0.55) 50%, transparent 70% );
	transform: translateX(-120%);
	opacity: 0;
	pointer-events: none;
	transition: transform 700ms var(--tc-w-lift), opacity 200ms ease;
}

.tc-course-card:hover {
	transform: translateY(-6px);
	box-shadow: 0 22px 48px rgba(0, 0, 0, 0.38);
}

.tc-course-card:hover::after {
	transform: translateX(120%);
	opacity: 1;
}

.tc-course-card > * { position: relative; z-index: 1; }

/* Keyboard users get the same affordance as mouse users. */
.tc-course-card:focus-within {
	transform: translateY(-6px);
	box-shadow: 0 22px 48px rgba(0, 0, 0, 0.38);
}

/* Fallback palette so the grid looks right before Elementor writes its CSS. */
.tc-course-card--1 { background: #e9f2fb; }
.tc-course-card--2 { background: #fbf7dc; }
.tc-course-card--3 { background: #eaf4fb; }
.tc-course-card--4 { background: #fbe9ec; }
.tc-course-card--5 { background: #fdf2e3; }
.tc-course-card--6 { background: #e5f7ea; }

/*
 * The title is a normal link; its ::after is what makes the whole card
 * clickable. z-index 3 puts it above the card's own children (1) and the hover
 * sheen (0), which is what the old empty-anchor version got wrong — everything
 * sat at z-index 1 and the later siblings covered the link.
 */
.tc-course-card__link {
	color: inherit;
	text-decoration: none;
}

.tc-course-card__link::after {
	content: "";
	position: absolute;
	inset: 0;
	z-index: 3;
	border-radius: inherit;
}

.tc-course-card__link:focus-visible {
	outline: 3px solid currentColor;
	outline-offset: 3px;
	border-radius: 4px;
}

.tc-course-card__eyebrow {
	margin: 0;
	font-size: 0.875rem;
	font-weight: 600;
	opacity: 0.75;
}

.tc-course-card__title {
	margin: 0;
	font-size: clamp(1.35rem, 1.1rem + 0.8vw, 1.75rem);
	line-height: 1.25;
	font-weight: 800;
	color: inherit;
}

/* The heading must not create a stacking context, or the overlay would be
   trapped inside it and only cover the title. */
.tc-course-card__title { position: static; z-index: auto; }

.tc-course-card__text {
	margin: 0;
	font-size: 0.9375rem;
	line-height: 1.6;
	opacity: 0.85;
}

.tc-course-card__btn {
	display: inline-flex;
	align-items: center;
	gap: 0.4rem;
	margin-top: auto;
	padding: 0.7rem 1.35rem;
	border-radius: 999px;
	background: #f2c063;
	color: #1c1b1a;
	font-size: 0.9375rem;
	font-weight: 700;
	line-height: 1;
	transition: background var(--tc-w-transition), color var(--tc-w-transition);
}

.tc-course-card:hover .tc-course-card__btn span { transform: translateX(3px); }
.tc-course-card__btn span { transition: transform var(--tc-w-transition); }

/* ---------- Testimonials ---------- */

.tc-testimonials {
	display: grid;
	grid-template-columns: repeat(3, minmax(0, 1fr));
	gap: 24px;
}

.tc-testimonial {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 1rem;
	margin: 0;
	padding: 40px 32px;
	border-radius: 24px;
	background: #fff;
	text-align: center;
	transition:
		transform 320ms var(--tc-w-lift),
		box-shadow 320ms var(--tc-w-lift);
}

.tc-testimonial:hover {
	transform: translateY(-6px);
	box-shadow: 0 22px 48px rgba(0, 0, 0, 0.32);
}

.tc-testimonial__stars {
	color: #f2c063;
	font-size: 1.25rem;
	letter-spacing: 0.15em;
	line-height: 1;
}

.tc-testimonial__quote {
	margin: 0;
	color: #1c1b1a;
	font-size: 1rem;
	line-height: 1.7;
	quotes: "\201C" "\201D";
}
.tc-testimonial__quote::before { content: open-quote; }
.tc-testimonial__quote::after { content: close-quote; }

.tc-testimonial__author {
	margin-top: auto;
	padding-top: 0.5rem;
	color: #5a5754;
	font-size: 0.875rem;
	font-weight: 600;
}

.tc-testimonial__role { opacity: 0.75; font-weight: 400; }
.tc-testimonial__role::before { content: " · "; }

/* Google attribution — required whenever their review data is shown. */
.tc-testimonials__source {
	display: flex;
	align-items: center;
	justify-content: center;
	gap: 0.5rem;
	margin: 1.5rem 0 0;
	color: rgba(255, 255, 255, 0.6);
	font-size: 0.8125rem;
}

.tc-testimonials__gicon { display: flex; }

/* ---------- Stats bar ---------- */

.tc-section--stats { background: #f2c063; }

.tc-stats {
	display: grid;
	grid-template-columns: repeat(var(--tc-stat-cols, 4), minmax(0, 1fr));
	gap: 24px;
	align-items: end;
	--tc-stat-rule: rgba(28, 27, 26, 0.18);
}

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

/* The rule goes on the item rather than between grid tracks so it lines up
   with the text whatever the gap is set to, and it is dropped on the first item
   in each row rather than the first overall — otherwise a wrapped row starts
   with a stray line. */
.tc-stats.has-rules .tc-stat {
	border-inline-start: 1px solid var(--tc-stat-rule);
	padding-inline-start: 24px;
}

.tc-stats.has-rules .tc-stat:first-child { border-inline-start: 0; padding-inline-start: 0; }

.tc-stat__value {
	color: #1c1b1a;
	font-size: clamp(1.75rem, 1.1rem + 2.2vw, 2.75rem);
	font-weight: 800;
	line-height: 1.1;
	/* Tabular figures keep the width steady while the count-up runs, so the
	   row cannot jitter as digits change. */
	font-variant-numeric: tabular-nums;
	font-feature-settings: "tnum" 1;
}

.tc-stat__label {
	margin-top: 6px;
	color: #1c1b1a;
	font-size: clamp(0.8125rem, 0.75rem + 0.3vw, 1rem);
	line-height: 1.5;
}

/* ---------- Carousel ---------- */

/* The wrapper holds two things: the stage, which is still the ordinary
   .tc-course-grid / .tc-testimonials grid so every Style-tab control keeps
   working, and a hidden pool of every card the query returned. JS shuffles the
   pool and clones cards into fixed slots, so the grid never reflows. */

.tc-carousel { position: relative; }

/* Cards translate and lift, so give the clip a margin — otherwise a hover
   shadow gets sliced off. Where overflow-clip-margin is unsupported the clip
   simply happens at the edge, which still prevents a horizontal scrollbar. */
.tc-carousel--slide {
	overflow: clip;
	overflow-clip-margin: 28px;
}

.tc-carousel__slot {
	display: flex;
	min-width: 0;
}

.tc-carousel__slot > * {
	flex: 1 1 auto;
	min-width: 0;
}

/* The pool carries the grid class too, so with JS blocked or still loading the
   visitor simply sees every card in a normal grid. The stage takes over only
   once it has something in it. */
.tc-carousel:not(.is-ready) [data-carousel-stage] { display: none; }
.tc-carousel.is-ready .tc-carousel__pool { display: none; }

/* Two exit/enter pairs. Keyframes rather than transitions: the swap replaces
   the card mid-flight, and a transition would need a forced reflow between
   removing one class and adding the next to restart. */

@keyframes tc-slot-out-pop {
	from { opacity: 1; transform: scale(1); }
	to   { opacity: 0; transform: scale(0.94); }
}

@keyframes tc-slot-in-pop {
	from { opacity: 0; transform: scale(0.94); }
	to   { opacity: 1; transform: scale(1); }
}

/* --tc-dir flips the sign so "moving right" means the old card leaves to the
   right and the new one arrives from the left. */
@keyframes tc-slot-out-slide {
	from { opacity: 1; transform: translateX(0); }
	to   { opacity: 0; transform: translateX(calc(var(--tc-dir, 1) * 2.5rem)); }
}

@keyframes tc-slot-in-slide {
	from { opacity: 0; transform: translateX(calc(var(--tc-dir, 1) * -2.5rem)); }
	to   { opacity: 1; transform: translateX(0); }
}

.tc-carousel.is-dir-right { --tc-dir: 1; }
.tc-carousel.is-dir-left  { --tc-dir: -1; }

.tc-carousel--pop .tc-carousel__slot.is-leaving {
	animation: tc-slot-out-pop 300ms var(--tc-w-lift, ease) forwards;
}

.tc-carousel--pop .tc-carousel__slot.is-entering {
	animation: tc-slot-in-pop 400ms var(--tc-w-lift, ease);
}

.tc-carousel--slide .tc-carousel__slot.is-leaving {
	animation: tc-slot-out-slide 300ms var(--tc-w-lift, ease) forwards;
}

.tc-carousel--slide .tc-carousel__slot.is-entering {
	animation: tc-slot-in-slide 400ms var(--tc-w-lift, ease);
}

/* ---------- "See all" button ---------- */

.tc-section__cta {
	display: flex;
	margin-top: clamp(2rem, 4vw, 3rem);
}

.tc-section__cta.is-left   { justify-content: flex-start; }
.tc-section__cta.is-center { justify-content: center; }
.tc-section__cta.is-right  { justify-content: flex-end; }

.tc-btn-all {
	display: inline-flex;
	align-items: center;
	gap: 0.6em;
	padding: 0.9em 2em;
	border-radius: 999px;
	background: #f2c063;
	color: #1c1b1a;
	font-weight: 700;
	line-height: 1.2;
	text-decoration: none;
	transition:
		background-color var(--tc-w-transition, 220ms ease),
		color var(--tc-w-transition, 220ms ease),
		transform var(--tc-w-transition, 220ms ease);
}

.tc-btn-all span { transition: transform var(--tc-w-transition, 220ms ease); }

.tc-btn-all:hover,
.tc-btn-all:focus-visible { transform: translateY(-2px); }
.tc-btn-all:hover span,
.tc-btn-all:focus-visible span { transform: translateX(4px); }

/* ---------- Responsive ---------- */

@media (max-width: 900px) {
	.tc-course-grid,
	.tc-testimonials { grid-template-columns: repeat(2, minmax(0, 1fr)) !important; }
}

@media (max-width: 600px) {
	.tc-course-grid,
	.tc-testimonials { grid-template-columns: minmax(0, 1fr) !important; }
	.tc-section__eyebrow { letter-spacing: 0.25em; }
}

/* A carousel narrows with the grid rather than stacking its slots — three
   cards in a column is a list, not a carousel. The hidden slots keep rotating
   in the background, so nothing breaks if the window is widened again. */
@media (max-width: 900px) {
	.tc-carousel__slot:nth-child(n + 3) { display: none; }
}

@media (max-width: 600px) {
	.tc-carousel__slot:nth-child(n + 2) { display: none; }
}

/* Stats. Kept at plain single-class specificity so Elementor's own "Columns on
   mobile" control, which generates a higher-specificity rule, can override it. */
@media (max-width: 900px) {
	.tc-stats { grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); }
}

@media (max-width: 600px) {
	.tc-stats { grid-template-columns: repeat(2, minmax(0, 1fr)); }

	/* A vertical rule between rows of two reads as a mistake, so drop it. */
	.tc-stats.has-rules .tc-stat {
		border-inline-start: 0;
		padding-inline-start: 0;
	}
}

@media (prefers-reduced-motion: reduce) {
	.tc-carousel__slot.is-leaving,
	.tc-carousel__slot.is-entering { animation: none; }

	.tc-btn-all,
	.tc-btn-all span { transition: none; }

	.tc-btn-all:hover,
	.tc-btn-all:focus-visible { transform: none; }
}

/* ---------- Contact ---------- */

.tc-section--contact { color: #1c1b1a; }
.tc-section--contact .tc-section__title { color: #1c1b1a; }
.tc-section--contact .tc-section__eyebrow { color: #e0503c; }

.tc-contact {
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	gap: 48px;
	align-items: start;
}

/* Map first in the DOM order stays second visually unless flipped. */
.tc-contact--flip .tc-contact__details { order: 2; }
.tc-contact--flip .tc-contact__map { order: 1; }

@media (max-width: 860px) {
	.tc-contact { grid-template-columns: minmax(0, 1fr); }
	.tc-contact--flip .tc-contact__details,
	.tc-contact--flip .tc-contact__map { order: 0; }
}

.tc-contact__intro {
	margin: 0 0 1.5rem;
	max-width: 46ch;
	line-height: 1.8;
	color: #5a5754;
}

.tc-contact__list {
	list-style: none;
	margin: 0;
	padding: 0;
	display: flex;
	flex-direction: column;
	gap: 1.1rem;
}

.tc-contact__item {
	display: flex;
	align-items: flex-start;
	gap: 0.9rem;
	margin: 0;
}

.tc-contact__icon {
	flex: 0 0 auto;
	width: 42px;
	height: 42px;
	display: flex;
	align-items: center;
	justify-content: center;
	border-radius: 12px;
	background: #f6f1ec;
	color: #e0503c;
}

.tc-contact__body {
	display: flex;
	flex-direction: column;
	gap: 0.15rem;
	min-width: 0;
}

.tc-contact__label {
	font-size: 0.8125rem;
	font-weight: 700;
	letter-spacing: 0.02em;
	color: #1c1b1a;
}

.tc-contact__value {
	color: #5a5754;
	font-size: 0.9375rem;
	line-height: 1.7;
	overflow-wrap: break-word;
}

.tc-contact__hours { font-variant-numeric: tabular-nums; }

a.tc-contact__value { transition: color 180ms var(--tc-w-transition); }
a.tc-contact__value:hover { color: #e0503c; }

.tc-contact__social {
	list-style: none;
	display: flex;
	flex-wrap: wrap;
	gap: 0.5rem;
	margin: 1.5rem 0 0;
	padding: 0;
}

.tc-contact__chip {
	display: inline-flex;
	align-items: center;
	gap: 0.4rem;
	padding: 0.5rem 0.9rem;
	border: 1px solid rgba(28, 27, 26, 0.14);
	border-radius: 999px;
	color: #1c1b1a;
	font-size: 0.8125rem;
	font-weight: 600;
	text-decoration: none;
	transition: background 180ms var(--tc-w-transition), border-color 180ms var(--tc-w-transition), color 180ms var(--tc-w-transition);
}

.tc-contact__chip svg { width: 16px; height: 16px; }

.tc-contact__chip:hover {
	background: #e0503c;
	border-color: #e0503c;
	color: #fff;
}

.tc-contact__btn {
	display: inline-flex;
	align-items: center;
	gap: 0.45rem;
	margin-top: 1.75rem;
	padding: 0.9rem 1.6rem;
	border-radius: 999px;
	background: #e0503c;
	color: #fff;
	font-weight: 700;
	font-size: 0.9375rem;
	line-height: 1;
	text-decoration: none;
	transition: background 180ms var(--tc-w-transition), transform 180ms var(--tc-w-lift);
}

.tc-contact__btn:hover { background: #b93b2a; color: #fff; transform: translateY(-2px); }
.tc-contact__btn span { transition: transform 180ms var(--tc-w-transition); }
.tc-contact__btn:hover span { transform: translateX(3px); }

/* Map */

.tc-contact__map {
	position: relative;
	width: 100%;
	aspect-ratio: 4 / 3;
	border-radius: 16px;
	overflow: hidden;
	background: #f0efee;
	box-shadow: 0 10px 30px rgba(28, 27, 26, 0.12);
}

/* "Match the column height" — stretch instead of holding a ratio. */
.tc-contact__map.is-match {
	aspect-ratio: auto;
	align-self: stretch;
	min-height: 320px;
}

.tc-contact__map iframe {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	border: 0;
	display: block;
}

.tc-contact__map.is-empty {
	display: flex;
	align-items: center;
	justify-content: center;
	padding: 1.5rem;
	text-align: center;
	color: #8c8f94;
	box-shadow: none;
	border: 1px dashed rgba(28, 27, 26, 0.2);
}

@media (prefers-reduced-motion: reduce) {
	.tc-contact__btn,
	.tc-contact__btn span,
	.tc-contact__chip,
	a.tc-contact__value { transition: none; }
	.tc-contact__btn:hover { transform: none; }
	.tc-contact__btn:hover span { transform: none; }
}

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

/* Cards start slightly low and faded, then settle in sequence. The animation
   is driven purely by CSS; JS only adds .tc-in when the section scrolls into
   view. Without JS everything stays visible, so nothing can get stuck hidden. */

.tc-section .tc-course-card,
.tc-section .tc-testimonial,
.tc-section .tc-section__eyebrow,
.tc-section .tc-section__title {
	--tc-delay: calc(var(--tc-i, 0) * 70ms);
}

.tc-section.tc-reveal .tc-course-card,
.tc-section.tc-reveal .tc-testimonial,
.tc-section.tc-reveal .tc-section__eyebrow,
.tc-section.tc-reveal .tc-section__title {
	opacity: 0;
	transform: translateY(18px);
}

.tc-section.tc-reveal.tc-in .tc-course-card,
.tc-section.tc-reveal.tc-in .tc-testimonial,
.tc-section.tc-reveal.tc-in .tc-section__eyebrow,
.tc-section.tc-reveal.tc-in .tc-section__title {
	opacity: 1;
	transform: none;
	transition:
		opacity 520ms var(--tc-w-lift) var(--tc-delay),
		transform 520ms var(--tc-w-lift) var(--tc-delay);
}

.tc-section.tc-reveal .tc-section__eyebrow { --tc-delay: 0ms; }
.tc-section.tc-reveal .tc-section__title { --tc-delay: 60ms; }

/* Hover lift must not fight the reveal transition once it has finished. */
.tc-section.tc-in .tc-course-card:hover,
.tc-section.tc-in .tc-testimonial:hover { transition: transform 320ms var(--tc-w-lift), box-shadow 320ms var(--tc-w-lift); }

@media (prefers-reduced-motion: reduce) {
	.tc-course-card,
	.tc-testimonial,
	.tc-course-card__btn,
	.tc-course-card__btn span,
	.tc-course-card::after { transition: none !important; }

	.tc-course-card:hover,
	.tc-course-card:focus-within,
	.tc-testimonial:hover { transform: none; }

	.tc-section.tc-reveal .tc-course-card,
	.tc-section.tc-reveal .tc-testimonial,
	.tc-section.tc-reveal .tc-section__eyebrow,
	.tc-section.tc-reveal .tc-section__title {
		opacity: 1;
		transform: none;
	}
}

/* ---------- Spotlight ---------- */

.tc-section--spotlight { background: #141414; }

.tc-spot {
	--tc-spot-dim: 0.75;
	position: relative;
}

/*
 * Flex, not grid: the open panel grows by flex-grow, and flex-grow is one of
 * the few sizing properties that animates smoothly. Animating grid columns is
 * still unreliable across engines.
 */
.tc-spot__track {
	display: flex;
	gap: 16px;
	height: 380px;
}

.tc-spot__item {
	position: relative;
	flex: 1 1 0;
	min-width: 0;
	overflow: hidden;
	border-radius: 18px;
	isolation: isolate;
	background: #0d0d0d;
	transition: flex-grow 620ms cubic-bezier(0.16, 1, 0.3, 1);
}

.tc-spot__item.is-open { flex-grow: 3.2; }

.tc-spot__img {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	object-fit: cover;
	filter: brightness(var(--tc-spot-dim, 0.75));
	transform: scale(1.04);
	transition: filter 520ms ease, transform 900ms cubic-bezier(0.16, 1, 0.3, 1);
}

.tc-spot__item.is-open .tc-spot__img {
	filter: brightness(1);
	transform: scale(1);
}

.tc-spot__veil {
	position: absolute;
	inset: 0;
	z-index: 1;
	background: linear-gradient(
		to top,
		rgba(0, 0, 0, var(--tc-spot-veil-a, 0.78)) 0%,
		rgba(0, 0, 0, calc(var(--tc-spot-veil-a, 0.78) * 0.35)) 45%,
		transparent 78%
	);
	pointer-events: none;
}

/* The colour picker writes --tc-spot-veil; recolouring the gradient means
   rebuilding it, so the custom-colour case gets its own rule. */
.tc-spot__item[style*="--tc-spot-veil"] .tc-spot__veil {
	background: linear-gradient(
		to top,
		color-mix(in srgb, var(--tc-spot-veil, #000) calc(var(--tc-spot-veil-a, 0.78) * 100%), transparent) 0%,
		color-mix(in srgb, var(--tc-spot-veil, #000) calc(var(--tc-spot-veil-a, 0.78) * 35%), transparent) 45%,
		transparent 78%
	);
}

.tc-spot__body {
	position: absolute;
	inset: auto 0 0 0;
	z-index: 2;
	padding: clamp(16px, 2vw, 28px);
	color: #fff;
}

.tc-spot__eyebrow {
	margin: 0 0 0.35rem;
	color: #e9c46a;
	font-size: 0.75rem;
	font-weight: 700;
	letter-spacing: 0.18em;
	text-transform: uppercase;
	/* Closed panels are narrow; a wrapping eyebrow looks like a mistake. */
	white-space: nowrap;
	overflow: hidden;
	text-overflow: ellipsis;
	opacity: 0;
	transition: opacity 320ms ease;
}

.tc-spot__item.is-open .tc-spot__eyebrow { opacity: 1; }

.tc-spot__title {
	margin: 0;
	color: #fff;
	font-size: clamp(1.1rem, 0.9rem + 0.6vw, 1.6rem);
	line-height: 1.25;
	font-weight: 800;
	white-space: nowrap;
}

.tc-spot__item.is-open .tc-spot__title { white-space: normal; }

.tc-spot__link { color: inherit; text-decoration: none; }

/* One anchor covering the panel, at a z-index above the body and the veil —
   the same pattern the course cards use, and for the same reason. */
.tc-spot__link::after {
	content: "";
	position: absolute;
	inset: 0;
	z-index: 3;
	border-radius: inherit;
}

.tc-spot__text {
	margin: 0.5rem 0 0;
	max-width: 46ch;
	color: rgba(255, 255, 255, 0.82);
	font-size: 0.9375rem;
	line-height: 1.6;
	display: -webkit-box;
	-webkit-box-orient: vertical;
	-webkit-line-clamp: var(--tc-spot-lines, 3);
	overflow: hidden;
	/* Closed panels collapse the description rather than hiding it outright, so
	   the height change animates with the width instead of snapping. */
	max-height: 0;
	opacity: 0;
	transition: max-height 520ms cubic-bezier(0.16, 1, 0.3, 1), opacity 320ms ease, margin 520ms ease;
}

.tc-spot__item.is-open .tc-spot__text {
	max-height: 12em;
	opacity: 1;
}

/* ---------- Spotlight dots ---------- */

.tc-spot__dots {
	display: flex;
	justify-content: center;
	gap: 0.55rem;
	margin-top: clamp(1rem, 2vw, 1.75rem);
}

.tc-spot__dot {
	width: 8px;
	height: 8px;
	padding: 0;
	border: 0;
	border-radius: 999px;
	background: rgba(255, 255, 255, 0.35);
	cursor: pointer;
	transition: background 260ms ease, width 320ms cubic-bezier(0.16, 1, 0.3, 1);
}

.tc-spot__dot.is-on {
	width: 22px;
	background: #fff;
}

.tc-spot__dot:focus-visible { outline: 2px solid #fff; outline-offset: 3px; }

/* ---------- Spotlight on phones ---------- */

/*
 * There is no hover on a touch screen, so the accordion has nothing to open it.
 * Below 900px the row becomes a swipeable slider with every panel open — the
 * same content, a gesture that exists on the device.
 */
@media (max-width: 900px) {
	.tc-spot__track {
		gap: 12px;
		overflow-x: auto;
		scroll-snap-type: x mandatory;
		scrollbar-width: none;
		-webkit-overflow-scrolling: touch;
	}

	.tc-spot__track::-webkit-scrollbar { display: none; }

	.tc-spot__item,
	.tc-spot__item.is-open {
		flex: 0 0 86%;
		scroll-snap-align: center;
	}

	.tc-spot__img { filter: brightness(1); transform: none; }
	.tc-spot__eyebrow { opacity: 1; }
	.tc-spot__title { white-space: normal; }

	.tc-spot__text {
		max-height: 12em;
		opacity: 1;
	}
}

@media (prefers-reduced-motion: reduce) {
	.tc-spot__item,
	.tc-spot__img,
	.tc-spot__text,
	.tc-spot__eyebrow,
	.tc-spot__dot { transition: none; }

	.tc-spot__img { transform: none; }
}

/* ---------- Showcase ---------- */

.tc-section--showcase { background: #0d0d0d; }

.tc-show {
	--tc-show-list: 42%;
	--tc-show-scale: 1.5;

	display: grid;
	grid-template-columns: var(--tc-show-list) minmax(0, 1fr);
	gap: 56px;
	align-items: center;
}

/* Card on the left: the columns swap by order, not by rewriting the markup, so
   the reading order in the DOM stays heading → list → card. */
.tc-show--flip .tc-show__side { order: 2; }
.tc-show--flip .tc-show__stage { order: 1; }

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

.tc-show .tc-section__head { margin-bottom: clamp(1.75rem, 4vw, 3rem); }

.tc-show__list {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: 14px;
}

/*
 * Buttons, not links — these swap the card and go nowhere. Everything that
 * makes a button look like a button is stripped, but it stays a <button> so the
 * keyboard and screen-reader behaviour comes for free.
 */
.tc-show__name {
	position: relative;
	max-width: 100%;
	padding: 0.15em 0 0.15em 1.1em;
	border: 0;
	background: none;
	color: rgba(255, 255, 255, 0.45);
	font: inherit;
	font-size: 1rem;
	line-height: 1.45;
	text-align: left;
	cursor: pointer;
	transition: color 260ms ease, font-size 320ms cubic-bezier(0.16, 1, 0.3, 1);
}

/*
 * A marker as well as a size change. Size alone is a weak signal — it asks the
 * reader to compare two type sizes across a gap to work out which one is
 * selected, which is exactly the comparison some people cannot make quickly.
 */
.tc-show__name::before {
	content: "";
	position: absolute;
	left: 0;
	top: 50%;
	width: 3px;
	height: 0;
	border-radius: 999px;
	background: #e9c46a;
	transform: translateY(-50%);
	transition: height 320ms cubic-bezier(0.16, 1, 0.3, 1);
}

.tc-show__name:hover { color: rgba(255, 255, 255, 0.8); }

.tc-show__name.is-on {
	color: #fff;
	font-size: calc(1rem * var(--tc-show-scale, 1.5));
	font-weight: 700;
}

.tc-show__name.is-on::before { height: 1.1em; }

.tc-show__name:focus-visible {
	outline: 2px solid #fff;
	outline-offset: 4px;
	border-radius: 4px;
}

/* ---------- Showcase card ---------- */

/*
 * Every panel occupies the same grid cell, so the stage is as tall as the
 * tallest one and moving down the list never makes the page jump.
 */
.tc-show__stage { display: grid; }

.tc-show__panel {
	grid-area: 1 / 1;
	position: relative;
	overflow: hidden;
	border-radius: 24px;
	background: #d9d9d9;
	color: #1c1b1a;
	opacity: 0;
	visibility: hidden;
	transform: translateY(10px);
	transition: opacity 320ms ease, transform 420ms cubic-bezier(0.16, 1, 0.3, 1), visibility 320ms;
}

.tc-show__panel.is-on {
	opacity: 1;
	visibility: visible;
	transform: none;
}

/* [hidden] is set on the inactive panels for assistive tech; the grid stacking
   needs them in the box tree, so display is put back and visibility does the
   hiding instead. */
.tc-show__panel[hidden] { display: block; }

.tc-show__media {
	aspect-ratio: 4 / 3;
	overflow: hidden;
	background: rgba(28, 27, 26, 0.08);
}

.tc-show__img {
	width: 100%;
	height: 100%;
	object-fit: cover;
}

.tc-show__body { padding: 0 28px 28px; }

.tc-show__media + .tc-show__body { padding-top: 22px; }

/* No image: the body still needs a top edge. */
.tc-show__panel > .tc-show__body:first-child { padding-top: 28px; }

.tc-show__eyebrow {
	margin: 0 0 0.4rem;
	font-size: 0.8125rem;
	font-weight: 600;
	opacity: 0.65;
}

.tc-show__title {
	margin: 0;
	font-size: clamp(1.25rem, 1rem + 0.9vw, 1.75rem);
	line-height: 1.3;
	font-weight: 800;
	color: inherit;
	/* Must not create a stacking context, or the link overlay below would be
	   trapped inside the heading and only cover the title. */
	position: static;
	z-index: auto;
}

.tc-show__link { color: inherit; text-decoration: none; }

.tc-show__link::after {
	content: "";
	position: absolute;
	inset: 0;
	z-index: 3;
	border-radius: inherit;
}

.tc-show__text {
	margin: 0.6rem 0 0;
	font-size: 0.9375rem;
	line-height: 1.7;
	opacity: 0.85;
	display: -webkit-box;
	-webkit-box-orient: vertical;
	-webkit-line-clamp: var(--tc-show-lines, 4);
	overflow: hidden;
}

.tc-show__facts {
	list-style: none;
	margin: 0.9rem 0 0;
	padding: 0;
	display: flex;
	flex-wrap: wrap;
	gap: 0.4rem 1.4rem;
	font-size: 0.875rem;
	opacity: 0.75;
}

.tc-show__btn {
	display: inline-flex;
	align-items: center;
	gap: 0.45rem;
	margin-top: 1.25rem;
	padding: 0.7rem 1.4rem;
	border-radius: 999px;
	background: #1c1b1a;
	color: #fff;
	font-size: 0.9375rem;
	font-weight: 700;
	line-height: 1;
	transition: transform var(--tc-w-transition, 220ms ease);
}

.tc-show__panel:hover .tc-show__btn { transform: translateY(-2px); }
.tc-show__btn span { transition: transform var(--tc-w-transition, 220ms ease); }
.tc-show__panel:hover .tc-show__btn span { transform: translateX(4px); }

/* ---------- Showcase on phones ---------- */

/*
 * One column, list first. The list is the whole point of this block — turning
 * it into another slider on a phone would leave nothing that this design does
 * better than the two blocks already available.
 */
@media (max-width: 900px) {
	.tc-show {
		grid-template-columns: minmax(0, 1fr);
		gap: 28px;
	}

	.tc-show--flip .tc-show__side,
	.tc-show--flip .tc-show__stage { order: 0; }

	/* Names run across as chips rather than down the page, so the card is not
	   pushed below the fold by a long list. */
	.tc-show__list {
		flex-direction: row;
		flex-wrap: nowrap;
		gap: 8px;
		overflow-x: auto;
		scrollbar-width: none;
		padding-bottom: 4px;
	}

	.tc-show__list::-webkit-scrollbar { display: none; }

	.tc-show__name {
		flex: 0 0 auto;
		padding: 0.5em 1em;
		border-radius: 999px;
		background: rgba(255, 255, 255, 0.08);
		font-size: 0.9375rem;
		white-space: nowrap;
	}

	.tc-show__name.is-on {
		font-size: 0.9375rem;
		background: #fff;
		color: #1c1b1a;
	}

	.tc-show__name::before { display: none; }
}

@media (prefers-reduced-motion: reduce) {
	.tc-show__name,
	.tc-show__name::before,
	.tc-show__panel,
	.tc-show__btn,
	.tc-show__btn span { transition: none; }

	.tc-show__panel { transform: none; }
}

/* ---------- Media & Text ---------- */

.tc-section--mt { background: #fff; color: #1c1b1a; }
.tc-section--mt .tc-section__title { color: #1c1b1a; }

.tc-mt {
	--tc-mt-media: 50%;

	display: grid;
	grid-template-columns: var(--tc-mt-media) minmax(0, 1fr);
	gap: 56px;
	align-items: center;
}

/* Swapped by order rather than by rewriting the markup, so the DOM keeps
   image → words no matter which side the picture is drawn on. */
.tc-mt--flip .tc-mt__media { order: 2; }
.tc-mt--flip .tc-mt__body { order: 1; }

.tc-mt__media {
	position: relative;
	overflow: hidden;
	border-radius: 20px;
	aspect-ratio: 4 / 3;
	background: rgba(28, 27, 26, 0.06);
}

.tc-mt__media img,
.tc-mt__media iframe {
	display: block;
	width: 100%;
	height: 100%;
	border: 0;
	object-fit: cover;
}

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

.tc-mt__text {
	margin-top: 1rem;
	color: #5a5754;
	line-height: 1.8;
}

.tc-mt__text > :first-child { margin-top: 0; }
.tc-mt__text > :last-child { margin-bottom: 0; }

.tc-mt__list {
	list-style: none;
	margin: 1.25rem 0 0;
	padding: 0;
	display: grid;
	gap: 0.6rem;
	color: #5a5754;
	line-height: 1.7;
}

.tc-mt__list li {
	position: relative;
	padding-left: 1.75rem;
}

/* A tick drawn from a rotated border rather than an icon font or an SVG per
   row — nothing extra to load, and it takes the colour control directly. */
.tc-mt__list li::before {
	content: "";
	position: absolute;
	left: 0.25rem;
	top: 0.45em;
	width: 0.4em;
	height: 0.72em;
	border-right: 2px solid currentColor;
	border-bottom: 2px solid currentColor;
	transform: rotate(45deg);
	color: #e0503c;
}

.tc-mt__btn {
	display: inline-flex;
	align-items: center;
	gap: 0.5rem;
	margin-top: 1.75rem;
	padding: 0.85rem 1.75rem;
	border-radius: 999px;
	background: #e0503c;
	color: #fff;
	font-weight: 700;
	line-height: 1;
	text-decoration: none;
	transition: transform var(--tc-w-transition, 220ms ease), filter var(--tc-w-transition, 220ms ease);
}

.tc-mt__btn:hover { transform: translateY(-2px); filter: brightness(1.06); }
.tc-mt__btn span { transition: transform var(--tc-w-transition, 220ms ease); }
.tc-mt__btn:hover span { transform: translateX(4px); }

@media (max-width: 900px) {
	.tc-mt {
		grid-template-columns: minmax(0, 1fr);
		gap: 28px;
	}

	/*
	 * Stacked, the image always comes first. An image sitting under its own
	 * heading reads as belonging to whatever comes next, which is exactly wrong
	 * on a page of alternating blocks.
	 */
	.tc-mt--flip .tc-mt__media { order: 0; }
	.tc-mt--flip .tc-mt__body { order: 0; }
}

/* ---------- Gallery ---------- */

.tc-section--gallery { background: #fff; color: #1c1b1a; }
.tc-section--gallery .tc-section__title { color: #1c1b1a; }

.tc-gal { --tc-gal-cols: 3; }

.tc-gal--grid {
	display: grid;
	grid-template-columns: repeat(var(--tc-gal-cols, 3), minmax(0, 1fr));
	gap: 14px;
}

/*
 * Masonry with CSS columns. Real masonry layout is still not shipped widely
 * enough to rely on, and columns get the same look with no JS — the trade is
 * that reading order runs down each column rather than across, which for a
 * gallery of photographs carries no meaning anyway.
 */
.tc-gal--masonry {
	column-count: var(--tc-gal-cols, 3);
	column-gap: 14px;
	display: block;
}

.tc-gal--masonry .tc-gal__item {
	break-inside: avoid;
	margin-bottom: 14px;
	aspect-ratio: auto;
}

.tc-gal__item {
	position: relative;
	display: block;
	width: 100%;
	padding: 0;
	border: 0;
	margin: 0;
	overflow: hidden;
	border-radius: 14px;
	background: rgba(28, 27, 26, 0.06);
	aspect-ratio: 1 / 1;
	cursor: zoom-in;
}

figure.tc-gal__item { cursor: default; }

.tc-gal__img {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
	transition: transform 520ms var(--tc-w-lift);
}

.tc-gal--masonry .tc-gal__img { height: auto; }

.tc-gal--zoom .tc-gal__item:hover .tc-gal__img,
.tc-gal--zoom .tc-gal__item:focus-visible .tc-gal__img { transform: scale(1.05); }

.tc-gal__item:focus-visible { outline: 3px solid #e0503c; outline-offset: 3px; }

@media (max-width: 600px) {
	.tc-gal--grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
	.tc-gal--masonry { column-count: 2; }
}

/* ---------- Lightbox ---------- */

.tc-lb {
	position: fixed;
	inset: 0;
	z-index: 99999;
	display: flex;
	align-items: center;
	justify-content: center;
	padding: clamp(12px, 4vw, 48px);
	background: rgba(10, 10, 10, 0.94);
	opacity: 0;
	transition: opacity 220ms ease;
}

.tc-lb.is-on { opacity: 1; }

.tc-lb__img {
	max-width: 100%;
	max-height: 82vh;
	object-fit: contain;
	border-radius: 8px;
}

.tc-lb__cap {
	position: absolute;
	left: 0;
	right: 0;
	bottom: clamp(12px, 3vw, 28px);
	padding-inline: 4rem;
	color: rgba(255, 255, 255, 0.85);
	font-size: 0.9375rem;
	text-align: center;
}

.tc-lb__btn {
	position: absolute;
	display: grid;
	place-items: center;
	width: 46px;
	height: 46px;
	border: 0;
	border-radius: 999px;
	background: rgba(255, 255, 255, 0.14);
	color: #fff;
	font-size: 1.4rem;
	line-height: 1;
	cursor: pointer;
	transition: background 200ms ease;
}

.tc-lb__btn:hover { background: rgba(255, 255, 255, 0.28); }
.tc-lb__btn:focus-visible { outline: 2px solid #fff; outline-offset: 2px; }

.tc-lb__close { top: clamp(10px, 2vw, 24px); right: clamp(10px, 2vw, 24px); }
.tc-lb__prev { left: clamp(8px, 2vw, 24px); top: 50%; transform: translateY(-50%); }
.tc-lb__next { right: clamp(8px, 2vw, 24px); top: 50%; transform: translateY(-50%); }

/* Stop the page behind scrolling while the lightbox is up. */
body.tc-lb-open { overflow: hidden; }

@media (prefers-reduced-motion: reduce) {
	.tc-gal__img,
	.tc-lb { transition: none; }
}

/* ---------- FAQ ---------- */

.tc-section--faq { background: #faf7f4; color: #1c1b1a; }
.tc-section--faq .tc-section__title { color: #1c1b1a; }

.tc-faq { max-width: 800px; }

.tc-faq__item {
	border-bottom: 1px solid #e7e3df;
}

.tc-faq__q {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 1.5rem;
	padding: 1.15rem 0;
	color: #1c1b1a;
	font-size: clamp(1rem, 0.95rem + 0.3vw, 1.15rem);
	font-weight: 700;
	line-height: 1.5;
	cursor: pointer;
	list-style: none;
}

/* The default disclosure triangle is replaced by the plus sign below. */
.tc-faq__q::-webkit-details-marker { display: none; }
.tc-faq__q::marker { content: ""; }

.tc-faq__q:focus-visible { outline: 2px solid #e0503c; outline-offset: 3px; }

/* Plus and minus drawn from two bars — one of them is hidden when open. */
.tc-faq__sign {
	position: relative;
	flex: 0 0 auto;
	width: 18px;
	height: 18px;
	color: #e0503c;
}

.tc-faq__sign::before,
.tc-faq__sign::after {
	content: "";
	position: absolute;
	left: 50%;
	top: 50%;
	background: currentColor;
	transform: translate(-50%, -50%);
	transition: opacity 200ms ease, transform 260ms var(--tc-w-lift);
}

.tc-faq__sign::before { width: 100%; height: 2px; }
.tc-faq__sign::after { width: 2px; height: 100%; }

.tc-faq__item[open] .tc-faq__sign::after {
	opacity: 0;
	transform: translate(-50%, -50%) rotate(90deg);
}

.tc-faq__a {
	padding: 0 0 1.35rem;
	color: #5a5754;
	line-height: 1.8;
}

.tc-faq__a > :first-child { margin-top: 0; }
.tc-faq__a > :last-child { margin-bottom: 0; }

@media (prefers-reduced-motion: reduce) {
	.tc-faq__sign::before,
	.tc-faq__sign::after { transition: none; }
}

/* ---------- CTA band ---------- */

.tc-section--cta { background: #fff; }

.tc-cta {
	--tc-cta-scrim: 0.62;

	position: relative;
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: clamp(20px, 4vw, 48px);
	padding: 48px;
	border-radius: 24px;
	background-color: #1c1b1a;
	overflow: hidden;
	isolation: isolate;
}

.tc-cta--center {
	flex-direction: column;
	text-align: center;
}

.tc-cta--photo::before {
	content: "";
	position: absolute;
	inset: 0;
	z-index: -2;
	background-image: var(--tc-cta-img);
	background-size: cover;
	background-position: center;
}

/* The scrim is not optional when a photo is set: text over an unknown
   photograph is a contrast failure waiting to happen. It can be turned down to
   zero, but it is always in the stack. */
.tc-cta--photo::after {
	content: "";
	position: absolute;
	inset: 0;
	z-index: -1;
	background: rgba(0, 0, 0, var(--tc-cta-scrim, 0.62));
}

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

.tc-cta__eyebrow {
	margin: 0 0 0.4rem;
	color: rgba(255, 255, 255, 0.8);
	font-size: 0.8125rem;
	font-weight: 700;
	letter-spacing: 0.18em;
	text-transform: uppercase;
}

.tc-cta__title {
	margin: 0;
	color: #fff;
	font-size: clamp(1.5rem, 1.1rem + 1.6vw, 2.25rem);
	line-height: 1.25;
	font-weight: 800;
}

.tc-cta__text {
	margin: 0.6rem 0 0;
	max-width: 52ch;
	color: rgba(255, 255, 255, 0.8);
	line-height: 1.7;
}

.tc-cta--center .tc-cta__text { margin-inline: auto; }

.tc-cta__actions {
	display: flex;
	flex-wrap: wrap;
	gap: 0.75rem;
	flex: 0 0 auto;
}

.tc-cta__btn {
	display: inline-flex;
	align-items: center;
	padding: 0.9rem 1.85rem;
	border: 2px solid transparent;
	border-radius: 999px;
	font-weight: 700;
	line-height: 1;
	text-decoration: none;
	white-space: nowrap;
	transition: transform var(--tc-w-transition, 220ms ease), filter var(--tc-w-transition, 220ms ease);
}

.tc-cta__btn:hover { transform: translateY(-2px); }

.tc-cta__btn--main {
	background: #f2c063;
	border-color: #f2c063;
	color: #1c1b1a;
}

.tc-cta__btn--main:hover { filter: brightness(1.06); }

/* Outlined on purpose. Two buttons shouting equally loudly is the same as
   neither of them shouting. */
.tc-cta__btn--ghost {
	background: transparent;
	border-color: #fff;
	color: #fff;
}

.tc-cta__btn--ghost:hover { background: rgba(255, 255, 255, 0.12); }

@media (max-width: 780px) {
	.tc-cta {
		flex-direction: column;
		align-items: flex-start;
		text-align: left;
	}

	.tc-cta--center { align-items: center; text-align: center; }
	.tc-cta__actions { width: 100%; }
	.tc-cta__btn { flex: 1 1 auto; justify-content: center; }
}

@media (prefers-reduced-motion: reduce) {
	.tc-mt__btn,
	.tc-cta__btn { transition: none; }

	.tc-mt__btn:hover,
	.tc-cta__btn:hover { transform: none; }
}
