/* ==========================================================================
   EssenceTransfers — base.css
   Resets, base element behaviour, the container/rhythm primitives, and the
   small components reused everywhere (media placeholders, eyebrows).

   Design tokens live in theme.json and are consumed here as the
   --wp--preset--* / --wp--custom--* vars WordPress generates from it.
   Nothing is redeclared; the block below only provides *fallbacks* so the
   same stylesheet renders correctly outside WordPress (the static preview
   in /preview/, and the block editor before theme.json is parsed).

   RESPONSIVE STRATEGY (see IMPLEMENTATION-LOG.md for the full rationale)
   ---------------------------------------------------------------------
   Mobile-first. Every layout starts as a single fluid column and gains
   structure upward through four deliberate breakpoints:

     40rem  / 640px  — large phones landscape, small tablets: 2-up grids
     48rem  / 768px  — tablet portrait: editorial grids begin
     64rem  / 1024px — tablet landscape / laptop: desktop nav + full layouts
     82rem  / 1312px — large desktop: comfort adjustments only

   Sizing between those points is handled by clamp()/min()/max() and by
   auto-fit grids rather than by more breakpoints, so the layout stays
   correct at every intermediate width, not just at the tested numbers.
   ========================================================================== */

/* Self-hosted variable normal faces; Latin Extended includes Czech names.
   Only subsets needed by visible text load. No external font service. */
@font-face {
	font-family: Archivo; font-style: normal; font-weight: 400 700; font-display: swap;
	src: url('../fonts/archivo-latin-ext.woff2') format('woff2');
	unicode-range: U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF;
}
@font-face {
	font-family: Archivo; font-style: normal; font-weight: 400 700; font-display: swap;
	src: url('../fonts/archivo-latin.woff2') format('woff2');
	unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}
@font-face {
	font-family: Fraunces; font-style: normal; font-weight: 400 600; font-display: swap;
	src: url('../fonts/fraunces-latin-ext.woff2') format('woff2');
	unicode-range: U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF;
}
@font-face {
	font-family: Fraunces; font-style: normal; font-weight: 400 600; font-display: swap;
	src: url('../fonts/fraunces-latin.woff2') format('woff2');
	unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}

:root {
	/* Fallbacks only — WordPress overrides these from theme.json. */
	--wp--custom--gutter: clamp(1.25rem, 4vw, 4rem);
	--wp--custom--max-width: 1320px;
	--wp--custom--max-width-narrow: 46rem;
	--wp--custom--header-height: clamp(3.75rem, 2vw + 3.25rem, 4.75rem);
	--wp--preset--color--ivory: #f6f2ea;
	--wp--preset--color--stone: #eae3d3;
	--wp--preset--color--ink: #211e19;
	--wp--preset--color--ink-soft: #5c564a;
	--wp--preset--color--forest: #173229;
	--wp--preset--color--forest-deep: #0e211b;
	--wp--preset--color--forest-soft: #dde4da;
	--wp--preset--color--line: #dad1be;
	--wp--preset--color--accent-muted: #8a7c61;
	--wp--preset--font-family--display: Fraunces, ui-serif, Georgia, "Times New Roman", serif;
	--wp--preset--font-family--body: Archivo, ui-sans-serif, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
	--wp--preset--font-size--eyebrow: clamp(.68rem, .25vw + .63rem, .78rem);
	--wp--preset--font-size--small: .9375rem;
	--wp--preset--font-size--body: clamp(1rem, .2vw + .96rem, 1.0625rem);
	--wp--preset--font-size--lead: clamp(1.08rem, .9vw + .9rem, 1.4rem);
	--wp--preset--font-size--h3: clamp(1.35rem, 1.1vw + 1.1rem, 2.1rem);
	--wp--preset--font-size--h2: clamp(1.85rem, 2.6vw + 1.15rem, 3.1rem);
	--wp--preset--font-size--display: clamp(2.3rem, 5.2vw + .9rem, 4.6rem);
	--wp--preset--spacing--90: clamp(4rem, 8vw, 9rem);

	/* Local aliases — shorter to read, and one place to retune. */
	--et-gutter: var(--wp--custom--gutter);
	--et-max: var(--wp--custom--max-width);
	--et-max-narrow: var(--wp--custom--max-width-narrow);
	--et-header-h: var(--wp--custom--header-height);

	/* Minimum comfortable touch target (WCAG 2.2 AA target size). */
	--et-tap: 44px;
}

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

html {
	-webkit-text-size-adjust: 100%;
	scroll-behavior: smooth;
	/* Anchor links must not land underneath the sticky header. */
	scroll-padding-top: calc(var(--et-header-h) + 1rem);
}

/* Safety net only. Every known horizontal-overflow cause is fixed at
   source (see components.css); this catches a future editor-added element
   before it produces a horizontally scrolling page. `clip` rather than
   `hidden` because `hidden` would turn <body> into a scroll container and
   break `position: sticky` on the header. */
body {
	overflow-x: clip;
}

body {
	margin: 0;
	background: var(--wp--preset--color--ivory);
	color: var(--wp--preset--color--ink);
	font-family: var(--wp--preset--font-family--body);
	font-size: var(--wp--preset--font-size--body);
	line-height: 1.65;
	text-rendering: optimizeLegibility;
	-webkit-font-smoothing: antialiased;
}

/* Theme sections own their rhythm; WordPress must not add gaps between
   the header template part, main and footer. The template-part wrapper
   carries sticky positioning so its child header is not confined to a
   wrapper only one header tall. */
.wp-site-blocks { padding-block: 0; }
.wp-site-blocks > * { margin-block: 0; }
.wp-site-blocks > .wp-block-template-part:has(.et-header) {
	position: sticky;
	top: var(--et-admin-offset, 0px);
	z-index: 100;
}
body.admin-bar { --et-admin-offset: 32px; }
body.admin-bar .et-header { top: var(--et-admin-offset); }
body.admin-bar .et-mobile-menu { top: var(--et-admin-offset); }
@media (max-width: 782px) {
	body.admin-bar { --et-admin-offset: 46px; }
}
/* WordPress scrolls its toolbar away on narrow phones. */
@media (max-width: 600px) {
	body.admin-bar { --et-admin-offset: 0px; }
}

h1, h2, h3, h4, h5, h6 {
	font-family: var(--wp--preset--font-family--display);
	font-weight: 480;
	line-height: 1.1;
	letter-spacing: -.01em;
}

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

/* Every image that fills a slot crops rather than distorts. Focal point is
   controllable per-image via --et-focal (and --et-focal-mobile below the
   tablet breakpoint) so a face or a vehicle is never cropped out. */
.et-img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	object-position: var(--et-focal-mobile, var(--et-focal, 50% 50%));
}
@media (min-width: 48rem) {
	.et-img {
		object-position: var(--et-focal, 50% 50%);
	}
}

/* Headings: balanced, measure-capped, and incapable of overflowing on a
   long unbroken word (a long German/Czech place name, a pasted URL). */
h1, h2, h3, h4 {
	text-wrap: balance;
	max-width: 24ch;
	overflow-wrap: break-word;
}
h1.et-no-measure, h2.et-no-measure, h3.et-no-measure, h4.et-no-measure {
	max-width: none;
}

p {
	max-width: 68ch;
	overflow-wrap: break-word;
}
p.et-no-measure {
	max-width: none;
}

::selection {
	background: var(--wp--preset--color--forest);
	color: var(--wp--preset--color--ivory);
}

/* Visible, confident focus state everywhere — never removed without a
   replacement. */
a:focus-visible,
button:focus-visible,
input:focus-visible,
textarea:focus-visible,
select:focus-visible,
summary:focus-visible,
[tabindex]:focus-visible {
	outline: 2px solid var(--wp--preset--color--forest);
	outline-offset: 3px;
	border-radius: 1px;
}
.et-section--on-dark a:focus-visible,
.et-section--on-dark button:focus-visible,
.et-footer a:focus-visible {
	outline-color: var(--wp--preset--color--ivory);
}

/* Skip link */
.skip-link {
	position: absolute;
	left: -9999px;
	top: 0;
	z-index: 1000;
	background: var(--wp--preset--color--forest);
	color: var(--wp--preset--color--ivory);
	padding: 0.9rem 1.4rem;
	font-size: 0.9rem;
	letter-spacing: 0.04em;
}
.skip-link:focus {
	left: 1rem;
	top: 1rem;
}

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

/* ---- Container ---------------------------------------------------------
   One class replaces the repeated inline max-width/padding that used to sit
   on every section wrapper. Having it in CSS is what makes the gutter and
   the maximum width tunable per breakpoint at all. */
.et-container {
	width: 100%;
	max-width: var(--et-max);
	margin-inline: auto;
	padding-inline: var(--et-gutter);
}
.et-container--narrow {
	max-width: calc(var(--et-max-narrow) + (var(--et-gutter) * 2));
}

/* Full-bleed escape hatch for horizontal rails: cancels the container's
   gutter so a rail can run to the screen edge, while keeping its first and
   last cards aligned to the text above it. Never widens the page — the
   negative margin only ever equals the padding it cancels. */
.et-bleed {
	margin-inline: calc(var(--et-gutter) * -1);
	padding-inline: var(--et-gutter);
}

/* ---- Eyebrow label (used above nearly every section heading) ----------
   Wraps rather than overflowing: the rule is a non-shrinking flex item and
   the text is free to break across lines on a 320px screen. */
.et-eyebrow {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 0.5em 0.6em;
	font-family: var(--wp--preset--font-family--body);
	font-size: var(--wp--preset--font-size--eyebrow);
	font-weight: 600;
	letter-spacing: 0.12em;
	text-transform: uppercase;
	line-height: 1.35;
	color: var(--wp--preset--color--accent-muted);
	max-width: 100%;
}
.et-eyebrow::before {
	content: "";
	display: block;
	width: 1.6em;
	height: 1px;
	background: currentColor;
	opacity: 0.6;
	flex: none;
}
@media (min-width: 48rem) {
	.et-eyebrow {
		letter-spacing: 0.16em;
	}
}
.et-section--on-dark .et-eyebrow {
	color: var(--wp--preset--color--forest-soft);
	opacity: 0.85;
}

/* Eyebrow rendered as discrete terms (hero). Wraps at the separators
   instead of mid-phrase, so it degrades gracefully at 320px. */
.et-eyebrow--terms > span {
	display: inline-flex;
	align-items: center;
	gap: 0.6em;
	white-space: nowrap;
}
.et-eyebrow--terms > span + span::before {
	content: "\00B7";
	opacity: 0.7;
}

/* ---- Section rhythm --------------------------------------------------- */
.et-section {
	padding-block: var(--wp--preset--spacing--90);
}
.et-section--tight {
	padding-block: clamp(3rem, 6vw, 5.5rem);
}
.et-section--ivory { background: var(--wp--preset--color--ivory); }
.et-section--stone { background: var(--wp--preset--color--stone); }
.et-section--on-dark {
	background: var(--wp--preset--color--forest-deep);
	color: var(--wp--preset--color--ivory);
}
.et-section--on-dark h1,
.et-section--on-dark h2,
.et-section--on-dark h3,
.et-section--on-dark p { color: var(--wp--preset--color--ivory); }
.et-section--on-dark .et-ink-soft-on-dark { color: var(--wp--preset--color--forest-soft); }

/* Standard section header: heading block on the left, a "see all" link on
   the right that drops beneath it once there isn't room for both. */
.et-section-head {
	display: flex;
	flex-wrap: wrap;
	justify-content: space-between;
	align-items: flex-end;
	gap: 1rem 1.5rem;
	margin-bottom: clamp(2rem, 4vw, 3rem);
}
.et-section-head__title {
	margin: 0.6rem 0 0;
}

/* ---- Media placeholder --------------------------------------------------
   Every image slot in this phase uses this component instead of a fake
   photo. It renders at the correct aspect ratio so the surrounding layout
   never depends on one exact crop, and disappears the moment a real <img>
   replaces it. */
.et-media-placeholder {
	position: relative;
	width: 100%;
	display: flex;
	align-items: flex-end;
	overflow: hidden;
	background: linear-gradient(135deg, var(--wp--preset--color--forest-soft) 0%, var(--wp--preset--color--stone) 55%, var(--wp--preset--color--ivory) 100%);
	border: 1px solid var(--wp--preset--color--line);
}
.et-media-placeholder--deep {
	background: linear-gradient(135deg, var(--wp--preset--color--forest-deep) 0%, var(--wp--preset--color--forest) 100%);
	border-color: rgba(246, 242, 234, 0.14);
}
.et-media-placeholder::before {
	content: "";
	position: absolute;
	inset: 0;
	background-image: repeating-linear-gradient(135deg, rgba(23, 50, 41, 0.05) 0 2px, transparent 2px 34px);
	pointer-events: none;
}
.et-media-placeholder__label {
	position: relative;
	margin: 0.75rem;
	padding: 0.5rem 0.75rem;
	background: rgba(246, 242, 234, 0.88);
	color: var(--wp--preset--color--ink-soft);
	font-size: 0.68rem;
	font-weight: 600;
	letter-spacing: 0.06em;
	text-transform: uppercase;
	line-height: 1.4;
	max-width: calc(100% - 1.5rem);
}
.et-media-placeholder--deep .et-media-placeholder__label {
	background: rgba(14, 33, 27, 0.72);
	color: var(--wp--preset--color--forest-soft);
}
/* The placeholder caption is development scaffolding, not content. It is
   useful on a desktop review pass and only noise on a phone. */
@media (max-width: 47.99rem) {
	.et-media-placeholder__label {
		font-size: 0.62rem;
		margin: 0.5rem;
		padding: 0.4rem 0.55rem;
	}
	.et-hero .et-media-placeholder__label {
		display: none;
	}
}

/* Common aspect ratios. Ratios shift with viewport where a desktop crop
   would be wrong on a phone — a 4:5 portrait beside text becomes a 3:2
   landscape once it is stacked full-width. */
.et-ratio-16-9  { aspect-ratio: 16 / 9; }
.et-ratio-4-3   { aspect-ratio: 4 / 3; }
.et-ratio-3-2   { aspect-ratio: 3 / 2; }
.et-ratio-4-5   { aspect-ratio: 4 / 5; }
.et-ratio-1-1   { aspect-ratio: 1 / 1; }
.et-ratio-21-9  { aspect-ratio: 21 / 9; }

.et-ratio-responsive-portrait { aspect-ratio: 3 / 2; }
@media (min-width: 56rem) {
	.et-ratio-responsive-portrait { aspect-ratio: 4 / 5; }
}

/* ---- Scroll-reveal (progressive enhancement; see assets/js/reveal.js) -- */
.et-reveal {
	opacity: 1;
	transform: none;
}
.js-reveal-ready .et-reveal {
	opacity: 0;
	transform: translateY(14px);
	transition: opacity 0.6s cubic-bezier(.22,.61,.36,1), transform 0.6s cubic-bezier(.22,.61,.36,1);
}
.js-reveal-ready .et-reveal.is-visible {
	opacity: 1;
	transform: translateY(0);
}

/* ---- Reduced motion ----------------------------------------------------
   Placed last so it wins. Covers transitions/animations globally and, in
   addition, neutralises the transform-based affordances (card zoom, arrow
   nudge) rather than letting them snap instantly. */
@media (prefers-reduced-motion: reduce) {
	html {
		scroll-behavior: auto;
	}
	*,
	*::before,
	*::after {
		animation-duration: 0.01ms !important;
		animation-iteration-count: 1 !important;
		transition-duration: 0.01ms !important;
		scroll-behavior: auto !important;
	}
	.js-reveal-ready .et-reveal {
		opacity: 1;
		transform: none;
	}
	.et-destination-card:hover .et-destination-card__media,
	.et-link:hover .et-link__arrow,
	.et-destination-card:hover .et-media-placeholder {
		transform: none !important;
	}
	.et-rail {
		scroll-behavior: auto;
	}
}
