/*
Theme Name: Joel Jones Digital
Theme URI:
Author: Joel Jones Digital
Author URI: https://joeljonesdigital.com
Description: Custom block theme for Joel Jones Digital — web design and development for small businesses and individuals. Poppins type, blue-to-cyan gradient system, WCAG 2.2 AA.
Requires at least: 6.7
Tested up to: 7.1
Requires PHP: 7.4
Version: 2.5.3
License: GNU General Public License v2 or later
License URI: http://www.gnu.org/licenses/gpl-2.0.html
Text Domain: joel-jones-digital
Tags: one-column, custom-colors, custom-menu, custom-logo, editor-style, featured-images, full-site-editing, block-patterns, block-styles, translation-ready, accessibility-ready, portfolio
*/

/* ==========================================================================
   1. Base
   ========================================================================== */

body {
	-webkit-font-smoothing: antialiased;
	-moz-osx-font-smoothing: grayscale;
}

/* The mockup's universal link hover is blue -> cyan. theme.json already sets the
   link color + text-safe cyan hover (#077B97, WCAG); nothing more needed here. */

/* Never ship a control with no visible focus indicator. */
:where(a, button, input, select, textarea, summary, .wp-element-button):focus:not(:focus-visible) {
	outline: none;
}

/* ==========================================================================
   2. Keyboard focus visibility  (REBUILD-MASTER §11.3)
   Two variants: an accent-blue ring is invisible (1:1) against the gradient's
   blue end, so gradient sections get a white ring instead.
   ========================================================================== */

a:focus-visible,
button:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible,
summary:focus-visible,
.wp-element-button:focus-visible,
.wp-block-navigation-item__content:focus-visible {
	outline: 2px solid var(--wp--preset--color--accent-blue);
	outline-offset: 2px;
	border-radius: 2px;
}

.jjd-gradient-section a:focus-visible,
.jjd-gradient-section button:focus-visible,
.jjd-gradient-section .wp-element-button:focus-visible,
.jjd-header a:focus-visible,
.jjd-header .wp-block-navigation-item__content:focus-visible,
.jjd-footer a:focus-visible {
	outline: 2px solid #ffffff;
	outline-offset: 2px;
}

/* ==========================================================================
   3. Skip-to-content link  (REBUILD-MASTER §11.4 — WP core injects it; only the
   focused-state colours are re-branded here, positioning is left to core.)
   ========================================================================== */

.skip-link.screen-reader-text:focus {
	background-color: var(--wp--preset--color--accent-blue);
	color: #ffffff;
	border-radius: 0 0 8px 0;
	box-shadow: 0 4px 12px rgba(15, 23, 42, 0.25);
}

/* ==========================================================================
   4. Header  —  transparent bar sitting over each page's gradient hero
   ========================================================================== */

/* Anchor the absolutely-positioned header to the site container rather than the
   viewport, so it sits below the WP admin bar for logged-in users automatically
   (the admin bar shifts .wp-site-blocks down via html margin-top). */
.wp-site-blocks { position: relative; }

/* Full-width sections butt directly against each other, the header, and the
   footer — their own padding is the only spacing. Cancel the block-gap margin
   WordPress's flow layout adds between every sibling. */
.jjd-main,
.jjd-main > .wp-block-post-content,
.jjd-main > .wp-block-post-content > *,
.wp-site-blocks > * {
	margin-block: 0;
}

.jjd-header {
	position: absolute;
	inset: 0 0 auto 0;
	z-index: 20;
	background: transparent;
}

.jjd-header .wp-block-group {
	background: transparent;
}

.jjd-header__bar {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 16px 32px;
	flex-wrap: wrap;
	max-width: 1200px;
	margin-inline: auto;
	padding-block: clamp(20px, 4vw, 32px);
	padding-inline: clamp(24px, 5vw, 48px);
}

.jjd-header__logo img {
	height: 52px;
	width: auto;
	display: block;
}

.jjd-header .wp-block-navigation {
	--navigation-layout-gap: 32px;
	font-size: 0.9375rem;
	font-weight: 500;
}

.jjd-header .wp-block-navigation a,
.jjd-header .wp-block-navigation .wp-block-navigation-item__content {
	color: #ffffff;
	text-decoration: none;
	text-underline-offset: 4px;
	/* Comfortable keyboard/pointer target even though the visible text is small. */
	padding-block: 6px;
}

.jjd-header .wp-block-navigation a:hover,
.jjd-header .wp-block-navigation a:focus-visible {
	text-decoration: underline;
	color: #ffffff;
}

/* Mobile (<=600px): the nav collapses to a hamburger + full-screen overlay
   (overlayMenu:"mobile" in the header pattern). The closed button needs to be
   white for the gradient header; the open overlay's navy background and white
   links come from the block's overlayBackgroundColor / overlayTextColor. */
.jjd-header .wp-block-navigation__responsive-container-open,
.jjd-header .wp-block-navigation__responsive-container-close {
	color: #ffffff;
	padding: 6px;
}
.jjd-header .wp-block-navigation__responsive-container-open svg,
.jjd-header .wp-block-navigation__responsive-container-close svg {
	width: 28px;
	height: 28px;
	fill: currentColor;
}
.jjd-header .wp-block-navigation__responsive-container.is-menu-open {
	padding: clamp(24px, 14vw, 72px) clamp(24px, 6vw, 48px);
}
/* The nav is right-justified for the desktop bar; left-align it in the overlay. */
.jjd-header .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-container-content,
.jjd-header .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__container {
	align-items: flex-start;
	text-align: left;
}
.jjd-header .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-container-content {
	padding-top: clamp(32px, 12vw, 64px);
}
.jjd-header .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__container {
	gap: 6px;
	width: 100%;
}
.jjd-header .wp-block-navigation__responsive-container.is-menu-open a {
	font-size: 1.375rem;
	padding-block: 12px;
}

/* Pages without a gradient hero (index / plain page / 404): solid header so the
   white logo and nav stay legible. */
body:not(.jjd-hero-page) .jjd-header {
	position: static;
	background: var(--wp--preset--color--footer-bg);
}

/* ==========================================================================
   5. Gradient sections + decorative blobs
   The flat dark scrim (rgba(15,23,42,.3)) is stacked over the gradient so white
   text clears 4.5:1 anywhere on it  (REBUILD-MASTER §1, "Gradient text-contrast scrim").
   ========================================================================== */

.jjd-gradient-section {
	position: relative;
	isolation: isolate;
	overflow: hidden;
	background:
		linear-gradient(rgba(15, 23, 42, 0.3), rgba(15, 23, 42, 0.3)),
		linear-gradient(135deg, #1A56DB 0%, #0891B2 100%);
	color: #ffffff;
}

.jjd-gradient-section.is-reversed {
	background:
		linear-gradient(rgba(15, 23, 42, 0.3), rgba(15, 23, 42, 0.3)),
		linear-gradient(135deg, #0891B2 0%, #1A56DB 100%);
}

/* Light sections that also carry decorative blobs */
.jjd-has-blobs {
	position: relative;
	isolation: isolate;
	overflow: hidden;
}

.jjd-gradient-section > *:not(.jjd-blob),
.jjd-has-blobs > *:not(.jjd-blob) {
	position: relative;
	z-index: 1;
}

.jjd-blob {
	position: absolute;
	z-index: 0;
	pointer-events: none;
	background: rgba(255, 255, 255, 0.07);
}

.jjd-blob-1 { top: -80px; left: -100px; width: 320px; height: 320px; border-radius: 45% 55% 60% 40%; }
.jjd-blob-2 { bottom: -120px; right: -80px; width: 380px; height: 380px; background: rgba(255, 255, 255, 0.06); border-radius: 60% 40% 45% 55%; }
.jjd-blob-3 { top: 28%; right: 8%; width: 140px; height: 140px; background: rgba(255, 255, 255, 0.08); border-radius: 55% 45% 40% 60%; }

/* Solid-tint blobs used on the light (#F1F5F9) sections */
.jjd-blob--tint { background: linear-gradient(135deg, #1A56DB 0%, #0891B2 100%); opacity: 0.9; }

/* On phones/tablets the columns stack, so these bold blobs end up directly
   behind the dark body text and kill its contrast. Shrink them to corner
   accents and drop the opacity so text stays readable over them. */
@media (max-width: 900px) {
	.jjd-blob--tint {
		opacity: 0.14;
		max-width: 150px !important;
		max-height: 150px !important;
	}
}

.jjd-gradient-section :where(h1, h2, h3) { color: #ffffff; }
.jjd-gradient-section p { color: rgba(255, 255, 255, 0.9); }
.jjd-gradient-section a:not(.wp-element-button) { color: #ffffff; }

/* ==========================================================================
   6. Kickers / eyebrows / accent sub-lines
   ========================================================================== */

.jjd-kicker {
	font-size: 0.875rem;
	font-weight: 600;
	text-transform: uppercase;
	letter-spacing: 1.5px;
	color: var(--wp--preset--color--accent-blue);
	margin: 0;
}

.jjd-gradient-section .jjd-kicker,
.jjd-kicker.is-on-gradient {
	/* 0.85 measured ~4.8:1 against the darkest (cyan) end of the hero
	   gradient — a legal AA pass but a much thinner margin than every other
	   on-gradient text here. Matches .jjd-gradient-section p's existing 0.9,
	   which gives ~5.1:1 at that same worst-case point. */
	color: rgba(255, 255, 255, 0.9);
}

/* A white card floating on a gradient section (the mid-page health-check CTA):
   the kicker sits on white, so it needs the accent-blue color, not white. */
.jjd-gradient-section .jjd-card .jjd-kicker {
	color: var(--wp--preset--color--accent-blue);
}

/* Small reassurance line under a CTA (e.g. response time) — sizes down and
   softens whatever text color it inherits, rather than setting its own, so
   it reads correctly on both gradient sections (white text) and white cards. */
.jjd-microcopy {
	font-size: 0.875rem;
	opacity: 0.85;
	margin: 0;
}

.jjd-eyebrow-cyan {
	font-size: 1rem;
	font-weight: 600;
	color: var(--wp--preset--color--accent-cyan-text);
	margin: 0;
}

/* ==========================================================================
   7. Buttons  —  on-gradient variations  (names registered in functions.php)
   ========================================================================== */

.wp-block-button.is-style-on-gradient .wp-element-button {
	background-color: #ffffff;
	color: var(--wp--preset--color--accent-blue);
	border: none;
	transition: transform 0.15s ease, box-shadow 0.15s ease;
}

.wp-block-button.is-style-on-gradient .wp-element-button:hover,
.wp-block-button.is-style-on-gradient .wp-element-button:focus-visible {
	background-color: #ffffff;
	color: var(--wp--preset--color--accent-blue);
	transform: translateY(-2px);
	box-shadow: 0 8px 20px rgba(0, 0, 0, 0.18);
}

.wp-block-button.is-style-on-gradient-outline .wp-element-button {
	background-color: transparent;
	color: #ffffff;
	border: 2px solid #ffffff;
	transition: background-color 0.15s ease, transform 0.15s ease;
}

.wp-block-button.is-style-on-gradient-outline .wp-element-button:hover,
.wp-block-button.is-style-on-gradient-outline .wp-element-button:focus-visible {
	background-color: rgba(255, 255, 255, 0.15);
	color: #ffffff;
	transform: translateY(-2px);
}

/* Solid accent buttons lift on hover too (matches the mockup) */
.wp-block-button:not(.is-style-on-gradient):not(.is-style-on-gradient-outline) .wp-element-button {
	transition: background-color 0.15s ease, transform 0.15s ease, box-shadow 0.15s ease;
}
.wp-block-button:not(.is-style-on-gradient):not(.is-style-on-gradient-outline):not(.is-style-secondary) .wp-element-button:hover {
	transform: translateY(-2px);
	box-shadow: 0 8px 20px rgba(0, 0, 0, 0.18);
}

/* Secondary button for light sections: outlined accent-blue (pairs with the
   default solid button as primary). Border via inset box-shadow so it doesn't
   change the box size vs. the solid variant. */
.wp-block-button.is-style-secondary .wp-element-button {
	background-color: transparent;
	color: var(--wp--preset--color--accent-blue);
	box-shadow: inset 0 0 0 2px var(--wp--preset--color--accent-blue);
	transition: background-color 0.15s ease, color 0.15s ease, transform 0.15s ease;
}
.wp-block-button.is-style-secondary .wp-element-button:hover,
.wp-block-button.is-style-secondary .wp-element-button:focus-visible {
	background-color: var(--wp--preset--color--accent-blue);
	color: var(--wp--preset--color--base);
	transform: translateY(-2px);
}

/* ==========================================================================
   8. Cards  (REBUILD-MASTER §1 "Cards" — several distinct treatments)
   ========================================================================== */

.jjd-card {
	border-radius: 16px;
	padding: clamp(28px, 4vw, 32px);
}

/* Health-check callout — white card floating on the gradient section */
.jjd-card--float {
	background: #ffffff;
	color: var(--wp--preset--color--body-text);
	max-width: 640px;
	margin-inline: auto;
}
.jjd-card--float :where(h1, h2, h3) { color: var(--wp--preset--color--heading); }
.jjd-card--float p { color: var(--wp--preset--color--body-text); }

/* Core-build cards — soft blue/cyan gradient tint */
.jjd-card--tint {
	background: linear-gradient(135deg, rgba(26, 86, 219, 0.07) 0%, rgba(8, 145, 178, 0.07) 100%);
	padding: 32px;
}
.jjd-card--tint .jjd-card__label {
	font-size: 0.875rem;
	font-weight: 600;
	text-transform: uppercase;
	letter-spacing: 1px;
	color: var(--wp--preset--color--accent-cyan-text);
}

/* Testimonial cards — white on the #F1F5F9 section */
.jjd-card--testimonial {
	background: #ffffff;
	padding: 32px;
	display: flex;
	flex-direction: column;
	gap: 16px;
	justify-content: space-between;
}
.jjd-card--testimonial .jjd-card__author {
	font-size: 0.9375rem;
	font-weight: 600;
	color: var(--wp--preset--color--heading);
}

/* Services pricing cards */
.jjd-card--price {
	padding: clamp(32px, 5vw, 44px);
	display: flex;
	flex-direction: column;
	gap: 12px;
	align-items: flex-start;
}
.jjd-card--price.has-tint-bg { background: var(--wp--preset--color--section-subtle); }
.jjd-card--price.is-primary {
	background: #ffffff;
	border: 2px solid var(--wp--preset--color--accent-blue);
}
.jjd-card--price.is-free {
	position: relative;
	overflow: hidden;
	color: #ffffff;
	background:
		linear-gradient(rgba(15, 23, 42, 0.3), rgba(15, 23, 42, 0.3)),
		linear-gradient(135deg, #1A56DB 0%, #0891B2 100%);
}
.jjd-card--price.is-free :where(h1, h2, h3) { color: #ffffff; }
.jjd-card--price.is-free p { color: rgba(255, 255, 255, 0.9); }
.jjd-card--price .jjd-price {
	font-size: 1.375rem;
	font-weight: 600;
	color: var(--wp--preset--color--accent-blue);
	margin: 0;
}
.jjd-card--price.is-free .jjd-price { color: #ffffff; }
.jjd-card--price .jjd-price-list-wrap { width: 100%; }

.jjd-price-row {
	display: flex;
	justify-content: space-between;
	align-items: baseline;
	gap: 16px;
	padding-block: 18px;
	border-bottom: 1px solid var(--wp--preset--color--border);
	font-size: 0.9375rem;
	color: var(--wp--preset--color--heading);
}
.jjd-price-row:last-of-type { border-bottom: 0; }
.jjd-price-row span:last-child { font-weight: 600; color: var(--wp--preset--color--accent-blue); white-space: nowrap; }

/* Contact sidebar card */
.jjd-card--subtle {
	background: var(--wp--preset--color--section-subtle);
	border-radius: 16px;
	padding: 36px;
	height: fit-content;
}

/* ==========================================================================
   9. Process steps (Home "How it works")
   ========================================================================== */

.jjd-step { display: flex; gap: 20px; align-items: flex-start; }
.jjd-step__num {
	flex: none;
	width: 44px;
	height: 44px;
	border-radius: 50%;
	background: linear-gradient(135deg, #1A56DB 0%, #0891B2 100%);
	color: #ffffff;
	font-size: 1.125rem;
	font-weight: 600;
	display: flex;
	align-items: center;
	justify-content: center;
}

/* ==========================================================================
   10. Photo slot (headshot placeholder — real image dropped in later)
   ========================================================================== */

.jjd-photo-slot {
	position: relative;
	margin: 0;
	aspect-ratio: 1;
	min-width: 200px;
	overflow: hidden;
	background: linear-gradient(135deg, rgba(26, 86, 219, 0.12) 0%, rgba(8, 145, 178, 0.12) 100%);
	border-radius: 65% 35% 55% 45% / 45% 55% 40% 60%;
	color: var(--wp--preset--color--body-text);
	font-size: 0.875rem;
	text-align: center;
}

.jjd-photo-frame { position: relative; }

/* Homepage "Who's behind this" — a 1:1 crop (matches the About-page headshot),
   with a decorative gradient blob offset behind it (top-right). */
.jjd-split:not(.jjd-split--wide) .jjd-photo-frame {
	max-width: 300px;
}
.jjd-split:not(.jjd-split--wide) .jjd-photo-slot {
	position: relative;
	z-index: 1;
	aspect-ratio: 1 / 1;
	/* Asymmetric organic mask — lopsided pebble, bulging upper-left / lower-right */
	border-radius: 72% 28% 42% 58% / 58% 68% 32% 42%;
}
.jjd-split:not(.jjd-split--wide) .jjd-photo-frame::before {
	content: "";
	position: absolute;
	z-index: 0;
	inset: -18px -26px 22px 26px;
	background: linear-gradient(135deg, #1A56DB 0%, #0891B2 100%);
	border-radius: 40% 60% 65% 35% / 55% 40% 60% 45%;
	pointer-events: none;
}
/* Placeholder (no image dropped in yet) */
.jjd-photo-slot:not(:has(img)) {
	display: grid;
	place-items: center;
	padding: 16px;
}
.jjd-gradient-section .jjd-photo-slot {
	background: rgba(255, 255, 255, 0.15);
	border: 3px solid rgba(255, 255, 255, 0.4);
	color: rgba(255, 255, 255, 0.9);
}
.jjd-photo-slot img {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
	object-position: center 22%;
}

/* ==========================================================================
   11. Emphasis underline — reusable rich-text format for headings. Applied
   from the block editor toolbar (assets/js/editor-format-emphasis.js), which
   wraps the selection in <mark class="jjd-emphasis">. Meant for a short
   phrase (a word or a few), not a wrapping multi-line selection.

   Draws in left-to-right as it scrolls into view (assets/js/emphasis-draw.js
   adds .is-drawn). The clipped "undrawn" state only applies under .jjd-js
   (see jjd_js_flag()), so a page with that script blocked just shows the
   underline fully drawn — it's never left missing.
   ========================================================================== */
.jjd-emphasis {
	position: relative;
	background: none;
	color: inherit;
}
.jjd-emphasis::after {
	content: "";
	position: absolute;
	left: -2%;
	right: -3%;
	bottom: -0.22em;
	height: 0.28em;
	background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 300 24' preserveAspectRatio='none'%3E%3Cpath d='M4,16 C55,4 90,22 140,10 C185,0 220,20 260,8 C275,4 285,10 296,7' fill='none' stroke='%23F43F5E' stroke-width='7' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
	background-repeat: no-repeat;
	background-size: 100% 100%;
	pointer-events: none;
}
.jjd-js .jjd-emphasis::after {
	clip-path: inset(0 100% 0 0);
	transition: clip-path 0.7s cubic-bezier(0.65, 0, 0.35, 1);
	will-change: clip-path;
}
.jjd-js .jjd-emphasis.is-drawn::after {
	clip-path: inset(0 0 0 0);
}
@media (prefers-reduced-motion: reduce) {
	.jjd-js .jjd-emphasis::after {
		clip-path: inset(0 0 0 0);
		transition: none;
	}
}

/* ==========================================================================
   12. FAQ  —  native <details> accordion, one open at a time ([name])
   ========================================================================== */

.jjd-faq__item { border-bottom: 1px solid var(--wp--preset--color--border); }
.jjd-faq__item:first-child { border-top: 1px solid var(--wp--preset--color--border); }

.jjd-faq__q {
	list-style: none;                /* drop the default disclosure triangle */
	cursor: pointer;
	display: flex;
	align-items: flex-start;
	justify-content: space-between;
	gap: 20px;
	padding: 20px 0;
}
.jjd-faq__q::-webkit-details-marker { display: none; }

.jjd-faq__q h3 {
	margin: 0;
	font-size: 1.0625rem;
	font-weight: 600;
	line-height: 1.4;
	color: var(--wp--preset--color--heading);
}

/* chevron: points down when closed, up when open */
.jjd-faq__q::after {
	content: "";
	flex: none;
	width: 9px;
	height: 9px;
	margin-top: 6px;
	border-right: 2px solid var(--wp--preset--color--accent-blue);
	border-bottom: 2px solid var(--wp--preset--color--accent-blue);
	transform: rotate(45deg);
	transition: transform 0.2s ease;
}
.jjd-faq__item[open] .jjd-faq__q::after { transform: rotate(-135deg); }

.jjd-faq__a {
	margin: 0;
	padding: 0 40px 22px 0;
	color: var(--wp--preset--color--body-text);
}

/* ==========================================================================
   13. Footer
   ========================================================================== */

.jjd-footer {
	background: var(--wp--preset--color--footer-bg);
	color: rgba(255, 255, 255, 0.85);
	padding-block: 32px 28px;
}
.jjd-footer a { color: rgba(255, 255, 255, 0.85); text-decoration: none; text-underline-offset: 4px; }
.jjd-footer a:hover, .jjd-footer a:focus-visible { text-decoration: underline; color: #ffffff; }

.jjd-footer__top,
.jjd-footer__meta {
	max-width: 1200px;
	margin-inline: auto;
	padding-inline: clamp(24px, 5vw, 48px);
	display: flex;
	align-items: center;
	justify-content: space-between;
	flex-wrap: wrap;
	gap: 16px;
}
.jjd-footer__logo img { height: 42px; width: auto; display: block; }
.jjd-footer .wp-block-navigation { --navigation-layout-gap: 32px; font-size: 0.9375rem; font-weight: 500; }

.jjd-footer__divider.wp-block-separator {
	/* !important beats core's `.wp-block-separator:not(.is-style-wide):not(.is-style-dots){width:100px}` (0,3,0). */
	width: calc(100% - 2 * clamp(24px, 5vw, 48px)) !important;
	max-width: 1104px !important; /* 1200 content box minus its 48px inline padding, so it lines up */
	margin: 24px auto 0;
	border: 0;
	border-top: 1px solid rgba(255, 255, 255, 0.12);
	opacity: 1;
}
.jjd-footer__secondary {
	max-width: 1200px;
	margin: 20px auto 0;
	padding-inline: clamp(24px, 5vw, 48px);
	display: flex;
	flex-direction: column;
	gap: 12px;
}
.jjd-footer__links { display: flex; gap: 24px; flex-wrap: wrap; font-size: 0.875rem; }
.jjd-footer__links a,
.jjd-footer__email { color: rgba(255, 255, 255, 0.6); }
.jjd-footer__links a:hover { color: #ffffff; }
/* Copyright: 0.6 not the mockup's 0.4 — 0.4 fails 4.5:1 at 13-14px (REBUILD-MASTER §1). */
.jjd-footer__copyright { font-size: 0.875rem; color: rgba(255, 255, 255, 0.6); margin: 0; }
/* Email is shown but deliberately NOT a link, everywhere it appears (REBUILD-MASTER §4.1). */
.jjd-footer__email { font-size: 0.875rem; }

/* ==========================================================================
   14. Section rhythm helpers
   ========================================================================== */

.jjd-section {
	padding-block: clamp(64px, 8vw, 96px);
	padding-inline: clamp(24px, 5vw, 48px);
}
.jjd-section--tight { padding-block: clamp(48px, 6vw, 72px); }
/* Stacked columns + corner blobs need a little more breathing room on phones. */
@media (max-width: 900px) {
	.jjd-section--tight { padding-block: 64px; }
}
.jjd-hero {
	padding-top: clamp(120px, 16vw, 168px);
	padding-bottom: clamp(56px, 8vw, 96px);
	padding-inline: clamp(24px, 5vw, 48px);
}

/* Home hero: taller, with the content vertically centred, and a wider measure
   so the two H1 sentences (split with <br>) each sit on one line on desktop. */
.jjd-hero--tall {
	display: flex;
	flex-direction: column;
	justify-content: center;
	min-height: min(82vh, 780px);
	padding-top: clamp(150px, 19vw, 200px);
	padding-bottom: clamp(72px, 10vw, 110px);
}
.jjd-hero--tall .jjd-measure { max-width: 940px; width: 100%; }
.jjd-hero--tall h1,
.jjd-hero--tall .jjd-measure > p { text-wrap: balance; }
@media (max-width: 700px) {
	.jjd-hero--tall { min-height: 0; }
}

.jjd-measure { max-width: 720px; margin-inline: auto; }
.jjd-measure-wide { max-width: 1100px; margin-inline: auto; }

/* Blog post body — a wider reading measure than the shared .jjd-measure.
   post-content uses a constrained layout pinned to theme.json's 720px
   contentSize and carries WP's global side padding, so both are overridden
   here to let the article body run to 860px. The section wrapper still
   supplies the outer gutter on small screens. */
.jjd-article { max-width: 860px; margin-inline: auto; }
.jjd-article .wp-block-post-content { padding-left: 0; padding-right: 0; }
.jjd-article .wp-block-post-content > *:not(.alignwide):not(.alignfull) {
	max-width: 860px;
	margin-inline: auto;
}
/* Links inside article prose (inline citations + the Sources list) need a
   non-color signal per WCAG 1.4.1 — theme.json turns the underline off for
   links site-wide (nav/buttons/cards read as links from context instead),
   but a link sitting in a paragraph or list has no other cue, so restore
   the underline just here. */
.jjd-article .wp-block-post-content a {
	text-decoration: underline;
	text-underline-offset: 3px;
}
/* Code blocks: a long line scrolls inside the block instead of widening the
   page on a phone. Smaller than body text so more fits per line. */
.jjd-article .wp-block-code {
	overflow-x: auto;
	font-size: 0.875rem;
	line-height: 1.55;
}
/* Section headings need more air above them than the 24px block gap, or a long
   post reads as one undifferentiated column. */
.jjd-article .wp-block-post-content > h2 { margin-top: 3rem; }
.jjd-article .wp-block-post-content > h3 { margin-top: 2rem; }
.jjd-article .wp-block-post-content > h2:first-child,
.jjd-article .wp-block-post-content > h3:first-child { margin-top: 0; }
.jjd-center { text-align: center; }
.jjd-center .wp-block-buttons { justify-content: center; }
.jjd-stack-sm { display: flex; flex-direction: column; gap: 14px; }
.jjd-stack-sm.jjd-center { align-items: center; }

/* These containers space their children with `gap`; neutralise the block-gap
   margin WordPress's flow layout also adds to sibling blocks, or spacing doubles. */
.jjd-grid > *,
.jjd-stack-sm > *,
.jjd-steps > *,
.jjd-step > *,
.jjd-price-list > *,
.jjd-faq > *,
.jjd-media-split > *,
.jjd-contact-layout > * {
	margin-block: 0;
}

/* Simple responsive grids */
.jjd-grid { display: grid; gap: 24px; }
.jjd-grid-3 { grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); }
.jjd-grid-2 { grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); }
.jjd-grid--gap-lg { gap: 32px; }

/* Home "About" split + About-page hero split */
.jjd-split {
	display: grid;
	grid-template-columns: 300px 1fr;
	gap: clamp(32px, 6vw, 56px);
	align-items: center;
}
.jjd-split--wide { grid-template-columns: 1fr 280px; }
@media (max-width: 720px) {
	.jjd-split, .jjd-split--wide { grid-template-columns: 1fr; }
	.jjd-split:not(.jjd-split--wide) .jjd-photo-frame { margin-inline: auto; }
}

/* Home "problem" section: text left, a media panel right — a large gradient
   blob (::before) with room for an image dropped in on top later. */
.jjd-media-split {
	display: grid;
	grid-template-columns: 1fr minmax(240px, 360px);
	gap: clamp(32px, 6vw, 64px);
	align-items: center;
}
.jjd-media-split .jjd-photo-frame { position: relative; }
.jjd-media-split .jjd-photo-slot {
	position: relative;
	z-index: 1;
	aspect-ratio: 4 / 5;
	border-radius: 68% 32% 58% 42% / 28% 32% 40% 56%;
}
.jjd-media-split .jjd-photo-frame::before {
	content: "";
	position: absolute;
	z-index: 0;
	inset: -44px -52px 32px 40px;
	background: linear-gradient(135deg, #1A56DB 0%, #0891B2 100%);
	border-radius: 44% 56% 62% 38% / 56% 42% 58% 44%;
	pointer-events: none;
}
@media (max-width: 820px) {
	.jjd-media-split { grid-template-columns: 1fr; }
	.jjd-media-split .jjd-photo-frame {
		max-width: 320px;
		margin: 12px auto 0;
	}
	.jjd-media-split .jjd-photo-frame::before { inset: -24px -30px 20px 26px; }
}

/* Process steps stack */
.jjd-steps { display: flex; flex-direction: column; gap: 32px; }

/* About page — stacked blocks separated by hairline dividers */
.jjd-about-blocks > * {
	padding-block: 40px;
	border-bottom: 1px solid var(--wp--preset--color--border);
}
.jjd-about-blocks > *:first-child { padding-top: 0; }
.jjd-about-blocks > *:last-child { border-bottom: 0; padding-bottom: 0; }
.jjd-about-blocks h2 { margin: 0 0 12px; font-size: 1.625rem; }

/* Services pricing list */
.jjd-price-list { display: flex; flex-direction: column; gap: 24px; }

/* Portfolio single — framed screenshot */
.jjd-single-shot {
	margin: 0;
	border: 1px solid var(--wp--preset--color--border);
	border-radius: 16px;
	overflow: hidden;
}
.jjd-single-shot img { display: block; width: 100%; height: auto; }

/* ==========================================================================
   15. Reduced motion — kill the button/blob transitions too
   ========================================================================== */

@media (prefers-reduced-motion: reduce) {
	*, *::before, *::after {
		animation-duration: 0.001ms !important;
		transition-duration: 0.001ms !important;
	}
}
