/*
Theme Name: Francismixe
Description: Site vitrine de Francismixe — DJ & événementiel
Author: Francis Mixe
Version: 0.7.0
Requires at least: 6.6
Requires PHP: 8.3
Text Domain: francismixe
License: GPL-2.0-or-later
*/

/* =========================================================
   BEIGE ÉDITORIAL — one ground, full-bleed photographs.
   Beige ground, marron type, accents on the h3 and the rules.
   No border-radius, no shadow, no gradient, no filter.
   Sections:
     1. Tokens
     2. Reset & document
     3. Site frame, rail offset, band width chain
     4. Surfaces & bands
     5. Typography
     6. Links, buttons
     7. Photos & captions
     8. fm-* components
     9. Navigation rail / mobile topbar
    10. Footer
    11. Contact form
    12. Focus
    13. Reduced motion
   ========================================================= */

/* =========================================================
   1. Tokens
   ========================================================= */

:root {
	/* Geometry */
	--fm-rail: 96px;
	--fm-site-max: 1696px; /* 1600 (native photo width) + rail */
	--fm-gutter: clamp(1.75rem, 3.5vw, 3rem);
	/* Vertical rhythm. The gap between two neighbouring blocks is elsewhere:
	   theme.json, styles.spacing.blockGap. */
	--fm-band-pad: clamp(2.5rem, 4.6vw, 4.25rem);
	--fm-band-pad-hero: clamp(3.5rem, 6.4vw, 5.75rem);
	--fm-flow: clamp(0.875rem, 1.3vw, 1.25rem);
	--fm-flow-lg: clamp(1.5rem, 2.4vw, 2.25rem);
	--fm-col-gap: clamp(1.5rem, 2.6vw, 2.5rem);
	--fm-row-gap: clamp(1.75rem, 3.2vw, 2.75rem);

	/* Hairlines, one per surface */
	--fm-hairline: #ae8c6c; /* on base, 2.67 */
	--fm-hairline-marron: #927062; /* on marron */

	/* Secondary inks, all AA */
	--fm-ink-2-base: #67584c; /* 5.88 on base */
	--fm-ink-2-marron: #dac9ac; /* 5.06 on marron */

	/* Form field background: base darkened, bounded by its marron border */
	--fm-field-bg: #e6d9b4; /* marron type on it: 5.85 */

	/* Brand hues are 1.75–3.03 on base, so type and rules use them darkened
	   past 4.5 with margin. The pure hues stay in theme.json for fills. */
	--fm-ink-bleu: #44689f; /* 4.85 */
	--fm-ink-rouge: #c32e1e; /* 4.85 */
	--fm-ink-vert: #3d734b; /* 4.82 */
	--fm-ink-jaune: #8c5e0e; /* 4.86 */

	/* Accent: page-level, then per-surface ink. Overridden by fm-accent-* */
	--fm-page-accent: var(--fm-ink-jaune);
	--fm-accent: var(--fm-page-accent);
	--fm-accent-hover: color-mix(in srgb, var(--fm-accent) 85%, #000000);

	/* Current-surface derived inks */
	--fm-ink-2: var(--fm-ink-2-base);
	--fm-line: var(--fm-hairline);

	--fm-ease: cubic-bezier(0.22, 1, 0.36, 1);
}

/* Page accent, set by the markup on <main> and on the footer template part */
.fm-accent-jaune { --fm-page-accent: var(--fm-ink-jaune); }
.fm-accent-rouge { --fm-page-accent: var(--fm-ink-rouge); }
.fm-accent-bleu { --fm-page-accent: var(--fm-ink-bleu); }
.fm-accent-vert { --fm-page-accent: var(--fm-ink-vert); }

/* =========================================================
   2. Reset & document
   ========================================================= */

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

body {
	margin: 0;
	-webkit-font-smoothing: antialiased;
	text-rendering: optimizeLegibility;
}

img,
svg {
	display: block;
	max-inline-size: 100%;
	block-size: auto;
}

/* =========================================================
   3. Site frame, rail offset, band width chain

   Full-bleed is obtained WITHOUT 100vw and WITHOUT negative
   margins: a band is a plain block-level `.alignfull` child, so
   `width: auto` fills the padded content box of .wp-site-blocks.
   The rail lives in that padding, so no band can slide under it
   and no horizontal scrollbar can appear.
   ========================================================= */

.wp-site-blocks {
	max-inline-size: none;
}

/* blockGap must not open nuit gaps between header / main / footer */
.wp-site-blocks > * {
	margin-block: 0;
}

/* WP caps .entry-content at contentSize; bands need the whole content box */
main > .entry-content,
.wp-block-post-content {
	max-inline-size: none;
}

/* Blocks that sit directly in the flow (outside any .fm-band) still need
   the site gutter — a paragraph with no wrapper would otherwise touch
   the viewport edge, since .entry-content itself carries no padding. */
.entry-content > :not(.fm-band, .alignfull, .alignwide) {
	padding-inline: var(--fm-gutter);
}

@media (min-width: 782px) {
	.wp-site-blocks {
		max-inline-size: var(--fm-site-max);
		margin-inline: auto;
		padding-inline-start: var(--fm-rail);
	}
}

/* =========================================================
   4. Surfaces & bands
   ========================================================= */

.fm-band {
	margin: 0;
	border-radius: 0;
	padding-block: var(--fm-band-pad);
	padding-inline: var(--fm-gutter);
}

.fm-band--hero {
	padding-block: var(--fm-band-pad-hero);
}

/* One ground for the whole site (client's call: no coloured blocks), so the
   photographs and the hairlines are what divide a page. The four class names
   are kept — they are stored in the page content — and now differ by layout
   only. Turning a band back into a dark one is one background-color away. */
.fm-band--nuit,
.fm-band--marron,
.fm-band--creme,
.fm-band--accent {
	background-color: var(--wp--preset--color--base);
	color: var(--wp--preset--color--contrast);
	--fm-accent: var(--fm-page-accent);
	--fm-ink-2: var(--fm-ink-2-base);
	--fm-line: var(--fm-hairline);
}

/* Was the breathing band: keeps its tighter block padding */
.fm-band--creme {
	padding-block: clamp(3rem, 5vw, 4.5rem);
}

/* Left-ranged flow: cancel the residual constrained/wide caps */
.fm-band > :is(.wp-block-group, .wp-block-columns, .wp-block-buttons, .wp-block-list, .entry-content, figure),
.fm-band :is(.alignwide, .alignfull) {
	max-inline-size: none;
	margin-inline: 0;
}

.fm-band :is(h1, h2) + * {
	margin-block-start: var(--fm-flow-lg);
}

.fm-band .wp-block-columns {
	gap: var(--fm-row-gap) var(--fm-col-gap);
	align-items: start;
	margin-block: 0;
}

/* A grid that follows a titled intro breathes, so its cell hairlines never
   line up with the accent rule of the h2 above */
.fm-band > * + .wp-block-columns {
	margin-block-start: var(--fm-flow-lg);
}

/* Marron editorial spread: the media column runs out to the band edge.
   Direct-child figures only — card cells keep their own padding. */
@media (min-width: 782px) {
	.fm-band--marron .wp-block-columns > .wp-block-column:last-child > .wp-block-image {
		margin-inline-end: calc(-1 * var(--fm-gutter));
	}
}

.fm-band .wp-block-buttons {
	gap: var(--fm-flow);
}

.fm-band :is(ul, ol) {
	padding-inline-start: 1.1em;
}

/* Corporate: the 3-item list of the marron band reads as an editorial list */
.fm-band--marron .wp-block-column > .wp-block-list {
	list-style: none;
	padding-inline-start: 0;
	margin-block: 0;
}

.fm-band--marron .wp-block-column > .wp-block-list > li {
	border-block-start: 1px solid var(--fm-line);
	padding-block: 0.75rem;
	max-inline-size: none;
}

/* =========================================================
   5. Typography

   The scale lives in theme.json (preset font-size classes are
   !important). Here: measures, weights, no-hyphenation.
   ========================================================= */

:is(h1, h2, h3, h4),
.fm-index {
	hyphens: none;
	-webkit-hyphens: none;
	overflow-wrap: normal;
	word-break: normal;
	text-wrap: balance;
	margin-block: 0;
}

p,
li {
	text-wrap: pretty;
}

/* Reading measures — in ch, so widening a band never lengthens a line */
h1 { max-inline-size: 18ch; }
h2 { max-inline-size: 22ch; }
h3 { max-inline-size: 34ch; }

p,
li,
ul,
ol,
dl {
	max-inline-size: 68ch;
}

p.has-large-font-size {
	max-inline-size: 44ch;
}

p.has-small-font-size,
figcaption {
	max-inline-size: 52ch;
}

/* H1 and H2 inherit the marron type; H3 carries the page accent */
h3 {
	color: var(--fm-accent);
}

strong {
	font-weight: 800;
	font-style: normal;
}

/* Secondary text on each surface */
.fm-band p.has-small-font-size:not(.fm-eyebrow),
.fm-band figcaption {
	color: var(--fm-ink-2);
}

/* =========================================================
   6. Links, buttons
   ========================================================= */

a {
	color: inherit;
	text-decoration: underline;
	text-decoration-thickness: 1px;
	text-underline-offset: 0.18em;
	transition: text-decoration-thickness 160ms linear, color 160ms linear;
}

a:hover,
a:focus-visible {
	text-decoration-thickness: 2px;
}

/* Body links stay marron and underlined: an accent fill would be the only
   coloured area of a page, and colour never carries meaning here. */
.fm-band a:not(.wp-block-button__link) {
	color: var(--wp--preset--color--contrast);
}

/* Filled button: marron ground, beige type (7.07). An accent fill would sit
   at 1.75–3.03 against the beige ground and lose its own outline. */
.wp-block-button__link,
.wp-block-button .wp-block-button__link {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-block-size: 48px;
	block-size: auto;
	padding: 0.85em 1.8em;
	border: 0;
	border-radius: 0;
	box-shadow: none;
	background-color: var(--wp--preset--color--contrast);
	color: var(--wp--preset--color--base);
	font-size: 1rem;
	font-weight: 800;
	letter-spacing: 0.06em;
	line-height: 1.2;
	text-transform: uppercase;
	text-decoration: none;
	transition: background-color 160ms linear, color 160ms linear;
}

/* Without this a label longer than its line shrinks to its longest word */
.wp-block-button {
	max-inline-size: 100%;
}

@media (max-width: 781.98px) {
	.wp-block-buttons > .wp-block-button {
		flex: 1 1 100%;
	}

	.wp-block-button__link {
		inline-size: 100%;
		text-wrap: balance;
	}
}

/* Hover moves to the page accent — 4.5 against the beige type it keeps */
.wp-block-button__link:hover,
.wp-block-button__link:focus-visible {
	background-color: var(--fm-accent);
	color: var(--wp--preset--color--base);
	text-decoration: none;
}

/* Brand hues picked as a TEXT colour from wp-admin land at 1.75 to 3.03 on
   the beige ground. The core preset class carries !important, so matching it
   is the only way to keep the chosen hue and make it readable. */
.has-bleu-color { color: var(--fm-ink-bleu) !important; }
.has-rouge-color { color: var(--fm-ink-rouge) !important; }
.has-vert-color { color: var(--fm-ink-vert) !important; }
.has-jaune-color { color: var(--fm-ink-jaune) !important; }

/* Anything given a dark ground from wp-admin: without this its type stays
   marron on marron and an accent h3 falls to 2.34. The background control is
   on by default for group, heading, paragraph, columns and quote, so these
   rules key on the ground class alone, whatever block carries it. The custom
   properties inherit, so nested blocks follow. */
.has-contrast-background-color,
.has-nuit-background-color {
	color: var(--wp--preset--color--base);
	/* Both, since cards and rules read the page-level one directly */
	--fm-page-accent: var(--wp--preset--color--base);
	--fm-accent: var(--wp--preset--color--base);
	--fm-ink-2: var(--fm-ink-2-marron);
	--fm-line: var(--fm-hairline-marron);
}

/* Focus rings are marron, which is this ground: they would vanish.
   The card needs its own line — its selector outranks a bare :focus-visible. */
.has-contrast-background-color :focus-visible,
.has-nuit-background-color :focus-visible,
.has-contrast-background-color .fm-card-link:has(a:focus-visible),
.has-nuit-background-color .fm-card-link:has(a:focus-visible) {
	outline-color: var(--wp--preset--color--base);
}

.has-contrast-background-color a:not(.wp-block-button__link),
.has-nuit-background-color a:not(.wp-block-button__link) {
	color: var(--wp--preset--color--base);
}

/* The marron button would vanish into a marron ground: it flips */
.has-contrast-background-color .wp-block-button__link:not([class*="background-color"]),
.has-nuit-background-color .wp-block-button__link:not([class*="background-color"]) {
	background-color: var(--wp--preset--color--base);
	color: var(--wp--preset--color--contrast);
}

.has-contrast-background-color .wp-block-button__link:not([class*="background-color"]):hover,
.has-contrast-background-color .wp-block-button__link:not([class*="background-color"]):focus-visible,
.has-nuit-background-color .wp-block-button__link:not([class*="background-color"]):hover,
.has-nuit-background-color .wp-block-button__link:not([class*="background-color"]):focus-visible {
	background-color: var(--fm-field-bg);
	color: var(--wp--preset--color--contrast);
}

/* Held line: type left, button beside it. Two hairlines replace the fill
   the band used to carry. */
.fm-band--accent {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 1.5rem 2.5rem;
	padding-block: clamp(2.5rem, 4vw, 3.5rem);
	border-block: 1px solid var(--fm-line);
}

.fm-band--accent > * {
	margin-block: 0;
}

.fm-band--accent p {
	max-inline-size: 40ch;
	margin: 0;
}

/* =========================================================
   7. Photos & captions

   Each image keeps its file's ratio; a caption keeps one size
   whatever width its photo gets.
   ========================================================= */

.wp-block-image {
	margin: 0;
}

.wp-block-image img,
.fm-bleed img {
	display: block;
	inline-size: 100%;
	block-size: auto;
	aspect-ratio: auto;
	/* Fits the pixels inside the declared box, should the attributes go stale */
	object-fit: contain;
	border-radius: 0;
	box-shadow: none;
	filter: none;
}

/* A portrait is the one orientation that outgrows the screen in a full-bleed
   band; the crop it then takes is bottom-anchored, keeping the watermark. */
.fm-bleed img.fm-portrait {
	max-block-size: 100svh;
	object-fit: cover;
	object-position: 50% 100%;
}

/* In-column photo: a hairline is the only border allowed on an image */
.fm-band .wp-block-image:not(.fm-bleed) img {
	border: 1px solid var(--fm-line);
}

/* Same size as a credit inside a photo: gallery, video and embed captions too */
figcaption,
.wp-element-caption {
	margin-block: 0.75rem 0;
	font-size: clamp(0.6875rem, 0.6455rem + 0.1852vw, 0.8125rem);
	font-weight: 500;
	letter-spacing: 0.01em;
	line-height: 1.45;
	text-align: left;
	color: var(--fm-ink-2);
}

/* Core aligns a figure with display:table, where a 100%-wide image resolves
   its height against an undefined table width. Block keeps that determinate. */
figure.wp-block-image,
figure.wp-block-image.aligncenter,
figure.wp-block-image.alignleft,
figure.wp-block-image.alignright {
	display: block;
	position: relative;
	container-type: inline-size;
}

/* Second selector outranks core's own gallery caption rule */
figure.wp-block-image > figcaption,
figure.wp-block-gallery.has-nested-images figure.wp-block-image > figcaption {
	position: absolute;
	inset-block-start: auto;
	inset-inline: 0;
	bottom: 0.75rem;
	bottom: clamp(0.5rem, 1.4cqi, 1.5rem);
	z-index: 2;
	inline-size: fit-content;
	max-inline-size: min(88%, 60ch);
	max-block-size: calc(100% - 1rem);
	margin: 0 auto;
	padding: 0.35em 0.9em;
	overflow: hidden;
	font-size: clamp(0.6875rem, 0.6455rem + 0.1852vw, 0.8125rem);
	font-weight: 500;
	letter-spacing: 0.01em;
	line-height: 1.35;
	text-align: center;
	text-shadow: none;
	text-wrap: balance;
	background: rgba(46, 29, 26, 0.78); /* nuit, for engines without color-mix() */
	background: color-mix(in srgb, var(--wp--preset--color--nuit) 78%, transparent);
	color: var(--wp--preset--color--base);
}

/* Core veils gallery captions with a blurred gradient — not in this theme */
figure.wp-block-gallery.has-nested-images figure.wp-block-image:has(figcaption)::before {
	display: none;
}

/* Too narrow to hold a readable credit: the caption drops below the photo
   rather than being clipped inside it. */
@container (max-inline-size: 200px) {
	figure.wp-block-image > figcaption,
	figure.wp-block-gallery.has-nested-images figure.wp-block-image > figcaption {
		position: static;
		inline-size: auto;
		max-inline-size: none;
		max-block-size: none;
		margin: 0.4rem 0 0;
		padding: 0;
		overflow: visible;
		background: none;
		color: var(--fm-ink-2);
	}
}

/* =========================================================
   8. fm-* components
   ========================================================= */

/* --- E1 reveal: one axis, 12px, one-shot (JS-gated) --- */
.fm-js .fm-reveal {
	opacity: 0;
	transform: translateY(12px);
	transition: opacity 480ms var(--fm-ease), transform 480ms var(--fm-ease);
}

.fm-js .fm-reveal.is-visible {
	opacity: 1;
	transform: none;
}

.fm-reveal--delay-1 { transition-delay: 80ms; }
.fm-reveal--delay-2 { transition-delay: 160ms; }

/* --- fm-eyebrow: label + 6px accent square (size comes from the small preset) --- */
.fm-eyebrow {
	display: flex;
	align-items: flex-start;
	gap: 0.7em;
	max-inline-size: 40ch;
	margin-block-end: 0;
	font-weight: 500;
	letter-spacing: 0.16em;
	line-height: 1.2;
	text-transform: uppercase;
	color: var(--fm-accent);
}

/* Square sits on the first line, never in the leading of a wrapped eyebrow */
.fm-eyebrow::before {
	content: "";
	flex: none;
	inline-size: 6px;
	block-size: 6px;
	margin-block-start: 0.42em;
	border-radius: 0;
	background: var(--fm-accent);
}

.fm-eyebrow + * {
	margin-block-start: 0.75rem;
}


/* --- fm-underline-in: static 2px accent rule across the title measure --- */
.fm-underline-in {
	display: block;
	position: relative;
	padding-block-end: 0.7rem;
}

.fm-underline-in::after {
	content: "";
	position: absolute;
	inset-inline: 0;
	inset-block-end: 0;
	block-size: 2px;
	background: var(--fm-accent);
}

/* h3 keeps the class but never the rule (5 pillar h3 would stack 5 rules) */
h3.fm-underline-in {
	padding-block-end: 0;
}

h3.fm-underline-in::after {
	content: none;
}

/* --- fm-card-link: editorial cell, fully clickable, no box --- */
.fm-card-link {
	position: relative;
	background: none;
	border-radius: 0;
	box-shadow: none;
	overflow: visible;
	border-block-start: 2px solid var(--fm-page-accent);
	padding-block-start: 1.25rem;
}

/* Cells that carry their own theme colour keep it in the eyebrow square and
   the link only: three coloured rules side by side read as a rainbow.
   --fm-accent has to be re-declared here — var() resolves where it is
   declared, so the band's `var(--fm-page-accent)` is already jaune. */
.fm-card-link.fm-accent-bleu,
.fm-card-link.fm-accent-vert,
.fm-card-link.fm-accent-rouge,
.fm-card-link.fm-accent-jaune {
	border-block-start: 1px solid var(--fm-line);
	--fm-accent: var(--fm-page-accent);
}

.fm-card-link a::after {
	content: "";
	position: absolute;
	inset: 0;
}

.fm-card-link:has(a:focus-visible) {
	outline: 2px solid var(--wp--preset--color--contrast);
	outline-offset: 3px;
}

/* --- fm-mark: neutralised, emphasis moves to weight --- */
mark {
	background: none;
	color: inherit;
}

mark.fm-mark,
.fm-mark {
	background: none;
	color: inherit;
	font-weight: 800;
	padding: 0;
	border-radius: 0;
}

/* --- fm-cell: non-clickable editorial cell --- */
.fm-cell {
	border-block-start: 1px solid var(--fm-line);
	padding-block-start: 1.25rem;
}

/* --- fm-rule: hairline separator --- */
.fm-rule {
	block-size: 1px;
	border: 0;
	margin: 0;
	background: var(--fm-line);
}

/* is-style-wide re-adds a border-bottom at 2 classes: outrank it, stay 1px */
.wp-block-separator.fm-rule {
	border: 0;
}

/* Centred between the two rows it separates */
.fm-band > .fm-rule {
	margin-block: var(--fm-flow-lg) 0;
}

/* --- fm-index: pillar numeral (size/weight come from the markup) --- */
.fm-index {
	line-height: 1;
	letter-spacing: -0.02em;
	max-inline-size: none;
}

/* --- fm-bleed: edge-to-edge photograph, hairline top and bottom --- */
.fm-bleed {
	margin: 0;
	padding: 0;
	border-block: 1px solid var(--fm-hairline);
	border-radius: 0;
}

/* --- fm-btn--ghost: second button of a band, no second fill --- */
.fm-btn--ghost .wp-block-button__link,
.wp-block-button__link.fm-btn--ghost {
	background-color: transparent;
	border: 1px solid currentColor;
	color: var(--wp--preset--color--contrast);
}

.fm-btn--ghost .wp-block-button__link:hover,
.fm-btn--ghost .wp-block-button__link:focus-visible,
.wp-block-button__link.fm-btn--ghost:hover,
.wp-block-button__link.fm-btn--ghost:focus-visible {
	background-color: var(--wp--preset--color--contrast);
	color: var(--wp--preset--color--base);
}

/* =========================================================
   9. Navigation — fm-rail

   Chrome only: no palette colour ever appears in the rail.
   ========================================================= */

.wp-block-template-part:has(> .fm-rail),
header:has(> .fm-rail) {
	position: sticky;
	top: 0;
	z-index: 100;
}

.fm-rail {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 1rem;
	background-color: var(--wp--preset--color--base);
	color: var(--wp--preset--color--contrast);
	border-radius: 0;
}

.fm-rail a {
	text-decoration: none;
}

.fm-rail .wp-block-site-title {
	margin: 0;
	max-inline-size: none;
}

.fm-rail .wp-block-site-title a {
	color: var(--wp--preset--color--contrast);
	font-size: 0.9375rem;
	font-weight: 800;
	letter-spacing: 0.08em;
	text-transform: uppercase;
}

.fm-rail .wp-block-navigation a {
	color: var(--fm-ink-2-base);
	font-size: 0.8125rem;
	font-weight: 500;
	letter-spacing: 0.14em;
	text-transform: uppercase;
	transition: color 160ms linear;
}

.fm-rail .wp-block-navigation a:hover,
.fm-rail .wp-block-navigation a:focus-visible {
	color: var(--wp--preset--color--contrast);
}

.fm-rail .wp-block-navigation a[aria-current="page"],
.fm-rail .current-menu-item > a {
	color: var(--wp--preset--color--contrast);
	font-weight: 800;
}

.fm-rail .wp-block-social-links {
	gap: 0.75rem;
	max-inline-size: none;
}

.fm-rail .wp-block-social-link .wp-block-social-link-anchor {
	color: var(--fm-ink-2-base);
	transition: color 160ms linear;
}

.fm-rail .wp-block-social-link .wp-block-social-link-anchor svg {
	inline-size: 20px;
	block-size: 20px;
	fill: currentColor;
}

.fm-rail .wp-block-social-link .wp-block-social-link-anchor:hover,
.fm-rail .wp-block-social-link .wp-block-social-link-anchor:focus-visible {
	color: var(--wp--preset--color--contrast);
}

/* --- Mobile < 782px: 56px topbar + base overlay --- */
@media (max-width: 781.98px) {
	.fm-rail {
		min-block-size: 56px;
		padding-block: 0;
		padding-inline: var(--fm-gutter);
		border-block-end: 1px solid var(--fm-hairline);
	}

	.fm-rail .wp-block-site-title a {
		letter-spacing: 0.06em;
	}

	.fm-rail .wp-block-social-links {
		display: none;
	}

	.fm-rail .wp-block-navigation__responsive-container-open,
	.fm-rail .wp-block-navigation__responsive-container-close {
		display: flex;
		align-items: center;
		justify-content: center;
		min-inline-size: 44px;
		min-block-size: 44px;
		color: var(--wp--preset--color--contrast);
	}

	.fm-rail .wp-block-navigation__responsive-container.is-menu-open {
		background-color: var(--wp--preset--color--base);
		color: var(--wp--preset--color--contrast);
		padding: 2rem 1.5rem;
	}

	.fm-rail .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__container {
		gap: 1.25rem;
	}

	.fm-rail .wp-block-navigation__responsive-container.is-menu-open a {
		display: inline-block;
		padding-block: 0.5rem;
		color: var(--wp--preset--color--contrast);
		font-size: 1.75rem;
		font-weight: 800;
		letter-spacing: 0;
	}

	.fm-rail .wp-block-navigation__responsive-container.is-menu-open a[aria-current="page"]::before,
	.fm-rail .wp-block-navigation__responsive-container.is-menu-open .current-menu-item > a::before {
		content: "";
		display: inline-block;
		inline-size: 3px;
		block-size: 1em;
		margin-inline-end: 0.5em;
		background: var(--fm-page-accent);
		vertical-align: -0.1em;
	}
}

/* --- Desktop >= 782px: fixed vertical left rail --- */
@media (min-width: 782px) {
	.wp-block-template-part:has(> .fm-rail),
	header:has(> .fm-rail) {
		position: static;
	}

	.fm-rail {
		position: fixed;
		inset-block: 0;
		/* % — not vw — so the scrollbar never pushes the rail off the frame */
		inset-inline-start: max(0px, calc((100% - var(--fm-site-max)) / 2));
		inline-size: var(--fm-rail);
		flex-direction: column;
		justify-content: space-between;
		padding-block: 1.5rem;
		border-block-end: none;
		border-inline-end: 1px solid var(--fm-hairline);
		z-index: 100;
	}

	.fm-rail .wp-block-site-title a {
		writing-mode: vertical-rl;
		transform: rotate(180deg);
	}

	.fm-rail .wp-block-navigation {
		flex: 1;
		display: flex;
		align-items: center;
		justify-content: center;
		align-self: stretch;
	}

	.fm-rail .wp-block-navigation .wp-block-navigation__container {
		display: flex;
		flex-direction: column;
		align-items: center;
		gap: 1.75rem;
		margin: 0;
		padding: 0;
		list-style: none;
		inline-size: 100%;
	}

	.fm-rail .wp-block-navigation .wp-block-navigation-item {
		position: relative;
		align-self: stretch;
		display: flex;
		justify-content: center;
	}

	.fm-rail .wp-block-navigation a {
		writing-mode: vertical-rl;
		transform: rotate(180deg);
	}

	/* Current page: a 2px rule pinned to the inner edge of the rail */
	.fm-rail .wp-block-navigation-item:has(> a[aria-current="page"])::after,
	.fm-rail .wp-block-navigation-item.current-menu-item::after {
		content: "";
		position: absolute;
		top: 50%;
		right: 0;
		inline-size: 2px;
		block-size: 1.5rem;
		transform: translateY(-50%);
		background: var(--fm-page-accent);
	}

	.fm-rail .wp-block-social-links {
		margin: 0;
		padding: 0;
		justify-content: center;
	}
}

/* =========================================================
   10. Footer — S2, topped by a 2px rule in the page accent
   ========================================================= */

.fm-footer {
	position: relative;
	margin-block-start: 0;
	padding-block: var(--fm-band-pad) 2rem;
	padding-inline: var(--fm-gutter);
	border-radius: 0;
	background-color: var(--wp--preset--color--base);
	color: var(--wp--preset--color--contrast);
	--fm-accent: var(--fm-page-accent);
	--fm-ink-2: var(--fm-ink-2-base);
	--fm-line: var(--fm-hairline);
}

.fm-footer::before {
	content: "";
	position: absolute;
	inset: 0 0 auto 0;
	block-size: 2px;
	background: var(--fm-page-accent);
}

.fm-footer > *,
.fm-footer :is(.alignwide, .alignfull) {
	max-inline-size: none;
	margin-inline: 0;
}

.fm-footer .wp-block-columns {
	gap: var(--fm-row-gap) var(--fm-col-gap);
	align-items: start;
	margin-block: 0;
}

.fm-footer a {
	color: var(--wp--preset--color--contrast);
}

.fm-footer p {
	margin-block: 0.35em;
}

.fm-footer > .wp-block-group:last-child p {
	color: var(--fm-ink-2-base);
}

.fm-footer__legal {
	gap: 0.35rem 1.5rem;
}

/* Rendered by a shortcode, so it carries no preset size class */
.fm-cookies-link {
	font-size: clamp(0.8125rem, 0.7917rem + 0.0926vw, 0.875rem);
	color: var(--wp--preset--color--contrast);
}

/* =========================================================
   11. Contact form — markup produced by inc/contact-form.php.
   Lives on S3: input happens in the light, colour never carries
   the message.
   ========================================================= */

.fm-form {
	display: grid;
	gap: 1.25rem;
	max-inline-size: 720px;
}

.fm-form__form {
	display: grid;
	gap: 1.25rem;
}

/* Honeypot: visually removed, must stay empty */
.fm-form__hp {
	position: absolute;
	left: -9999px;
	width: 1px;
	height: 1px;
	overflow: hidden;
}

.fm-form__field {
	display: grid;
	gap: 0.4rem;
	margin: 0;
	max-inline-size: none;
}

.fm-form__label {
	font-size: clamp(0.8125rem, 0.7917rem + 0.0926vw, 0.875rem);
	font-weight: 500;
	letter-spacing: 0.16em;
	text-transform: uppercase;
	color: var(--wp--preset--color--contrast);
}

.fm-form__intro,
.fm-form__hint {
	margin: 0;
	max-inline-size: none;
	font-size: clamp(0.8125rem, 0.7917rem + 0.0926vw, 0.875rem);
	color: var(--fm-ink-2-base);
}

.fm-form__hint {
	margin-block: 0.15rem 0.5rem;
}

.fm-form__input,
.fm-form__select,
.fm-form__textarea {
	inline-size: 100%;
	min-block-size: 48px;
	padding: 0.75rem 1rem;
	font: inherit;
	border: 1px solid var(--wp--preset--color--contrast);
	border-radius: 0;
	background-color: var(--fm-field-bg);
	color: var(--wp--preset--color--contrast);
}

/* Date and guest count read as values, not as sentences */
.fm-form__input--compact {
	max-inline-size: 16rem;
}

.fm-form__textarea {
	min-block-size: 10rem;
	resize: vertical;
}

.fm-form__textarea--short {
	min-block-size: 5.5rem;
}

/* Choice groups: fieldset reset, then one tappable box per option */
.fm-form__group {
	margin: 0;
	padding: 0;
	border: 0;
	min-inline-size: 0;
}

.fm-form__group > legend {
	padding: 0;
	margin-block-end: 0.4rem;
}

.fm-form__choices {
	display: flex;
	flex-wrap: wrap;
	gap: 0.5rem 0.75rem;
}

.fm-form__choice {
	display: inline-flex;
	align-items: center;
	gap: 0.55rem;
	min-block-size: 48px;
	padding: 0.5rem 1rem;
	border: 1px solid var(--wp--preset--color--contrast);
	background-color: var(--fm-field-bg);
	color: var(--wp--preset--color--contrast);
	cursor: pointer;
}

.fm-form__choice input {
	flex: none;
	inline-size: 1.1rem;
	block-size: 1.1rem;
	margin: 0;
	accent-color: var(--wp--preset--color--contrast);
}

.fm-form__choice:has(input:checked) {
	border-color: var(--wp--preset--color--contrast);
	background-color: var(--wp--preset--color--contrast);
	color: var(--wp--preset--color--base);
}

.fm-form__choice:has(input:checked) input {
	accent-color: var(--wp--preset--color--base);
}

.fm-form__input:focus-visible,
.fm-form__select:focus-visible,
.fm-form__textarea:focus-visible {
	border-color: var(--wp--preset--color--contrast);
	outline: 2px solid var(--wp--preset--color--contrast);
	outline-offset: 1px;
}

.fm-form__actions {
	margin: 0;
	justify-self: start;
	max-inline-size: none;
}

.fm-form__submit {
	min-block-size: 48px;
	padding: 0.85em 2em;
	border: 0;
	border-radius: 0;
	font: inherit;
	font-size: 1rem;
	font-weight: 800;
	letter-spacing: 0.06em;
	text-transform: uppercase;
	background-color: var(--wp--preset--color--contrast);
	color: var(--wp--preset--color--base);
	cursor: pointer;
	transition: background-color 160ms linear;
}

.fm-form__submit:hover,
.fm-form__submit:focus-visible {
	background-color: var(--fm-accent);
}

.fm-form__rgpd {
	font-size: clamp(0.8125rem, 0.7917rem + 0.0926vw, 0.875rem);
	color: var(--fm-ink-2-base);
}

.fm-form__msg {
	padding: 0.875rem 0 0.875rem 1rem;
	border: 0;
	border-radius: 0;
	background: none;
	color: var(--wp--preset--color--contrast);
}

.fm-form__msg--success {
	border-inline-start: 3px solid var(--wp--preset--color--vert);
}

.fm-form__msg--error {
	border-inline-start: 3px solid var(--wp--preset--color--rouge);
}

/* =========================================================
   12. Focus — marron, never the accent (jaune on base is 1.75)
   ========================================================= */

:focus-visible {
	outline: 2px solid var(--wp--preset--color--contrast);
	outline-offset: 2px;
}

/* On a filled marron button the ring has to clear the fill to be seen */
.wp-block-button__link:focus-visible,
.fm-form__submit:focus-visible {
	outline-offset: 3px;
}

/* =========================================================
   13. Reduced motion
   ========================================================= */

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

	.fm-js .fm-reveal {
		opacity: 1 !important;
		transform: none !important;
	}
}
