card-05-balance-gauge

Carte solde à jauge compteur

Montrer un solde et sa progression dans un grand panneau menthe : une jauge « compteur » (part acquise en plein, part restante en hachures) surmonte un chiffre héros posé en bas, la tendance en regard.

cardslideweb776×494px10 benchmarks

Télécharger le .zip

Le fragment RÉEL, dans son propre document, sur le sol de sa charte — pas une image. Ce que vous voyez est exactement ce que vous collerez.

Employer quand

Carte centrale d'un dashboard où un montant unique doit dominer ET porter une notion d'avancement vers un objectif. Le panneau teinté plein la distingue des cartes de détail.

Éviter quand

Il n'y a pas de progression à raconter (la jauge devient un ornement — un simple grand chiffre suffit), ou il faut plusieurs séries : une jauge ne lit qu'un ratio à la fois.

Notes

La jauge est un demi-cercle « arc-en-ciel » (ouvert vers le bas) coupé en deux : l'arc plein noir porte l'acquis, l'arc hachuré (fond menthe + traits menthe-profond via <pattern>) porte le reste à courir, un curseur lilas marque la position. Le panneau est en position:relative et les trois blocs (jauge, tendance, chiffre) en absolute : c'est ce qui permet d'ancrer le chiffre en bas-droite et la tendance en bas-gauche sans qu'ils se disputent la place — deux benchmarks vérifient le non-recouvrement et l'alignement de pied. Le contraste du chiffre sur menthe (≥ 4,5) est atteignable en encre noire, donc exigé.

Mots-clés

cartesoldejaugecompteurgaugeprogressiondashboardmenthepanneauchiffre-hero

Benchmarks — la géométrie, en assertions vérifiables

Rejouables par node bin/check.mjs card-05-balance-gauge : le pattern se prouve, il ne se croit pas.

assertionmesureattendu
marges intérieures ≈ 5,4 % de la largeurnum('.vl-balance','paddingLeft') / W0.054 ± 0.02
le panneau menthe occupe l'essentiel de la carte (> 65 % de la hauteur)box('.vl-panel').h / H≥ 0.65
jauge centrée horizontalement dans le panneau (± 4 px)Math.abs((box('.vl-gauge').left + box('.vl-gauge').w / 2) - (box('.vl-panel').left + box('.vl-panel').w / 2))≤ 4
chiffre héros ancré en bas-DROITE du panneau (au-delà du milieu)box('.vl-balance__big').left / W≥ 0.5
tendance ancrée en bas-GAUCHE, à gauche du chiffre héros (pas de recouvrement)box('.vl-balance__big').left - box('.vl-balance__stat').right≥ 8
chiffre et tendance sur la MÊME ligne de pied (± 12 px)Math.abs(box('.vl-balance__big').bottom - box('.vl-balance__stat').bottom)≤ 12
le chiffre héros appartient à l'échelle display : ≥ 40 pxnum('.vl-balance__big','fontSize')≥ 40
contraste du titre ≥ 7 (il nomme la carte)contrast('.vl-balance__title')≥ 7
contraste du chiffre héros sur la menthe ≥ 4,5contrast('.vl-balance__big')≥ 4.5
aucun débordement du contenu hors de la carteoverflow('.vl-balance')≤ 0

Le code

fragment — patterns/card-05-balance-gauge.html Télécharger
<!-- card-05-balance-gauge — fragment autonome. Couleurs via --vl-* uniquement, aucune valeur en dur. -->
<div class="vl-balance">
  <div class="vl-balance__head">
    <h2 class="vl-balance__title">Current balance</h2>
    <div class="vl-balance__nav">
      <span class="vl-balance__circ"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M15 6l-6 6 6 6"/></svg></span>
      <span class="vl-balance__circ"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M9 6l6 6-6 6"/></svg></span>
    </div>
  </div>
  <div class="vl-panel">
    <span class="vl-panel__chip">
      <svg viewBox="0 0 24 24" fill="none" stroke="var(--vl-ink)" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M4 19V5M4 19h16M8 16l3-4 3 2 4-6"/></svg>
    </span>
    <svg class="vl-gauge" viewBox="0 0 300 168" fill="none">
      <defs>
        <pattern id="vlhatch" width="8" height="8" patternTransform="rotate(45)" patternUnits="userSpaceOnUse">
          <rect width="8" height="8" fill="var(--vl-mint)"/>
          <line x1="0" y1="0" x2="0" y2="8" stroke="var(--vl-mint-deep)" stroke-width="4"/>
        </pattern>
      </defs>
      <path class="vl-gauge__done" d="M25 150 A125 125 0 0 1 128.3 26.9" stroke="var(--vl-ink)" stroke-width="20" stroke-linecap="round"/>
      <path class="vl-gauge__todo" d="M128.3 26.9 A125 125 0 0 1 275 150" stroke="url(#vlhatch)" stroke-width="20" stroke-linecap="round"/>
      <circle class="vl-gauge__knob" cx="252" cy="78" r="10" fill="var(--vl-lilac-deep)" stroke="var(--vl-surface-light)" stroke-width="3"/>
    </svg>
    <div class="vl-balance__stat">
      <div class="vl-balance__pct">14%
        <svg viewBox="0 0 24 24" width="12" height="12" fill="none" stroke="currentColor" stroke-width="2.6" stroke-linecap="round" stroke-linejoin="round"><path d="M7 17L17 7M8 7h9v9"/></svg>
      </div>
      <div class="vl-balance__avg">Avg score: 18,324$</div>
    </div>
    <div class="vl-balance__big">15,368$</div>
  </div>
</div>

<style>
/* Carte de solde : en-tête léger (titre + navigation), puis un GRAND panneau menthe qui
   occupe la carte et porte une jauge « compteur » — arc noir = acquis, arc hachuré = reste
   à courir, avec un curseur lilas. Chiffre héros en bas-droit, tendance en bas-gauche. */
.vl-balance {
  width: 776px; height: 494px;
  background: var(--vl-surface-light); color: var(--vl-ink);
  border-radius: var(--vl-radius-card); padding: 30px;
  display: flex; flex-direction: column;
  font-family: Inter, -apple-system, "Helvetica Neue", Arial, sans-serif;
}
.vl-balance__head { display: flex; justify-content: space-between; align-items: center; }
.vl-balance__title { margin: 0; font-size: 18px; font-weight: 600; letter-spacing: -0.01em; }
.vl-balance__nav { display: flex; gap: 10px; }
.vl-balance__circ {
  width: 34px; height: 34px; border-radius: 50%; border: 1px solid var(--vl-hairline);
  display: inline-flex; align-items: center; justify-content: center;
}
.vl-balance__circ svg { width: 14px; height: 14px; }
.vl-panel {
  margin-top: 22px; flex: 1; position: relative;
  background: var(--vl-mint); border-radius: var(--vl-radius-sub); padding: 24px; overflow: hidden;
}
.vl-panel__chip {
  width: 42px; height: 42px; border-radius: 50%; background: var(--vl-surface-light);
  display: inline-flex; align-items: center; justify-content: center;
}
.vl-panel__chip svg { width: 18px; height: 18px; }
.vl-gauge { position: absolute; left: 50%; top: 48%; transform: translate(-50%,-50%); width: 300px; }
.vl-balance__stat { position: absolute; left: 24px; bottom: 22px; }
.vl-balance__pct { font-size: 17px; font-weight: 700; color: var(--vl-ink); }
.vl-balance__avg { font-size: 11px; font-weight: 500; color: var(--vl-ink-on-mint); margin-top: 2px; }
.vl-balance__big { position: absolute; right: 24px; bottom: 20px; font-size: 46px; font-weight: 700; line-height: 1; letter-spacing: -0.02em; color: var(--vl-ink); }
</style>
tokens de la charte — systems/ref-11-finance-dashboard-mint.json Télécharger
:root {
  --vl-bg: #E6EAE4;
  --vl-board: #E6EAE4;
  --vl-surface-light: #FFFFFF;
  --vl-surface-soft: #F1F2EF;
  --vl-surface-dark: #141414;
  --vl-mint: #B4E3A0;
  --vl-mint-deep: #8FCE72;
  --vl-lilac: #B6ABE6;
  --vl-lilac-deep: #9A8ADE;
  --vl-ink: #181A17;
  --vl-ink-muted: #7C817A;
  --vl-ink-on-mint: #3D5A30;
  --vl-ink-on-lilac: #3E3270;
  --vl-ink-invert: #FFFFFF;
  --vl-ink-invert-muted: #9CA09A;
  --vl-hairline: #E3E5E1;
  --vl-hairline-invert: #333333;
  --vl-radius-card: 26px;
  --vl-radius-sub: 20px;
  --vl-radius-chip: 14px;
  --vl-gap: 20px;
}
les métadonnées — patterns/card-05-balance-gauge.json (télécharger)
{
  "name": "Carte solde à jauge compteur",
  "family": "card",
  "ref": "ref-11-finance-dashboard-mint",
  "intent": "Montrer un solde et sa progression dans un grand panneau menthe : une jauge « compteur » (part acquise en plein, part restante en hachures) surmonte un chiffre héros posé en bas, la tendance en regard.",
  "when_to_use": "Carte centrale d'un dashboard où un montant unique doit dominer ET porter une notion d'avancement vers un objectif. Le panneau teinté plein la distingue des cartes de détail.",
  "avoid_when": "Il n'y a pas de progression à raconter (la jauge devient un ornement — un simple grand chiffre suffit), ou il faut plusieurs séries : une jauge ne lit qu'un ratio à la fois.",
  "tags": [
    "carte",
    "solde",
    "jauge",
    "compteur",
    "gauge",
    "progression",
    "dashboard",
    "menthe",
    "panneau",
    "chiffre-hero"
  ],
  "vars": [
    {
      "name": "--vl-mint",
      "role": "aplat du panneau + fond des hachures",
      "default": "#B4E3A0"
    },
    {
      "name": "--vl-mint-deep",
      "role": "trait des hachures (reste à courir)",
      "default": "#8FCE72"
    },
    {
      "name": "--vl-ink",
      "role": "arc acquis de la jauge + chiffre héros",
      "default": "#181A17"
    },
    {
      "name": "--vl-lilac-deep",
      "role": "curseur de la jauge",
      "default": "#9A8ADE"
    },
    {
      "name": "--vl-radius-sub",
      "role": "rayon du panneau interne",
      "default": "20px"
    }
  ],
  "slots": [
    "title",
    "nav",
    "gauge",
    "trend",
    "figure"
  ],
  "geometry": {
    "root": ".vl-balance",
    "frame": [
      776,
      494
    ],
    "ratios": {
      "pad_over_width": 0.054,
      "panel_over_height": 0.72
    },
    "type_px": {
      "title": 18,
      "figure": 46,
      "avg": 11
    },
    "pad_ratio": {
      "top": 0.064,
      "x": 0.054,
      "bottom": 0.064
    }
  },
  "benchmarks": [
    {
      "name": "marges intérieures ≈ 5,4 % de la largeur",
      "measure": "num('.vl-balance','paddingLeft') / W",
      "expect": 0.054,
      "tol": 0.02
    },
    {
      "name": "le panneau menthe occupe l'essentiel de la carte (> 65 % de la hauteur)",
      "measure": "box('.vl-panel').h / H",
      "min": 0.65
    },
    {
      "name": "jauge centrée horizontalement dans le panneau (± 4 px)",
      "measure": "Math.abs((box('.vl-gauge').left + box('.vl-gauge').w / 2) - (box('.vl-panel').left + box('.vl-panel').w / 2))",
      "max": 4
    },
    {
      "name": "chiffre héros ancré en bas-DROITE du panneau (au-delà du milieu)",
      "measure": "box('.vl-balance__big').left / W",
      "min": 0.5
    },
    {
      "name": "tendance ancrée en bas-GAUCHE, à gauche du chiffre héros (pas de recouvrement)",
      "measure": "box('.vl-balance__big').left - box('.vl-balance__stat').right",
      "min": 8
    },
    {
      "name": "chiffre et tendance sur la MÊME ligne de pied (± 12 px)",
      "measure": "Math.abs(box('.vl-balance__big').bottom - box('.vl-balance__stat').bottom)",
      "max": 12
    },
    {
      "name": "le chiffre héros appartient à l'échelle display : ≥ 40 px",
      "measure": "num('.vl-balance__big','fontSize')",
      "min": 40
    },
    {
      "name": "contraste du titre ≥ 7 (il nomme la carte)",
      "measure": "contrast('.vl-balance__title')",
      "min": 7
    },
    {
      "name": "contraste du chiffre héros sur la menthe ≥ 4,5",
      "measure": "contrast('.vl-balance__big')",
      "min": 4.5
    },
    {
      "name": "aucun débordement du contenu hors de la carte",
      "measure": "overflow('.vl-balance')",
      "max": 0
    }
  ],
  "notes": "La jauge est un demi-cercle « arc-en-ciel » (ouvert vers le bas) coupé en deux : l'arc plein noir porte l'acquis, l'arc hachuré (fond menthe + traits menthe-profond via <pattern>) porte le reste à courir, un curseur lilas marque la position. Le panneau est en position:relative et les trois blocs (jauge, tendance, chiffre) en absolute : c'est ce qui permet d'ancrer le chiffre en bas-droite et la tendance en bas-gauche sans qu'ils se disputent la place — deux benchmarks vérifient le non-recouvrement et l'alignement de pied. Le contraste du chiffre sur menthe (≥ 4,5) est atteignable en encre noire, donc exigé.",
  "id": "card-05-balance-gauge"
}

À côté