/* ============================================================
   PURPLE PEPPER — DESIGN TOKENS (système "Signal")
   ============================================================
   Source de vérité unique pour les outils SaaS internes/clients
   (ocara-app, bilanCarbonePerso, recupTel, futurs outils).

   Dérivé de la charte graphique officielle (Gabarit Officiel Purple
   Pepper v2026 Template) et de l'exploration validée dans charte-graphique-web/
   (7 directions → Signal Nocturne retenu → 4 déclinaisons sombre/
   claire × atmosphérique/mate → bibliothèque de composants).
   Voir signal-nocturne.html pour la démo vivante de chaque bloc.

   USAGE
   -----
   1. Importer ce fichier avant vos propres styles.
   2. Choisir l'exposition en posant data-theme sur <html> ou <body> :
        <html data-theme="nocturne-aurora">   (sombre, halos — défaut)
        <html data-theme="nocturne-contraste"> (sombre, mat)
        <html data-theme="diurne-aurora">      (clair, halos)
        <html data-theme="diurne-contraste">   (clair, mat)
      Sans data-theme : respecte prefers-color-scheme du système
      (nocturne-aurora en sombre, diurne-aurora en clair).
   3. Utiliser les classes de composants (.btn, .badge, .field, .alert,
      .panel, .card, .tabbar, .datatable, .pagination…) — elles lisent
      les tokens ci-dessous et s'adaptent automatiquement à l'exposition
      active, sans rien à réécrire par outil.

   Décision prise le 2026-08-09 : le dégradé en aplat sur .btn-primary
   (jugé "kitsch/vintage" à l'usage) est remplacé par un anneau dégradé
   tournant autour d'un fill neutre (inspiré de Linear/Raycast, cf.
   décisions README). .btn-secondary reçoit un spotlight au curseur.
   Charger signal-effects.js (copié à côté de ce fichier) pour activer
   le spotlight — sans lui, les boutons restent visuellement corrects,
   juste sans l'effet de survol.

   Décisions prises le 2026-08-04 :
   - ocara-app (climateOffice-adapt) : remplace le reskin "Vibrant/
     Piment" (27/07) par Signal Nocturne. Exposition par défaut proposée :
     nocturne-aurora (outil expert, usage prolongé, écran de pilotage) —
     à confirmer avant intégration.
   - recupTel/webapp : remplace ses tokens actuels par diurne-contraste
     (garde son organisation --brand/--line existante, change les valeurs).
   - bilanCarbonePerso : a déjà sa propre identité ("Tableau de bord",
     violet #7e57c2 sur fond clair, choisie via /design-lab le 27/07) —
     PAS encore tranché si elle bascule sur Signal Nocturne ou si elle
     reste telle quelle. Ne pas toucher ce projet sans redemander.
   ============================================================ */

/* ============ 1. CONSTANTES DE MARQUE (fixes, gabarit officiel) ============ */
:root{
  /* Les 4 piments — échelle sémantique (succès/attention/progression/erreur
     ET catégories Planet/Purpose/People/Profit selon le contexte) */
  --pp-planet:  #2D5A27;
  --pp-purpose: #1E4D6E;
  --pp-people:  #C59247;
  --pp-profit:  #8D2D3E;

  /* Accent de marque (extrait au pixel du logo officiel) */
  --pp-magenta: #8E24AA;
  --pp-violet:  #14121F; /* Midnight Purple — fond sombre de référence */
  --pp-paper:   #FAF8FF; /* fond clair de référence */

  /* Dégradé signature du logo (piment) — réservé aux boutons pleine
     taille et à la pagination. NE PAS l'utiliser sur des éléments
     < ~24px (checkbox, radio, toggle, petits badges) : à cette échelle,
     le dégradé linéaire crée un moiré visible à l'intersection avec le
     border-radius. Utiliser --pp-magenta en aplat à la place. */
  --pp-gradient: linear-gradient(90deg, #EC1E8C 0%, #8E24AA 55%, #3B6FE0 100%);

  --pp-font-display: 'Montserrat', sans-serif; /* 900 — grands titres */
  --pp-font-heading: 'Poppins', sans-serif;    /* 600/700 — titres standards, UI */
  --pp-font-body:    'Lato', sans-serif;       /* 400/700 — texte courant */

  --pp-radius-btn: 999px;   /* pilule — constant sur les 4 expositions */
  --pp-radius-card: 18px;
  --pp-radius-field: 10px;
}

/* ============ 2. EXPOSITIONS SIGNAL ============ */
/* Ordre de cascade : défaut (nocturne-aurora) → media query système
   → data-theme explicite (priorité la plus haute). */

:root,
[data-theme="nocturne-aurora"]{
  --bg-solid:#100e1c;
  --bg-glow:radial-gradient(70% 60% at 85% 0%, rgba(142,36,170,.32), transparent 60%), radial-gradient(50% 50% at 0% 100%, rgba(59,111,224,.2), transparent 60%);
  --surface:rgba(255,255,255,.05); --border:rgba(255,255,255,.1); --panel-blur:blur(18px);
  --ink:#fff; --body:#c9c5de; --muted:#8b85a8; --accent:#c9a8e0;
  --panel-shadow:0 30px 60px -20px rgba(142,36,170,.25);
  --primary-shadow:0 8px 24px -6px rgba(142,36,170,.6); --primary-shadow-hover:0 10px 30px -4px rgba(142,36,170,.85);
  --secondary-bg:transparent; --secondary-text:#fff; --secondary-border:rgba(255,255,255,.25);
  --ghost-line:rgba(201,168,224,.4);
  --spot-color:rgba(236,30,140,.4);
  --badge-text:#fff; --badge-planet-bg:rgba(45,90,39,.28); --badge-purpose-bg:rgba(30,77,110,.32); --badge-people-bg:rgba(197,146,71,.28); --badge-profit-bg:rgba(141,45,62,.32);
  --field-bg:rgba(255,255,255,.06); --field-border:rgba(255,255,255,.16);
  --card-bg:rgba(255,255,255,.05); --card-shadow:0 20px 40px -22px rgba(0,0,0,.5);
  --alert-success-bg:rgba(45,90,39,.24); --alert-success-fg:#bfe3b3;
  --alert-warning-bg:rgba(197,146,71,.22); --alert-warning-fg:#f0d9ab;
  --alert-error-bg:rgba(141,45,62,.26); --alert-error-fg:#f3b9c3;
  --alert-info-bg:rgba(30,77,110,.26); --alert-info-fg:#a9d3ec;
}

[data-theme="nocturne-contraste"]{
  --bg-solid:#0A0912; --bg-glow:none;
  --surface:#17141f; --border:rgba(255,255,255,.14); --panel-blur:none;
  --ink:#fff; --body:#b7b2cc; --muted:#7d7796; --accent:#e0b8f0;
  --panel-shadow:0 1px 0 rgba(255,255,255,.05) inset, 0 24px 40px -30px rgba(0,0,0,.7);
  --primary-shadow:0 4px 14px -4px rgba(142,36,170,.45); --primary-shadow-hover:0 6px 18px -3px rgba(142,36,170,.6);
  --secondary-bg:transparent; --secondary-text:#fff; --secondary-border:rgba(255,255,255,.22);
  --ghost-line:rgba(224,184,240,.4);
  --spot-color:rgba(236,30,140,.4);
  --badge-text:#fff; --badge-planet-bg:rgba(45,90,39,.32); --badge-purpose-bg:rgba(30,77,110,.36); --badge-people-bg:rgba(197,146,71,.32); --badge-profit-bg:rgba(141,45,62,.36);
  --field-bg:#131019; --field-border:rgba(255,255,255,.18);
  --card-bg:#17141f; --card-shadow:0 1px 0 rgba(255,255,255,.05) inset, 0 16px 30px -24px rgba(0,0,0,.6);
  --alert-success-bg:#19241a; --alert-success-fg:#a9d69d;
  --alert-warning-bg:#241e14; --alert-warning-fg:#e0c48c;
  --alert-error-bg:#241318; --alert-error-fg:#e6a2b0;
  --alert-info-bg:#131c22; --alert-info-fg:#8fc2de;
}

[data-theme="diurne-aurora"]{
  --bg-solid:#FAF8FF;
  --bg-glow:radial-gradient(70% 60% at 85% 0%, rgba(142,36,170,.12), transparent 60%), radial-gradient(50% 50% at 0% 100%, rgba(59,111,224,.1), transparent 60%);
  --surface:rgba(255,255,255,.72); --border:rgba(20,18,31,.08); --panel-blur:blur(14px);
  --ink:#1c1330; --body:#5b5470; --muted:#9791ac; --accent:#8E24AA;
  --panel-shadow:0 30px 60px -30px rgba(142,36,170,.22);
  --primary-shadow:0 14px 28px -10px rgba(142,36,170,.35); --primary-shadow-hover:0 16px 32px -8px rgba(142,36,170,.5);
  --secondary-bg:rgba(255,255,255,.6); --secondary-text:#1c1330; --secondary-border:rgba(20,18,31,.14);
  --ghost-line:rgba(142,36,170,.35);
    --spot-color:rgba(142,36,170,.22);
  --badge-planet-bg:rgba(45,90,39,.12); --badge-purpose-bg:rgba(30,77,110,.12); --badge-people-bg:rgba(197,146,71,.18); --badge-profit-bg:rgba(141,45,62,.12);
  --badge-text-planet:#2D5A27; --badge-text-purpose:#1E4D6E; --badge-text-people:#8a6423; --badge-text-profit:#8D2D3E;
  --field-bg:rgba(255,255,255,.8); --field-border:rgba(20,18,31,.12);
  --card-bg:rgba(255,255,255,.75); --card-shadow:0 24px 44px -28px rgba(142,36,170,.28);
  --alert-success-bg:rgba(45,90,39,.08); --alert-success-fg:#2D5A27;
  --alert-warning-bg:rgba(197,146,71,.14); --alert-warning-fg:#8a6423;
  --alert-error-bg:rgba(141,45,62,.08); --alert-error-fg:#8D2D3E;
  --alert-info-bg:rgba(30,77,110,.08); --alert-info-fg:#1E4D6E;
}

[data-theme="diurne-contraste"]{
  --bg-solid:#FFFFFF; --bg-glow:none;
  --surface:#ffffff; --border:#E7E3F3; --panel-blur:none;
  --ink:#14121F; --body:#4b4a5a; --muted:#8a869c; --accent:#8E24AA;
  --panel-shadow:0 1px 2px rgba(20,18,31,.04);
  --primary-shadow:0 6px 16px -6px rgba(142,36,170,.3); --primary-shadow-hover:0 8px 18px -5px rgba(142,36,170,.42);
  --secondary-bg:transparent; --secondary-text:#14121F; --secondary-border:#14121F;
  --ghost-line:rgba(142,36,170,.4);
  --spot-color:rgba(142,36,170,.22);
  --badge-planet-bg:rgba(45,90,39,.1); --badge-purpose-bg:rgba(30,77,110,.1); --badge-people-bg:rgba(197,146,71,.15); --badge-profit-bg:rgba(141,45,62,.1);
  --badge-text-planet:#2D5A27; --badge-text-purpose:#1E4D6E; --badge-text-people:#8a6423; --badge-text-profit:#8D2D3E;
  --field-bg:#fff; --field-border:#d8d4e8;
  --card-bg:#fff; --card-shadow:0 1px 2px rgba(20,18,31,.05);
  --alert-success-bg:rgba(45,90,39,.06); --alert-success-fg:#2D5A27;
  --alert-warning-bg:rgba(197,146,71,.12); --alert-warning-fg:#8a6423;
  --alert-error-bg:rgba(141,45,62,.06); --alert-error-fg:#8D2D3E;
  --alert-info-bg:rgba(30,77,110,.06); --alert-info-fg:#1E4D6E;
}

/* Bascule automatique en l'absence de data-theme explicite */
@media (prefers-color-scheme: light){
  :root:not([data-theme]){
    --bg-solid:#FAF8FF;
    --bg-glow:radial-gradient(70% 60% at 85% 0%, rgba(142,36,170,.12), transparent 60%), radial-gradient(50% 50% at 0% 100%, rgba(59,111,224,.1), transparent 60%);
    --surface:rgba(255,255,255,.72); --border:rgba(20,18,31,.08); --panel-blur:blur(14px);
    --ink:#1c1330; --body:#5b5470; --muted:#9791ac; --accent:#8E24AA;
    --panel-shadow:0 30px 60px -30px rgba(142,36,170,.22);
    --primary-shadow:0 14px 28px -10px rgba(142,36,170,.35); --primary-shadow-hover:0 16px 32px -8px rgba(142,36,170,.5);
    --secondary-bg:rgba(255,255,255,.6); --secondary-text:#1c1330; --secondary-border:rgba(20,18,31,.14);
    --ghost-line:rgba(142,36,170,.35);
    --spot-color:rgba(142,36,170,.22);
    --badge-planet-bg:rgba(45,90,39,.12); --badge-purpose-bg:rgba(30,77,110,.12); --badge-people-bg:rgba(197,146,71,.18); --badge-profit-bg:rgba(141,45,62,.12);
    --badge-text-planet:#2D5A27; --badge-text-purpose:#1E4D6E; --badge-text-people:#8a6423; --badge-text-profit:#8D2D3E;
    --field-bg:rgba(255,255,255,.8); --field-border:rgba(20,18,31,.12);
    --card-bg:rgba(255,255,255,.75); --card-shadow:0 24px 44px -28px rgba(142,36,170,.28);
    --alert-success-bg:rgba(45,90,39,.08); --alert-success-fg:#2D5A27;
    --alert-warning-bg:rgba(197,146,71,.14); --alert-warning-fg:#8a6423;
    --alert-error-bg:rgba(141,45,62,.08); --alert-error-fg:#8D2D3E;
    --alert-info-bg:rgba(30,77,110,.08); --alert-info-fg:#1E4D6E;
  }
}

body{ background:var(--bg-solid); color:var(--body); }

/* ============ 3. TYPE SCALE ============ */
.pp-h1{font-family:var(--pp-font-display);font-weight:900;color:var(--ink);font-size:clamp(1.6rem,2.4vw,2.3rem);line-height:1.1;}
.pp-h2{font-family:var(--pp-font-heading);font-weight:700;color:var(--ink);font-size:1.22rem;margin-top:1.2rem;}
.pp-h3{font-family:var(--pp-font-heading);font-weight:600;color:var(--ink);font-size:.96rem;margin-top:.9rem;opacity:.85;}
.pp-body{font-family:var(--pp-font-body);font-size:.92rem;line-height:1.65;color:var(--body);}

/* ============ 4. BOUTONS ============ */
.btn{font-family:var(--pp-font-heading);font-weight:700;font-size:.85rem;padding:.76rem 1.5rem;border-radius:var(--pp-radius-btn);display:inline-flex;align-items:center;gap:.5rem;border:none;cursor:pointer;transition:transform .15s ease, box-shadow .15s ease, opacity .15s ease;}
.btn:active{transform:translateY(1px) scale(.99);}

/* Primaire (refonte 2026-08-09, cf. décisions README) : le trio
   magenta/violet/bleu ne remplit plus le bouton en aplat (jugé "kitsch"
   après comparaison avec Linear/Raycast) — il tourne en anneau fin
   autour d'un fill neutre (couleur de page), façon Perplexity/Copilot.
   Le fill --bg-solid + l'anneau + --primary-shadow suffisent à détacher
   le bouton même sur un fond de la même famille de couleur. Respecte
   prefers-reduced-motion (anneau figé, pas de flicker). */
/* Deux calques : ::before (l'anneau, plus grand, z -2) peint AVANT le fond
   du bouton ; ::after (le fill neutre, taille exacte, z -1) peint PAR-DESSUS
   ::before mais SOUS le texte — masque le centre, ne laisse dépasser que
   les 2,5px d'anneau. Le fond propre du bouton est transparent : c'est
   ::after qui porte le fill (piège vécu : un z-index négatif seul ne cache
   PAS un pseudo-élément derrière le fond du parent — le fond du parent se
   peint en tout premier, donc un ::before à z-index négatif recouvre quand
   même tout le bouton s'il n'y a rien d'autre par-dessus). */
@property --pp-angle{syntax:'<angle>';initial-value:0deg;inherits:false;}
.btn-primary{position:relative;z-index:0;background:transparent;color:var(--ink);box-shadow:var(--primary-shadow);}
.btn-primary::before{content:'';position:absolute;inset:-2.5px;z-index:-2;border-radius:inherit;background:conic-gradient(from var(--pp-angle),#EC1E8C,#8E24AA,#3B6FE0,#EC1E8C);animation:pp-ring-spin 4s linear infinite;}
.btn-primary::after{content:'';position:absolute;inset:0;z-index:-1;border-radius:inherit;background:var(--bg-solid);}
.btn-primary:hover{box-shadow:var(--primary-shadow-hover,var(--primary-shadow));opacity:.96;}
@keyframes pp-ring-spin{to{--pp-angle:360deg;}}
@media (prefers-reduced-motion:reduce){.btn-primary::before{animation:none;}}

/* Secondaire ("Annuler" etc., refonte 2026-08-09) : hérite du spotlight
   qui suivait le curseur sur le primaire pendant l'exploration — un
   halo doux suit la souris au survol. Nécessite d'appeler
   ppEffects.initSpotlight('.btn-secondary') (voir signal-effects.js) ;
   sans le script chargé, le bouton reste identique à avant (::after
   invisible tant que --mx/--my ne sont pas mis à jour). */
.btn-secondary{position:relative;overflow:hidden;background:var(--secondary-bg,transparent);color:var(--secondary-text);border:1px solid var(--secondary-border);}
.btn-secondary::after{content:'';position:absolute;inset:0;border-radius:inherit;background:radial-gradient(110px 110px at var(--mx,50%) var(--my,50%), var(--spot-color,rgba(142,36,170,.3)), transparent 70%);opacity:0;transition:opacity .25s ease;pointer-events:none;}
.btn-secondary:hover::after{opacity:1;}

.btn-ghost{background:transparent;color:var(--accent);padding:.5rem 0;font-weight:600;border-bottom:1px solid var(--ghost-line);border-radius:0;}

/* ============ 5. BADGES (4 piments) ============ */
.badge{font-family:var(--pp-font-heading);font-weight:700;font-size:.68rem;padding:.34rem .75rem;border-radius:999px;display:inline-flex;align-items:center;gap:.4rem;border:none;}
.badge .bdot{width:6px;height:6px;border-radius:50%;}
.badge--planet{background:var(--badge-planet-bg);color:var(--badge-text-planet,var(--badge-text));} .badge--planet .bdot{background:var(--pp-planet);}
.badge--purpose{background:var(--badge-purpose-bg);color:var(--badge-text-purpose,var(--badge-text));} .badge--purpose .bdot{background:var(--pp-purpose);}
.badge--people{background:var(--badge-people-bg);color:var(--badge-text-people,var(--badge-text));} .badge--people .bdot{background:var(--pp-people);}
.badge--profit{background:var(--badge-profit-bg);color:var(--badge-text-profit,var(--badge-text));} .badge--profit .bdot{background:var(--pp-profit);}

/* ============ 6. FORMULAIRE ============ */
.field{margin-top:1.5rem;max-width:340px;}
.field label{font-family:var(--pp-font-heading);font-size:.75rem;font-weight:700;color:var(--ink);display:block;margin-bottom:.4rem;}
.field input, .field textarea, .selectwrap select{width:100%;padding:.7rem .9rem;border-radius:var(--pp-radius-field);border:1px solid var(--field-border);background:var(--field-bg);color:var(--ink);font-family:var(--pp-font-body);font-size:.87rem;}
.field input::placeholder, .field textarea::placeholder{color:var(--muted);opacity:.6;}
.field textarea{resize:vertical;min-height:76px;}
.field .help{font-size:.7rem;color:var(--muted);margin-top:.4rem;}

.selectwrap{position:relative;}
.selectwrap select{padding-right:2.2rem;appearance:none;-webkit-appearance:none;}
.selectwrap svg{position:absolute;right:.8rem;top:50%;transform:translateY(-50%);width:14px;height:14px;color:var(--muted);pointer-events:none;}

/* Checkbox / radio / toggle — aplat --pp-magenta volontairement (pas le
   dégradé --pp-gradient, cf. note en haut de fichier) */
.optrow{display:flex;flex-direction:column;gap:.7rem;}
.opt{position:relative;display:flex;align-items:center;gap:.6rem;font-family:var(--pp-font-body);font-size:.86rem;color:var(--body);cursor:pointer;}
.opt input{position:absolute;opacity:0;width:1px;height:1px;}
.opt .box{width:18px;height:18px;border-radius:5px;border:1.5px solid var(--field-border);background:var(--field-bg);flex:none;display:flex;align-items:center;justify-content:center;}
.opt .box svg{width:11px;height:11px;opacity:0;color:#fff;}
.opt input:checked + .box{background:var(--pp-magenta);border-color:transparent;}
.opt input:checked + .box svg{opacity:1;}
.opt.radio .box{border-radius:50%;}
.opt.radio .box .dot{width:8px;height:8px;border-radius:50%;background:#fff;opacity:0;}
.opt.radio input:checked + .box{background:var(--pp-magenta);border-color:transparent;}
.opt.radio input:checked + .box .dot{opacity:1;}

.switchopt{position:relative;display:flex;align-items:center;gap:.7rem;font-family:var(--pp-font-body);font-size:.86rem;color:var(--body);cursor:pointer;}
.switchopt input{position:absolute;opacity:0;width:1px;height:1px;}
.switchopt .track{width:38px;height:22px;border-radius:999px;background:var(--field-bg);border:1px solid var(--field-border);position:relative;flex:none;}
.switchopt .thumb{position:absolute;top:2px;left:2px;width:16px;height:16px;border-radius:50%;background:var(--muted);transition:transform .15s ease;}
.switchopt input:checked + .track{background:var(--pp-magenta);border-color:transparent;}
.switchopt input:checked + .track .thumb{transform:translateX(16px);background:#fff;}

/* ============ 7. RETOURS SYSTÈME ============ */
.alert{display:flex;gap:.8rem;padding:1rem 1.1rem;border-radius:12px;}
.alert svg{width:18px;height:18px;flex:none;margin-top:.1rem;}
.alert .at{font-family:var(--pp-font-heading);font-weight:700;font-size:.84rem;}
.alert .ad{font-family:var(--pp-font-body);font-size:.82rem;margin-top:.2rem;line-height:1.5;opacity:.85;}
.alert--success{background:var(--alert-success-bg);color:var(--alert-success-fg);}
.alert--warning{background:var(--alert-warning-bg);color:var(--alert-warning-fg);}
.alert--error{background:var(--alert-error-bg);color:var(--alert-error-fg);}
.alert--info{background:var(--alert-info-bg);color:var(--alert-info-fg);}

.emptystate{border:1px dashed var(--border);border-radius:16px;padding:2.4rem 1.5rem;text-align:center;}
.emptystate .glyph{width:42px;height:42px;margin:0 auto 1rem;color:var(--accent);}
.emptystate h4{font-family:var(--pp-font-heading);font-weight:700;font-size:.92rem;color:var(--ink);margin:0;}
.emptystate p{font-family:var(--pp-font-body);font-size:.83rem;color:var(--muted);margin-top:.4rem;max-width:34ch;margin-left:auto;margin-right:auto;}
.emptystate .btn{margin-top:1.3rem;}

/* ============ 8. SURFACES (cartes, panneaux, barre d'app) ============ */
.panel{background:var(--surface);border:1px solid var(--border);border-radius:20px;padding:2.2rem;box-shadow:var(--panel-shadow,none);backdrop-filter:var(--panel-blur,none);}
.card{background:var(--card-bg);border:1px solid var(--border);border-radius:var(--pp-radius-card);box-shadow:var(--card-shadow,none);backdrop-filter:var(--panel-blur,none);}
.topbar{background:var(--surface);border:1px solid var(--border);border-radius:14px;padding:.85rem 1.1rem;display:flex;align-items:center;justify-content:space-between;gap:1rem;backdrop-filter:var(--panel-blur,none);}
.topbar .brand{display:flex;align-items:center;gap:.5rem;font-family:var(--pp-font-heading);font-weight:700;font-size:.85rem;color:var(--ink);}
.topbar nav{display:flex;gap:1.05rem;}
.topbar nav a{font-size:.72rem;color:var(--muted);font-weight:600;font-family:var(--pp-font-heading);text-decoration:none;}
.topbar nav a.current{color:var(--ink);}

/* ============ 9. DONNÉES (tabs, table, pagination) ============ */
.tabbar{display:flex;gap:1.6rem;border-bottom:1px solid var(--border);margin-bottom:1.2rem;}
.tabbar button{background:none;border:none;padding:.2rem 0 .8rem;font-family:var(--pp-font-heading);font-weight:600;font-size:.8rem;color:var(--muted);border-bottom:2px solid transparent;cursor:pointer;}
.tabbar button.active{color:var(--ink);border-color:var(--accent);}

.datatable{width:100%;border-collapse:collapse;font-size:.82rem;}
.datatable th{text-align:left;font-family:var(--pp-font-heading);font-weight:700;font-size:.66rem;text-transform:uppercase;letter-spacing:.06em;color:var(--muted);padding:.6rem .7rem;border-bottom:1px solid var(--border);}
.datatable td{padding:.75rem .7rem;border-bottom:1px solid var(--border);color:var(--body);font-family:var(--pp-font-body);}
.datatable tr:last-child td{border-bottom:none;}
.datatable .cname{color:var(--ink);font-weight:700;font-family:var(--pp-font-heading);font-size:.82rem;}

/* Pagination — aplat --pp-magenta (même raison que checkbox/radio/toggle) */
.pagination{display:flex;align-items:center;gap:.4rem;}
.pagination button{width:30px;height:30px;border-radius:8px;border:1px solid var(--border);background:var(--surface);color:var(--muted);font-family:var(--pp-font-heading);font-size:.78rem;font-weight:600;cursor:pointer;}
.pagination button.active{background:var(--pp-magenta);color:#fff;border-color:transparent;}
.pagination .ellipsis{color:var(--muted);padding:0 .2rem;font-size:.8rem;}

/* ============ 10. MARQUE ============ */
.pp-chili{width:1em;height:1em;overflow:visible;fill:currentColor;}
/* <svg class="pp-chili" viewBox="0 0 64 64"><path d="M44 10c-4-4-11-4-15 0-9 9-13 22-9 34 3 9 13 12 20 6 10-8 14-24 8-36-1-2-3-3-4-4z"/></svg> */

/* ============ 11. EFFETS (scroll/reveal/spotlight, ajouté 2026-08-09) ============
   CSS seule ici — la logique (IntersectionObserver, mousemove) est dans
   signal-effects.js, à charger une fois par page. Sans le script, ces
   classes sont inertes (pas de FOUC, juste pas d'animation). */

/* révélation mot par mot — ppEffects.initWordReveal('.wordreveal') */
.wordreveal .word{display:inline-block;opacity:0;transform:translateY(.5em);transition:opacity .5s cubic-bezier(.16,1,.3,1), transform .5s cubic-bezier(.16,1,.3,1);}
.wordreveal .word.in{opacity:1;transform:translateY(0);}
@media (prefers-reduced-motion:reduce){.wordreveal .word{opacity:1;transform:none;}}

/* carte spotlight — ppEffects.initSpotlight('.spotcard') ; réutilise
   --card-bg/--border existants, ajoute juste le halo au survol */
.spotcard{position:relative;overflow:hidden;background:var(--card-bg);border:1px solid var(--border);border-radius:var(--pp-radius-card);box-shadow:var(--card-shadow,none);}
.spotcard::before{content:'';position:absolute;inset:0;border-radius:inherit;background:radial-gradient(240px 240px at var(--mx,50%) var(--my,50%), var(--spot-color,rgba(142,36,170,.2)), transparent 70%);opacity:0;transition:opacity .3s ease;pointer-events:none;}
.spotcard:hover::before{opacity:1;}

/* compteur animé — pas de classe dédiée, juste
   <span data-countup-target="128">0</span> + ppEffects.initCounters('[data-countup-target]') */

/* ============================================================
   INTÉGRATION PAR PROJET
   ============================================================

   ocara-app / bilanCarbonePerso (Next.js + Tailwind CSS v4)
   ----------------------------------------------------------
   Dans app/globals.css, après `@import "tailwindcss";` :
     @import "../charte-graphique-web/tokens.css"; (ou copie locale du fichier)
   Puis, si besoin d'utilitaires Tailwind (bg-ink, text-muted...) :
     @theme inline {
       --color-ink: var(--ink);
       --color-body: var(--body);
       --color-muted: var(--muted);
       --color-accent: var(--accent);
       --color-surface: var(--surface);
       --color-border: var(--border);
     }
   Poser data-theme sur <html> dans app/layout.tsx (server-rendered,
   pas de flash) :
     <html lang="fr" data-theme="nocturne-aurora">

   recupTel/webapp (HTML + CSS vanilla, pas de build)
   ----------------------------------------------------------
   <link rel="stylesheet" href="tokens.css"> avant le <style> existant,
   puis remplacer le bloc :root actuel (--bg/--panel/--ink/--brand...)
   par un mapping vers les nouveaux tokens : --panel:var(--surface),
   --line:var(--border), --brand:var(--pp-magenta), etc. — même
   stratégie que bilanCarbonePerso le 27/07 (garder les noms de classes
   existants, changer les valeurs). Forcer <html data-theme="diurne-contraste">.
   ============================================================ */
