/*
Theme Name: Philou
Theme URI: https://philippemeylan.ch/
Author: Philippe Meylan
Author URI: https://philippemeylan.ch/
Description: Thème bloc (FSE) sur mesure pour Philou — marque personnelle réunissant ses territoires créatifs sous une seule voix typographique. Le nom est le logo : identité sobre, papier crème, filets 1px, Outfit + Space Mono.
Requires at least: 6.5
Tested up to: 7.0
Requires PHP: 7.4
Version: 1.1.2
License: GNU General Public License v2 or later
License URI: http://www.gnu.org/licenses/gpl-2.0.html
Text Domain: philou
Tags: full-site-editing, block-templates, one-column, custom-colors, custom-menu, accessibility-ready
*/

/* ==========================================================================
   Philou — feuille de composants.
   Toutes les valeurs proviennent des presets de theme.json (--wp--preset--*
   et --wp--custom--*). Aucune valeur de design en dur ici.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. Accents de territoire
   Une seule variable d'accent par bloc — jamais de collision de territoires.
   -------------------------------------------------------------------------- */

/*
 * Chaque territoire pose quatre variables :
 *   --ph-accent      la couleur d'aplat (fonds, bordures, boutons)
 *   --ph-accent-text la même couleur, mais lisible en texte et en icône
 *   --ph-tint        le fond teinté des pastilles
 *   --ph-on-accent   la couleur du texte posé SUR l'aplat
 * Les deux premières ne diffèrent que pour Idea : le jaune ne passe pas en texte.
 */

.ph-t-design {
	--ph-accent: var(--wp--preset--color--orange);
	--ph-accent-text: var(--wp--preset--color--orange);
	--ph-tint: var(--wp--preset--color--orange-tint);
	--ph-on-accent: var(--wp--preset--color--surface);
}

.ph-t-sound {
	--ph-accent: var(--wp--preset--color--teal);
	--ph-accent-text: var(--wp--preset--color--teal);
	--ph-tint: var(--wp--preset--color--teal-tint);
	--ph-on-accent: var(--wp--preset--color--surface);
}

.ph-t-writing {
	--ph-accent: var(--wp--preset--color--ink);
	--ph-accent-text: var(--wp--preset--color--ink);
	--ph-tint: var(--wp--preset--color--surface-sunken);
	--ph-on-accent: var(--wp--preset--color--surface);
}

.ph-t-idea {
	--ph-accent: var(--wp--preset--color--yellow);
	/* Le jaune vif tombe à 1,5:1 sur blanc : illisible en texte comme en icône.
	   Le jaune foncé du système prend le relais dès qu'il s'agit de lire (5:1). */
	--ph-accent-text: var(--wp--preset--color--yellow-ink);
	--ph-tint: var(--wp--preset--color--yellow-tint);
	/* Le jaune ne porte jamais de texte clair : contraste AA impossible. */
	--ph-on-accent: var(--wp--preset--color--ink);
}

.ph-t-plum {
	--ph-accent: var(--wp--preset--color--plum);
	--ph-accent-text: var(--wp--preset--color--plum);
	--ph-tint: var(--wp--preset--color--plum-tint);
	--ph-on-accent: var(--wp--preset--color--surface);
}

/* Accent disponible pour une rubrique supplémentaire — voir le README §3.7. */
.ph-t-olive {
	--ph-accent: var(--wp--preset--color--olive);
	--ph-accent-text: var(--wp--preset--color--olive);
	--ph-tint: var(--wp--preset--color--olive-tint);
	--ph-on-accent: var(--wp--preset--color--surface);
}

/* --------------------------------------------------------------------------
   2. Typographie de marque
   -------------------------------------------------------------------------- */

/* Eyebrow Space Mono : « 01 · PALETTE ». Jamais d'emoji, jamais de pictogramme. */
.ph-eyebrow {
	font-family: var(--wp--preset--font-family--space-mono);
	font-size: var(--wp--preset--font-size--xs);
	font-weight: 400;
	letter-spacing: var(--wp--custom--letter-spacing--eyebrow);
	text-transform: uppercase;
	color: var(--wp--preset--color--text-muted);
}

/* Méta Space Mono sans capitales forcées (dates, catégories). */
.ph-meta {
	font-family: var(--wp--preset--font-family--space-mono);
	font-size: var(--wp--preset--font-size--xs);
	color: var(--wp--preset--color--text-muted);
	letter-spacing: 0;
}

/* Le nom est le logo : le mot-clé de territoire prend la couleur, pas « Philou ». */
.ph-wordmark {
	font-family: var(--wp--preset--font-family--outfit);
	font-weight: 600;
	letter-spacing: -0.03em;
	line-height: 0.95;
	color: var(--wp--preset--color--ink);
	white-space: nowrap;
}

.ph-wordmark .ph-wordmark__key {
	font-weight: 500;
	color: var(--ph-accent-text, var(--wp--preset--color--ink));
}

/* Longueur de ligne confortable pour les paragraphes de tête. */
.ph-measure {
	max-width: var(--wp--custom--measure);
}

/*
 * Attention en composition : la mise en page « contenu contraint » de
 * WordPress pose margin-inline:auto sur chaque enfant, ce qui CENTRE tout bloc
 * plus étroit que la colonne — donc tout .ph-measure. Placez-le toujours dans
 * un groupe en flux (« Par défaut ») imbriqué dans la section contrainte :
 * le groupe prend la colonne, le texte reste calé à gauche.
 */

/* --------------------------------------------------------------------------
   3. Icônes Lucide
   SVG inline, trait fin, colorées par currentColor — jamais d'emoji.
   -------------------------------------------------------------------------- */

.ph-icon {
	display: inline-flex;
	flex: none;
	line-height: 0;
	color: currentColor;
}

.ph-icon svg {
	width: 1em;
	height: 1em;
	stroke: currentColor;
	fill: none;
}

/* Pastille d'icône teintée — le seul aplat coloré des cartes. */
.ph-icon-badge {
	display: grid;
	place-items: center;
	flex: none;
	width: var(--wp--preset--spacing--7);
	height: var(--wp--preset--spacing--7);
	border-radius: var(--wp--custom--radius--md);
	background: var(--ph-tint, var(--wp--preset--color--surface-sunken));
	color: var(--ph-accent-text, var(--wp--preset--color--ink));
	font-size: 22px;
}

.ph-icon-badge--lg {
	width: var(--wp--preset--spacing--8);
	height: var(--wp--preset--spacing--8);
	border-radius: var(--wp--custom--radius--lg);
	font-size: 28px;
}

/*
 * Icône posée par une simple CLASSE, sans toucher au code.
 *
 * Le SVG est appliqué en masque et coloré par `currentColor` : l'icône prend
 * donc automatiquement la couleur du territoire, exactement comme les SVG
 * inline. Changer d'icône revient à changer `ph-ico-palette` en
 * `ph-ico-camera` dans le panneau « Avancé » du bloc — c'est ce qui rend une
 * nouvelle rubrique créable depuis l'éditeur seul.
 *
 * Les SVG inline restent pris en charge (règle `.ph-icon svg` ci-dessus) :
 * les pages déjà publiées continuent de s'afficher sans aucune retouche.
 */
.ph-ico {
	display: block;
	width: 1em;
	height: 1em;
	background-color: currentColor;
	-webkit-mask: var(--ph-ico-src) center / contain no-repeat;
	mask: var(--ph-ico-src) center / contain no-repeat;
}

.ph-ico-audio-lines {
	--ph-ico-src: url("assets/icons/audio-lines.svg");
}
.ph-ico-book-open {
	--ph-ico-src: url("assets/icons/book-open.svg");
}
.ph-ico-camera {
	--ph-ico-src: url("assets/icons/camera.svg");
}
.ph-ico-code {
	--ph-ico-src: url("assets/icons/code.svg");
}
.ph-ico-compass {
	--ph-ico-src: url("assets/icons/compass.svg");
}
.ph-ico-globe {
	--ph-ico-src: url("assets/icons/globe.svg");
}
.ph-ico-hammer {
	--ph-ico-src: url("assets/icons/hammer.svg");
}
.ph-ico-layers {
	--ph-ico-src: url("assets/icons/layers.svg");
}
.ph-ico-lightbulb {
	--ph-ico-src: url("assets/icons/lightbulb.svg");
}
.ph-ico-music {
	--ph-ico-src: url("assets/icons/music.svg");
}
.ph-ico-palette {
	--ph-ico-src: url("assets/icons/palette.svg");
}
.ph-ico-pen-line {
	--ph-ico-src: url("assets/icons/pen-line.svg");
}
.ph-ico-sparkles {
	--ph-ico-src: url("assets/icons/sparkles.svg");
}
.ph-ico-video {
	--ph-ico-src: url("assets/icons/video.svg");
}

/* --------------------------------------------------------------------------
   4. En-tête collant
   -------------------------------------------------------------------------- */

.ph-header {
	position: sticky;
	top: 0;
	z-index: 100;
	border-bottom: 1px solid var(--wp--preset--color--border);
	/* Fond opaque plutôt qu'un blur : rendu identique partout, zéro coût GPU. */
	background: var(--wp--preset--color--paper);
}

.ph-header__inner {
	min-height: var(--wp--preset--spacing--9);
}

/* Sous 400px, wordmark + Menu + Access ne tiennent plus à leur taille nominale :
   on resserre plutôt que de laisser déborder. Les cibles restent à 44px. */
@media (max-width: 400px) {
	.ph-header .wp-block-site-title {
		font-size: 22px;
	}

	.ph-header .wp-block-button__link,
	.ph-nav .wp-block-navigation__responsive-container-open {
		padding-left: var(--wp--preset--spacing--4);
		padding-right: var(--wp--preset--spacing--4);
		font-size: var(--wp--preset--font-size--sm);
	}
}

/* Bouton « Access » : contour prune, la seule couleur d'accent de l'en-tête. */
.ph-btn-outline .wp-block-button__link,
.wp-block-button.ph-btn-outline > .wp-block-button__link {
	background-color: transparent;
	color: var(--wp--preset--color--plum);
	border-color: var(--wp--preset--color--plum);
}

.ph-btn-outline .wp-block-button__link:hover,
.ph-btn-outline .wp-block-button__link:focus {
	background-color: var(--wp--preset--color--plum);
	color: var(--wp--preset--color--surface);
}

/* --------------------------------------------------------------------------
   5. Menu déroulant
   Le bloc Navigation natif est réglé en superposition permanente sans icône :
   WordPress affiche alors le mot « Menu » et gère l'ouverture, la fermeture,
   la touche Échap et le piège à focus. La CSS ci-dessous se contente de
   transformer son panneau plein écran en menu déroulant ancré sous le bouton.
   Aucun JavaScript maison, et le menu reste modifiable dans l'éditeur.
   -------------------------------------------------------------------------- */

/* Repère de positionnement du panneau. */
.ph-nav {
	position: relative;
}

.ph-nav .wp-block-navigation__responsive-container-open,
.ph-nav .wp-block-navigation__responsive-container-close {
	font-family: var(--wp--preset--font-family--outfit);
	font-size: var(--wp--preset--font-size--base);
	font-weight: 600;
	letter-spacing: -0.01em;
	color: var(--wp--preset--color--text-strong);
	padding: 11px 22px;
	min-height: var(--wp--custom--target);
	/* Même gabarit pour « Menu » et « Fermer » : le second se superpose
	   exactement au premier, l'effet est celui d'un simple changement de mot. */
	min-width: 108px;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	border: 1px solid var(--wp--preset--color--border);
	border-radius: var(--wp--custom--radius--pill);
	background: var(--wp--preset--color--surface);
	transition: border-color var(--wp--custom--transition), color var(--wp--custom--transition);
}

.ph-nav .wp-block-navigation__responsive-container-open:hover,
.ph-nav .wp-block-navigation__responsive-container-close:hover {
	border-color: var(--wp--preset--color--plum);
	color: var(--wp--preset--color--plum);
}

/*
 * Le panneau. WordPress le pose en `position: fixed` plein écran ; on le
 * ramène en panneau absolu sous le bouton — une carte comme les autres :
 * surface blanche, filet 1px, coins doux, ombre discrète.
 */
.ph-nav .wp-block-navigation__responsive-container.is-menu-open {
	position: absolute;
	top: calc(100% + var(--wp--preset--spacing--3));
	right: 0;
	bottom: auto;
	left: auto;
	z-index: 120;
	width: max-content;
	min-width: 232px;
	max-width: calc(100vw - var(--wp--preset--spacing--5) * 2);
	/* Aucun rembourrage ici : il est porté par la liste, pour que le calage
	   du bouton « Fermer » ne dépende que du filet de 1px. */
	padding: 0;
	border: 1px solid var(--wp--preset--color--border);
	border-radius: var(--wp--custom--radius--lg);
	box-shadow: var(--wp--preset--shadow--md);
	overflow: visible;
}

/* Les enveloppes internes de WordPress prévoient la place d'un plein écran. */
.ph-nav .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-close,
.ph-nav .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-dialog,
.ph-nav .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-container-content {
	max-width: none;
	margin: 0;
	padding: 0;
}

.ph-nav .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__container {
	gap: 2px;
	align-items: stretch;
	padding: var(--wp--preset--spacing--2);
}

/* « Fermer » se pose exactement sur « Menu » : on remonte de la hauteur du
   bouton, plus l'écart au panneau, plus le filet — l'effet est celui d'un
   simple changement de mot, et le bouton d'ouverture reste caché dessous. */
.ph-nav .wp-block-navigation__responsive-container-close {
	position: absolute;
	top: calc((var(--wp--custom--target) + var(--wp--preset--spacing--3) + 1px) * -1);
	right: -1px;
	z-index: 2;
}

/* Entrées du menu : lignes cliquables, cible de 44px, alignées à gauche. */
.ph-nav .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation-item__content {
	display: flex;
	align-items: center;
	width: 100%;
	min-height: var(--wp--custom--target);
	padding: var(--wp--preset--spacing--2) var(--wp--preset--spacing--3);
	border-radius: var(--wp--custom--radius--sm);
	font-size: var(--wp--preset--font-size--base);
	font-weight: 500;
	letter-spacing: 0;
	color: var(--wp--preset--color--text-strong);
	text-decoration: none;
	transition: background-color var(--wp--custom--transition), color var(--wp--custom--transition);
}

.ph-nav .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation-item__content:hover,
.ph-nav .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation-item__content:focus {
	background-color: var(--wp--preset--color--surface-sunken);
	color: var(--wp--preset--color--plum);
}

/* Un menu déroulant n'est pas une fenêtre modale : pas de blocage du défilement. */
html.has-modal-open {
	overflow: visible;
}

/* --------------------------------------------------------------------------
   6. Cartes
   Surface blanche + filet 1px + radius lg/xl + ombre douce. Sobres.
   -------------------------------------------------------------------------- */

.ph-card {
	position: relative;
	background: var(--wp--preset--color--surface);
	border: 1px solid var(--wp--preset--color--border);
	border-radius: var(--wp--custom--radius--xl);
	box-shadow: var(--wp--preset--shadow--sm);
	transition: transform var(--wp--custom--transition), box-shadow var(--wp--custom--transition),
		border-color var(--wp--custom--transition);
}

/* Carte entièrement cliquable, un seul arrêt de tabulation :
   le lien du titre s'étend sur toute la carte via ::after. */
.ph-card__link::after {
	content: "";
	position: absolute;
	inset: 0;
	border-radius: inherit;
}

.ph-card:has(.ph-card__link:hover),
.ph-card:has(.ph-card__link:focus-visible) {
	transform: translateY(-3px);
	box-shadow: var(--wp--preset--shadow--md);
	border-color: var(--ph-accent, var(--wp--preset--color--border));
}

/* L'anneau de focus se pose sur la carte, pas sur le mot. */
.ph-card:has(.ph-card__link:focus-visible) {
	outline: 2px solid var(--wp--preset--color--plum);
	outline-offset: 2px;
	box-shadow: 0 0 0 3px var(--wp--custom--focus-ring);
}

/* On n'efface l'anneau du lien QUE si le navigateur sait le reporter sur la
   carte via :has(). Sans ce garde-fou, un navigateur sans :has() n'afficherait
   plus aucun indicateur de focus. */
@supports selector(:has(a)) {
	.ph-card .ph-card__link:focus-visible {
		outline: none;
		box-shadow: none;
	}
}

.ph-card__link,
.ph-card__link:hover,
.ph-card__link:focus {
	text-decoration: none;
	color: inherit;
}

/* Repli pour les navigateurs sans :has() — le survol reste, sans le décalage. */
@supports not selector(:has(a)) {
	.ph-card:hover {
		box-shadow: var(--wp--preset--shadow--md);
	}
}

/* Carte de territoire : hauteur homogène sur toute la grille. */
.ph-card-territory {
	min-height: 180px;
	padding: var(--wp--preset--spacing--6);
	display: flex;
	flex-direction: column;
	gap: var(--wp--preset--spacing--4);
}

.ph-card-territory__top {
	display: flex;
	align-items: center;
	justify-content: space-between;
}

.ph-card-territory__body {
	margin-top: auto;
}

/* Flèche « sortante » discrète, elle s'anime avec la carte. */
.ph-arrow {
	color: var(--wp--preset--color--text-faint);
	font-size: 20px;
	transition: color var(--wp--custom--transition), transform var(--wp--custom--transition);
}

.ph-card:has(.ph-card__link:hover) .ph-arrow,
.ph-card:has(.ph-card__link:focus-visible) .ph-arrow {
	color: var(--ph-accent-text, var(--wp--preset--color--text-muted));
	transform: translate(2px, -2px);
}

/* --------------------------------------------------------------------------
   7. Carte-lien (pages de rubrique)
   Titre + description + résumé + image, pointant vers une page web.
   -------------------------------------------------------------------------- */

.ph-link-card {
	overflow: hidden;
	border-radius: var(--wp--custom--radius--lg);
	display: flex;
	flex-direction: column;
}

.ph-link-card__media {
	position: relative;
	/* Bande basse, comme le prototype — le visuel accompagne le texte, il ne
	   l'écrase pas. L'image est recadrée par object-fit. */
	height: 150px;
	flex: none;
	/* Repli quand aucune image n'est fournie : aplat teinté + grande icône. */
	background: color-mix(in srgb, var(--ph-accent, var(--wp--preset--color--ink)) 12%, var(--wp--preset--color--surface));
	display: grid;
	place-items: center;
	border-bottom: 1px solid var(--wp--preset--color--border-soft);
	overflow: hidden;
}

.ph-link-card__media .ph-icon {
	font-size: 40px;
	color: color-mix(in srgb, var(--ph-accent, var(--wp--preset--color--ink)) 60%, var(--wp--preset--color--paper));
}

.ph-link-card__media img,
.ph-link-card__media .wp-block-image,
.ph-link-card__media figure {
	position: absolute;
	inset: 0;
	margin: 0;
	width: 100%;
	height: 100%;
}

.ph-link-card__media img {
	object-fit: cover;
	display: block;
}

.ph-link-card__body {
	padding: var(--wp--preset--spacing--5);
	display: flex;
	flex-direction: column;
	gap: var(--wp--preset--spacing--2);
	flex: 1;
}

.ph-link-card__title {
	font-size: 17px;
	font-weight: 600;
	letter-spacing: -0.01em;
	line-height: var(--wp--custom--line-height--snug);
	color: var(--wp--preset--color--text-strong);
	margin: 0;
}

/* --------------------------------------------------------------------------
   8. Grilles
   Grille auto-adaptative : le nombre de colonnes découle de la place
   disponible, pas d'un nombre de cartes écrit en dur. Ajouter une cinquième
   ou une sixième rubrique ne demande donc aucune modification de CSS.
   -------------------------------------------------------------------------- */

/*
 * Le nom « ph-grid-2 » est conservé : il est déjà inscrit dans le contenu des
 * pages publiées. Le renommer casserait la mise en page des pages existantes.
 *
 * La largeur minimale d'une carte est volontairement fluide :
 *   · min(100%, …)  — jamais plus large que le conteneur, donc aucun
 *                     débordement sur les très petits écrans (320px) ;
 *   · clamp(300px, 30vw, 380px) — 300px sur mobile et tablette, ce qui donne
 *                     deux colonnes dès ~670px de fenêtre ; 380px sur grand
 *                     écran, ce qui en interdit une troisième dans les 1080px
 *                     de la colonne de contenu et préserve le 2×2 d'origine.
 * Une troisième colonne n'apparaîtrait que si la largeur de contenu était
 * un jour élargie — la grille suivrait alors d'elle-même.
 */
.ph-grid-2 {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(min(100%, clamp(300px, 30vw, 380px)), 1fr));
	gap: 18px;
	align-items: stretch;
}

/*
 * `align-items: stretch` n'égalise les cartes qu'à l'intérieur d'une rangée.
 * Une rubrique seule sur sa rangée — la cinquième, la septième… — retombait
 * donc sur la hauteur de son propre texte et paraissait plus courte que les
 * autres. `grid-auto-rows: 1fr` donne à toutes les rangées la hauteur de la
 * plus haute : la carte esseulée s'aligne sur ses voisines, quel que soit le
 * nombre de rubriques.
 *
 * Réservé aux écrans à deux colonnes (~672px et au-delà, voir le calcul
 * ci-dessus). Sur téléphone, chaque carte est seule sur sa rangée : un
 * plancher commun n'y ajouterait que du vide sous les textes courts.
 */
@media (min-width: 700px) {
	.ph-grid-2 {
		grid-auto-rows: 1fr;
	}
}

/* Le groupe qui porte la grille reçoit aussi « is-layout-flow » de WordPress,
   qui pose une marge haute sur tous les enfants sauf le premier. Dans une
   grille, cette marge décale les cartes dans leur cellule : on l'annule,
   l'espacement est déjà assuré par « gap ». */
.ph-grid-2 > * {
	margin-block: 0;
}

/* --------------------------------------------------------------------------
   9. Formulaire de contact
   -------------------------------------------------------------------------- */

.ph-form {
	display: flex;
	flex-direction: column;
	gap: var(--wp--preset--spacing--3);
}

.ph-field {
	display: flex;
	flex-direction: column;
	gap: var(--wp--preset--spacing--1);
}

/* Formulaire pleine largeur : nom et email côte à côte dès la tablette. */
.ph-form__row {
	display: grid;
	grid-template-columns: 1fr;
	gap: var(--wp--preset--spacing--3);
}

@media (min-width: 700px) {
	.ph-form__row {
		grid-template-columns: 1fr 1fr;
	}
}

/* Le bouton reste à sa taille naturelle et la mention l'accompagne. */
.ph-form__actions {
	display: flex;
	align-items: center;
	flex-wrap: wrap;
	gap: var(--wp--preset--spacing--4);
	margin-top: var(--wp--preset--spacing--2);
}

.ph-field__label {
	font-size: var(--wp--preset--font-size--sm);
	font-weight: 500;
	color: var(--wp--preset--color--text-strong);
}

.ph-form input[type="text"],
.ph-form input[type="email"],
.ph-form textarea {
	font-family: var(--wp--preset--font-family--outfit);
	font-size: var(--wp--preset--font-size--base);
	font-weight: 300;
	color: var(--wp--preset--color--text-strong);
	background: var(--wp--preset--color--surface);
	border: 1px solid var(--wp--preset--color--border);
	border-radius: var(--wp--custom--radius--md);
	padding: 11px 14px;
	min-height: var(--wp--custom--target);
	width: 100%;
	transition: border-color var(--wp--custom--transition);
}

.ph-form input::placeholder,
.ph-form textarea::placeholder {
	color: var(--wp--preset--color--text-faint);
}

.ph-form input:hover,
.ph-form textarea:hover {
	border-color: var(--wp--preset--color--text-faint);
}

.ph-form textarea {
	resize: vertical;
	line-height: var(--wp--custom--line-height--normal);
}

.ph-form button[type="submit"] {
	font-family: var(--wp--preset--font-family--outfit);
	font-size: var(--wp--preset--font-size--base);
	font-weight: 600;
	letter-spacing: -0.01em;
	color: var(--wp--preset--color--surface);
	background: var(--wp--preset--color--plum);
	border: 1px solid transparent;
	border-radius: var(--wp--custom--radius--pill);
	padding: 11px 22px;
	min-height: var(--wp--custom--target);
	cursor: pointer;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: var(--wp--preset--spacing--2);
	transition: background-color var(--wp--custom--transition), transform 120ms ease;
}

.ph-form button[type="submit"]:hover,
.ph-form button[type="submit"]:focus {
	background: var(--wp--preset--color--ink);
}

.ph-form button[type="submit"]:active {
	transform: translateY(1px);
}

/* Piège à robots — invisible à l'écran, hors du flux de tabulation et du lecteur d'écran. */
.ph-hp {
	position: absolute !important;
	left: -9999px !important;
	width: 1px;
	height: 1px;
	overflow: hidden;
}

.ph-form__note {
	font-size: var(--wp--preset--font-size--sm);
	color: var(--wp--preset--color--text-muted);
	margin: 0;
}

.ph-form__error {
	font-size: var(--wp--preset--font-size--sm);
	color: var(--wp--preset--color--danger);
	margin: 0;
}

.ph-form input[aria-invalid="true"],
.ph-form textarea[aria-invalid="true"] {
	border-color: var(--wp--preset--color--danger);
}

.ph-alert {
	display: flex;
	align-items: flex-start;
	gap: var(--wp--preset--spacing--2);
	border-radius: var(--wp--custom--radius--md);
	padding: var(--wp--preset--spacing--3) var(--wp--preset--spacing--4);
	font-size: var(--wp--preset--font-size--base);
	font-weight: 500;
	margin-bottom: var(--wp--preset--spacing--4);
}

.ph-alert--ok {
	background: var(--wp--preset--color--teal-tint);
	color: var(--wp--preset--color--teal);
}

.ph-alert--error {
	background: color-mix(in srgb, var(--wp--preset--color--danger) 12%, var(--wp--preset--color--surface));
	color: var(--wp--preset--color--danger);
}

/* Ligne de contact directe, sous un filet doux. */
.ph-contact-direct {
	border-top: 1px solid var(--wp--preset--color--border-soft);
	margin-top: var(--wp--preset--spacing--5);
	padding-top: var(--wp--preset--spacing--4);
	display: flex;
	align-items: center;
	gap: var(--wp--preset--spacing--2);
	font-family: var(--wp--preset--font-family--space-mono);
	font-size: 13px;
	color: var(--wp--preset--color--text-muted);
}

.ph-contact-direct a {
	color: inherit;
	text-decoration: none;
}

.ph-contact-direct a:hover {
	color: var(--wp--preset--color--plum);
	text-decoration: underline;
}

/* --------------------------------------------------------------------------
   10. Pied de page
   -------------------------------------------------------------------------- */

.ph-footer {
	border-top: 1px solid var(--wp--preset--color--border);
}

.ph-footer__social {
	display: flex;
	align-items: center;
	gap: var(--wp--preset--spacing--5);
}

.ph-footer__social a {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	/* Cible tactile de 44px alors que l'icône n'en fait que 18. */
	width: var(--wp--custom--target);
	height: var(--wp--custom--target);
	margin: calc(var(--wp--preset--spacing--3) * -1);
	color: var(--wp--preset--color--text-muted);
	font-size: 18px;
	border-radius: var(--wp--custom--radius--pill);
	transition: color var(--wp--custom--transition);
}

.ph-footer__social a:hover {
	color: var(--wp--preset--color--plum);
}

/* --------------------------------------------------------------------------
   11. Page Access — écran verrouillé et liste d'apps
   -------------------------------------------------------------------------- */

.ph-lock {
	max-width: 460px;
	margin: var(--wp--preset--spacing--10) auto;
}

.ph-lock .ph-card {
	padding: var(--wp--preset--spacing--6);
	display: flex;
	flex-direction: column;
	gap: var(--wp--preset--spacing--4);
}

.ph-lock h2 {
	font-size: var(--wp--preset--font-size--lg);
	letter-spacing: var(--wp--custom--letter-spacing--tight);
	margin: 0;
}

.ph-lock .post-password-form {
	display: flex;
	flex-direction: column;
	gap: var(--wp--preset--spacing--3);
	text-align: left;
	margin: 0;
}

.ph-lock .post-password-form p {
	margin: 0;
	display: flex;
	flex-direction: column;
	gap: var(--wp--preset--spacing--1);
	font-size: var(--wp--preset--font-size--sm);
	color: var(--wp--preset--color--text-body);
}

.ph-lock .post-password-form label {
	display: flex;
	flex-direction: column;
	gap: var(--wp--preset--spacing--1);
	font-size: var(--wp--preset--font-size--sm);
	font-weight: 500;
	color: var(--wp--preset--color--text-strong);
	width: 100%;
}

.ph-lock .post-password-form input[type="password"] {
	font-family: var(--wp--preset--font-family--outfit);
	font-size: var(--wp--preset--font-size--base);
	color: var(--wp--preset--color--text-strong);
	background: var(--wp--preset--color--surface);
	border: 1px solid var(--wp--preset--color--border);
	border-radius: var(--wp--custom--radius--md);
	padding: 11px 14px;
	min-height: var(--wp--custom--target);
	width: 100%;
}

.ph-lock .post-password-form input[type="submit"] {
	font-family: var(--wp--preset--font-family--outfit);
	font-size: var(--wp--preset--font-size--base);
	font-weight: 600;
	color: var(--wp--preset--color--surface);
	background: var(--wp--preset--color--plum);
	border: 1px solid transparent;
	border-radius: var(--wp--custom--radius--pill);
	padding: 11px 22px;
	min-height: var(--wp--custom--target);
	cursor: pointer;
	transition: background-color var(--wp--custom--transition);
}

.ph-lock .post-password-form input[type="submit"]:hover,
.ph-lock .post-password-form input[type="submit"]:focus {
	background: var(--wp--preset--color--ink);
}

/* Liste d'applications : lignes séparées par un filet, pas des cartes. */
.ph-apps {
	list-style: none;
	/* margin-block seulement : les marges latérales restent en « auto » pour
	   que la liste s'aligne sur la colonne de contenu, comme les titres. */
	margin-block: 0;
	padding: 0;
	border: 1px solid var(--wp--preset--color--border);
	border-radius: var(--wp--custom--radius--lg);
	background: var(--wp--preset--color--surface);
	overflow: hidden;
	box-shadow: var(--wp--preset--shadow--sm);
}

.ph-apps li + li {
	border-top: 1px solid var(--wp--preset--color--border-soft);
}

.ph-apps a {
	display: flex;
	align-items: center;
	gap: var(--wp--preset--spacing--4);
	padding: var(--wp--preset--spacing--4) var(--wp--preset--spacing--5);
	min-height: var(--wp--custom--target);
	text-decoration: none;
	color: var(--wp--preset--color--text-strong);
	transition: background-color var(--wp--custom--transition);
}

.ph-apps a:hover {
	background: var(--wp--preset--color--surface-sunken);
}

.ph-apps__name {
	font-size: var(--wp--preset--font-size--base);
	font-weight: 500;
}

.ph-apps__desc {
	font-size: var(--wp--preset--font-size--sm);
	font-weight: 300;
	color: var(--wp--preset--color--text-muted);
	margin: 0;
}

.ph-apps__url {
	font-family: var(--wp--preset--font-family--space-mono);
	font-size: var(--wp--preset--font-size--xs);
	color: var(--wp--preset--color--text-faint);
	margin-left: auto;
	flex: none;
}

@media (max-width: 600px) {
	.ph-apps__url {
		display: none;
	}
}

/* --------------------------------------------------------------------------
   12. Divers
   -------------------------------------------------------------------------- */

/* Le lien d'évitement est fourni par WordPress pour les thèmes blocs : il vise
   le premier <main>, que chaque gabarit du thème déclare. On garde seulement la
   classe d'accessibilité qu'il utilise. */
.screen-reader-text {
	border: 0;
	clip-path: inset(50%);
	height: 1px;
	margin: -1px;
	overflow: hidden;
	padding: 0;
	position: absolute;
	width: 1px;
	word-wrap: normal !important;
}

/* Ancre de section : l'en-tête collant ne doit pas recouvrir la cible. */
:target {
	scroll-margin-top: var(--wp--preset--spacing--10);
}

html {
	scroll-behavior: smooth;
}
