/*
 * Ellesschrijft shared styles
 * Cross-block utility classes and block style variations,
 * based on the pen.dev design and the /site HTML/CSS reference
 * (site/style.css is the authoritative source for exact values).
 */

/* Google Fonts loaded via @import (not a separate wp_enqueue_style link)
   so the block editor's iframed canvas picks it up: Gutenberg only copies
   same-origin stylesheets into the editor iframe and silently drops
   cross-origin <link> tags, which left Afacad Flux/Ephesis missing in the
   editor while the frontend (loaded outside that iframe) was unaffected. */
@import url('https://fonts.googleapis.com/css2?family=Afacad+Flux:wght@100..1000&family=Ephesis:wght@400&display=swap');

/* WP's nav-block modal sets overflow:hidden on <html> while open, which
   removes the scrollbar and widens the usable viewport by its width
   (~15px) — enough to visibly shift anything positioned against the
   viewport edge (e.g. the header's fixed-position close button below)
   between the closed and open state. Reserve the scrollbar's space
   permanently so nothing shifts when it toggles. */
html {
	scrollbar-gutter: stable;
}

/* Button style variations (core/button) */
.wp-block-button.is-style-es-primary .wp-block-button__link {
	background-color: #17a796;
	color: #ffffff;
	border-radius: 999px;
	padding: 12px 28px;
	font-weight: 600;
	letter-spacing: 0.5px;
}

.wp-block-button.is-style-es-primary .wp-block-button__link:hover {
	background-color: #12907f;
}

.wp-block-button.is-style-es-secondary .wp-block-button__link {
	background-color: transparent;
	color: #0c4a40;
	border: 1.5px solid #0c4a40;
	border-radius: 999px;
	padding: 12px 28px;
	font-weight: 600;
}

.wp-block-button.is-style-es-secondary .wp-block-button__link:hover {
	background-color: #0c4a40;
	color: #ffffff;
}

/* "Script" heading style (core/heading) — the cursive accent line
   used above most section titles in the design, e.g. "Wat ik voor je
   schrijft" above "Diensten". */
.wp-block-heading.is-style-es-script {
	font-family: 'Ephesis', cursive;
	font-weight: 400;
	color: #17a796;
	line-height: 1;
}

/* Circular portrait used in dark testimonial/about strips (core/image).
   Fluid by design (340px capped at 70vw) rather than a breakpoint swap —
   matches site/style.css .about-strip .portret exactly. */
.es-portrait-circle img {
	width: 340px;
	max-width: 70vw;
	height: auto;
	aspect-ratio: 1 / 1;
	object-fit: cover;
	border-radius: 50%;
}

/* Organic asymmetric image corners (core/image), the design's
   signature 120px/24px/120px/24px rounded-corner treatment. */
.wp-block-image.is-style-es-organic img {
	border-radius: 120px 24px 120px 24px;
}

/* Category tag pill, used on portfolio cards. */
.ellesschrijft-tag {
	display: inline-flex;
	padding: 4px 14px;
	background-color: #e6f5f1;
	border-radius: 999px;
	color: #17a796;
	font-family: 'Afacad Flux', system-ui, sans-serif;
	font-size: 13px;
	font-weight: 600;
	letter-spacing: 0.5px;
	text-transform: uppercase;
}

/* Teaser card markup, shared between the static ellesschrijft/card
   block and the dynamic ellesschrijft/portfolio-grid block, so both
   produce visually identical cards from one CSS definition. Matches
   site/style.css .pcard (white bg) — the default. */
.ellesschrijft-card {
	display: flex;
	flex-direction: column;
	background-color: #ffffff;
	border: 1px solid #0c4a4014;
	border-radius: 20px;
	overflow: hidden;
	text-decoration: none;
	color: inherit;
}

.ellesschrijft-card__image {
	display: block;
	width: 100%;
	height: auto;
	aspect-ratio: 16 / 10;
	object-fit: cover;
}

.ellesschrijft-card__body {
	display: flex;
	flex-direction: column;
	gap: 10px;
	padding: 22px 26px 26px;
}

.ellesschrijft-card__body > .ellesschrijft-tag {
	align-self: flex-start;
}

.ellesschrijft-card__title {
	margin: 0;
	font-family: 'Afacad Flux', system-ui, sans-serif;
	font-size: 24px;
	line-height: 1.1;
	font-weight: 700;
	color: #0c4a40;
}

.ellesschrijft-card__desc {
	margin: 0;
	font-family: 'Afacad Flux', system-ui, sans-serif;
	font-size: 16px;
	line-height: 1.45;
	color: #5a6e69;
}

.ellesschrijft-card__link {
	display: inline-flex;
	align-items: center;
	gap: 6px;
	font-family: 'Afacad Flux', system-ui, sans-serif;
	font-size: 16px;
	font-weight: 600;
	color: #17a796;
}

.ellesschrijft-card__arrow {
	flex-shrink: 0;
}

/* Home/Diensten "service card" variant — apply via the block's own
   className attribute (e.g. "ellesschrijft-card--service"). Matches
   site/style.css .card (ivory bg, roomier padding/type) as distinct
   from the white .pcard portfolio default above.

   Height fix: core/columns stretches each column to the row's tallest
   column by default (align-items:stretch/normal), but that only
   equalizes the *column* boxes — this block's own root div and its
   inner .ellesschrijft-card are plain block/flex elements sized to their
   own content, so a card with shorter copy still rendered shorter than
   its (already-equal-height) column. Fill 100% of the column instead. */
.ellesschrijft-card--service.wp-block-ellesschrijft-card {
	height: 100%;
	box-sizing: border-box;
}

.ellesschrijft-card--service .ellesschrijft-card {
	height: 100%;
	box-sizing: border-box;
	background-color: #fbfaf7;
}

.ellesschrijft-card--service .ellesschrijft-card__body {
	padding: 24px 28px 28px;
	gap: 12px;
}

.ellesschrijft-card--service .ellesschrijft-card__title {
	font-size: 26px;
}

.ellesschrijft-card--service .ellesschrijft-card__desc {
	font-size: 17px;
}

/* Grid layout for the portfolio-grid dynamic block. */
.ellesschrijft-portfolio-grid {
	display: grid;
	grid-template-columns: repeat(var(--es-grid-columns, 3), 1fr);
	gap: 32px;
	max-width: 1440px;
	margin: 0 auto;
	padding: 24px 80px 64px;
	box-sizing: border-box;
}

.es-related .ellesschrijft-portfolio-grid {
	max-width: none;
	margin: 0;
	padding: 0;
}

@media (max-width: 900px) {
	.ellesschrijft-portfolio-grid {
		padding: 16px 40px 48px;
	}
}

@media (max-width: 1100px) {
	.ellesschrijft-portfolio-grid {
		grid-template-columns: repeat(2, 1fr);
	}
}

@media (max-width: 900px) {
	.ellesschrijft-portfolio-grid {
		grid-template-columns: 1fr;
		gap: 20px;
	}
}

/* ---------- Generic full-width section ---------- */
/* Every full-bleed section on the site follows the same two-layer shape,
   matching site/style.css exactly: an OUTER element that is always full
   viewport width and carries the background color only (no side
   padding, no max-width), and an INNER element ("...__inner" or, for
   generic sections, "section") that is capped at 1440px, centered with
   margin:0 auto, and carries the 80px/40px side padding. Never put both
   the background AND the padding/max-width on the same element — WP
   applies its own negative margins to full-aligned blocks, which wins
   over a plain "margin:0 auto" on that same element and breaks centering.
   Apply "section-white"/"section-dark" on the OUTER wrapper for the
   background; sections with neither modifier simply show the page's own
   ivory background — that IS the alternation (ivory / white / dark /
   ...), so skipping the modifier is a valid, intentional choice. */
.section-white {
	background-color: #ffffff;
}

.section-dark {
	background-color: #0c4a40;
}

.section {
	max-width: 1440px;
	margin: 0 auto;
	padding: 80px;
	box-sizing: border-box;
}

@media (max-width: 900px) {
	.section {
		padding: 48px 40px;
	}
}

/* Header — fixed to the top of the viewport while scrolling, with a
   translucent, blurred version of the ivory background instead of a
   flat one. Fixed (not sticky) because an ancestor's overflow makes
   sticky positioning not take effect in this theme. The outer element
   (.es-header) is the full-bleed bar; .es-header__inner is the capped,
   centered row that holds the logo/nav/button. */
.es-header.wp-block-group {
	position: fixed;
	top: 0;
	left: 0;
	right: 0;
	z-index: 100;
	background-color: rgba(251, 250, 247, 0.8);
	-webkit-backdrop-filter: blur(10px);
	backdrop-filter: blur(10px);
	padding: 0;
}

/* The WP admin bar is itself fixed to the very top when logged in, so
   push the fixed header down below it instead of letting them overlap —
   32px is the admin bar's default height, 46px its height from WP core's
   own admin-bar breakpoint (782px) down. */
.admin-bar .es-header.wp-block-group {
	margin-top: 32px;
}

@media (max-width: 782px) {
	.admin-bar .es-header.wp-block-group {
		margin-top: 46px;
	}
}

/* Same admin-bar offset as above, but on body itself and switching at the
   site's own md breakpoint (900px) instead of WP core's 782px, to match
   every other breakpoint on the site. */
body.admin-bar {
	padding-top: 46px;
}

@media (min-width: 901px) {
	body.admin-bar {
		padding-top: 32px;
	}
}

.es-header__inner {
	width: 100%;
	max-width: 1440px;
	margin: 0 auto !important; /* override core's own .wp-block-navigation__container margin:auto */
	padding: 12px 80px;
	box-sizing: border-box;
}

/* Caps the logo so it can never crowd out the nav/CTA on narrow screens,
   e.g. when a long custom logo image is uploaded via the Site Icon/Logo
   settings instead of the current compact "Elles schrijft" wordmark. */
.es-header .wp-block-site-logo {
	max-width: 40vw;
}

/* Contact CTA: the header bar's own button (next to the logo) is for
   desktop only; on mobile it's replaced by the "es-nav-mobile-cta" button
   block appended to the nav's own content (see wp_navigation post 4),
   which shows up at the bottom of the mobile dropdown instead. */
@media (max-width: 900px) {
	.es-header .wp-block-buttons:not(.es-nav-mobile-cta) {
		display: none;
	}
}

@media (min-width: 901px) {
	.es-header .es-nav-mobile-cta {
		display: none;
	}
}

@media (max-width: 900px) {
	.es-header__inner {
		padding: 12px 40px;
	}
}

/* Core's navigation block switches to the hamburger/overlay menu at its
   own fixed 600px breakpoint (baked into WP core's block-library CSS).
   Override it so the switch happens at the site's own md breakpoint
   (900px) instead, matching every other section on the site. */
@media (max-width: 900px) {
	/* body-prefixed for a guaranteed specificity win: core's own
	   "@media (min-width:600px) .responsive-container-open:not(.always-shown)"
	   ties this at 2 class-equivalents, which would otherwise depend on
	   stylesheet load order rather than the rule itself. */
	body .es-header .wp-block-navigation__responsive-container-open {
		display: flex;
	}

	.es-header .wp-block-navigation__responsive-container:not(.is-menu-open) {
		display: none;
		position: fixed;
	}
}

/* Core's own open-icon is a reduced 2-bar glyph; swap it for a bigger,
   proper 3-line hamburger via a masked ::before (same technique as the
   .es-bullets checkmark below) — sized up from core's own 24px icon per
   request. */
.es-header .wp-block-navigation__responsive-container-open svg {
	display: none;
}

.es-header .wp-block-navigation__responsive-container-open::before {
	content: '';
	display: block;
	width: 30px;
	height: 22px;
	background-color: #0c4a40;
	-webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M4 6h16v2H4zM4 11h16v2H4zM4 16h16v2H4z'/%3E%3C/svg%3E") center / contain no-repeat;
	mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M4 6h16v2H4zM4 11h16v2H4zM4 16h16v2H4z'/%3E%3C/svg%3E") center / contain no-repeat;
}

/* Core keeps the hamburger visible even while the panel is open (our own
   "display: flex !important" above forces it to show at all at ≤900px in
   the first place, since core hides it below 782px by default) — without
   this, both the hamburger and the × below would show at once. The
   responsive-container that gets ".is-menu-open" is a sibling of the open
   button (both children of the <nav>), not an ancestor, hence :has()
   rather than a simple descendant/sibling selector. */
.es-header nav:has(.wp-block-navigation__responsive-container.is-menu-open) .wp-block-navigation__responsive-container-open {
	display: none;
}

/* Close button repositioned onto the exact spot the hamburger occupies,
   so the two read as one button whose icon morphs from ≡ to ✕. Its
   containing block is .es-header (backdrop-filter qualifies it) — this
   used to be muddied by .wp-block-navigation__responsive-container
   itself acting as the containing block instead, but only because core's
   slide-in *animation* gave it an actively-animated (non-none) transform;
   now that the animation is disabled above, that no longer applies and
   the search correctly reaches .es-header, confirmed via an inline-style
   probe. top:50%/translateY(-50%) matches the real hamburger's own
   measured position within the header (its center sits at exactly 50%
   of the header's height). */
@media (max-width: 900px) {
	.es-header .wp-block-navigation__responsive-container-close {
		position: fixed;
		top: 50%;
		right: 40px;
		bottom: auto;
		left: auto;
		transform: translateY(-50%);
		z-index: 101;
	}
}

@media (max-width: 412px) {
	.es-header .wp-block-navigation__responsive-container-close {
		right: 24px;
	}
}

/* Open state (< 900px): style the panel as a simple ivory dropdown below
   the header bar — matching site/style.css's .nav-links treatment —
   instead of core's default unstyled/fullscreen dialog look. */
@media (max-width: 900px) {
	.es-header .wp-block-navigation__responsive-container.is-menu-open {
		/* Three classes here (.es-header + .responsive-container +
		   .is-menu-open) already out-specifies core's own two-class rule
		   for this same element, so none of these need !important. */
		position: fixed;
		inset: auto;
		top: 78px;
		left: 0;
		right: 0;
		background-color: #fbfaf7;
		box-shadow: 0 16px 30px rgba(12, 74, 64, 0.08);
		border-bottom: 1px solid #e4e0d8;
		/* Core's slide-in transform comes from a *running animation*
		   (".wp-block-navigation__responsive-container.is-menu-open" +
		   "@media not (prefers-reduced-motion)"), which keeps re-applying
		   its own transform every frame — a plain "transform: none" rule,
		   however specific, cannot out-rank an active animation (animation
		   output beats normal-origin rules in the cascade, !important
		   aside). Stopping the animation itself instead — a plain
		   (non-animated) property — is a normal specificity contest we
		   already win with 3 classes vs core's 2, so no !important needed
		   here either. */
		animation: none;
		transform: none;
		/* Core's own overflow:auto clips anything positioned outside this
		   box's edges — including the close button above, which is
		   deliberately positioned above this container's own top edge
		   (back into the header). Without this, the button computes the
		   right layout position but paints as invisible, clipped away. */
		overflow: visible;
	}

	/* top:100% instead of a hardcoded px value: .es-header is the
	   containing block here (its backdrop-filter makes it one for fixed
	   descendants), and its own margin-top already shifts the whole bar
	   down when the admin bar is showing — so 100% of its own height
	   lands the dropdown right below it regardless of admin-bar state or
	   breakpoint, replacing what used to be two separate hardcoded values
	   (110px at 900px, 124px at 782px). Four classes here vs three on the
	   base rule above wins this on specificity alone. */
	.admin-bar .es-header .wp-block-navigation__responsive-container.is-menu-open {
		top: 100%;
	}
}

/* WP core's own navigation-block CSS (block-library/style.min.css) pushes
   the mobile overlay dialog down by an extra 46px/32px whenever the admin
   bar is showing — on top of the top:110px/124px we already set above for
   that exact case, doubling the offset. Neutralized here by exactly
   cloning core's own selector and prefixing "body" onto it: a bare clone
   would tie core's specificity and depend on stylesheet load order (this
   plugin's CSS happens to load after block-library's, so it would win
   today, but that's implicit and would silently break if enqueue order
   ever changed) — the extra type selector guarantees the win outright. */
body.has-modal-open .admin-bar .is-menu-open:where(:not(.disable-default-overlay)) .wp-block-navigation__responsive-dialog {
	margin-top: 0;
}

/* Same core rule, different overreach: it pads the top of the open panel
   with calc(24px + 2rem) — the 2rem is core's own extra space for its
   fullscreen dialog look, which our dropdown styling above doesn't need.
   Plain 24px matches the panel's own gap elsewhere. Same "body" prefix
   trick as above, for the same reason (exact clone of core's selector). */
body .wp-block-navigation__responsive-container.is-menu-open:not(.disable-default-overlay) .wp-block-navigation__responsive-container-content {
	padding-top: 24px;
}

/* Core's own x-padding here is clamp(1rem, --wp--style--root--padding-*,
   20rem) — theme.json root padding, unrelated to this site's own
   40px/80px section rhythm. Replace it with the same three-tier x-padding
   every section uses (80px / 40px at 900px / 24px at 412px), so the open
   mobile nav lines up with the header/content below it instead of using
   its own independent scale. "body" prefix again, same reason. */
body .wp-block-navigation__responsive-container.is-menu-open:not(.disable-default-overlay) {
	padding-left: 80px;
	padding-right: 80px;
}

@media (max-width: 900px) {
	body .wp-block-navigation__responsive-container.is-menu-open:not(.disable-default-overlay) {
		padding-left: 40px;
		padding-right: 40px;
	}
}

@media (max-width: 412px) {
	body .wp-block-navigation__responsive-container.is-menu-open:not(.disable-default-overlay) {
		padding-left: 24px;
		padding-right: 24px;
	}
}

@media (max-width: 782px) {
	.es-header .wp-block-navigation__responsive-dialog {
		max-width: 1440px;
		margin: 0 auto;
		padding: 0;
		box-sizing: border-box;
	}

	/* Both branches scoped under .es-header (not just the first) so both
	   carry the same 2-class specificity, safely above core's 1-class
	   ".wp-block-navigation__container" rule for the same properties. */
	.es-header .wp-block-navigation__responsive-container-content,
	.es-header .wp-block-navigation__container {
		flex-direction: column;
		align-items: flex-start;
		gap: 20px;
	}
}

@media (min-width: 901px) {
	/* body-prefixed: core's own tied-specificity rule for this same
	   property at this same breakpoint (see the 900px block above). */
	body .es-header .wp-block-navigation__responsive-container-open {
		display: none;
	}

	/* Same reasoning: core's ":not(.hidden-by-default):not(.is-menu-open)"
	   variant ties this at 3 class-equivalents (1 class + 2 :not()) vs
	   ours (2 classes + 1 :not()). */
	body .es-header .wp-block-navigation__responsive-container:not(.is-menu-open) {
		display: block;
		position: relative;
	}
}

/* Fixed headers are taken out of normal flow, so push the page content
   down by the header's own height to avoid it hiding under the header
   on load. Height varies slightly by breakpoint (logo/nav wrap). */
body:not(.wp-admin) .wp-site-blocks {
	padding-top: 85px;
}

@media (max-width: 900px) {
	body:not(.wp-admin) .wp-site-blocks {
		padding-top: 78px;
	}
}

/* Footer — a darker green than the other dark-green sections (about-strip,
   quote-strip, cta-banner dark), matching site/style.css's
   .site-footer { background: linear-gradient(#00000080,#00000080), var(--green-dark) }.
   Outer (.es-footer) is full-bleed with only the color; .es-footer__inner
   is capped at 1440px and holds the actual padding/content. */
footer {
	margin: 0;
}

.es-footer.wp-block-group {
	background-color: #0c4a40;
	background-image: linear-gradient(#00000080, #00000080);
	padding: 0;
}

.es-footer__inner {
	max-width: 1440px;
	margin: 0 auto;
	padding: 56px 80px;
	box-sizing: border-box;
}

@media (max-width: 900px) {
	.es-footer__inner {
		padding: 40px 40px;
	}
}

/* ---------- Checklist bullets (Diensten page) ---------- */
/* Apply "es-bullets" as the className on a core/list; each core/list-item
   gets a teal checkmark instead of a browser bullet. Matches
   site/style.css .bullets exactly. */
.es-bullets {
	list-style: none;
	display: flex;
	flex-direction: column;
	gap: 10px;
	margin: 0;
	padding: 0;
}

.es-bullets li {
	display: flex;
	align-items: center;
	gap: 10px;
	font-family: 'Afacad Flux', system-ui, sans-serif;
	font-size: 17px;
	font-weight: 500;
	color: #22332f;
}

.es-bullets li::before {
	content: '';
	flex-shrink: 0;
	width: 16px;
	height: 16px;
	background-color: #17a796;
	-webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='20 6 9 17 4 12'/%3E%3C/svg%3E") center / contain no-repeat;
	mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='20 6 9 17 4 12'/%3E%3C/svg%3E") center / contain no-repeat;
}

@media (max-width: 900px) {
	.es-bullets li {
		font-size: 15px;
	}
}

/* ---------- Full-bleed background, capped+centered content ---------- */
/* Shared by every full-width colored section (about-strip, quote-strip,
   cta-banner, footer): the section itself spans the viewport edge to
   edge, but its content never exceeds 1440px and sits on 80px side
   padding (40px on mobile) — via a ::before pseudo-element that paints
   the background past the section's own capped box, so the box itself
   can be centered and width-limited without clipping the color. */
.es-full-bleed {
	position: relative;
	z-index: 0;
	max-width: 1440px;
	margin: 0 auto;
	box-sizing: border-box;
}

.es-full-bleed::before {
	content: '';
	position: absolute;
	top: 0;
	bottom: 0;
	left: -100vw;
	right: -100vw;
	z-index: -1;
}

/* ---------- About/testimonial strip (Home + Over mij teaser) ---------- */
.es-about-strip {
	background-color: #0c4a40;
}

.es-about-strip__inner {
	display: flex;
	align-items: center;
	gap: 72px;
	max-width: 1440px;
	margin: 0 auto;
	padding: 72px 80px;
	box-sizing: border-box;
}

.es-about-strip-copy {
	display: flex;
	flex-direction: column;
	gap: 20px;
	align-items: flex-start;
}

.es-about-strip-copy .wp-block-heading.is-style-es-script {
	color: #7bd4c4;
	font-size: 44px;
	line-height: 1.15;
}

.es-about-strip-copy p {
	color: #dcefea;
	font-size: 19px;
	line-height: 1.5;
	max-width: 620px;
	margin: 0;
}

.es-about-strip-copy a {
	color: #ffffff;
	font-weight: 600;
	text-decoration: none;
}

@media (max-width: 900px) {
	.es-about-strip__inner {
		flex-direction: column;
		padding: 48px 40px;
		gap: 24px;
	}

	.es-about-strip-copy .wp-block-heading.is-style-es-script {
		font-size: 30px;
	}

	.es-about-strip-copy p {
		font-size: 16px;
	}
}

/* ---------- Intro (Over mij hero) ---------- */
.es-intro__inner {
	display: flex;
	align-items: center;
	gap: 72px;
	padding: 64px 80px 72px;
	max-width: 1440px;
	margin: 0 auto;
	box-sizing: border-box;
}

.es-intro-visual {
	position: relative;
	/* flex:1 1 0% (not the old fixed 480px + flex-shrink:0) keeps this an
	   even 50/50 split with .es-intro-copy at any width down to the
	   900px stack breakpoint — a fixed-width image next to a shrinkable
	   text column let the copy get squeezed too narrow while the photo
	   stayed full size as the viewport narrowed. */
	flex: 1 1 0%;
	max-width: 100%;
}

.es-intro-visual img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	border-radius: 120px 24px 120px 24px;
}

/* Two classes (not just `.es-intro-badge`) so this beats the block
   editor's own `.block-editor-block-list__block { position: relative }`
   rule: className is applied directly to this core/group block's root
   element, which also carries block-editor-block-list__block, so both
   rules are single-class selectors of equal specificity and the editor's
   (loaded after ours) wins the tie — the badge rendered as a static,
   full-width block below the image in the editor instead of the small
   absolutely-positioned card seen on the frontend. */
.wp-block-group.es-intro-badge {
	position: absolute;
	right: -24px;
	bottom: 36px;
	background-color: #ffffff;
	border-radius: 16px;
	padding: 18px 26px;
	box-shadow: 0 10px 30px #0c4a4022;
}

.es-intro-badge .wp-block-heading.is-style-es-script {
	font-size: 30px;
	line-height: 1;
}

.es-intro-copy {
	flex: 1 1 0%;
	display: flex;
	flex-direction: column;
	gap: 20px;
	align-items: flex-start;
}

.es-intro-copy .wp-block-heading.is-style-es-script {
	font-size: 52px;
	line-height: 1;
}

.es-intro-copy h1 {
	color: #0c4a40;
	font-size: 52px;
	font-weight: 700;
	line-height: 1.05;
}

.es-intro-copy p {
	color: #5a6e69;
	font-size: 19px;
	line-height: 1.5;
	max-width: 620px;
}

@media (max-width: 900px) {
	.es-intro__inner {
		flex-direction: column;
		align-items: stretch;
		padding: 32px 40px 48px;
		gap: 24px;
	}

	.es-intro-visual {
		/* Reset the desktop 50/50 flex-basis: in the stacked column layout
		   here, flex-basis applies to height, not width, so it must not
		   carry over. */
		flex: none;
		width: 100%;
		max-width: 420px;
		align-self: center;
	}

	.es-intro-copy {
		flex: none;
	}

	.es-intro-visual img {
		border-radius: 80px 20px 80px 20px;
	}

	.es-intro-badge {
		right: 12px;
		bottom: 24px;
		padding: 14px 20px;
	}

	.es-intro-badge .wp-block-heading.is-style-es-script {
		font-size: 24px;
	}

	.es-intro-copy .wp-block-heading.is-style-es-script {
		font-size: 38px;
	}

	.es-intro-copy h1 {
		font-size: 32px;
		line-height: 1.1;
	}

	.es-intro-copy p {
		font-size: 16px;
	}
}

/* ---------- Story (Over mij) ---------- */
.es-story {
	display: flex;
	align-items: center;
	gap: 72px;
	padding: 80px;
	max-width: 1440px;
	margin: 0 auto;
}

.es-story-copy {
	flex: 1;
	display: flex;
	flex-direction: column;
	gap: 16px;
}

.es-story-copy .wp-block-heading.is-style-es-script {
	font-size: 38px;
	line-height: 1;
}

.es-story-copy h2 {
	color: #0c4a40;
	font-size: 38px;
	font-weight: 700;
}

.es-story-copy p {
	color: #5a6e69;
	font-size: 18px;
	line-height: 1.5;
}

.es-story .es-meta-card-wrap,
.es-story .wp-block-ellesschrijft-timeline {
	/* width: 460px; */
	flex-shrink: 0;
}

@media (max-width: 1100px) {
	.es-story {
		flex-direction: column;
		align-items: stretch;
	}

	.es-story .es-meta-card-wrap,
	.es-story .wp-block-ellesschrijft-timeline {
		/* width: 100%; */
	}
}

@media (max-width: 900px) {
	.es-story {
		padding: 48px 0px;
		gap: 24px;
	}

	.es-story-copy .wp-block-heading.is-style-es-script {
		font-size: 28px;
	}

	.es-story-copy h2 {
		font-size: 28px;
	}

	.es-story-copy p {
		font-size: 16px;
	}
}

/* ---------- Page header (Diensten / Portfolio / Contact intro) ---------- */
.es-page-header {
	max-width: 1440px;
	margin: 0 auto;
	box-sizing: border-box;
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 8px;
	padding: 64px 80px 32px;
	text-align: center;
}

.es-page-header .wp-block-heading.is-style-es-script {
	font-size: 48px;
}

.es-page-header h1 {
	color: #0c4a40;
	font-size: 52px;
	font-weight: 700;
}

.es-page-header p {
	color: #5a6e69;
	font-size: 19px;
	line-height: 1.5;
	max-width: 680px;
	margin: 0 auto;
}

@media (max-width: 900px) {
	.es-page-header {
		padding: 40px 40px 16px;
		gap: 6px;
	}

	.es-page-header .wp-block-heading.is-style-es-script {
		font-size: 36px;
	}

	.es-page-header h1 {
		font-size: 38px;
	}

	.es-page-header p {
		font-size: 17px;
	}
}

/* ---------- Dienst row (Diensten page, alternating image/text) ---------- */
.es-dienst {
	padding: 56px 0;
}

.es-dienst > .es-dienst-inner {
	display: flex;
	align-items: center;
	gap: 72px;
	max-width: 1280px;
	margin: 0 auto;
	padding: 0 80px;
	box-sizing: border-box;
}

.es-dienst.es-dienst-white {
	background-color: #ffffff;
}

.es-dienst-img {
	flex: 0 0 45%;
	max-width: 520px;
	width: 100%;
	min-width: 0;
}

.es-dienst-img img {
	display: block;
	width: 100%;
	height: auto;
	aspect-ratio: 520 / 380;
	object-fit: cover;
	border-radius: 120px 24px 120px 24px;
}

.es-dienst-copy {
	flex: 1;
	min-width: 0;
	display: flex;
	flex-direction: column;
	gap: 16px;
	align-items: flex-start;
}

.es-dienst-copy .wp-block-heading.is-style-es-script {
	font-size: 34px;
	line-height: 1.1;
}

.es-dienst-copy h2 {
	margin: 0;
	color: #0c4a40;
	font-size: 36px;
	font-weight: 700;
}

.es-dienst-copy p {
	color: #5a6e69;
	font-size: 18px;
	line-height: 1.5;
}

@media (max-width: 900px) {
	.es-dienst > .es-dienst-inner {
		flex-direction: column;
		align-items: stretch;
		gap: 20px;
		padding: 40px 40px;
	}

	.es-dienst {
		padding: 0;
	}

	.es-dienst-img {
		flex: none;
		width: 100%;
		max-width: none;
		order: -1;
	}

	.es-dienst-img img {
		aspect-ratio: 16 / 10;
		border-radius: 80px 20px 80px 20px;
	}

	.es-dienst-copy .wp-block-heading.is-style-es-script {
		font-size: 26px;
	}

	.es-dienst-copy h2 {
		font-size: 28px;
	}

	.es-dienst-copy p {
		font-size: 16px;
	}
}

/* ---------- Stats row (Over mij) ---------- */
.es-stats {
	background-color: #ffffff;
}

.es-stats__inner {
	display: flex;
	gap: 32px;
	max-width: 1440px;
	margin: 0 auto;
	padding: 48px 80px;
	box-sizing: border-box;
}

.es-stat {
	flex: 1;
	text-align: center;
}

.es-stat .wp-block-heading.is-style-es-script {
	margin: 0;
	font-size: 46px;
	line-height: 1.1;
	display: block;
}

.es-stat p {
	font-size: 16px;
	font-weight: 500;
	color: #22332f;
	margin: 0;
}

@media (max-width: 900px) {
	.es-stats__inner {
		flex-wrap: wrap;
		padding: 40px 40px;
		gap: 24px 16px;
	}

	.es-stat {
		flex: 1 1 40%;
	}

	.es-stat .wp-block-heading.is-style-es-script {
		font-size: 36px;
	}

	.es-stat p {
		font-size: 14px;
	}
}

/* ---------- Quote strip (Over mij) ---------- */
.es-quote-strip {
	background-color: #0c4a40;
}

.es-quote-strip__inner {
	max-width: 1440px;
	margin: 0 auto;
	box-sizing: border-box;
	text-align: center;
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 16px;
	padding: 72px 80px;
}

.es-quote-strip blockquote {
	border: none;
	padding: 0;
	font-family: 'Ephesis', cursive;
	color: #7bd4c4;
	font-size: 46px;
	line-height: 1.2;
	max-width: 860px;
	margin: 0;
}

.es-quote-strip cite {
	font-family: 'Afacad Flux', system-ui, sans-serif;
	color: #dcefea;
	font-size: 17px;
	font-weight: 600;
	letter-spacing: 1px;
	font-style: normal;
}

@media (max-width: 900px) {
	.es-quote-strip__inner {
		padding: 48px 40px;
		gap: 14px;
	}

	.es-quote-strip blockquote {
		font-size: 30px;
		line-height: 1.25;
	}

	.es-quote-strip cite {
		font-size: 15px;
	}
}

/* ---------- Contact page ---------- */
/* display:grid + 1fr 1fr (not flex) for the two columns: with flex,
   even identical flex:1 1 0% on both sides did not produce an even
   split, because .es-form-card carries its own padding/border and
   .es-contact-side doesn't — box-sizing:border-box on the card made no
   measurable difference (confirmed by testing), so something about how
   this engine resolves flex-basis with per-item padding was still
   skewing the two content-box shares. Grid's 1fr tracks size the
   container's own columns first, independent of each item's box model,
   so both are genuinely equal regardless of padding/border differences.

   body-prefixed: the block's own "flex" layout setting emits
   ".wp-block-group-is-layout-flex { display:flex }" (same 0,1,0
   specificity as ".es-contact-main" alone), which would otherwise win
   this display:grid override purely on source order. */
body .es-contact-main {
	display: grid;
	grid-template-columns: 1fr 1fr;
	gap: 48px;
	align-items: start;
	padding: 32px 80px 80px;
	max-width: 1440px;
	margin: 0 auto;
	box-sizing: border-box;
}

.es-form-card {
	background-color: #ffffff;
	border: 1px solid #0c4a4014;
	border-radius: 24px;
	padding: 40px;
	box-sizing: border-box;
}

.es-form-card > .wp-block-heading {
	color: #0c4a40;
	font-size: 26px;
	font-weight: 700;
	margin: 0 0 20px;
}

.es-contact-side {
	display: flex;
	flex-direction: column;
	gap: 24px;
}

.es-info-card {
	background-color: #0c4a40;
	border-radius: 24px;
	padding: 36px;
	display: flex;
	flex-direction: column;
	gap: 24px;
}

.es-info-card .wp-block-heading.is-style-es-script {
	color: #7bd4c4;
	font-size: 36px;
	line-height: 1;
}

.es-info-row {
	display: flex;
	gap: 14px;
	align-items: flex-start;
}

.es-info-icon {
	width: 40px;
	height: 40px;
	background-color: #ffffff1a;
	border-radius: 12px;
	display: flex;
	align-items: center;
	justify-content: center;
	flex-shrink: 0;
}

.es-info-row .es-lbl {
	display: block;
	color: #9cc4bb;
	font-size: 14px;
	font-weight: 600;
	letter-spacing: 0.5px;
}

.es-info-row .es-val {
	color: #ffffff;
	font-size: 17px;
	line-height: 1.4;
}

.es-socials {
	display: flex;
	gap: 12px;
	padding-top: 8px;
}

.es-socials .wp-social-link {
	background-color: #ffffff1a;
}

.es-socials .wp-social-link:hover {
	background-color: #ffffff33;
}

.es-socials .wp-social-link a,
.es-socials .wp-social-link svg {
	fill: #ffffff;
}

.es-contact-photo img {
	width: 100%;
	height: auto;
	aspect-ratio: 1 / 1;
	object-fit: cover;
	border-radius: 24px;
}

@media (max-width: 900px) {
	/* Same "body" prefix as the base rule, so this ties its specificity
	   instead of losing to it outright (a plain ".es-contact-main" here
	   would be less specific than "body .es-contact-main" above). */
	body .es-contact-main {
		grid-template-columns: 1fr;
		padding: 16px 0 56px;
		gap: 24px;
	}

	.es-form-card {
		width: 100%;
		padding: 24px;
	}

	.es-form-card > .wp-block-heading {
		font-size: 22px;
	}

	.es-contact-side {
		width: 100%;
	}

	.es-info-card {
		padding: 28px;
		gap: 20px;
	}

	.es-contact-photo img {
		aspect-ratio: 16 / 10;
	}
}

/* ---------- Portfolio detail ---------- */
.es-project-head {
	padding: 48px 80px 40px;
	max-width: 1440px;
	margin: 0 auto;
	display: flex;
	flex-direction: column;
	gap: 20px;
}

.es-back-link {
	display: inline-flex;
	align-items: center;
	gap: 8px;
	color: #17a796;
	font-size: 16px;
	font-weight: 600;
	text-decoration: none;
}

.es-title-row {
	display: flex;
	justify-content: space-between;
	align-items: flex-end;
	gap: 40px;
}

.es-title-col {
	display: flex;
	flex-direction: column;
	gap: 12px;
	align-items: flex-start;
}

.es-title-col h1 {
	color: #0c4a40;
	font-size: 56px;
	font-weight: 700;
	line-height: 1;
	margin: 0;
}

.es-title-col p {
	color: #5a6e69;
	font-size: 19px;
	line-height: 1.5;
	max-width: 720px;
	margin: 0;
}

.es-meta-card-wrap {
	width: 300px;
	flex-shrink: 0;
}

.es-project-hero {
	padding: 8px 80px 0;
	max-width: 1440px;
	margin: 0 auto;
}

.es-project-hero img {
	width: 100%;
	height: auto;
	aspect-ratio: 21 / 9;
	object-fit: cover;
	border-radius: 28px;
}

.es-project-body {
	max-width: 880px;
	margin: 0 auto;
	padding: 64px 80px;
	display: flex;
	flex-direction: column;
	gap: 28px;
}

.es-project-body h2 {
	color: #0c4a40;
	font-size: 30px;
	font-weight: 700;
	margin: 0;
}

.es-project-body p {
	color: #5a6e69;
	font-size: 19px;
	line-height: 1.6;
	margin: 0;
}

.es-pull-quote {
	display: flex;
	align-items: center;
	gap: 24px;
	padding: 12px 0;
}

.es-pull-quote .es-bar {
	width: 4px;
	align-self: stretch;
	min-height: 96px;
	background-color: #17a796;
	border-radius: 2px;
	flex-shrink: 0;
}

.es-pull-quote blockquote,
.es-pull-quote p {
	font-family: 'Ephesis', cursive;
	color: #0c4a40;
	font-size: 38px;
	line-height: 1.25;
	margin: 0;
}

.es-image-row {
	display: flex;
	gap: 24px;
}

.es-image-row img {
	flex: 1;
	min-width: 0;
	height: auto;
	aspect-ratio: 16 / 10;
	object-fit: cover;
	border-radius: 20px;
}

.es-related {
	background-color: #ffffff;
}

.es-related__inner {
	max-width: 1440px;
	margin: 0 auto;
	box-sizing: border-box;
	padding: 64px 80px 80px;
}

.es-related__inner .ellesschrijft-portfolio-grid {
	padding: 0;
}

.es-related .section-header {
	margin-bottom: 48px;
}

@media (max-width: 1100px) {
	.es-title-row {
		flex-direction: column;
		align-items: stretch;
	}

	.es-meta-card-wrap {
		width: 100%;
	}
}

@media (max-width: 900px) {
	.es-project-head {
		padding: 28px 40px 24px;
		gap: 14px;
	}

	.es-title-col h1 {
		font-size: 32px;
		line-height: 1.05;
	}

	.es-title-col p {
		font-size: 16px;
	}

	.es-project-hero {
		padding: 0 40px;
	}

	.es-project-hero img {
		aspect-ratio: 16 / 10;
		border-radius: 20px;
	}

	.es-project-body {
		padding: 40px 40px;
		gap: 18px;
	}

	.es-project-body h2 {
		font-size: 24px;
	}

	.es-project-body p {
		font-size: 16px;
	}

	.es-pull-quote {
		gap: 16px;
	}

	.es-pull-quote blockquote,
	.es-pull-quote p {
		font-size: 26px;
	}

	.es-image-row {
		flex-direction: column;
		gap: 16px;
	}

	.es-related__inner {
		padding: 48px 40px;
	}

	.es-related .section-header {
		margin-bottom: 28px;
	}
}

/* Base typography and page background, so Afacad Flux + the ivory ground
   apply wherever the active theme's own theme.json doesn't already set
   them. Matches site/style.css body { background: var(--bg) }.

   The Gutenberg editor iframe puts its own ".editor-styles-wrapper" class
   on <body> (WP's block-editor/content.min.css sets a background on that
   class), which as a class selector outranks a plain "body" type selector
   regardless of source order — so without repeating the rule against that
   class, the editor canvas falls back to WP's neutral gray (#dddddd)
   instead of the design's ivory, even though this stylesheet is loaded
   inside the iframe. Front-end <body> never has that class, so this is a
   no-op there. */
body,
body.editor-styles-wrapper {
	background-color: #fbfaf7;
	font-family: 'Afacad Flux', system-ui, sans-serif;
}

/* WordPress adds a margin-block-start (blockGap) before every block that
   follows another inside a constrained content flow — including the last
   block before the footer template part, which reads as an unwanted gap
   between a full-bleed CTA/section and the footer. Zero it on the last
   child of the page content so the footer sits flush against it. */
.entry-content.is-layout-constrained > *:last-child {
	margin-block-end: 0;
}

/* Overrides theme.json's global-styles-inline-css blockGap rule. Its own
   selector is ":root :where(.is-layout-constrained) > *" — :where() has
   zero specificity, so that whole selector is really just as specific as
   ":root" alone. Cloning it verbatim would tie; "html:root" (a compound
   selector matching the same single <html> element) adds one type
   selector's worth of specificity on top of :root, safely ahead of the
   zero-cost :where() core uses, without relying on load order. Kills the
   gap above/below every direct child of a constrained block, not just
   between them. */
html:root :where(.is-layout-constrained) > * {
	margin-block-start: 0;
	margin-block-end: 0;
}

/* One specific Columns block's own saved gap (an auto-generated,
   per-instance hash class from theme.json/global styles) was set to 0;
   restore the design's normal 32px gap for it. body-prefixed: core's
   rule for this exact class ties our specificity otherwise. */
body .wp-container-core-columns-is-layout-b5f679f9 {
	gap: 32px;
}

/* WP core sets the admin bar to position:absolute below 600px (so it
   scrolls away with the page on small screens) — but our own header/nav
   offsets throughout this file assume a consistently position:fixed
   admin bar at every width. Force it back to fixed. Core's own rule is
   the bare ID selector "#wpadminbar", which normally can only be beaten
   by another ID or !important — adding "body" in front contributes one
   extra type selector on top of the (already-maximal) ID weight, which
   is enough since both sides are otherwise identical IDs. */
@media screen and (max-width: 600px) {
	body #wpadminbar {
		position: fixed;
	}
}

/* Contact Form 7 styling, matching the design's contact form fields. */
.wpcf7-form {
	font-family: 'Afacad Flux', system-ui, sans-serif;
	display: flex;
	flex-direction: column;
	gap: 20px;
}

.wpcf7-form p {
	margin: 0;
}

.wpcf7-form label {
	display: flex;
	flex-direction: column;
	gap: 8px;
	font-size: 15px;
	font-weight: 600;
	color: #22332f;
}

.wpcf7-form input[type="text"],
.wpcf7-form input[type="email"],
.wpcf7-form textarea {
	width: 100%;
	box-sizing: border-box;
	padding: 13px 16px;
	background-color: #fbfaf7;
	border: 1px solid #0c4a4022;
	border-radius: 12px;
	font-family: inherit;
	font-size: 16px;
	color: #22332f;
}

.wpcf7-form input[type="text"]::placeholder,
.wpcf7-form input[type="email"]::placeholder,
.wpcf7-form textarea::placeholder {
	color: #9aaaa5;
}

.wpcf7-form input[type="text"]:focus,
.wpcf7-form input[type="email"]:focus,
.wpcf7-form textarea:focus {
	outline: 2px solid #17a796;
	border-color: transparent;
}

.wpcf7-form textarea {
	min-height: 140px;
	resize: vertical;
}

.wpcf7-form input[type="submit"] {
	width: 100%;
	box-sizing: border-box;
	padding: 12px 28px;
	background-color: #17a796;
	color: #ffffff;
	font-family: inherit;
	font-size: 17px;
	font-weight: 600;
	letter-spacing: 0.5px;
	border: none;
	border-radius: 999px;
	cursor: pointer;
}

.wpcf7-form input[type="submit"]:hover {
	background-color: #0c4a40;
}

.wpcf7-form input[type="submit"]:disabled {
	opacity: 0.6;
	cursor: default;
}

.wpcf7-not-valid-tip {
	margin-top: 4px;
	font-size: 13px;
	color: #c0392b;
}

/* CF7's own plugin CSS targets this as ".wpcf7 form .wpcf7-response-output"
   (2 classes + a type selector) — matching that exact shape plus a
   leading "body" beats it outright rather than relying on load order. */
body .wpcf7 form .wpcf7-response-output {
	margin-top: 16px;
	padding: 12px 16px;
	border-radius: 12px;
	font-size: 14px;
}

/* Optional wrapper for putting two CF7 fields side by side, e.g. Naam
   + E-mail (see docs/contact-form-7-setup.md). */
.contact-form-row {
	display: flex;
	gap: 16px;
}

.contact-form-row p {
	flex: 1;
	margin: 0;
}

@media (max-width: 900px) {
	.contact-form-row {
		flex-direction: column;
	}
}

/* ---------- Extra-small mobile (≤412px) ---------- */
/* Below the smallest common phone width (412px = Pixel's CSS width),
   every section-level container — header, footer, and every full-bleed
   section that follows the OUTER/__inner pattern documented above —
   drops its horizontal padding from 40px to 24px, so copy doesn't sit
   flush against the edge on the narrowest real devices. Only the
   x-padding changes here; each selector's own vertical padding (set in
   its 900px rule above) is left alone, hence padding-left/right instead
   of the padding shorthand. Hero, cta-banner, and prev-next-nav get the
   matching override in their own block's style.scss, since they build
   into separate stylesheets. */
@media (max-width: 412px) {
	.ellesschrijft-portfolio-grid,
	.section,
	.es-footer__inner,
	.es-about-strip__inner,
	.es-intro__inner,
	.es-page-header,
	.es-dienst > .es-dienst-inner,
	.es-stats__inner,
	.es-quote-strip__inner,
	.es-project-head,
	.es-project-hero,
	.es-project-body,
	.es-related__inner {
		padding-left: 24px;
		padding-right: 24px;
	}

	.es-header__inner {
		padding-left: 24px;
		padding-right: 24px;
	}
}
