456 lines
12 KiB
CSS
456 lines
12 KiB
CSS
/* ==========================================================================
|
|
components.css — Blocs réutilisables
|
|
--------------------------------------------------------------------------
|
|
Nomenclature BEM : .bloc, .bloc__element, .bloc--modificateur.
|
|
Intérêt : la spécificité reste plate (une classe = 0,1,0), le nom dit
|
|
à quoi appartient l'élément, et aucun style ne fuit hors de son bloc.
|
|
========================================================================== */
|
|
|
|
@layer components {
|
|
|
|
/* ======================================================================
|
|
EYEBROW — étiquette au-dessus d'un titre
|
|
====================================================================== */
|
|
|
|
.eyebrow {
|
|
display: block;
|
|
font-family: var(--font-mono);
|
|
font-size: var(--text-xs);
|
|
letter-spacing: 0.04em;
|
|
color: var(--color-accent-dark);
|
|
margin-block-end: var(--space-md);
|
|
}
|
|
|
|
/* Le prompt de terminal est purement décoratif : généré en CSS, il
|
|
n'est donc pas lu par les lecteurs d'écran ni copié avec le texte. */
|
|
.eyebrow::before {
|
|
content: ">_ ";
|
|
color: var(--color-accent);
|
|
}
|
|
|
|
/* ======================================================================
|
|
TITRES
|
|
====================================================================== */
|
|
|
|
.page-title {
|
|
font-size: var(--text-2xl);
|
|
letter-spacing: -0.03em;
|
|
margin-block-end: var(--space-sm);
|
|
}
|
|
|
|
.page-subtitle {
|
|
font-family: var(--font-mono);
|
|
font-size: var(--text-md);
|
|
font-weight: var(--weight-regular);
|
|
line-height: var(--leading-snug);
|
|
color: var(--color-ink-soft);
|
|
max-inline-size: 40ch;
|
|
margin-block-end: var(--space-lg);
|
|
}
|
|
|
|
.section-title {
|
|
font-size: var(--text-xl);
|
|
margin-block-end: var(--space-xl);
|
|
scroll-margin-block-start: calc(var(--header-height) + var(--space-lg));
|
|
}
|
|
|
|
.section-title::before {
|
|
content: ">_ ";
|
|
color: var(--color-accent);
|
|
}
|
|
|
|
/* ======================================================================
|
|
LISTE DE CONTACTS
|
|
====================================================================== */
|
|
|
|
.contact-list {
|
|
display: flex;
|
|
flex-wrap: wrap;
|
|
gap: var(--space-xs) var(--space-lg);
|
|
list-style: none;
|
|
margin: 0;
|
|
padding: 0;
|
|
font-family: var(--font-mono);
|
|
font-size: var(--text-sm);
|
|
color: var(--color-ink-faint);
|
|
}
|
|
|
|
.contact-list li {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
gap: var(--space-2xs);
|
|
}
|
|
|
|
.contact-list__icon {
|
|
inline-size: 0.95rem;
|
|
block-size: 0.95rem;
|
|
stroke: var(--color-accent);
|
|
stroke-width: 1.8;
|
|
fill: none;
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
/* ======================================================================
|
|
BOUTONS D'ACTION
|
|
Deux niveaux seulement : principal (plein) et secondaire (contour).
|
|
Au-delà, la hiérarchie visuelle devient illisible.
|
|
====================================================================== */
|
|
|
|
.actions {
|
|
display: flex;
|
|
flex-wrap: wrap;
|
|
gap: var(--space-sm);
|
|
margin-block-start: var(--space-lg);
|
|
}
|
|
|
|
.button {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
gap: var(--space-xs);
|
|
min-block-size: var(--tap-target);
|
|
padding-inline: var(--space-md);
|
|
font-family: var(--font-mono);
|
|
font-size: var(--text-sm);
|
|
font-weight: var(--weight-medium);
|
|
text-decoration: none;
|
|
border-radius: var(--radius-md);
|
|
border: 1px solid transparent;
|
|
transition: background-color var(--transition-fast),
|
|
border-color var(--transition-fast),
|
|
color var(--transition-fast);
|
|
}
|
|
|
|
.button__icon {
|
|
inline-size: 1rem;
|
|
block-size: 1rem;
|
|
stroke: currentcolor;
|
|
stroke-width: 1.9;
|
|
fill: none;
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
.button--primary {
|
|
background-color: var(--color-accent-dark);
|
|
color: var(--color-ink-inverse);
|
|
}
|
|
|
|
.button--primary:hover {
|
|
background-color: var(--color-ink);
|
|
color: var(--color-ink-inverse);
|
|
}
|
|
|
|
.button--secondary {
|
|
background-color: var(--color-surface);
|
|
border-color: var(--color-line-strong);
|
|
color: var(--color-ink-soft);
|
|
}
|
|
|
|
.button--secondary:hover {
|
|
border-color: var(--color-accent);
|
|
color: var(--color-accent-dark);
|
|
}
|
|
|
|
/* ======================================================================
|
|
INTRODUCTION
|
|
====================================================================== */
|
|
|
|
.intro { padding-block: var(--space-2xl) var(--space-xl); }
|
|
|
|
.intro__heading {
|
|
font-size: var(--text-lg);
|
|
line-height: var(--leading-snug);
|
|
max-inline-size: 34ch;
|
|
margin-block-end: var(--space-lg);
|
|
}
|
|
|
|
.intro__text {
|
|
color: var(--color-ink-soft);
|
|
max-inline-size: var(--width-prose);
|
|
margin-block-end: var(--space-md);
|
|
}
|
|
|
|
.intro__text strong {
|
|
color: var(--color-ink);
|
|
font-weight: var(--weight-semibold);
|
|
}
|
|
|
|
/* Dernier paragraphe mis en exergue par un filet latéral plutôt que par
|
|
un fond coloré : plus sobre, et imprimable sans consommer d'encre. */
|
|
.intro__text--highlight {
|
|
border-inline-start: 3px solid var(--color-accent);
|
|
padding-inline-start: var(--space-lg);
|
|
color: var(--color-ink);
|
|
}
|
|
|
|
/* ======================================================================
|
|
ENTRÉE DE PARCOURS (timeline)
|
|
====================================================================== */
|
|
|
|
.entry {
|
|
position: relative;
|
|
padding-inline-start: var(--space-lg);
|
|
padding-block-end: var(--space-xl);
|
|
border-inline-start: 2px solid var(--color-line);
|
|
}
|
|
|
|
/* La dernière entrée ne prolonge pas le trait dans le vide */
|
|
.entry:last-child {
|
|
padding-block-end: 0;
|
|
border-inline-start-color: transparent;
|
|
}
|
|
|
|
/* Pastille de jalon. Décorative : aucune information n'en dépend. */
|
|
.entry::before {
|
|
content: "";
|
|
position: absolute;
|
|
inset-inline-start: -7px;
|
|
inset-block-start: 0.55rem;
|
|
inline-size: 12px;
|
|
block-size: 12px;
|
|
border-radius: 50%;
|
|
background-color: var(--color-bg);
|
|
border: 2px solid var(--color-accent);
|
|
}
|
|
|
|
.entry__date {
|
|
display: block;
|
|
font-family: var(--font-mono);
|
|
font-size: var(--text-xs);
|
|
font-weight: var(--weight-medium);
|
|
color: var(--color-accent-dark);
|
|
margin-block-end: var(--space-2xs);
|
|
}
|
|
|
|
.entry__role {
|
|
font-size: var(--text-md);
|
|
margin-block-end: var(--space-2xs);
|
|
}
|
|
|
|
.entry__org {
|
|
font-family: var(--font-mono);
|
|
font-size: var(--text-sm);
|
|
color: var(--color-ink-faint);
|
|
margin-block-end: var(--space-md);
|
|
}
|
|
|
|
.entry__note {
|
|
color: var(--color-ink-soft);
|
|
font-size: var(--text-sm);
|
|
max-inline-size: var(--width-prose);
|
|
}
|
|
|
|
/* ======================================================================
|
|
FICHE DE COURS
|
|
====================================================================== */
|
|
|
|
.course {
|
|
background-color: var(--color-surface);
|
|
border: 1px solid var(--color-line);
|
|
border-radius: var(--radius-md);
|
|
padding: var(--space-md);
|
|
margin-block-end: var(--space-xs);
|
|
transition: border-color var(--transition-base);
|
|
}
|
|
|
|
.course:last-child { margin-block-end: 0; }
|
|
.course:hover { border-color: var(--color-line-strong); }
|
|
|
|
.course__name {
|
|
display: block;
|
|
font-family: var(--font-mono);
|
|
font-size: var(--text-sm);
|
|
font-weight: var(--weight-bold);
|
|
margin-block-end: var(--space-2xs);
|
|
}
|
|
|
|
.course__name::before {
|
|
content: "▪ ";
|
|
color: var(--color-accent);
|
|
}
|
|
|
|
.course__desc {
|
|
font-size: var(--text-sm);
|
|
color: var(--color-ink-soft);
|
|
line-height: 1.65;
|
|
}
|
|
|
|
/* ======================================================================
|
|
LISTE À PUCES PERSONNALISÉE
|
|
Puce en ::before plutôt que list-style-image : couleur pilotable par
|
|
variable, alignement contrôlé au pixel.
|
|
====================================================================== */
|
|
|
|
.marker-list {
|
|
list-style: none;
|
|
margin: 0;
|
|
padding: 0;
|
|
color: var(--color-ink-soft);
|
|
font-size: var(--text-sm);
|
|
}
|
|
|
|
.marker-list li {
|
|
position: relative;
|
|
padding-inline-start: var(--space-md);
|
|
margin-block-end: var(--space-xs);
|
|
}
|
|
|
|
.marker-list li:last-child { margin-block-end: 0; }
|
|
|
|
.marker-list li::before {
|
|
content: "▪";
|
|
position: absolute;
|
|
inset-inline-start: 0;
|
|
color: var(--color-accent);
|
|
}
|
|
|
|
/* ======================================================================
|
|
CARTE
|
|
====================================================================== */
|
|
|
|
.card {
|
|
background-color: var(--color-surface);
|
|
border: 1px solid var(--color-line);
|
|
border-radius: var(--radius-md);
|
|
padding: var(--space-lg);
|
|
box-shadow: var(--shadow-sm);
|
|
transition: border-color var(--transition-base),
|
|
transform var(--transition-base),
|
|
box-shadow var(--transition-base);
|
|
}
|
|
|
|
.card:hover {
|
|
border-color: var(--color-accent);
|
|
transform: translateY(-2px);
|
|
box-shadow: var(--shadow-md);
|
|
}
|
|
|
|
.card__title {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: var(--space-xs);
|
|
font-size: var(--text-base);
|
|
margin-block-end: var(--space-sm);
|
|
}
|
|
|
|
.card__icon {
|
|
inline-size: 1.1rem;
|
|
block-size: 1.1rem;
|
|
stroke: var(--color-accent);
|
|
stroke-width: 1.8;
|
|
fill: none;
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
/* ======================================================================
|
|
PROJET
|
|
====================================================================== */
|
|
|
|
.project {
|
|
background-color: var(--color-surface);
|
|
border: 1px solid var(--color-line);
|
|
border-radius: var(--radius-md);
|
|
padding: var(--space-lg);
|
|
margin-block-end: var(--space-sm);
|
|
transition: border-color var(--transition-base);
|
|
}
|
|
|
|
.project:last-child { margin-block-end: 0; }
|
|
.project:hover { border-color: var(--color-line-strong); }
|
|
|
|
.project__header {
|
|
display: flex;
|
|
flex-wrap: wrap;
|
|
align-items: baseline;
|
|
gap: var(--space-2xs) var(--space-sm);
|
|
margin-block-end: var(--space-xs);
|
|
}
|
|
|
|
.project__title { font-size: var(--text-base); }
|
|
|
|
.project__desc {
|
|
color: var(--color-ink-soft);
|
|
font-size: var(--text-sm);
|
|
max-inline-size: var(--width-prose);
|
|
}
|
|
|
|
.project__desc + .project__desc { margin-block-start: var(--space-xs); }
|
|
|
|
.project__stack {
|
|
display: flex;
|
|
flex-wrap: wrap;
|
|
gap: var(--space-2xs);
|
|
list-style: none;
|
|
margin: var(--space-sm) 0 0;
|
|
padding: 0;
|
|
}
|
|
|
|
.project__stack li {
|
|
font-family: var(--font-mono);
|
|
font-size: var(--text-2xs);
|
|
color: var(--color-ink-faint);
|
|
background-color: var(--color-surface-alt);
|
|
border-radius: var(--radius-sm);
|
|
padding: 2px var(--space-xs);
|
|
}
|
|
|
|
/* ======================================================================
|
|
BADGE
|
|
====================================================================== */
|
|
|
|
.badge {
|
|
font-family: var(--font-mono);
|
|
font-size: var(--text-xs);
|
|
font-weight: var(--weight-medium);
|
|
color: var(--color-accent-dark);
|
|
background-color: var(--color-accent-wash);
|
|
border: 1px solid var(--color-accent-border);
|
|
border-radius: var(--radius-sm);
|
|
padding: 2px var(--space-xs);
|
|
white-space: nowrap;
|
|
}
|
|
|
|
/* Variante neutre : signale un état non abouti sans l'emphase de l'accent */
|
|
.badge--muted {
|
|
color: var(--color-ink-faint);
|
|
background-color: var(--color-surface-alt);
|
|
border-color: var(--color-line-strong);
|
|
}
|
|
|
|
/* ======================================================================
|
|
FORMATION
|
|
====================================================================== */
|
|
|
|
.education {
|
|
border-inline-start: 2px solid var(--color-line);
|
|
padding-inline-start: var(--space-lg);
|
|
}
|
|
|
|
.education__degree {
|
|
font-size: var(--text-base);
|
|
margin-block-end: var(--space-2xs);
|
|
}
|
|
|
|
.education__school {
|
|
font-family: var(--font-mono);
|
|
font-size: var(--text-sm);
|
|
color: var(--color-ink-faint);
|
|
}
|
|
|
|
/* ======================================================================
|
|
BLOC DE CONTACT (appel à l'action de fin de page)
|
|
====================================================================== */
|
|
|
|
.contact-block {
|
|
background-color: var(--color-surface);
|
|
border: 1px solid var(--color-line);
|
|
border-radius: var(--radius-md);
|
|
padding: var(--space-xl);
|
|
}
|
|
|
|
.contact-block__text {
|
|
color: var(--color-ink-soft);
|
|
max-inline-size: var(--width-prose);
|
|
}
|
|
}
|