Peels

Démarrer

Un fichier CSS, un attribut sur <html>, du HTML sémantique. Aucune dépendance.

Les fichiers

peels.css

Tout Peels + le thème livré. L'usage standard — ~140 Ko.

peels-extended.css

Le même + tous les thèmes optionnels (couleur, typographie, densité) — pour un sélecteur de thème.

Le minimum

Le <link> charge Peels ; data-theme="peels" active le thème livré. Sans l'attribut, le socle reste à l'état vide (voir plus bas). Votre CSS vit dans un second fichier : non-layeré, il gagne toujours.

<!doctype html>
<html lang="fr" data-theme="peels">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="stylesheet" href="peels.css">
  <link rel="stylesheet" href="site.css">
</head>
<body>
  <h1>Titre</h1>
  <p>Du HTML sémantique, rendu propre.</p>
  <button>Action</button>
</body>
</html>
  • data-theme-mode="dark" ou "light" force le schéma — sinon light-dark() suit l'OS. Fonctionne aussi à l'état vide.
  • data-icon="…" — icônes en CSS pur, aucune police.

L'état vide

Sans data-theme, aucune règle du layer theme ne s'applique : gris pur, police système. La toile vierge pour écrire votre propre thème, sous votre propre valeur d'attribut.

<html>                 <!-- état vide : socle seul -->
<html data-theme="peels">  <!-- thème livré -->

Un contexte précis

Les rôles --peels-* se posent globalement ou sur un contexte et héritent : ici, fond crème et filets accentués partout, et seuls les boutons de l'aside deviennent des pilules plus grosses.

/* site.css */
@layer theme {
  :root {
    --peels-surface-page: light-dark(#fbf7ef, #181a20);
    --peels-component-radius: 0.65rem;
    --peels-blockquote-border: var(--peels-border-accent);
    --peels-hr-color: var(--peels-border-accent);
  }
  /* Un contexte pose les variables sur lui-même : seuls les
     boutons de l'encadré deviennent des pilules plus grosses. */
  aside {
    --peels-component-radius: 99px;
    --peels-btn-font-scale: 1;
    --peels-btn-min-height: 4rem;
  }
}

Vos trois couleurs

L'identité se pose dans @layer theme — le layer où Peels range ses thèmes. Les paires light-dark() règlent clair et sombre d'un coup ; le socle dérive survols, fonds doux et bordures. Les rôles --peels-font-* se règlent de la même façon.

/* site.css — vos 3 couleurs + votre rampe neutre */
@layer theme {
  :root {
    --brand:  light-dark(oklch(0.55 0.19 150), oklch(0.72 0.17 155));
    --action: light-dark(oklch(0.50 0.19 215), oklch(0.70 0.15 215));
    --accent: light-dark(oklch(0.58 0.19 330), oklch(0.74 0.15 335));

    --neutral-bg:          light-dark(#f6f9f7, #101713);
    --neutral-bg-elevated: light-dark(#ffffff, #1a231e);
    --neutral-bg-sunken:   light-dark(#e9f0ec, #0c120f);
    --neutral-text:        light-dark(#1c2620, #eaf2ed);
    --neutral-text-muted:  light-dark(#59695f, #a4b3a9);
    --neutral-border:      light-dark(#d3e0d8, #2f3d35);
  }
}

Au-delà des variables

Quand aucune variable ne suffit : votre CSS non-layeré gagne toujours. Étendez un élément (article) ou construisez le vôtre ([data-timeline]) en vous appuyant sur les rôles --peels-* — il suit le thème et le clair/sombre comme un natif.

/* site.css — non layeré : gagne toujours */
article:hover {
  translate: 0 -2px;
  box-shadow: var(--peels-elevation-2);
}

/* Élément maison appuyé sur le contrat */
[data-timeline] {
  --_tl-line: var(--peels-border-subtle);
  --_tl-dot: var(--peels-border-accent);

  padding-inline-start: 1.6rem;
  list-style: none;
  position: relative;
}
[data-timeline]::before {
  content: "";
  position: absolute;
  inset-block: 0.5em;
  border-inline-start: 2px solid var(--_tl-line);
}
[data-timeline] > li::before {
  content: "";
  position: absolute;
  inline-size: 0.8rem;
  block-size: 0.8rem;
  inset-inline-start: -1.5rem;
  inset-block-start: 0.6em;
  border-radius: 50%;
  background: var(--_tl-dot);
}