/* ========================================================================== 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); } }