/*
Theme Name: Frameline
Theme URI: https://example.com/frameline/
Author: Frameline
Author URI: https://example.com/
Description: A fast, dependency-free photography theme built around a hero carousel, a portfolio shell that works with any gallery plugin, and structured data written for local photography businesses. Self-hosted variable fonts, no third-party requests, no page builder required.
Version: 1.0.0
Requires at least: 5.9
Tested up to: 6.8
Requires PHP: 7.2
License: GNU General Public License v2 or later
License URI: http://www.gnu.org/licenses/gpl-2.0.html
Text Domain: frameline
Tags: photography, portfolio, blog, one-column, custom-colors, custom-logo, custom-menu, featured-images, block-patterns, block-styles, translation-ready, full-width-template
*/

/* ==========================================================================
   0. Typefaces
   Self-hosted variable fonts. Serving them from this origin removes a
   third-party request from the critical path — no extra DNS lookup, no TLS
   handshake, no stylesheet round trip before the font can even be requested —
   and removes the privacy question that comes with a third-party font CDN.
   Latin subsets only: 156KB for both faces across every weight.
   ========================================================================== */

@font-face {
	font-family: "Fraunces";
	font-style: normal;
	font-weight: 100 900;
	font-display: swap;
	src: url("assets/fonts/fraunces-var.woff2") format("woff2-variations");
}

@font-face {
	font-family: "Archivo";
	font-style: normal;
	font-weight: 100 900;
	font-display: swap;
	src: url("assets/fonts/archivo-var.woff2") format("woff2-variations");
}

/* ==========================================================================
   1. Design tokens
   Colour values are overridden at runtime by inc/dynamic-css.php, which
   prints Customizer values into this same :root block. Keep the names stable.
   ========================================================================== */

:root {
	--fl-ground: #101114;          /* page background */
	--fl-ground-2: #17191e;        /* raised surfaces, footer */
	--fl-paper: #f2efe9;           /* primary text on dark */
	--fl-dim: #a2a2ab;             /* secondary text on dark */
	--fl-gold: #c9a227;            /* brand accent */
	--fl-gold-lift: #e3c463;       /* accent on hover / focus */
	--fl-line: rgba(233, 228, 216, 0.14);

	/* Type */
	--fl-display: "Fraunces", "Iowan Old Style", Georgia, serif;
	--fl-body: "Archivo", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;

	/* Space the fixed header occupies. Every element that sits beneath it
	   reserves this, so nothing can slide underneath at any viewport size. */
	/* WordPress pushes the document down for the admin bar but fixed elements
	   keep measuring from the top of the viewport, so the header has to step
	   down by the same amount or it sits underneath it. Zero for visitors. */
	--fl-adminbar-h: 0px;

	--fl-header-h: 6rem;

	/* Gap between the bottom of the header and the top of the hero headline.
	   Sized to leave a clear band for the site tagline. */
	--fl-hero-gap: clamp(0.4rem, 1.2vh, 0.85rem);

	/* Measure and rhythm */
	--fl-measure: 68ch;
	--fl-gutter: clamp(1.25rem, 5vw, 4.5rem);
	--fl-wide: 1440px;
	--fl-section: clamp(4.5rem, 11vh, 9rem);

	/* Motion */
	--fl-ease: cubic-bezier(0.22, 0.61, 0.36, 1);
}

/* Light mode follows the OS/browser preference. No manual toggle.
   The palette inverts; the gold darkens so it still clears AA on paper. */
@media (prefers-color-scheme: light) {
	:root {
		--fl-ground: #f1efea;
		--fl-ground-2: #e7e3db;
		--fl-paper: #17181c;       /* body text: near-ink, never grey */
		--fl-dim: #3d3e44;         /* secondary text: AA on light ground */
		--fl-gold: #8a6c12;
		--fl-gold-lift: #6f560a;
		--fl-line: rgba(23, 24, 28, 0.16);
	}
}

/* ==========================================================================
   2. Reset and base
   ========================================================================== */

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

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

body {
	margin: 0;
	background: var(--fl-ground);
	color: var(--fl-paper);
	font-family: var(--fl-body);
	font-size: clamp(1rem, 0.97rem + 0.18vw, 1.0625rem);
	line-height: 1.65;
	font-weight: 400;
	-webkit-font-smoothing: antialiased;
	overflow-x: hidden;
}

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

a {
	color: inherit;
	text-decoration-color: var(--fl-gold);
	text-underline-offset: 0.22em;
	text-decoration-thickness: 1px;
	transition: color 0.2s var(--fl-ease);
}

a:hover { color: var(--fl-gold-lift); }

:focus-visible {
	outline: 2px solid var(--fl-gold-lift);
	outline-offset: 3px;
}

h1, h2, h3, h4 {
	font-family: var(--fl-display);
	font-weight: 500;
	font-variation-settings: "SOFT" 12, "WONK" 1, "opsz" 40;
	line-height: 1.08;
	letter-spacing: -0.012em;
	margin: 0 0 0.5em;
	text-wrap: balance;
}

h1 { font-size: clamp(2.5rem, 1.6rem + 4.2vw, 5.25rem); }
h2 { font-size: clamp(1.9rem, 1.35rem + 2.4vw, 3.25rem); }
h3 { font-size: clamp(1.2rem, 1.05rem + 0.7vw, 1.6rem); line-height: 1.2; }

p { margin: 0 0 1.1em; max-width: var(--fl-measure); }

.fl-lede {
	font-size: clamp(1.1rem, 1rem + 0.55vw, 1.375rem);
	line-height: 1.5;
	color: var(--fl-paper);
}

.fl-muted { color: var(--fl-dim); }

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

.skip-link {
	position: absolute;
	left: 1rem; top: -4rem;
	z-index: 999;
	background: var(--fl-gold);
	color: #101114;
	padding: 0.75rem 1.25rem;
	font-weight: 600;
	transition: top 0.2s var(--fl-ease);
}

.skip-link:focus { top: 1rem; color: #101114; }

/* ==========================================================================
   3. Layout primitives
   ========================================================================== */

.fl-wrap {
	width: 100%;
	max-width: var(--fl-wide);
	margin-inline: auto;
	padding-inline: var(--fl-gutter);
}

.fl-section { padding-block: var(--fl-section); }

.fl-rule {
	border: 0;
	border-top: 1px solid var(--fl-line);
	margin: 0;
}

/* ==========================================================================
   4. Site header — transparent over the hero, solid once scrolled past it
   ========================================================================== */

/* The wordmark and tagline need 5.3rem; a custom logo at its 42px maximum
   plus the tagline needs 5.78rem. The reserve follows whichever is in use. */
body.fl-has-logo { --fl-header-h: 6.75rem; }

body.admin-bar { --fl-adminbar-h: 32px; }

@media screen and (max-width: 782px) {
	body.admin-bar { --fl-adminbar-h: 46px; }
}

.fl-header {
	position: fixed;
	top: var(--fl-adminbar-h);
	left: 0;
	right: 0;
	bottom: auto;
	z-index: 60;
	padding-block: 1rem;
	background: transparent;
	border-bottom: 1px solid transparent;
	transition: background 0.3s var(--fl-ease), border-color 0.3s var(--fl-ease);
}

.fl-header.is-solid {
	background: color-mix(in srgb, var(--fl-ground) 92%, transparent);
	backdrop-filter: saturate(140%) blur(10px);
	border-bottom-color: var(--fl-line);
}

/* Inner pages start below the header rather than under it. */
/*
 * Inner pages use a sticky header, which stays in the document flow and takes
 * up its own height. The body must NOT also reserve space for it — that was a
 * leftover from when the header was fixed here too, and it counted the header
 * twice, dropping every inner page about 180px down the screen.
 */
body:not(.home) { padding-top: 0; }

body:not(.home) .fl-header {
	position: sticky;
	top: var(--fl-adminbar-h);
	background: var(--fl-ground);
	border-bottom-color: var(--fl-line);
}

.fl-header__inner {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 1.5rem;
}

.fl-brand {
	display: inline-flex;
	align-items: baseline;
	gap: 0.55rem;
	font-family: var(--fl-display);
	font-size: 1.3rem;
	font-weight: 600;
	letter-spacing: -0.01em;
	text-decoration: none;
}

.fl-brand img { max-height: 42px; width: auto; }
.fl-brand__mark { color: var(--fl-gold); }

.fl-brandblock {
	display: flex;
	flex-direction: column;
	gap: 0.1rem;
	min-width: 0;
}

.fl-brand__tagline {
	display: block;
	font-size: 0.78rem;
	line-height: 1.35;
	letter-spacing: 0.035em;
	color: var(--fl-dim);
	max-width: 46ch;
}

/*
 * Over the hero the header sits on a photograph, so its text has to be light
 * regardless of the visitor's colour scheme — in light mode the inherited ink
 * would otherwise be near-invisible against a dark image.
 */
body.fl-has-hero .fl-header:not(.is-solid) {
	color: #f2efe9;
	text-shadow: 0 1px 14px rgba(0, 0, 0, 0.55);
}

body.fl-has-hero .fl-header:not(.is-solid) .fl-brand__tagline {
	color: rgba(242, 239, 233, 0.85);
}

.fl-nav ul {
	display: flex;
	align-items: center;
	gap: clamp(1rem, 2.2vw, 2.25rem);
	margin: 0; padding: 0;
	list-style: none;
}

.fl-nav a {
	text-decoration: none;
	font-size: 0.95rem;
	letter-spacing: 0.01em;
	padding-block: 0.35rem;
	border-bottom: 1px solid transparent;
}

.fl-nav .current-menu-item > a,
.fl-nav a:hover { border-bottom-color: var(--fl-gold); }

.fl-nav__toggle {
	display: none;
	background: none;
	border: 1px solid var(--fl-line);
	color: inherit;
	font: inherit;
	font-size: 0.9rem;
	padding: 0.5rem 0.9rem;
	cursor: pointer;
}

@media (max-width: 600px) {
	:root { --fl-header-h: 5.25rem; }

	/* The tagline wraps to three lines on a phone and pushes the header
	   out of proportion; the footer still carries it. */
	.fl-brand__tagline { display: none; }
}

@media (max-width: 860px) {
	.fl-nav__toggle { display: block; }

	.fl-nav {
		position: absolute;
		inset: 100% 0 auto 0;
		background: var(--fl-ground);
		border-bottom: 1px solid var(--fl-line);
		display: none;
	}

	.fl-nav.is-open { display: block; }

	.fl-nav ul {
		flex-direction: column;
		align-items: flex-start;
		gap: 0;
		padding: var(--fl-gutter);
	}

	.fl-nav li { width: 100%; }
	.fl-nav a { display: block; padding-block: 0.85rem; width: 100%; }
}

/* ==========================================================================
   5. Hero carousel — the front page's one bold element
   Structure: full-bleed frame, caption anchored bottom-left, contact-sheet
   frame counter and tick navigation across the bottom edge.
   ========================================================================== */

.fl-hero {
	position: relative;
	background: var(--fl-ground-2);
}

.fl-hero__viewport {
	display: flex;
	overflow-x: auto;
	overflow-y: hidden;
	scroll-snap-type: x mandatory;
	scrollbar-width: none;
	-ms-overflow-style: none;
	/* Height is locked before images load, so the carousel never shifts layout. */
	height: 100svh;
	min-height: 540px;
	max-height: 980px;
}

.fl-hero__viewport::-webkit-scrollbar { display: none; }

.fl-hero__slide {
	position: relative;
	flex: 0 0 100%;
	width: 100%;
	height: 100%;
	scroll-snap-align: center;
	scroll-snap-stop: always;
}

.fl-hero__slide img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	object-position: center;
}

/*
 * A frame taller than it is wide is shown whole rather than cropped to the
 * landscape shape of the carousel. The letterbox either side is the page
 * ground, so it reads as a deliberate mat rather than a mistake.
 */
.fl-hero__slide--portrait { background: var(--fl-ground); }

.fl-hero__slide--portrait img {
	object-fit: contain;
	object-position: center;
}

/* On wide screens the portrait frame sits right of centre, which keeps the
   headline on ground rather than on the photograph. */
@media (min-width: 1000px) {
	.fl-hero__slide--portrait img { object-position: 72% center; }
}

/* Legibility scrim. Kept to the lower third so the photograph stays the subject. */
.fl-hero__slide::after {
	content: "";
	position: absolute;
	inset: 0;
	background:
		/* Left column, where the headline and buttons live. */
		linear-gradient(to right, rgba(8, 9, 11, 0.72) 0%, rgba(8, 9, 11, 0.34) 46%, rgba(8, 9, 11, 0) 72%),
		/* Top band for the header, and the lower band for the control strip. */
		linear-gradient(to bottom, rgba(8, 9, 11, 0.58) 0%, rgba(8, 9, 11, 0) 26%, rgba(8, 9, 11, 0) 58%, rgba(8, 9, 11, 0.8) 100%);
	pointer-events: none;
}

.fl-hero__caption {
	position: absolute;
	left: var(--fl-gutter);
	/* Bounded top and bottom, not bottom alone. The block still sits low in
	   the frame, but it can never grow up past the header no matter how tall
	   the headline wraps or how short the viewport is. */
	top: calc(var(--fl-adminbar-h) + var(--fl-header-h) + var(--fl-hero-gap));
	bottom: clamp(6.5rem, 12vh, 9rem);
	z-index: 2;
	display: flex;
	flex-direction: column;
	/* Anchored to the top of its box, so the headline sits a fixed distance
	   below the site title at every viewport height instead of drifting up
	   and down with the bottom edge. */
	justify-content: flex-start;
	width: min(46ch, 78vw);
	max-width: min(46ch, 78vw);
	color: #f2efe9;
	text-shadow: 0 1px 24px rgba(0, 0, 0, 0.5);
}

/* Short viewports: laptops, landscape phones, split screens. The headline
   steps down rather than eating the space reserved for the header. */
@media (max-height: 760px) {
	.fl-hero__caption h1 { font-size: clamp(1.9rem, 1.2rem + 2.6vw, 3.1rem); }
	.fl-hero__caption p {
		font-size: 1rem;
		margin-bottom: 1.1rem;
	}
}

@media (max-height: 560px) {
	.fl-hero__caption p { display: none; }
}

.fl-hero__caption h1,
.fl-hero__caption p { color: #f2efe9; }

.fl-hero__caption p {
	font-size: clamp(1.05rem, 0.95rem + 0.5vw, 1.3rem);
	margin-bottom: 1.6rem;
}

.fl-hero__frame-caption {
	position: absolute;
	right: var(--fl-gutter);
	bottom: clamp(6.5rem, 12vh, 9rem);
	z-index: 2;
	max-width: 26ch;
	text-align: right;
	font-size: 0.85rem;
	line-height: 1.45;
	color: rgba(242, 239, 233, 0.82);
	text-shadow: 0 1px 20px rgba(0, 0, 0, 0.6);
}

@media (max-width: 720px) {
	.fl-hero__frame-caption { display: none; }
	.fl-hero__caption { bottom: clamp(5.5rem, 14vh, 8rem); }
}

/* Contact-sheet control strip */
.fl-hero__strip {
	position: absolute;
	inset: auto 0 0 0;
	z-index: 3;
	display: flex;
	align-items: center;
	gap: 1rem;
	padding: 0.9rem var(--fl-gutter) 1.4rem;
}

.fl-hero__counter {
	font-family: var(--fl-body);
	font-variant-numeric: tabular-nums;
	font-size: 0.8rem;
	letter-spacing: 0.06em;
	color: rgba(242, 239, 233, 0.9);
	min-width: 5.5ch;
}

.fl-hero__counter b { color: var(--fl-gold-lift); font-weight: 600; }

.fl-hero__ticks {
	display: flex;
	flex: 1 1 auto;
	gap: 6px;
	margin: 0; padding: 0;
	list-style: none;
}

.fl-hero__tick {
	flex: 1 1 0;
	background: none;
	border: 0;
	padding: 0;
	height: 22px;
	cursor: pointer;
	display: block;
}

.fl-hero__tick::before {
	content: "";
	display: block;
	height: 2px;
	margin-top: 10px;
	background: rgba(242, 239, 233, 0.32);
	transition: background 0.25s var(--fl-ease);
}

.fl-hero__tick:hover::before { background: rgba(242, 239, 233, 0.7); }

.fl-hero__tick[aria-current="true"]::before {
	background: var(--fl-gold);
	box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.25);
}

.fl-hero__btn {
	background: none;
	border: 1px solid rgba(242, 239, 233, 0.4);
	color: #f2efe9;
	width: 38px; height: 38px;
	display: grid;
	place-items: center;
	cursor: pointer;
	transition: border-color 0.2s var(--fl-ease), background 0.2s var(--fl-ease);
}

.fl-hero__btn:hover {
	border-color: var(--fl-gold);
	background: rgba(201, 162, 39, 0.16);
}

.fl-hero__btn svg { width: 14px; height: 14px; fill: currentColor; }

/* Empty state shown in the editor/admin preview when no slides are set yet. */
.fl-hero--empty {
	display: grid;
	place-items: center;
	text-align: center;
	min-height: 70svh;
	/* The header is fixed and overlays this section, so its height is added
	   to the top padding rather than left to chance. */
	padding: calc(var(--fl-adminbar-h) + var(--fl-header-h) + var(--fl-gutter)) var(--fl-gutter) var(--fl-gutter);
	border-bottom: 1px solid var(--fl-line);
}

.fl-hero--empty p { margin-inline: auto; }

/* ==========================================================================
   6. Buttons
   ========================================================================== */

.fl-btn {
	display: inline-block;
	font-family: var(--fl-body);
	font-size: 0.95rem;
	font-weight: 600;
	letter-spacing: 0.01em;
	padding: 0.85rem 1.6rem;
	border: 1px solid var(--fl-gold);
	background: var(--fl-gold);
	color: #101114;
	text-decoration: none;
	transition: background 0.2s var(--fl-ease), color 0.2s var(--fl-ease), border-color 0.2s var(--fl-ease);
}

.fl-btn:hover {
	background: var(--fl-gold-lift);
	border-color: var(--fl-gold-lift);
	color: #101114;
}

.fl-btn--ghost {
	background: transparent;
	color: #f2efe9;
	border-color: rgba(242, 239, 233, 0.55);
}

.fl-btn--ghost:hover {
	background: rgba(242, 239, 233, 0.12);
	color: #f2efe9;
	border-color: #f2efe9;
}

.fl-btn-row {
	display: flex;
	flex-wrap: wrap;
	gap: 0.75rem;
}

/* ==========================================================================
   7. Homepage sections
   ========================================================================== */

/* Statement */
.fl-statement .fl-wrap {
	display: grid;
	grid-template-columns: minmax(0, 1fr);
	gap: 1.5rem;
}

@media (min-width: 900px) {
	.fl-statement .fl-wrap {
		grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
		gap: clamp(2rem, 6vw, 6rem);
		align-items: start;
	}
}

/* Services: rows, not cards. The hairline rule carries the structure. */
.fl-services__list { border-top: 1px solid var(--fl-line); }

.fl-service {
	display: grid;
	grid-template-columns: minmax(0, 1fr);
	gap: 0.5rem 2rem;
	padding-block: clamp(1.75rem, 4vw, 2.75rem);
	border-bottom: 1px solid var(--fl-line);
}

@media (min-width: 860px) {
	.fl-service {
		grid-template-columns: minmax(0, 4fr) minmax(0, 6fr) minmax(0, 2fr);
		align-items: baseline;
	}
}

.fl-service h3 { margin: 0; }
.fl-service p { margin: 0; color: var(--fl-dim); }

.fl-service__meta {
	font-size: 0.85rem;
	color: var(--fl-gold);
	letter-spacing: 0.02em;
}

@media (min-width: 860px) {
	.fl-service__meta { text-align: right; }
}

/* Process: a genuine sequence, so the frames are numbered. */
.fl-steps {
	display: grid;
	gap: clamp(1.5rem, 4vw, 3rem);
	grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
	margin-top: 2.5rem;
}

.fl-step { border-top: 2px solid var(--fl-gold); padding-top: 1rem; }

.fl-step__n {
	font-family: var(--fl-body);
	font-variant-numeric: tabular-nums;
	font-size: 0.8rem;
	color: var(--fl-gold);
	letter-spacing: 0.08em;
	display: block;
	margin-bottom: 0.4rem;
}

.fl-step h3 { margin-bottom: 0.35rem; }
.fl-step p { color: var(--fl-dim); margin: 0; }

/* Call to action band */
.fl-cta {
	background: var(--fl-ground-2);
	border-top: 1px solid var(--fl-line);
	border-bottom: 1px solid var(--fl-line);
}

.fl-cta .fl-wrap {
	display: grid;
	gap: 1.75rem;
	align-items: center;
}

@media (min-width: 900px) {
	.fl-cta .fl-wrap {
		grid-template-columns: minmax(0, 1fr) auto;
		gap: 3rem;
	}
}

.fl-cta h2 { margin-bottom: 0.35rem; }
.fl-cta p { margin: 0; color: var(--fl-dim); }

/* ==========================================================================
   8. Generic page / post content
   ========================================================================== */

.fl-page-head { padding-block: clamp(2.5rem, 6vw, 5rem) 1.5rem; }
.fl-entry { padding-bottom: var(--fl-section); }
.fl-entry > * { max-width: var(--fl-measure); }
.fl-entry > .alignwide { max-width: 1100px; }
.fl-entry > .alignfull { max-width: none; }

/*
 * The measure above exists to keep prose readable, and it should not govern
 * layout. Columns and the patterns built from them are structure, not text:
 * held to 68ch, a two-column contact block gives its left column barely
 * 150px, which is what made the details look crushed. These take the full
 * width of the page wrapper instead.
 */
.fl-entry > .wp-block-columns,
.fl-entry > .fl-contact,
.fl-entry > .fl-packages,
.fl-entry > .fl-steps-pattern,
.fl-entry > .fl-beforeafter,
.fl-entry > .fl-bio,
.fl-entry > .fl-cta-pattern,
.fl-entry > .wp-block-group.is-style-fl-panel,
.fl-entry > .wp-block-gallery {
	max-width: none;
	width: 100%;
}
.fl-entry img { margin-block: 2rem; }

.fl-entry blockquote {
	border-left: 2px solid var(--fl-gold);
	margin-inline: 0;
	padding-left: 1.25rem;
	font-family: var(--fl-display);
	font-size: 1.2rem;
}

/* ==========================================================================
   8b. Inner page hero and portfolio
   ========================================================================== */

.fl-page-hero {
	padding-block: clamp(2.5rem, 6vw, 4.5rem) clamp(1.5rem, 3vw, 2.5rem);
	border-bottom: 1px solid var(--fl-line);
}

.fl-page-hero h1 { margin-bottom: 0.4em; }
.fl-page-hero .fl-lede { color: var(--fl-dim); margin: 0; }

/* With a featured image the hero becomes a band; the scrim keeps the title
   readable over any photograph, light or dark. */
.fl-page-hero--image {
	position: relative;
	background-size: cover;
	background-position: center;
	border-bottom: 0;
	padding-block: clamp(5rem, 14vw, 9rem) clamp(3rem, 7vw, 5rem);
}

.fl-page-hero--image::before {
	content: "";
	position: absolute;
	inset: 0;
	background: linear-gradient(to right, rgba(8, 9, 11, 0.8) 0%, rgba(8, 9, 11, 0.45) 55%, rgba(8, 9, 11, 0.2) 100%);
}

.fl-page-hero--image .fl-wrap { position: relative; }
.fl-page-hero--image h1 { color: #f2efe9; }
.fl-page-hero--image .fl-lede { color: rgba(242, 239, 233, 0.88); }

/* Portfolio shell. Headings and copy are held to a readable measure; the
   gallery output the plugin produces is left at full width and left alone. */
.fl-portfolio { padding-block: var(--fl-section); }

.fl-portfolio > h2,
.fl-portfolio > h3,
.fl-portfolio > p { max-width: var(--fl-measure); }

.fl-portfolio__heading {
	margin-top: clamp(2.5rem, 6vw, 4.5rem);
	padding-top: clamp(1.5rem, 3vw, 2.25rem);
	border-top: 1px solid var(--fl-line);
}

.fl-portfolio > .fl-portfolio__heading:first-child {
	margin-top: 0;
	padding-top: 0;
	border-top: 0;
}

.fl-portfolio__lede {
	color: var(--fl-dim);
	margin-bottom: 1.75rem;
}

/* Breathing room around whatever the gallery plugin renders, without
   touching its internals. The attribute selector catches third-party gallery
   wrappers generically rather than naming one vendor. */
.fl-portfolio .gallery,
.fl-portfolio [class*="gallery"],
.fl-portfolio .wp-block-gallery {
	margin-block: 1.5rem clamp(2rem, 5vw, 3.5rem);
}

.fl-notice {
	border: 1px solid var(--fl-line);
	padding: clamp(1.5rem, 4vw, 2.5rem);
	background: var(--fl-ground-2);
}

.fl-notice h2 { font-size: 1.4rem; }
.fl-notice p { color: var(--fl-dim); }

/* ==========================================================================
   8c. Blog: cards, post, pagination, comments
   ========================================================================== */

.fl-cards {
	display: grid;
	gap: clamp(2rem, 4vw, 3.25rem);
	grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
}

.fl-card { display: flex; flex-direction: column; }

.fl-card__media {
	display: block;
	aspect-ratio: 3 / 2;
	overflow: hidden;
	background: var(--fl-ground-2);
	margin-bottom: 1.1rem;
}

.fl-card__img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	transition: transform 0.5s var(--fl-ease);
}

.fl-card:hover .fl-card__img { transform: scale(1.03); }

/* Stands in for a missing featured image without pretending to be one. */
.fl-card__placeholder {
	display: grid;
	place-items: center;
	width: 100%;
	height: 100%;
	font-family: var(--fl-display);
	font-size: 3rem;
	color: var(--fl-gold);
	opacity: 0.55;
}

.fl-card__meta {
	font-size: 0.8rem;
	letter-spacing: 0.03em;
	color: var(--fl-dim);
	margin: 0 0 0.4rem;
}

.fl-card__meta a { color: var(--fl-gold); text-decoration: none; }
.fl-card__meta a:hover { text-decoration: underline; }
.fl-card__sep { margin-inline: 0.45rem; }

.fl-card__title {
	font-size: clamp(1.2rem, 1.05rem + 0.5vw, 1.5rem);
	margin: 0 0 0.5rem;
}

.fl-card__title a { text-decoration: none; }
.fl-card__title a:hover { color: var(--fl-gold-lift); }

.fl-card__excerpt {
	color: var(--fl-dim);
	margin: 0;
	font-size: 0.95rem;
}

/* Single post */
.fl-postmeta {
	font-size: 0.85rem;
	letter-spacing: 0.03em;
	color: var(--fl-dim);
	margin-bottom: 0.6rem;
}

.fl-postmeta a { color: var(--fl-gold); text-decoration: none; }

.fl-post__feature { margin: 0 0 clamp(2rem, 5vw, 3.5rem); }

.fl-post__featureimg {
	width: 100%;
	max-height: 70svh;
	object-fit: cover;
}

.fl-post__feature figcaption {
	max-width: var(--fl-wide);
	margin: 0.6rem auto 0;
	padding-inline: var(--fl-gutter);
	font-size: 0.82rem;
	color: var(--fl-dim);
}

.fl-post__tags {
	margin-top: 2.5rem;
	font-size: 0.85rem;
}

.fl-post__tags a {
	display: inline-block;
	border: 1px solid var(--fl-line);
	padding: 0.25rem 0.7rem;
	margin: 0 0.3rem 0.4rem 0;
	text-decoration: none;
	color: var(--fl-dim);
}

.fl-post__tags a:hover { border-color: var(--fl-gold); color: var(--fl-gold-lift); }

/* Previous / next */
.fl-postnav {
	display: grid;
	gap: 1rem;
	margin-block: clamp(2.5rem, 6vw, 4rem);
	padding-top: 1.75rem;
	border-top: 1px solid var(--fl-line);
}

@media (min-width: 720px) {
	.fl-postnav { grid-template-columns: 1fr 1fr; }
	.fl-postnav__link--next { text-align: right; }
}

.fl-postnav__link { text-decoration: none; display: block; }

.fl-postnav__label {
	display: block;
	font-size: 0.75rem;
	letter-spacing: 0.08em;
	color: var(--fl-gold);
	margin-bottom: 0.25rem;
}

.fl-postnav__title {
	font-family: var(--fl-display);
	font-size: 1.1rem;
	line-height: 1.25;
}

/* Pagination */
.navigation.pagination {
	margin-top: clamp(2.5rem, 6vw, 4rem);
	padding-top: 1.75rem;
	border-top: 1px solid var(--fl-line);
}

.nav-links {
	display: flex;
	flex-wrap: wrap;
	gap: 0.4rem;
	align-items: center;
}

.nav-links .page-numbers {
	display: inline-block;
	min-width: 2.4rem;
	text-align: center;
	padding: 0.5rem 0.75rem;
	border: 1px solid var(--fl-line);
	text-decoration: none;
	font-size: 0.9rem;
	font-variant-numeric: tabular-nums;
}

.nav-links .page-numbers:hover { border-color: var(--fl-gold); }

.nav-links .page-numbers.current {
	background: var(--fl-gold);
	border-color: var(--fl-gold);
	color: #101114;
	font-weight: 600;
}

.nav-links .dots { border-color: transparent; }

/* Comments */
.fl-comments {
	margin-top: clamp(2.5rem, 6vw, 4rem);
	padding-top: 1.75rem;
	border-top: 1px solid var(--fl-line);
	max-width: var(--fl-measure);
}

.fl-comments__title { font-size: 1.4rem; margin-bottom: 1.25rem; }

.fl-comments__list,
.fl-comments__list .children {
	list-style: none;
	margin: 0;
	padding: 0;
}

.fl-comments__list .children { margin-left: 1.5rem; padding-left: 1rem; border-left: 1px solid var(--fl-line); }

.fl-comments__list li { margin-bottom: 1.75rem; }

.fl-comments .comment-meta {
	font-size: 0.82rem;
	color: var(--fl-dim);
	margin-bottom: 0.5rem;
}

.fl-comments .comment-author img {
	border-radius: 50%;
	display: inline-block;
	vertical-align: middle;
	margin-right: 0.5rem;
}

.fl-comments .comment-author .fn { font-style: normal; font-weight: 600; }

.fl-comments .comment-content p { font-size: 0.95rem; }

.fl-comments .reply { font-size: 0.82rem; }

.comment-form label {
	display: block;
	font-size: 0.85rem;
	font-weight: 600;
	margin-bottom: 0.3rem;
}

.comment-form input[type="text"],
.comment-form input[type="email"],
.comment-form input[type="url"],
.comment-form textarea {
	width: 100%;
	max-width: 100%;
	padding: 0.7rem 0.85rem;
	background: var(--fl-ground-2);
	border: 1px solid var(--fl-line);
	color: var(--fl-paper);
	font: inherit;
	font-size: 0.95rem;
	margin-bottom: 1rem;
}

.comment-form textarea { min-height: 9rem; resize: vertical; }

.comment-form input:focus,
.comment-form textarea:focus { border-color: var(--fl-gold); outline: none; }

.comment-form .comment-notes,
.comment-form .form-submit { margin-bottom: 1rem; }

.comment-form .comment-notes { font-size: 0.85rem; color: var(--fl-dim); }

/* Search form */
.fl-search {
	display: flex;
	flex-wrap: wrap;
	gap: 0.5rem;
	margin-block: 1.5rem;
}

.fl-search input[type="search"] {
	flex: 1 1 14rem;
	padding: 0.8rem 1rem;
	background: var(--fl-ground-2);
	border: 1px solid var(--fl-line);
	color: var(--fl-paper);
	font: inherit;
}

.fl-search input[type="search"]:focus { border-color: var(--fl-gold); outline: none; }

/* ==========================================================================
   8d. Block styles and pattern support
   ========================================================================== */

/* Separator: gold hairline */
.wp-block-separator.is-style-fl-gold {
	border: 0;
	border-top: 1px solid var(--fl-gold);
	opacity: 1;
	max-width: 100%;
}

/* Image: framed */
.wp-block-image.is-style-fl-framed img {
	border: 1px solid var(--fl-line);
	padding: 0.5rem;
	background: var(--fl-ground-2);
}

/* Image: full bleed */
.wp-block-image.is-style-fl-bleed img { width: 100%; }
.wp-block-image.is-style-fl-bleed figcaption {
	max-width: var(--fl-wide);
	margin-inline: auto;
	padding-inline: var(--fl-gutter);
	color: var(--fl-dim);
	font-size: 0.85rem;
}

/* Button: ghost */
.wp-block-button.is-style-fl-ghost .wp-block-button__link {
	background: transparent;
	border: 1px solid var(--fl-paper);
	color: var(--fl-paper);
	border-radius: 0;
}

.wp-block-button.is-style-fl-ghost .wp-block-button__link:hover {
	border-color: var(--fl-gold);
	color: var(--fl-gold-lift);
}

/* Quote: display serif */
.wp-block-quote.is-style-fl-display {
	border-left: 2px solid var(--fl-gold);
	padding-left: 1.5rem;
}

.wp-block-quote.is-style-fl-display p {
	font-family: var(--fl-display);
	font-size: clamp(1.2rem, 1rem + 0.9vw, 1.7rem);
	line-height: 1.3;
}

.wp-block-quote.is-style-fl-display cite {
	font-family: var(--fl-body);
	font-size: 0.85rem;
	font-style: normal;
	color: var(--fl-dim);
}

/* Group: raised panel */
.wp-block-group.is-style-fl-panel {
	background: var(--fl-ground-2);
	border: 1px solid var(--fl-line);
	padding: clamp(1.5rem, 4vw, 2.5rem);
}

/* Pattern support */
.fl-packages { gap: clamp(1.5rem, 3vw, 2.5rem); }

.fl-package {
	border-top: 2px solid var(--fl-gold);
	padding-top: 1.25rem;
}

.fl-package h3 { margin-bottom: 0.2rem; }

.fl-package__price {
	font-family: var(--fl-display);
	font-size: 2rem;
	line-height: 1;
	margin: 0 0 0.25rem;
}

.fl-package__note {
	color: var(--fl-dim);
	font-size: 0.85rem;
	margin-bottom: 1rem;
}

.fl-package ul { padding-left: 1.1rem; }
.fl-package li { margin-bottom: 0.4rem; font-size: 0.95rem; }

.fl-faq {
	border-bottom: 1px solid var(--fl-line);
	padding-block: 1rem;
}

.fl-faq summary {
	cursor: pointer;
	font-family: var(--fl-display);
	font-size: 1.15rem;
}

.fl-faq summary::marker { color: var(--fl-gold); }
.fl-faq p { margin-top: 0.75rem; color: var(--fl-dim); }

.fl-cta-pattern {
	background: var(--fl-ground-2);
	border-block: 1px solid var(--fl-line);
	padding: clamp(2.5rem, 6vw, 4rem) var(--fl-gutter);
	text-align: left;
}

.fl-steps-pattern .fl-step { border-top: 2px solid var(--fl-gold); padding-top: 1rem; }

.fl-beforeafter figcaption,
.fl-bio figcaption { color: var(--fl-dim); font-size: 0.85rem; }

/* Business details block */
.fl-details {
	display: grid;
	grid-template-columns: auto 1fr;
	gap: 0.4rem 1.25rem;
	margin: 0;
	font-size: 0.95rem;
}

.fl-details dt {
	color: var(--fl-gold);
	font-size: 0.78rem;
	letter-spacing: 0.06em;
	padding-top: 0.15rem;
}

.fl-details dd { margin: 0; }
.fl-details a { text-decoration: none; }
.fl-details a:hover { text-decoration: underline; }

/* The two contact columns need real separation: details and a form read as
   one crowded block when they sit close together. */
.fl-contact {
	gap: clamp(2.5rem, 7vw, 6rem);
	row-gap: clamp(2.5rem, 5vw, 3.5rem);
}

@media (min-width: 900px) {
	.fl-contact > .wp-block-column:first-child {
		position: relative;
		/* Keeps the details column readable if the container is narrow or the
		   inline width from an older insert is small. */
		min-width: 17rem;
	}

	/*
	 * The divider is drawn in the middle of the gap by a pseudo-element, not as
	 * a border with padding on the column itself. With box-sizing: border-box,
	 * padding comes out of the column's declared width, so a padded divider
	 * squeezes the contact details instead of giving them room. This costs the
	 * column no width at all.
	 */
	.fl-contact > .wp-block-column:first-child::after {
		content: "";
		position: absolute;
		top: 0;
		bottom: 0;
		right: calc(-1 * clamp(1.25rem, 3.5vw, 3rem));
		border-right: 1px solid var(--fl-line);
		pointer-events: none;
	}
}

/* Breadcrumbs */
.fl-crumbs { margin-bottom: 0.9rem; }

.fl-crumbs ol {
	display: flex;
	flex-wrap: wrap;
	gap: 0.35rem;
	list-style: none;
	margin: 0;
	padding: 0;
	font-size: 0.8rem;
	letter-spacing: 0.02em;
	color: var(--fl-dim);
}

.fl-crumbs li + li::before {
	content: "/";
	margin-right: 0.35rem;
	color: var(--fl-line);
}

.fl-crumbs a { color: var(--fl-dim); text-decoration: none; }
.fl-crumbs a:hover { color: var(--fl-gold-lift); }
.fl-crumbs [aria-current="page"] { color: var(--fl-paper); }

.fl-page-hero--image .fl-crumbs,
.fl-page-hero--image .fl-crumbs a { color: rgba(242, 239, 233, 0.8); }

/* Client portal link in the header */
.fl-portal {
	display: none;
	font-size: 0.85rem;
	letter-spacing: 0.02em;
	text-decoration: none;
	border: 1px solid var(--fl-line);
	padding: 0.45rem 0.9rem;
	white-space: nowrap;
}

.fl-portal:hover { border-color: var(--fl-gold); color: var(--fl-gold-lift); }

@media (min-width: 861px) {
	.fl-portal { display: inline-block; }
}

/* Related posts */
.fl-related {
	margin-top: clamp(3rem, 7vw, 5rem);
	padding-top: 2rem;
	border-top: 1px solid var(--fl-line);
}

.fl-related__title {
	font-size: clamp(1.3rem, 1.1rem + 0.7vw, 1.7rem);
	margin-bottom: 1.75rem;
}

.fl-related .fl-cards { grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); }
.fl-related .fl-card__title { font-size: 1.1rem; }

/* Alternating section grounds.
   A page of identical dark sections separated by hairlines reads as flat; the
   alternation gives it rhythm without introducing another colour. */
.fl-section--alt,
.wp-block-group.is-style-fl-band {
	background: var(--fl-ground-2);
	border-block: 1px solid var(--fl-line);
	padding-block: var(--fl-section);
}

.fl-entry > .wp-block-group.is-style-fl-band,
.fl-entry > .fl-section--alt {
	max-width: none;
	width: 100%;
}

/* Recent posts block */
.fl-recent { margin-block: clamp(2.5rem, 6vw, 4rem); }

.fl-recent__title {
	font-size: clamp(1.4rem, 1.15rem + 0.9vw, 2rem);
	margin-bottom: 1.75rem;
}

/* Before and after slider */
.fl-ba {
	--fl-ba-split: 50%;
	margin: clamp(1.5rem, 4vw, 2.5rem) 0;
}

.fl-ba__frame {
	position: relative;
	overflow: hidden;
	touch-action: none;
	cursor: ew-resize;
	background: var(--fl-ground-2);
	line-height: 0;
}

.fl-ba__layer { position: relative; }

.fl-ba__layer--before {
	position: absolute;
	inset: 0;
	/* The clip is the whole mechanism: the before image is simply cut off at
	   the split point, so both images stay real, selectable <img> elements. */
	clip-path: inset(0 calc(100% - var(--fl-ba-split)) 0 0);
}

.fl-ba__img {
	display: block;
	width: 100%;
	height: auto;
}

.fl-ba__layer--before .fl-ba__img {
	position: absolute;
	inset: 0;
	height: 100%;
	object-fit: cover;
}

.fl-ba__tag {
	position: absolute;
	bottom: 0.75rem;
	font-family: var(--fl-body);
	font-size: 0.72rem;
	letter-spacing: 0.08em;
	line-height: 1;
	padding: 0.4rem 0.7rem;
	background: rgba(8, 9, 11, 0.72);
	color: #f2efe9;
}

.fl-ba__tag--before { left: 0.75rem; }
.fl-ba__tag--after { right: 0.75rem; }

.fl-ba__handle {
	position: absolute;
	top: 0;
	bottom: 0;
	left: var(--fl-ba-split);
	width: 2px;
	margin-left: -1px;
	background: var(--fl-gold);
	pointer-events: none;
}

.fl-ba__handle::after {
	content: "";
	position: absolute;
	top: 50%;
	left: 50%;
	width: 2.4rem;
	height: 2.4rem;
	transform: translate(-50%, -50%);
	border: 2px solid var(--fl-gold);
	border-radius: 50%;
	background: rgba(8, 9, 11, 0.55);
}

/* The range input is the accessible control, kept visible beneath the frame. */
.fl-ba__range {
	display: block;
	width: 100%;
	margin-top: 0.75rem;
	accent-color: var(--fl-gold);
}

/* ==========================================================================
   8e. Legacy class aliases
   Content saved before the class prefix changed still carries lk-* names.
   Rewriting every page's markup to fix that would be a destructive migration
   for a purely cosmetic gain, so the old names are aliased instead. New
   content only ever uses the current prefix. Safe to delete once no site in
   the wild has pre-rename content.
   ========================================================================== */

.lk-wrap { width: 100%; max-width: var(--fl-wide); margin-inline: auto; padding-inline: var(--fl-gutter); }
.lk-section { padding-block: var(--fl-section); }
.lk-lede { font-size: clamp(1.1rem, 1rem + 0.55vw, 1.375rem); line-height: 1.5; }
.lk-muted { color: var(--fl-dim); }
.lk-btn { display: inline-block; font-family: var(--fl-body); font-size: 0.95rem; font-weight: 600; padding: 0.85rem 1.6rem; border: 1px solid var(--fl-gold); background: var(--fl-gold); color: #101114; text-decoration: none; }
.lk-btn--ghost { background: transparent; color: #f2efe9; border-color: rgba(242, 239, 233, 0.55); }
.lk-service { display: grid; gap: 0.5rem 2rem; padding-block: clamp(1.75rem, 4vw, 2.75rem); border-bottom: 1px solid var(--fl-line); }
.lk-service__meta { font-size: 0.85rem; color: var(--fl-gold); }
.lk-step { border-top: 2px solid var(--fl-gold); padding-top: 1rem; }
.lk-step__n { font-variant-numeric: tabular-nums; font-size: 0.8rem; color: var(--fl-gold); letter-spacing: 0.08em; }
.lk-package { border-top: 2px solid var(--fl-gold); padding-top: 1.25rem; }
.lk-package__price { font-family: var(--fl-display); font-size: 2rem; line-height: 1; margin: 0 0 0.25rem; }
.lk-package__note { color: var(--fl-dim); font-size: 0.85rem; margin-bottom: 1rem; }
.lk-faq { border-bottom: 1px solid var(--fl-line); padding-block: 1rem; }
.lk-cta-pattern { background: var(--fl-ground-2); border-block: 1px solid var(--fl-line); padding: clamp(2.5rem, 6vw, 4rem) var(--fl-gutter); }
.lk-portfolio__heading { margin-top: clamp(2.5rem, 6vw, 4.5rem); padding-top: clamp(1.5rem, 3vw, 2.25rem); border-top: 1px solid var(--fl-line); }
.lk-portfolio__lede { color: var(--fl-dim); margin-bottom: 1.75rem; }
.lk-contact { gap: clamp(2.5rem, 7vw, 6rem); }
.lk-bio figcaption,
.lk-beforeafter figcaption { color: var(--fl-dim); font-size: 0.85rem; }

.lk-entry > .lk-contact,
.lk-entry > .lk-packages,
.lk-entry > .lk-steps-pattern,
.lk-entry > .lk-beforeafter,
.lk-entry > .lk-bio,
.lk-entry > .lk-cta-pattern { max-width: none; width: 100%; }

/* ==========================================================================
   9. Footer
   ========================================================================== */

.fl-footer {
	background: var(--fl-ground-2);
	border-top: 1px solid var(--fl-line);
	padding-block: clamp(3rem, 7vw, 5rem) 2rem;
	font-size: 0.95rem;
}

.fl-footer__grid {
	display: grid;
	gap: 2.5rem;
	grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
	padding-bottom: 2.5rem;
}

.fl-footer h4 {
	font-family: var(--fl-body);
	font-size: 0.82rem;
	font-weight: 600;
	letter-spacing: 0.08em;
	color: var(--fl-gold);
	margin-bottom: 0.9rem;
}

.fl-footer ul { list-style: none; margin: 0; padding: 0; }
.fl-footer li { margin-bottom: 0.5rem; }
.fl-footer a { text-decoration: none; }
.fl-footer a:hover { text-decoration: underline; }

.fl-footer__base {
	border-top: 1px solid var(--fl-line);
	padding-top: 1.5rem;
	display: flex;
	flex-wrap: wrap;
	gap: 1rem;
	justify-content: space-between;
	color: var(--fl-dim);
	font-size: 0.85rem;
}

.fl-social {
	display: flex;
	gap: 0.9rem;
	list-style: none;
	margin: 0; padding: 0;
}

.fl-social a {
	display: grid;
	place-items: center;
	width: 38px; height: 38px;
	border: 1px solid var(--fl-line);
}

.fl-social a:hover { border-color: var(--fl-gold); }
.fl-social svg { width: 17px; height: 17px; fill: currentColor; }

/* ==========================================================================
   10. Reduced motion
   ========================================================================== */

@media (prefers-reduced-motion: reduce) {
	html { scroll-behavior: auto; }

	*,
	*::before,
	*::after {
		animation-duration: 0.001ms !important;
		transition-duration: 0.001ms !important;
	}
}
