Aller au contenu
Bibliotheque UIJABS

Cartes 17 variantes

Une carte est un objet cliquable dans une liste d'objets comparables. Si le contenu n'est pas comparable a ses voisins, ce n'est pas une carte, c'est un panneau. Regle tenue partout : une seule zone cliquable principale par carte, jamais un lien dans un lien.

A. Cartes de base

Le socle et ses declinaisons : cliquable, avec image, horizontale, coloree, selectionnable.

Pompe a chaleur air/eau

Remplacement d'une chaudiere fioul par une PAC 11 kW, avec depose et evacuation de la cuve.

Carte simple

Le socle. Titre, texte, pied d'actions. Tout le reste de ce fichier en derive.

Voir le codeMasquer le code
<div class="carte" style="max-width:320px">
  <div class="carte__corps">
    <h3 class="carte__titre">Pompe a chaleur air/eau</h3>
    <p class="carte__texte">Remplacement d'une chaudiere fioul par une PAC 11 kW, avec depose et evacuation de la cuve.</p>
  </div>
  <div class="carte__pied"><button class="btn btn--secondaire btn--sm">Detail</button><button class="btn btn--plein btn--sm">Choisir</button></div>
</div>
/* voir le socle .carte en haut du fichier */
flex flex-col rounded-xl border bg-white [&>div:last-child]:border-t [&>div:last-child]:bg-slate-50
Carte cliquable

Toute la carte est un lien. Un seul element interactif : imbriquer un bouton dans un lien casse la navigation au clavier.

Voir le codeMasquer le code
<div class="cartes-grille">
  <a href="#" class="carte carte--lien">
    <div class="carte__corps">
      <h3 class="carte__titre">Dossier 2026-103</h3>
      <p class="carte__texte">Neuilly-sur-Marne (93) - pose prevue le 24 septembre</p>
      <span class="carte__fleche">Ouvrir le dossier <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M5 12h14M13 5l7 7-7 7"/></svg></span>
    </div>
  </a>
  <a href="#" class="carte carte--lien">
    <div class="carte__corps">
      <h3 class="carte__titre">Dossier 2026-118</h3>
      <p class="carte__texte">Colombes (92) - devis envoye, en attente de signature</p>
      <span class="carte__fleche">Ouvrir le dossier <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M5 12h14M13 5l7 7-7 7"/></svg></span>
    </div>
  </a>
</div>
.carte--lien {
  text-decoration: none;
  color: inherit;
  transition: transform var(--t-base), box-shadow var(--t-base), border-color var(--t-fast);
}
.carte--lien:hover { transform: translateY(-2px); border-color: var(--c-primary); box-shadow: var(--sh-2); }
.carte--lien:focus-visible { outline: 2px solid var(--c-focus); outline-offset: 2px; }
.carte__fleche {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin-top: auto;
  padding-top: var(--sp-2);
  font-size: var(--fs-sm);
  font-weight: var(--fw-semi);
  color: var(--c-primary-ink);
}
.carte__fleche svg { width: 15px; height: 15px; transition: transform var(--t-base); }
.carte--lien:hover .carte__fleche svg { transform: translateX(4px); }
group block transition hover:-translate-y-0.5 hover:border-blue-500 hover:shadow-md
Termine
Pompe a chaleur

Maison 112 m2 a Neuilly

Depose fioul, PAC 11 kW, 4 radiateurs remplaces.

Isolation

Combles perdus a Colombes

Soufflage laine de roche, R = 7.

Carte avec image

Realisation, article, produit. Le rapport de l'image est fixe : sans lui, les cartes d'une meme rangee ne s'alignent plus.

Voir le codeMasquer le code
<div class="cartes-grille">
  <article class="carte">
    <div class="carte__image doc-photo doc-photo--3"><span class="doc-etat doc-etat--ok">Termine</span></div>
    <div class="carte__corps">
      <span class="carte__sur">Pompe a chaleur</span>
      <h3 class="carte__titre">Maison 112 m2 a Neuilly</h3>
      <p class="carte__texte">Depose fioul, PAC 11 kW, 4 radiateurs remplaces.</p>
    </div>
  </article>
  <article class="carte">
    <div class="carte__image doc-photo doc-photo--2"></div>
    <div class="carte__corps">
      <span class="carte__sur">Isolation</span>
      <h3 class="carte__titre">Combles perdus a Colombes</h3>
      <p class="carte__texte">Soufflage laine de roche, R = 7.</p>
    </div>
  </article>
</div>
.carte__image { position: relative; aspect-ratio: 16 / 10; background-size: cover; background-position: center; }
.carte__sur {
  font-size: 11px;
  font-weight: var(--fw-bold);
  text-transform: uppercase;
  letter-spacing: .06em;
  color: var(--c-primary-ink);
}
aspect-[16/10] w-full object-cover

Chauffe-eau thermodynamique 200 L

Classe A+, COP 3,2. Eligible MaPrimeRenov et CEE.

1 890 EUREn stock
Carte horizontale

Resultat de recherche, ligne de panier. Sur mobile elle repasse en vertical plutot que de comprimer l'image.

Voir le codeMasquer le code
<article class="carte carte--horizontale">
  <div class="carte__image doc-photo doc-photo--1"></div>
  <div class="carte__corps">
    <h3 class="carte__titre">Chauffe-eau thermodynamique 200 L</h3>
    <p class="carte__texte">Classe A+, COP 3,2. Eligible MaPrimeRenov et CEE.</p>
    <div class="carte__ligne"><strong class="carte__prix">1 890 EUR</strong><span class="doc-etiq doc-etiq--ok">En stock</span></div>
  </div>
</article>
.carte--horizontale { flex-direction: row; width: 100%; max-width: 480px; }
.carte--horizontale .carte__image { width: 150px; flex: none; aspect-ratio: auto; }
.carte__ligne { display: flex; align-items: center; gap: var(--sp-3); margin-top: auto; padding-top: var(--sp-2); }
.carte__prix { font-size: var(--fs-xl); font-weight: 800; letter-spacing: -.02em; color: var(--c-text); }
@media (max-width: 560px) {
  .carte--horizontale { flex-direction: column; }
  .carte--horizontale .carte__image { width: 100%; aspect-ratio: 16 / 9; }
}
flex flex-row max-sm:flex-col [&>div:first-child]:w-40 [&>div:first-child]:shrink-0
Chauffage

PAC air/eau

11 kW, monobloc

Isolation

Combles perdus

Soufflage, R = 7

Sanitaire

Chauffe-eau

200 L thermodynamique

Carte avec en-tete colore

Categoriser d'un coup d'oeil dans une grille : chaque famille sa teinte. La couleur double toujours un mot, jamais l'inverse.

Voir le codeMasquer le code
<div class="cartes-grille">
  <div class="carte"><div class="carte__bandeau">Chauffage</div><div class="carte__corps"><h3 class="carte__titre">PAC air/eau</h3><p class="carte__texte">11 kW, monobloc</p></div></div>
  <div class="carte"><div class="carte__bandeau carte__bandeau--vert">Isolation</div><div class="carte__corps"><h3 class="carte__titre">Combles perdus</h3><p class="carte__texte">Soufflage, R = 7</p></div></div>
  <div class="carte"><div class="carte__bandeau carte__bandeau--orange">Sanitaire</div><div class="carte__corps"><h3 class="carte__titre">Chauffe-eau</h3><p class="carte__texte">200 L thermodynamique</p></div></div>
</div>
.carte__bandeau {
  padding: 7px var(--sp-4);
  background: var(--c-primary);
  color: var(--c-primary-text);
  font-size: var(--fs-xs);
  font-weight: var(--fw-bold);
  text-transform: uppercase;
  letter-spacing: .05em;
}
.carte__bandeau--vert   { background: var(--c-success); }
.carte__bandeau--orange { background: var(--c-warn); }
.carte__bandeau--rouge  { background: var(--c-danger); }
border-t-4 border-t-blue-600
Carte selectionnable

Choix exclusif entre des offres decrites. Le radio reste present pour le clavier et les lecteurs d'ecran, meme s'il est masque visuellement.

Voir le codeMasquer le code
<div class="cartes-grille">
  <label class="carte carte--choix">
    <input type="radio" name="offre" checked>
    <div class="carte__corps">
      <span class="carte__coche"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m20 6-11 11-5-5"/></svg></span>
      <h3 class="carte__titre">Formule Essentielle</h3>
      <p class="carte__texte">Pose et mise en service, garantie 2 ans.</p>
      <strong class="carte__prix">4 280 EUR</strong>
    </div>
  </label>
  <label class="carte carte--choix">
    <input type="radio" name="offre">
    <div class="carte__corps">
      <span class="carte__coche"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m20 6-11 11-5-5"/></svg></span>
      <h3 class="carte__titre">Formule Serenite</h3>
      <p class="carte__texte">Pose, entretien annuel et garantie 5 ans.</p>
      <strong class="carte__prix">5 120 EUR</strong>
    </div>
  </label>
</div>
.carte--choix { cursor: pointer; transition: border-color var(--t-fast), box-shadow var(--t-fast); }
.carte--choix input { position: absolute; opacity: 0; width: 0; height: 0; }
.carte--choix .carte__corps { position: relative; }
.carte__coche {
  position: absolute;
  top: var(--sp-4); right: var(--sp-4);
  display: inline-flex; align-items: center; justify-content: center;
  width: 22px; height: 22px;
  border: 2px solid var(--c-border-strong);
  border-radius: var(--r-full);
  color: transparent;
}
.carte__coche svg { width: 13px; height: 13px; }
.carte--choix:hover { border-color: var(--c-border-strong); }
.carte--choix:has(input:checked) { border-color: var(--c-primary); box-shadow: 0 0 0 1px var(--c-primary); }
.carte--choix:has(input:checked) .carte__coche { background: var(--c-primary); border-color: var(--c-primary); color: #fff; }
.carte--choix:has(input:focus-visible) { outline: 2px solid var(--c-focus); outline-offset: 2px; }
has-[:checked]:border-blue-600 has-[:checked]:ring-1 has-[:checked]:ring-blue-600

B. Cartes de donnees

Tuiles de tableau de bord, jauges, personnes, dossiers. La variation porte toujours un signe et une fleche, jamais la couleur seule.

Chiffre d'affaires du mois 48 250 EUR +12,4 % vs aout
Devis en attente 17 -3 vs la semaine derniere
Taux de signature 62 % stable
Carte statistique

Tuile de tableau de bord. La variation porte un signe ET une fleche : lue en noir et blanc, la couleur seule ne dit rien.

Voir le codeMasquer le code
<div class="cartes-grille">
  <div class="carte stat">
    <span class="stat__label">Chiffre d'affaires du mois</span>
    <strong class="stat__valeur">48 250 EUR</strong>
    <span class="stat__delta is-hausse"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M12 19V5M5 12l7-7 7 7"/></svg> +12,4 % vs aout</span>
  </div>
  <div class="carte stat">
    <span class="stat__label">Devis en attente</span>
    <strong class="stat__valeur">17</strong>
    <span class="stat__delta is-baisse"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M12 19V5M5 12l7-7 7 7"/></svg> -3 vs la semaine derniere</span>
  </div>
  <div class="carte stat">
    <span class="stat__label">Taux de signature</span>
    <strong class="stat__valeur">62 %</strong>
    <span class="stat__delta">stable</span>
  </div>
</div>
.stat { padding: var(--sp-4); gap: 4px; }
.stat__label { font-size: var(--fs-sm); color: var(--c-text-muted); font-weight: var(--fw-medium); }
.stat__valeur { font-size: 28px; font-weight: 800; letter-spacing: -.03em; color: var(--c-text); font-variant-numeric: tabular-nums; }
.stat__delta {
  display: inline-flex; align-items: center; gap: 4px;
  font-size: var(--fs-xs); font-weight: var(--fw-semi); color: var(--c-text-muted);
}
.stat__delta svg { width: 13px; height: 13px; }
.stat__delta.is-hausse { color: var(--c-success); }
.stat__delta.is-baisse { color: var(--c-danger); }
.stat__delta.is-baisse svg { transform: rotate(180deg); }
flex flex-col gap-1 p-4 [&_strong]:text-3xl [&_strong]:font-extrabold [&_strong]:tabular-nums
Devis envoyes 34 +8 sur 30 jours
Interventions 12 -2 sur 30 jours
Carte statistique avec courbe

Meme tuile, plus la tendance. La courbe est decorative : le chiffre reste la seule information a lire.

Voir le codeMasquer le code
<div class="cartes-grille">
  <div class="carte stat stat--courbe">
    <span class="stat__label">Devis envoyes</span>
    <strong class="stat__valeur">34</strong>
    <span class="stat__delta is-hausse"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M12 19V5M5 12l7-7 7 7"/></svg> +8 sur 30 jours</span>
    <svg class="stat__courbe" viewBox="0 0 100 28" preserveAspectRatio="none" aria-hidden="true">
      <path d="M0 22 L14 19 L28 21 L42 12 L56 15 L70 7 L84 9 L100 2" fill="none" stroke="currentColor" stroke-width="2" vector-effect="non-scaling-stroke"/>
    </svg>
  </div>
  <div class="carte stat stat--courbe">
    <span class="stat__label">Interventions</span>
    <strong class="stat__valeur">12</strong>
    <span class="stat__delta is-baisse"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M12 19V5M5 12l7-7 7 7"/></svg> -2 sur 30 jours</span>
    <svg class="stat__courbe stat__courbe--baisse" viewBox="0 0 100 28" preserveAspectRatio="none" aria-hidden="true">
      <path d="M0 6 L14 9 L28 5 L42 14 L56 11 L70 18 L84 16 L100 23" fill="none" stroke="currentColor" stroke-width="2" vector-effect="non-scaling-stroke"/>
    </svg>
  </div>
</div>
.stat--courbe { position: relative; padding-bottom: var(--sp-8); overflow: hidden; }
.stat__courbe {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  height: 42px;
  color: var(--c-success);
  opacity: .45;
}
.stat__courbe--baisse { color: var(--c-danger); }
relative overflow-hidden [&_svg]:absolute [&_svg]:inset-x-0 [&_svg]:bottom-0 [&_svg]:h-10 [&_svg]:opacity-30
Objectif du trimestre 148 000 EUR
74 % de l'objectif - il reste 52 000 EUR
Dossiers complets 23 / 31
8 dossiers attendent une piece
Carte avec jauge

Une valeur rapportee a un objectif. Le reste a faire est plus utile que le pourcentage seul : c'est lui qui declenche l'action.

Voir le codeMasquer le code
<div class="cartes-grille">
  <div class="carte stat">
    <span class="stat__label">Objectif du trimestre</span>
    <strong class="stat__valeur">148 000 EUR</strong>
    <div class="stat__jauge"><span style="--p: 74%"></span></div>
    <span class="stat__delta">74 % de l'objectif - il reste 52 000 EUR</span>
  </div>
  <div class="carte stat">
    <span class="stat__label">Dossiers complets</span>
    <strong class="stat__valeur">23 / 31</strong>
    <div class="stat__jauge"><span class="is-alerte" style="--p: 74%"></span></div>
    <span class="stat__delta">8 dossiers attendent une piece</span>
  </div>
</div>
.stat__jauge { height: 8px; margin: 6px 0 4px; border-radius: var(--r-full); background: var(--c-surface-3); overflow: hidden; }
.stat__jauge span { display: block; height: 100%; width: var(--p, 0%); border-radius: inherit; background: var(--c-primary); transition: width var(--t-slow); }
.stat__jauge span.is-alerte { background: var(--c-warn); }
h-2 w-full rounded-full bg-slate-200 [&>span]:block [&>span]:h-full [&>span]:rounded-full
JK
Julien Krissi Gerant - JABS
SM
Sophie Martin Technicienne - equipe Nord
Carte de personne

Client, technicien, contact. Le moyen de contact est une action, pas un texte a recopier a la main.

Voir le codeMasquer le code
<div class="cartes-grille">
  <div class="carte personne">
    <span class="personne__avatar">JK</span>
    <div class="personne__corps">
      <strong>Julien Krissi</strong>
      <small>Gerant - JABS</small>
      <div class="personne__actions">
        <a href="tel:+33612345678" class="btn btn--secondaire btn--dense"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M22 16.9v3a2 2 0 0 1-2.2 2 19.8 19.8 0 0 1-8.6-3.1 19.5 19.5 0 0 1-6-6A19.8 19.8 0 0 1 2 4.2 2 2 0 0 1 4 2h3a2 2 0 0 1 2 1.7c.1 1 .4 1.9.7 2.8a2 2 0 0 1-.5 2.1L8 9.8a16 16 0 0 0 6 6l1.2-1.2a2 2 0 0 1 2.1-.5c.9.3 1.8.6 2.8.7A2 2 0 0 1 22 16.9Z"/></svg> Appeler</a>
        <a href="mailto:contact@jabsdev.fr" class="btn btn--secondaire btn--dense"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><rect x="2" y="4" width="20" height="16" rx="2"/><path d="m2 7 10 6 10-6"/></svg> Ecrire</a>
      </div>
    </div>
  </div>
  <div class="carte personne">
    <span class="personne__avatar personne__avatar--vert">SM</span>
    <div class="personne__corps">
      <strong>Sophie Martin</strong>
      <small>Technicienne - equipe Nord</small>
      <div class="personne__actions">
        <a href="tel:+33612345678" class="btn btn--secondaire btn--dense"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M22 16.9v3a2 2 0 0 1-2.2 2 19.8 19.8 0 0 1-8.6-3.1 19.5 19.5 0 0 1-6-6A19.8 19.8 0 0 1 2 4.2 2 2 0 0 1 4 2h3a2 2 0 0 1 2 1.7c.1 1 .4 1.9.7 2.8a2 2 0 0 1-.5 2.1L8 9.8a16 16 0 0 0 6 6l1.2-1.2a2 2 0 0 1 2.1-.5c.9.3 1.8.6 2.8.7A2 2 0 0 1 22 16.9Z"/></svg> Appeler</a>
      </div>
    </div>
  </div>
</div>
.personne { flex-direction: row; gap: var(--sp-3); padding: var(--sp-4); align-items: flex-start; }
.personne__avatar {
  display: inline-flex; align-items: center; justify-content: center;
  width: 46px; height: 46px;
  flex: none;
  border-radius: var(--r-full);
  background: var(--c-primary-soft);
  color: var(--c-primary-ink);
  font-size: var(--fs-md);
  font-weight: var(--fw-bold);
}
.personne__avatar--vert { background: var(--c-success-soft); color: var(--c-success); }
.personne__corps { display: flex; flex-direction: column; gap: 2px; min-width: 0; flex: 1; }
.personne__corps strong { font-size: var(--fs-md); font-weight: var(--fw-bold); }
.personne__corps small  { font-size: var(--fs-xs); color: var(--c-text-muted); }
.personne__actions { display: flex; flex-wrap: wrap; gap: var(--sp-2); margin-top: var(--sp-2); }
flex flex-row gap-3 p-4 [&_span:first-child]:h-12 [&_span:first-child]:w-12 [&_span:first-child]:rounded-full
Carte de dossier

L'objet central d'un CRM d'artisan : reference, client, statut, montant, prochaine echeance. Tout ce qui sert a decider, rien de plus.

Voir le codeMasquer le code
<div class="cartes-grille">
  <a href="#" class="carte carte--lien dossier">
    <div class="dossier__tete">
      <span class="dossier__ref">2026-103</span>
      <span class="doc-etiq doc-etiq--ok">Signe</span>
    </div>
    <div class="carte__corps">
      <h3 class="carte__titre">Krissi Julien</h3>
      <p class="carte__texte">Neuilly-sur-Marne (93) - PAC air/eau 11 kW</p>
      <dl class="dossier__infos">
        <div><dt>Montant</dt><dd>4 280 EUR</dd></div>
        <div><dt>Pose</dt><dd>24 sept.</dd></div>
        <div><dt>Equipe</dt><dd>Nord</dd></div>
      </dl>
    </div>
  </a>
  <a href="#" class="carte carte--lien dossier">
    <div class="dossier__tete">
      <span class="dossier__ref">2026-118</span>
      <span class="doc-etiq doc-etiq--attente">A relancer</span>
    </div>
    <div class="carte__corps">
      <h3 class="carte__titre">Martin Sophie</h3>
      <p class="carte__texte">Colombes (92) - chauffe-eau thermodynamique</p>
      <dl class="dossier__infos">
        <div><dt>Montant</dt><dd>1 890 EUR</dd></div>
        <div><dt>Devis</dt><dd>il y a 9 j</dd></div>
        <div><dt>Equipe</dt><dd>Ouest</dd></div>
      </dl>
    </div>
  </a>
</div>
.dossier__tete {
  display: flex; align-items: center; justify-content: space-between; gap: var(--sp-2);
  padding: var(--sp-2) var(--sp-4);
  background: var(--c-surface-2);
  border-bottom: 1px solid var(--c-border);
}
.dossier__ref { font-family: var(--font-mono); font-size: var(--fs-xs); font-weight: var(--fw-bold); color: var(--c-text-soft); }
.dossier__infos { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--sp-2); margin: var(--sp-3) 0 0; }
.dossier__infos dt { font-size: 10px; text-transform: uppercase; letter-spacing: .05em; color: var(--c-text-muted); }
.dossier__infos dd { margin: 2px 0 0; font-size: var(--fs-sm); font-weight: var(--fw-bold); color: var(--c-text); }
[&_dl]:grid [&_dl]:grid-cols-3 [&_dt]:text-[11px] [&_dt]:uppercase [&_dd]:font-bold

C. Editoriales et commerciales

Tarifs, temoignages, services, verre, rappels, squelettes.

Essentiel 29 EUR / mois
  • Devis et factures illimites
  • 1 utilisateur
  • Support par courriel
Le plus choisi Pro 59 EUR / mois
  • Tout Essentiel
  • 5 utilisateurs
  • Relances automatiques
  • Application mobile
Carte de tarif

Trois formules cote a cote. Celle du milieu est mise en avant : sans reperage, la comparaison prend trop de temps et personne ne choisit.

Voir le codeMasquer le code
<div class="cartes-grille cartes-grille--tarifs">
  <div class="carte tarif">
    <span class="tarif__nom">Essentiel</span>
    <span class="tarif__prix">29 <em>EUR / mois</em></span>
    <ul class="tarif__liste">
      <li><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m20 6-11 11-5-5"/></svg> Devis et factures illimites</li>
      <li><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m20 6-11 11-5-5"/></svg> 1 utilisateur</li>
      <li><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m20 6-11 11-5-5"/></svg> Support par courriel</li>
    </ul>
    <button class="btn btn--secondaire btn--bloc">Choisir</button>
  </div>
  <div class="carte tarif tarif--vedette">
    <span class="tarif__ruban">Le plus choisi</span>
    <span class="tarif__nom">Pro</span>
    <span class="tarif__prix">59 <em>EUR / mois</em></span>
    <ul class="tarif__liste">
      <li><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m20 6-11 11-5-5"/></svg> Tout Essentiel</li>
      <li><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m20 6-11 11-5-5"/></svg> 5 utilisateurs</li>
      <li><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m20 6-11 11-5-5"/></svg> Relances automatiques</li>
      <li><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m20 6-11 11-5-5"/></svg> Application mobile</li>
    </ul>
    <button class="btn btn--plein btn--bloc">Choisir</button>
  </div>
</div>
.cartes-grille--tarifs { grid-template-columns: repeat(auto-fill, minmax(230px, 1fr)); align-items: start; }
.tarif { padding: var(--sp-5); gap: var(--sp-3); position: relative; }
.tarif__nom { font-size: var(--fs-md); font-weight: var(--fw-bold); color: var(--c-text-soft); }
.tarif__prix { font-size: 34px; font-weight: 800; letter-spacing: -.03em; color: var(--c-text); }
.tarif__prix em { font-size: var(--fs-sm); font-weight: var(--fw-medium); font-style: normal; color: var(--c-text-muted); }
.tarif__liste { list-style: none; margin: 0 0 var(--sp-2); padding: 0; display: flex; flex-direction: column; gap: var(--sp-2); flex: 1; }
.tarif__liste li { display: flex; align-items: flex-start; gap: var(--sp-2); font-size: var(--fs-sm); color: var(--c-text-soft); line-height: 1.45; }
.tarif__liste svg { width: 15px; height: 15px; flex: none; margin-top: 2px; color: var(--c-success); }
.tarif--vedette { border: 2px solid var(--c-primary); box-shadow: var(--sh-3); }
.tarif__ruban {
  position: absolute;
  top: 0; right: var(--sp-4);
  transform: translateY(-50%);
  padding: 4px 12px;
  border-radius: var(--r-full);
  background: var(--c-primary);
  color: var(--c-primary-text);
  font-size: 11px;
  font-weight: var(--fw-bold);
}
relative [&.vedette]:border-2 [&.vedette]:border-blue-600 [&.vedette]:scale-105
Intervention rapide et proprete irreprochable. La pompe a chaleur a ete posee en deux jours, et le dossier MaPrimeRenov a ete monte par leurs soins.
MDMarie D.Neuilly-sur-Marne, aout 2026
Carte de temoignage

Preuve sociale d'une landing page. Un temoignage sans nom ni lieu ne convainc personne : les deux sont indispensables.

Voir le codeMasquer le code
<div class="cartes-grille">
  <figure class="carte temoignage">
    <div class="temoignage__notes"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m12 2 3.1 6.3 6.9 1-5 4.9 1.2 6.8L12 17.8 5.8 21l1.2-6.8-5-4.9 6.9-1Z"/></svg><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m12 2 3.1 6.3 6.9 1-5 4.9 1.2 6.8L12 17.8 5.8 21l1.2-6.8-5-4.9 6.9-1Z"/></svg><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m12 2 3.1 6.3 6.9 1-5 4.9 1.2 6.8L12 17.8 5.8 21l1.2-6.8-5-4.9 6.9-1Z"/></svg><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m12 2 3.1 6.3 6.9 1-5 4.9 1.2 6.8L12 17.8 5.8 21l1.2-6.8-5-4.9 6.9-1Z"/></svg><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m12 2 3.1 6.3 6.9 1-5 4.9 1.2 6.8L12 17.8 5.8 21l1.2-6.8-5-4.9 6.9-1Z"/></svg></div>
    <blockquote>Intervention rapide et proprete irreprochable. La pompe a chaleur a ete posee en deux jours, et le dossier MaPrimeRenov a ete monte par leurs soins.</blockquote>
    <figcaption><span class="personne__avatar">MD</span><span><strong>Marie D.</strong><small>Neuilly-sur-Marne, aout 2026</small></span></figcaption>
  </figure>
</div>
.temoignage { padding: var(--sp-5); gap: var(--sp-3); }
.temoignage__notes { display: flex; gap: 2px; color: var(--c-warn); }
.temoignage__notes svg { width: 16px; height: 16px; fill: currentColor; }
.temoignage blockquote { margin: 0; font-size: var(--fs-md); line-height: 1.6; color: var(--c-text); }
.temoignage figcaption { display: flex; align-items: center; gap: var(--sp-3); margin-top: auto; padding-top: var(--sp-2); }
.temoignage figcaption > span:last-child { display: flex; flex-direction: column; gap: 1px; }
.temoignage figcaption strong { font-size: var(--fs-sm); font-weight: var(--fw-bold); }
.temoignage figcaption small  { font-size: var(--fs-xs); color: var(--c-text-muted); }
.temoignage .personne__avatar { width: 38px; height: 38px; font-size: var(--fs-sm); }
[&_blockquote]:text-sm [&_blockquote]:italic [&_figcaption]:flex [&_figcaption]:items-center [&_figcaption]:gap-3
Carte de service

Grille de prestations d'un site vitrine. L'icone donne le rythme visuel, le titre porte le sens.

Voir le codeMasquer le code
<div class="cartes-grille">
  <a href="#" class="carte carte--lien service">
    <span class="service__icone"><svg viewBox="0 0 24 24" fill="none" aria-hidden="true"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8Z" fill="#e8453c"/><path d="M14 2v6h6" fill="#fff" fill-opacity=".35"/><text x="12" y="17" font-family="system-ui,sans-serif" font-size="6.5" font-weight="700" fill="#fff" text-anchor="middle">PDF</text></svg></span>
    <h3 class="carte__titre">Depannage 7j/7</h3>
    <p class="carte__texte">Intervention sous 2 h en Ile-de-France, y compris le week-end.</p>
  </a>
  <a href="#" class="carte carte--lien service">
    <span class="service__icone service__icone--vert"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><rect x="3" y="4" width="18" height="18" rx="2"/><path d="M16 2v4M8 2v4M3 10h18"/></svg></span>
    <h3 class="carte__titre">Entretien annuel</h3>
    <p class="carte__texte">Contrat avec rappel automatique et rapport apres visite.</p>
  </a>
</div>
.service { padding: var(--sp-5); gap: var(--sp-2); }
.service__icone {
  display: inline-flex; align-items: center; justify-content: center;
  width: 46px; height: 46px;
  margin-bottom: var(--sp-2);
  border-radius: var(--r-md);
  background: var(--c-primary-soft);
  color: var(--c-primary);
}
.service__icone svg { width: 23px; height: 23px; }
.service__icone--vert { background: var(--c-success-soft); color: var(--c-success); }
p-5 [&_span:first-child]:mb-3 [&_span:first-child]:inline-flex [&_span:first-child]:h-12 [&_span:first-child]:w-12

Devis gratuit sous 24 h

Etude thermique offerte, sans engagement.

Carte en verre

Posee sur une banniere en image. Assortie a la famille Liquid Glass des boutons : meme materiau, meme liser.

Voir le codeMasquer le code
<div class="demo-verre">
  <div class="carte carte--verre" style="max-width:280px">
    <div class="carte__corps">
      <h3 class="carte__titre">Devis gratuit sous 24 h</h3>
      <p class="carte__texte">Etude thermique offerte, sans engagement.</p>
      <button class="btn btn--lg-verre btn--lg-teinte">Demander mon devis</button>
    </div>
  </div>
</div>
.carte--verre {
  position: relative;
  isolation: isolate;
  border: none;
  background: rgba(255,255,255,.13);
  backdrop-filter: blur(16px) saturate(180%) brightness(1.06);
  -webkit-backdrop-filter: blur(16px) saturate(180%) brightness(1.06);
  box-shadow: 0 2px 10px rgba(0,0,0,.16), 0 14px 40px rgba(0,0,0,.22);
}
.carte--verre::after {
  content: "";
  position: absolute; inset: 0; z-index: -1;
  border-radius: inherit; padding: 1.5px;
  background: linear-gradient(140deg, rgba(255,255,255,.9), rgba(255,255,255,.2) 40%, rgba(255,255,255,.05) 55%, rgba(255,255,255,.7));
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
          mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
          mask-composite: exclude;
  pointer-events: none;
}
.carte--verre .carte__titre { color: #fff; text-shadow: 0 1px 4px rgba(0,0,0,.3); }
.carte--verre .carte__texte { color: rgba(255,255,255,.88); }
border-white/25 bg-white/12 text-white backdrop-blur-xl
Attestation obligatoire

Le Cerfa de TVA reduite doit etre signe avant le debut des travaux, pas apres.

Dossier complet

Toutes les pieces ont ete validees. Le versement interviendra sous 15 jours.

Carte de rappel

Encadre d'information dans une page : conseil, avertissement, note. Le liser lateral suffit, un cadre complet alourdit la lecture.

Voir le codeMasquer le code
<div class="demo-col demo-col--large">
  <div class="rappel"><span class="rappel__icone"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M12 9v4M12 17h.01M10.3 3.9 1.8 18a2 2 0 0 0 1.7 3h17a2 2 0 0 0 1.7-3L13.7 3.9a2 2 0 0 0-3.4 0Z"/></svg></span><div><strong>Attestation obligatoire</strong><p>Le Cerfa de TVA reduite doit etre signe avant le debut des travaux, pas apres.</p></div></div>
  <div class="rappel rappel--ok"><span class="rappel__icone"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m20 6-11 11-5-5"/></svg></span><div><strong>Dossier complet</strong><p>Toutes les pieces ont ete validees. Le versement interviendra sous 15 jours.</p></div></div>
</div>
.rappel {
  display: flex;
  gap: var(--sp-3);
  width: 100%;
  padding: var(--sp-4);
  border-radius: var(--r-md);
  border-left: 4px solid var(--c-warn);
  background: var(--c-warn-soft);
}
.rappel__icone { color: var(--c-warn); flex: none; }
.rappel__icone svg { width: 20px; height: 20px; }
.rappel strong { display: block; font-size: var(--fs-md); font-weight: var(--fw-bold); color: var(--c-text); }
.rappel p { margin: 3px 0 0; font-size: var(--fs-sm); color: var(--c-text-soft); line-height: 1.5; }
.rappel--ok { border-left-color: var(--c-success); background: var(--c-success-soft); }
.rappel--ok .rappel__icone { color: var(--c-success); }
.rappel--info { border-left-color: var(--c-info); background: var(--c-info-soft); }
.rappel--info .rappel__icone { color: var(--c-info); }
flex gap-3 rounded-lg border-l-4 border-l-amber-500 bg-amber-50 p-4
Squelette de carte

Pendant le chargement d'une grille. Meme gabarit que la carte reelle, sinon la page saute a l'arrivee des donnees.

Voir le codeMasquer le code
<div class="cartes-grille">
  <div class="carte"><div class="carte__image doc-squelette"></div><div class="carte__corps">
    <span class="doc-squelette doc-squelette--ligne" style="width:45%;height:10px"></span>
    <span class="doc-squelette doc-squelette--ligne" style="height:16px"></span>
    <span class="doc-squelette doc-squelette--ligne" style="width:80%"></span></div></div>
  <div class="carte"><div class="carte__image doc-squelette"></div><div class="carte__corps">
    <span class="doc-squelette doc-squelette--ligne" style="width:38%;height:10px"></span>
    <span class="doc-squelette doc-squelette--ligne" style="height:16px"></span>
    <span class="doc-squelette doc-squelette--ligne" style="width:65%"></span></div></div>
</div>
/* reutilise .doc-squelette de documents.css : un seul scintillement pour tout le catalogue */
animate-pulse (voir .doc-squelette dans documents.css)