Site personnel courcellematthi.eu
This commit is contained in:
@@ -0,0 +1,330 @@
|
||||
/* ==========================================================================
|
||||
layout.css — Structure de page
|
||||
--------------------------------------------------------------------------
|
||||
Conteneurs, en-tête collant, navigation, sections, grilles, pied de page.
|
||||
Ce fichier positionne ; components.css habille.
|
||||
========================================================================== */
|
||||
|
||||
@layer layout {
|
||||
|
||||
/* ======================================================================
|
||||
CONTENEUR
|
||||
Un seul conteneur réutilisé partout : la largeur de contenu est décidée
|
||||
à un seul endroit.
|
||||
====================================================================== */
|
||||
|
||||
.container {
|
||||
inline-size: 100%;
|
||||
max-inline-size: var(--width-content);
|
||||
margin-inline: auto;
|
||||
padding-inline: var(--gutter);
|
||||
}
|
||||
|
||||
/* ======================================================================
|
||||
LIEN D'ÉVITEMENT
|
||||
Premier élément focusable de la page. Permet à un utilisateur au
|
||||
clavier ou au lecteur d'écran de sauter la navigation pour atteindre
|
||||
directement le contenu. Critère WCAG 2.4.1 (Contourner des blocs).
|
||||
Masqué visuellement hors focus, mais jamais display:none — sinon il
|
||||
ne serait pas focusable.
|
||||
====================================================================== */
|
||||
|
||||
.skip-link {
|
||||
position: fixed;
|
||||
inset-block-start: var(--space-xs);
|
||||
inset-inline-start: var(--space-xs);
|
||||
z-index: var(--z-skip-link);
|
||||
padding: var(--space-xs) var(--space-md);
|
||||
background-color: var(--color-ink);
|
||||
color: var(--color-ink-inverse);
|
||||
font-family: var(--font-mono);
|
||||
font-size: var(--text-sm);
|
||||
text-decoration: none;
|
||||
border-radius: var(--radius-sm);
|
||||
transform: translateY(-200%);
|
||||
transition: transform var(--transition-fast);
|
||||
}
|
||||
|
||||
.skip-link:focus {
|
||||
transform: translateY(0);
|
||||
color: var(--color-ink-inverse);
|
||||
}
|
||||
|
||||
/* ======================================================================
|
||||
EN-TÊTE COLLANT
|
||||
====================================================================== */
|
||||
|
||||
.site-header {
|
||||
position: sticky;
|
||||
inset-block-start: 0;
|
||||
z-index: var(--z-sticky);
|
||||
background-color: var(--color-bg-translucent);
|
||||
border-block-end: 1px solid var(--color-line);
|
||||
|
||||
/* Flou d'arrière-plan : le contenu qui défile dessous reste deviné
|
||||
sans nuire à la lisibilité du menu. Dégradation propre si non
|
||||
supporté (le fond translucide suffit). */
|
||||
backdrop-filter: blur(10px);
|
||||
-webkit-backdrop-filter: blur(10px);
|
||||
}
|
||||
|
||||
.site-header__inner {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: var(--space-md);
|
||||
min-block-size: var(--header-height);
|
||||
}
|
||||
|
||||
.site-header__brand {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: var(--space-xs);
|
||||
font-family: var(--font-mono);
|
||||
font-size: var(--text-sm);
|
||||
font-weight: var(--weight-bold);
|
||||
color: var(--color-ink);
|
||||
text-decoration: none;
|
||||
letter-spacing: -0.01em;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.site-header__brand:hover { color: var(--color-ink); }
|
||||
|
||||
.site-header__logo {
|
||||
inline-size: 1.6rem;
|
||||
block-size: 1.6rem;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
/* ======================================================================
|
||||
NAVIGATION PRINCIPALE
|
||||
====================================================================== */
|
||||
|
||||
.site-nav__list {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: var(--space-lg);
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.site-nav__link {
|
||||
display: inline-block;
|
||||
font-family: var(--font-mono);
|
||||
font-size: var(--text-sm);
|
||||
color: var(--color-ink-faint);
|
||||
text-decoration: none;
|
||||
padding-block: var(--space-2xs);
|
||||
border-block-end: 2px solid transparent;
|
||||
transition: color var(--transition-fast), border-color var(--transition-fast);
|
||||
}
|
||||
|
||||
.site-nav__link:hover { color: var(--color-ink); }
|
||||
|
||||
/* Section courante. aria-current n'est pas qu'un sélecteur pratique :
|
||||
il annonce la position aux lecteurs d'écran. Le repère visuel repose
|
||||
sur la couleur ET sur une bordure — jamais sur la couleur seule
|
||||
(WCAG 1.4.1, information non véhiculée par la couleur uniquement). */
|
||||
.site-nav__link[aria-current="true"] {
|
||||
color: var(--color-ink);
|
||||
border-block-end-color: var(--color-accent);
|
||||
}
|
||||
|
||||
/* ======================================================================
|
||||
BOUTON MENU (mobile)
|
||||
====================================================================== */
|
||||
|
||||
.nav-toggle {
|
||||
display: none; /* Affiché uniquement sous le point de rupture */
|
||||
align-items: center;
|
||||
gap: var(--space-xs);
|
||||
min-block-size: var(--tap-target);
|
||||
padding-inline: var(--space-xs);
|
||||
font-family: var(--font-mono);
|
||||
font-size: var(--text-sm);
|
||||
color: var(--color-ink-soft);
|
||||
}
|
||||
|
||||
.nav-toggle__icon {
|
||||
inline-size: 1.15rem;
|
||||
block-size: 1.15rem;
|
||||
stroke: currentcolor;
|
||||
stroke-width: 2;
|
||||
fill: none;
|
||||
}
|
||||
|
||||
/* Les deux tracés de l'icône se transforment en croix à l'ouverture */
|
||||
.nav-toggle__line {
|
||||
transform-origin: center;
|
||||
transition: transform var(--transition-base), opacity var(--transition-fast);
|
||||
}
|
||||
|
||||
.nav-toggle[aria-expanded="true"] .nav-toggle__line--top { transform: translateY(5px) rotate(45deg); }
|
||||
.nav-toggle[aria-expanded="true"] .nav-toggle__line--middle { opacity: 0; }
|
||||
.nav-toggle[aria-expanded="true"] .nav-toggle__line--bottom { transform: translateY(-5px) rotate(-45deg); }
|
||||
|
||||
/* ======================================================================
|
||||
RÉGIONS DE CONTENU
|
||||
====================================================================== */
|
||||
|
||||
.masthead {
|
||||
padding-block: var(--space-3xl) var(--space-2xl);
|
||||
border-block-end: 1px solid var(--color-line);
|
||||
}
|
||||
|
||||
.section {
|
||||
padding-block: var(--space-3xl);
|
||||
border-block-start: 1px solid var(--color-line);
|
||||
}
|
||||
|
||||
/* ======================================================================
|
||||
GRILLE AUTO-ADAPTATIVE
|
||||
auto-fit + minmax : le nombre de colonnes s'ajuste seul à la largeur
|
||||
disponible, sans media query. Le min() interne évite le débordement
|
||||
sur les très petits écrans (une colonne ne peut pas être plus large
|
||||
que son conteneur).
|
||||
====================================================================== */
|
||||
|
||||
.grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(min(17.5rem, 100%), 1fr));
|
||||
gap: var(--space-md);
|
||||
}
|
||||
|
||||
.grid--wide {
|
||||
grid-template-columns: repeat(auto-fit, minmax(min(22rem, 100%), 1fr));
|
||||
}
|
||||
|
||||
/* Empilement vertical régulier */
|
||||
.stack > * + * { margin-block-start: var(--space-md); }
|
||||
|
||||
/* ======================================================================
|
||||
PIED DE PAGE
|
||||
====================================================================== */
|
||||
|
||||
.site-footer {
|
||||
border-block-start: 1px solid var(--color-line);
|
||||
padding-block: var(--space-xl) var(--space-2xl);
|
||||
}
|
||||
|
||||
.site-footer__inner {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
gap: var(--space-sm) var(--space-lg);
|
||||
font-family: var(--font-mono);
|
||||
font-size: var(--text-sm);
|
||||
color: var(--color-ink-faint);
|
||||
}
|
||||
|
||||
.site-footer__links {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: var(--space-md);
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
/* ======================================================================
|
||||
BOUTON RETOUR EN HAUT
|
||||
====================================================================== */
|
||||
|
||||
.to-top {
|
||||
position: fixed;
|
||||
inset-block-end: var(--space-lg);
|
||||
inset-inline-end: var(--space-lg);
|
||||
z-index: var(--z-overlay);
|
||||
display: grid;
|
||||
place-items: center;
|
||||
inline-size: var(--tap-target);
|
||||
block-size: var(--tap-target);
|
||||
background-color: var(--color-surface);
|
||||
border: 1px solid var(--color-line-strong);
|
||||
border-radius: var(--radius-full);
|
||||
box-shadow: var(--shadow-md);
|
||||
color: var(--color-ink-soft);
|
||||
|
||||
/* Masqué par défaut : révélé par JS après défilement.
|
||||
visibility (et non display) pour permettre la transition. */
|
||||
opacity: 0;
|
||||
visibility: hidden;
|
||||
transform: translateY(0.5rem);
|
||||
transition: opacity var(--transition-base),
|
||||
transform var(--transition-base),
|
||||
visibility var(--transition-base);
|
||||
}
|
||||
|
||||
.to-top[data-visible="true"] {
|
||||
opacity: 1;
|
||||
visibility: visible;
|
||||
transform: translateY(0);
|
||||
}
|
||||
|
||||
.to-top:hover {
|
||||
color: var(--color-accent-dark);
|
||||
border-color: var(--color-accent);
|
||||
}
|
||||
|
||||
/* ======================================================================
|
||||
POINT DE RUPTURE MOBILE
|
||||
Une seule media query pour toute la mise en page : le reste est fluide.
|
||||
Écrite en syntaxe de plage (width <= 46rem), lisible et sans le
|
||||
traditionnel « max-width: 45.999rem ».
|
||||
====================================================================== */
|
||||
|
||||
@media (width <= 46rem) {
|
||||
|
||||
.nav-toggle { display: inline-flex; }
|
||||
|
||||
.site-header__inner { position: relative; }
|
||||
|
||||
/* Le menu devient un panneau déroulant sous l'en-tête */
|
||||
.site-nav {
|
||||
position: absolute;
|
||||
inset-block-start: 100%;
|
||||
inset-inline: calc(var(--gutter) * -1);
|
||||
display: none;
|
||||
background-color: var(--color-surface);
|
||||
border-block-end: 1px solid var(--color-line);
|
||||
box-shadow: var(--shadow-md);
|
||||
}
|
||||
|
||||
.site-nav[data-open="true"] { display: block; }
|
||||
|
||||
.site-nav__list {
|
||||
flex-direction: column;
|
||||
align-items: stretch;
|
||||
gap: 0;
|
||||
padding: var(--space-xs) var(--gutter) var(--space-md);
|
||||
}
|
||||
|
||||
.site-nav__link {
|
||||
/* Hauteur de cible tactile conforme (44px minimum) */
|
||||
display: flex;
|
||||
align-items: center;
|
||||
min-block-size: var(--tap-target);
|
||||
padding-inline-start: var(--space-xs);
|
||||
border-block-end: 1px solid var(--color-line);
|
||||
border-inline-start: 2px solid transparent;
|
||||
}
|
||||
|
||||
/* Le repère de section active passe du bas au côté */
|
||||
.site-nav__link[aria-current="true"] {
|
||||
border-block-end-color: var(--color-line);
|
||||
border-inline-start-color: var(--color-accent);
|
||||
background-color: var(--color-accent-glow);
|
||||
}
|
||||
|
||||
.masthead { padding-block: var(--space-2xl) var(--space-xl); }
|
||||
.section { padding-block: var(--space-2xl); }
|
||||
|
||||
.to-top {
|
||||
inset-block-end: var(--space-md);
|
||||
inset-inline-end: var(--space-md);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user