‹ retour au site
labo de thèmes

composants

Bibliothèque de composants

Tout ce site est construit avec ces pièces. Les atomes forment des molécules, les molécules des organismes, et les organismes remplissent les gabarits de page. Change de thème en haut et regarde tout changer.

Fondations

tokens.*.css

Design tokens

Les composants ne touchent jamais une couleur brute. Un thème définit les tokens de base, les tokens sémantiques leur donnent un rôle, et les tokens de composant règlent chaque pièce. Change une valeur en bas et elle remonte jusqu’en haut.

  1. base --color-primary défini par le thème
  2. sémantique --primary ce que ça veut dire
  3. composant --btn-primary-bg où ça va
  1. base --color-base-000 défini par le thème
  2. sémantique --surface-sunken ce que ça veut dire
  3. composant --tag-bg où ça va
  4. Tag
global.css

Couches de cascade

Les styles s’empilent en trois couches, pour qu’un composant puisse toujours restyler ses atomes avec une simple classe.

  1. @layer basereset + utilitaires
  2. @layer uiatomes + molécules
  3. (unlayered)composants + pages, hors couche, donc ils gagnent toujours

Atomes

Les plus petites pièces. Chacune fait une seule chose et ne lit que des tokens.

ui/Button.astro

Button

Liens et actions. Sa surface vient des tokens de contrôles, donc un seul réglage du thème rend tous les boutons plats, biseautés ou arrondis.

Props

PropTypeDéfaut
variant?default (outlined), primary (filled), portal (glowing accent, for the loft), danger (destructive) 'default' | 'primary' | 'portal' | 'danger' 'default'
size?md for page CTAs, sm for dense tool UIs, icon for a single glyph 'md' | 'sm' | 'icon' 'md'
block?fill the container's width boolean –
icon?a pixelarticons name, drawn before the label string –

Plus tous les attributs natifs de <button> / <a>.

Tokens lus

composant
--fs-* --sp-* --ctl-border --ctl-radius --btn-bg --btn-fg --ctl-shadow --ctl-lift-hover --ctl-shadow-hover --btn-hover-border --btn-hover-fg --ctl-press --ctl-shadow-active --btn-primary-bg --btn-primary-fg --btn-primary-hover-bg
sémantique
--font-pixel --error --accent --foreground --secondary

Utilisation

<Button variant="primary" icon="mail" href="#contact">email me</Button>
<Button size="sm" block data-save>save</Button>
ui/Tag.astro

Tag

Petites étiquettes dans un creux : la techno d’une carte, ou un compteur.

React 19 WebRTC Rust 25 8

Props

PropTypeDéfaut
variant? 'label' | 'count' 'label'
hot? boolean –

Plus tous les attributs natifs de <span>.

Tokens lus

composant
--sink-border --sink-radius --tag-fg --tag-bg --sink-shadow --fs-* --sp-*
sémantique
--font-pixel --warning --on-warning

Utilisation

<Tag>WebRTC</Tag>
<Tag variant="count" hot>8</Tag>
ui/Badge.astro

Badge

Un statut dans une couleur pleine, avec par-dessus le texte lisible propre à cette couleur.

Livré Échec En revue En ligne

Props

PropTypeDéfaut
tone 'success' | 'error' | 'warning' | 'info' –

Plus tous les attributs natifs de <span>.

Tokens lus

composant
--fs-* --sp-* --sink-radius
sémantique
--font-pixel --success --on-success --error --on-error --warning --on-warning --info --on-info

Utilisation

<Badge tone="success">shipped</Badge>
ui/Chip.astro

Chip

Un mot dans un creux, plus grand et plus simple qu’une étiquette. Ceux qu’on peut retirer ont un ×.

TypeScript WebRTC AT Protocol atproto webrtc

Props

PropTypeDéfaut
removable? boolean –

Plus tous les attributs natifs de <span>.

Tokens lus

composant
--fs-* --sp-* --sink-border --sink-radius --sink-shadow --tag-bg
sémantique
--foreground-dim --surface-sunken --font-pixel --foreground --foreground-faint

Utilisation

<Chip>TypeScript</Chip>
<Chip removable>atproto</Chip>
ui/Field.astro

Field

Un champ de texte avec un glyphe au bord. Une erreur rend la bordure rouge.

Props

PropTypeDéfaut
icon string –
type? 'text' | 'search' | 'password' | 'email' | 'url' 'text'
placeholder? string –
name? string –
inputDir? 'ltr' | 'rtl' | 'auto' –
error? boolean –

Plus tous les attributs natifs de <label>.

Tokens lus

composant
--sp-* --fs-* --sink-border --sink-shadow --sink-radius
sémantique
--foreground-faint --foreground --surface-sunken --primary --error

Utilisation

<Field icon="@" placeholder="handle.bsky.social" />
<Field icon="⚿" type="password" error />
ui/Switch.astro

Switch

Un interrupteur construit sur une vraie case à cocher, donc le clavier et les formulaires marchent tout seuls.

Props

PropTypeDéfaut
label? string –

Plus tous les attributs natifs de <input>.

Tokens lus

composant
--sp-* --fs-* --ctl-radius
sémantique
--foreground-dim --surface-sunken --border-strong --foreground-faint --primary --on-accent --foreground

Utilisation

<Switch label="Scanlines" data-fx="--fx-scanline" />
ui/Segmented.astro

Segmented

Quelques options dont une seule peut être active. Celle choisie sort du creux.

Props

PropTypeDéfaut
options Option[] –
label string –

Plus tous les attributs natifs de <div>.

Construit avec

Tokens lus

composant
--sink-border --ctl-radius --fs-* --sp-*
sémantique
--surface-sunken --foreground-faint --surface --foreground --shadow-color

Utilisation

<Segmented label="Billing" options={[
  { label: 'Monthly' },
  { label: 'Yearly', pressed: true, badge: { text: '-20%', tone: 'warning' } },
]} />
ui/Eyebrow.astro

Eyebrow

La petite étiquette // au-dessus du titre d’une section.

sélection

Props

Aucune prop à lui.

Tokens lus

composant
--fs-* --sp-*
sémantique
--font-pixel --primary --foreground-faint

Utilisation

<Eyebrow>selected work</Eyebrow>

Molécules

Des atomes assemblés en une forme : une barre de fenêtre, une surface en relief.

ui/TitleBar.astro

TitleBar

La bande en haut d’une fenêtre : des points, un titre et un emplacement tout au bout. AIM en fait le dégradé bleu classique.

protoimsg.app 2025
now_playing.mod
// atproto · en direct ● en ligne

Props

PropTypeDéfaut
size?md on cards, sm on dense tool windows and dialogs 'md' | 'sm' 'md'
dots? boolean –

Plus tous les attributs natifs de <div>.

Tokens lus

composant
--sp-* --titlebar-bg --fs-* --titlebar-fg --ctl-radius --titlebar-accent
sémantique
--border --font-pixel --foreground-faint
du parent
--ac

Utilisation

<TitleBar dots>
  protoimsg.app
  <span slot="end">2025</span>
</TitleBar>
ui/Panel.astro

Panel

La surface en relief sur laquelle reposent toutes les cartes et fenêtres. Raised pour ce qu’on utilise, flat pour le contenu d’appui, lift pour les liens.

raised
flat
lift · survole-moi
window.txt

Panel + TitleBar

Props

PropTypeDéfaut
as? 'div' | 'article' | 'section' | 'aside' 'div'
elevation? 'raised' | 'flat' 'raised'
lift? boolean –

Plus tous les attributs natifs de <div>.

Tokens lus

composant
--card-bg --raise-border --raise-radius --raise-pad --raise-shadow --raise-shadow-static --lift-hover --raise-shadow-hover --card-border-hover

Utilisation

<Panel as="article" lift>
  <TitleBar dots>window.txt</TitleBar>
  …
</Panel>

Organismes

Des parties entières et reconnaissables du site, faites de molécules et d’atomes.

ProjectCard.astro

ProjectCard

Un Panel avec une TitleBar, un texte, des Tags et des liens. Toute la carte mène à son premier lien.

protoimsg.app 2025

protoIM

Fondateur & ingénieur principal · 2025–aujourd’hui

proto Instant Messenger — appels vidéo open source et multiplateformes sur l’AT Protocol : gratuits, sans compte obligatoire, en alternative à l’enfermement de FaceTime. Un monorepo TypeScript de 8 packages (~65K LOC) qui livre une seule plateforme temps réel sur le web (React 19), le desktop (Tauri v2 / Rust) et le mobile (Expo). Signalisation WebRTC faite main avec identifiants TURN à durée limitée sur un coturn auto-hébergé, SFU LiveKit pour les appels de groupe, Lexicons app.protoimsg.chat.* sur mesure, un indexeur Jetstream et 5 services Fly.io — dont un PDS auto-hébergé et la traduction en direct NLLB-200 dans ~17 langues.

React 19 WebRTC Tauri v2 Rust Expo LiveKit PDS Fly.io

Props

PropTypeDéfaut
project Project –

Construit avec

Tokens lus

composant
--sp-* --fs-*
sémantique
--primary --font-body --font-display --font-pixel --foreground-faint --foreground-dim --foreground

Utilisation

{featured(m).map((project) => <ProjectCard project={project} />)}
MiniCard.astro

MiniCard

Un Panel plat pour les petits projets.

nosky

Créateur & ingénieur principal · 2026

Client social ATProto (Expo/RN) qui contourne l’AppView centralisée — interroge directement les serveurs PDS suivis, avec fusion/tri côté client, sur la stack Microcosm (Slingshot, Constellation, Spacedust).

Props

PropTypeDéfaut
project MiniProject –

Construit avec

Tokens lus

composant
--sp-* --fs-*
sémantique
--font-display --info --font-pixel --foreground-faint --foreground-dim --warning

Utilisation

<MiniCard project={project} />
ArcadeCabinet.astro

ArcadeCabinet

Un Panel déguisé en borne d’arcade, avec un écran jouable ou verrouillé.

FAST HOPPER
0
RECORD 0

HOPPER

Designer & ingénieur · en ligne

Un jeu de plateforme vertical — grimpe une échelle infinie de plateformes et vise le meilleur score. Tourne sur une simulation déterministe, donc chaque partie est vérifiable. Classements mondiaux par difficulté (fast / faster), et tes records sont écrits directement dans ton repo ATProto sous forme d’enregistrements actor.rpg.stats.

TypeScript Canvas Deterministic Sim ATProto Records Leaderboards

Props

PropTypeDéfaut
game Game –

Construit avec

Tokens lus

composant
--cabinet-from --cabinet-to --sink-shadow --screen-star --screen-bg --fs-* --screen-shadow --platform-from --platform-to --platform-edge --platform-hi --player-glow --sp-* --locked-from --locked-to
sémantique
--primary --border --scanline-color-screen --font-pixel --foreground --foreground-dim --font-display --foreground-faint

Utilisation

<ArcadeCabinet game={game} />
AtStatusCard.astro

AtStatusCard

Mon statut Bluesky en direct, lu dans mon repo AT Protocol au chargement de la page.

Props

Aucune prop à lui.

Construit avec

Tokens lus

composant
--fs-* --titlebar-accent --sp-* --sink-radius
sémantique
--success --primary --surface-sunken --shadow-color-soft --font-display --foreground --info --border --font-pixel --foreground-faint

Utilisation

<AtStatusCard />
FeedbackForm.astro

FeedbackForm

Un Button qui ouvre un tiroir : une TitleBar au-dessus d’un formulaire, et sur mobile une feuille qu’on glisse pour fermer.

laisse un mot

Props

Aucune prop à lui.

Construit avec

Tokens lus

composant
--sp-* --fs-* --sink-border --sink-shadow --sink-radius
sémantique
--foreground --surface-sunken --foreground-faint --primary --foreground-dim --success --error

Utilisation

<FeedbackForm />

Gabarits

Les cadres dans lesquels les pages versent leur contenu.

Section.astro

Section

Chaque section de l’accueil : un Eyebrow, un titre, puis ce qu’il y a dedans.

sélection

Projets.

Cette boîte est une Section.

Props

PropTypeDéfaut
id? string –
eyebrow? string –
title? string –

Construit avec

Tokens lus

Aucun à lui. Ses atomes apportent les leurs.

Utilisation

<Section id="work" eyebrow="selected work" title="Things I've built">
  …
</Section>