/* ═══════════════════════════════════════════════════════════════════════════
   Socle visuel commun — la coque de la plateforme

   ── Pourquoi ce fichier existe ──────────────────────────────────────────

   Les quatre applications ont été construites l'une après l'autre, chacune
   avec sa feuille de style écrite à la main dans sa propre page : deux mille
   lignes au total, aucune partagée. Rien ne se ressemblait, et le système de
   design du 18/07 n'a jamais été appliqué — il vivait hors du dépôt, sous
   forme d'artefact.

   Ce fichier est la source unique des jetons visuels. Une couleur, une
   graisse, un rayon : ici et nulle part ailleurs.

   ── ⚠️ Ce fichier a changé deux fois le 07/08. Lire les deux. ───────────

   **1. Le matin.** La version brouillonnée le 06/08 déclarait « console, pas
   vitrine » : bandeau sombre, tables serrées, densité maximale. Daniel a
   tranché autrement — la plateforme se monte comme un CRM, aux principes de
   Huawei. Les deux ne tenaient pas ensemble ; le brouillon sombre a été
   remplacé, pas amendé.

   **2. L'après-midi.** Daniel : « je t'invite à regarder dsdrenov.com afin
   de reprendre le même design et principe des boutons de navigation ».
   L'accent cuivre retenu le matin **est remplacé par le rouge
   brique de la marque, #BE3734**. Ce n'est pas une impression du site : c'est
   la valeur lue dans son CSS.

   ── Ce qui vient d'où, pour que personne n'ait à le deviner ─────────────

   • **La structure et le rythme viennent de Huawei** : fond clair, cartes
     posées sans bordure dure, rayons larges, forte respiration, hiérarchie
     typographique nette. Un écran doit paraître calme même sous trente
     lignes de devis.
   • **La couleur et la forme des boutons viennent de dsdrenov.com** : rouge
     brique #BE3734, texte #FAFAFA, capsule, majuscules, transition douce.
   • **La famille typographique n'a PAS pu être lue** dans le CSS du site —
     le thème ne la déclare pas là où elle se récupère. On garde donc la pile
     système, et ce n'est pas un choix : c'est une donnée manquante. À
     corriger le jour où Daniel donne sa charte.

   ── ⛔ Une règle que le style ne doit jamais enfreindre ──────────────────

   **Aucun montant ne s'affiche sur l'écran de relevé.** C'est une règle
   métier, pas une préférence : le commercial relève, il ne chiffre pas. La
   coque n'affiche donc aucun chiffre d'affaires, aucun total, aucune devise —
   elle est injectée sur les quatre écrans, relevé compris.

   ⚠️ Servi sur `/commun/console.css` par le portail et les quatre serveurs.
   ═══════════════════════════════════════════════════════════════════════════ */

/* ═══════════════════════════════════════════════════════════════════════════
   HarmonyOS Sans — la police du système, servie par nous
   ═══════════════════════════════════════════════════════════════════════════

   **Daniel, 09/08 : « utilise tout le modèle de Huawei en open source :
   police, graphique, bouton, picto… tout. »**

   ⚠️ J'avais écarté cette police le matin même, sur une lecture prudente de
   sa licence. La lecture du texte réel — `polices/LICENSE_Fonts.txt`, article
   2 — dit autre chose : le droit accordé couvre expressément « use, copy,
   merge, **embed, bundle, redistribute** and/or sell unmodified copies […]
   **with any software** ». Ce qui est interdit, c'est de redistribuer la
   police **seule**, comme police — pas de la servir comme composant d'une
   application. La phrase suivante le dit elle-même : « This limitation does
   not apply to any work created by using HarmonyOS Sans Fonts. »

   ⛔ **Du TTF, pas du WOFF2.** Le WOFF2 pèserait trois fois moins, mais la
   conversion réécrit le fichier, et l'article 2.2 interdit toute
   modification. 400 ko économisés ne valent pas de dépendre de
   l'interprétation d'un juriste d'en face.

   ⛔ **La mention exigée par l'article 2.1 est dans le pied du menu de la
   coque**, à l'écran en permanence sur les cinq applications, et un banc la
   vérifie. Détail complet dans `polices/NOTICE.txt`.

   ⚠️ `font-display: swap` : le texte s'affiche tout de suite dans la pile
   système, puis bascule. Sans lui, 585 ko de polices retiendraient l'écran
   en blanc — sur un toit, en 4G, c'est l'écran de relevé qui attend. */

@font-face {
  font-family: 'HarmonyOS Sans';
  src: url('/commun/polices/HarmonyOS_Sans_Light.ttf') format('truetype');
  font-weight: 300; font-style: normal; font-display: swap;
}
@font-face {
  font-family: 'HarmonyOS Sans';
  src: url('/commun/polices/HarmonyOS_Sans_Regular.ttf') format('truetype');
  font-weight: 400; font-style: normal; font-display: swap;
}
@font-face {
  font-family: 'HarmonyOS Sans';
  src: url('/commun/polices/HarmonyOS_Sans_Medium.ttf') format('truetype');
  font-weight: 500; font-style: normal; font-display: swap;
}
@font-face {
  font-family: 'HarmonyOS Sans';
  src: url('/commun/polices/HarmonyOS_Sans_Bold.ttf') format('truetype');
  font-weight: 700; font-style: normal; font-display: swap;
}

:root {
  /* ═════════════════════════════════════════════════════════════════════
     ⛔ LES VALEURS CI-DESSOUS SONT CELLES DU SYSTÈME HARMONYOS, PAS UNE
     IMPRESSION DE CE À QUOI IL RESSEMBLE.

     **Daniel, 09/08 : « ça ne ressemble vraiment pas à Huawei, même les
     logos, les boutons… il faut vraiment que tu étudies le design et la
     nomenclature Huawei pour faire pareil. »**

     Il avait raison, et la cause était identifiable : le socle du 07/08
     imitait Huawei de mémoire. Les jetons sont désormais lus dans la source
     du système — `systemres/main/resources/base/element/{color,float}.json`
     du dépôt `openharmony/resources`. Le nom HarmonyOS de chaque jeton est
     écrit en regard, pour qu'on puisse vérifier au lieu de croire.

     ⚠️ **Une seule valeur est substituée, et c'est une décision de Daniel :**
     `ohos_id_color_emphasize` vaut `#007DFF` chez Huawei ; ici c'est le rouge
     brique #BE3734 de dsdrenov.com. L'accent est la couleur de la marque ;
     tout le reste — la structure — est celle de Huawei.
     ═════════════════════════════════════════════════════════════════════ */

  /* ── Surfaces ──────────────────────────────────────────────────────────
     Deux plans, pas quatre. Chez Huawei la page est `sub_background` et la
     carte est `background` : la carte est **plus claire** que la page, et
     c'est l'inverse de la plupart des interfaces de gestion. C'est ce
     renversement qui donne l'impression de calme — le contenu avance, le
     fond recule.

       ohos_id_color_sub_background  #F1F3F5   la page
       ohos_id_color_background      #FFFFFF   la carte, le dialogue
       ohos_id_color_list_card_bg    #FFFFFF   la carte de liste */
  --fond: #F1F3F5;
  --surface: #FFFFFF;
  --surface-2: #F1F3F5;
  --surface-3: #E7EAEE;

  /* ── Encres — UNE encre, quatre opacités ──────────────────────────────
     ⛔ C'est la différence la plus visible avec le socle qu'il remplace.
     Huawei ne déclare pas quatre gris : il déclare **une encre**, `#182431`,
     et quatre taux de contenu. Quatre gris distincts se décalent les uns des
     autres sur un fond teinté ; une encre à quatre opacités reste une seule
     famille, sur n'importe quel fond.

       ohos_id_color_primary    #182431 à 100 %   ohos_id_alpha_content_primary   0.9
       ohos_id_color_secondary  #182431 à  60 %   …_secondary                     0.6
       ohos_id_color_tertiary   #182431 à  40 %   …_tertiary                      0.4
       ohos_id_color_fourth     #182431 à  20 %   …_fourth                        0.2

     ⚠️ Le texte principal est à **0,9**, jamais à 1. Le noir plein sur blanc
     plein est ce qui fait « tableur » ; ce dixième retiré est une part réelle
     du calme de ce langage. */
  --encre-source: 24, 36, 49;                    /* #182431 */

  /* ⛔ **DEUX RAMPES, ET C'EST UNE DÉVIATION ASSUMÉE DE HARMONYOS.**
     Mesuré le 09/08 : la rampe telle que Huawei la déclare échoue au
     WCAG 2.2 AA sur du texte.

       encre-2 à 0,6 → contraste 4,25:1 sur blanc   (AA exige 4,5)
       encre-3 à 0,4 → contraste 2,41:1 sur blanc   (échoue même le 3:1
                                                     du « grand texte »)

     Chez Huawei, le tertiaire à 40 % sert au texte **désactivé** et aux
     icônes — pas au texte qu'on lit. Nous l'employions pour les aides de
     champ, les en-têtes de colonne et les sous-titres, c'est-à-dire pour du
     texte lu toute la journée, parfois sur un toit en plein soleil.

     ⚠️ **Reprendre un langage visuel ne veut pas dire reprendre ses
     défauts.** Les rôles de TEXTE prennent donc les opacités qui passent la
     norme ; les rôles NON textuels — icônes, filets, remplissages — gardent
     les valeurs de Huawei, où elles sont justes. Un banc mesure les ratios :
     ramener `--encre-3` à 0,4 le fera tomber. */
  --encre:   rgba(24, 36, 49, .9);    /* 11,6:1 — titres et texte fort */
  --encre-2: rgba(24, 36, 49, .74);   /*  6,7:1 — texte courant secondaire */
  --encre-3: rgba(24, 36, 49, .66);   /*  5,1:1 — aides, légendes, en-têtes */

  /* ⛔ Ces deux-là ne portent JAMAIS de texte. Ce sont les valeurs de Huawei,
     et elles sont justes pour ce qu'elles font. */
  --encre-4:     rgba(24, 36, 49, .38);   /* désactivé, chevrons, séparateurs */
  --encre-icone: rgba(24, 36, 49, .4);    /* ohos_id_color_tertiary */

  /* ── Filets ───────────────────────────────────────────────────────────
     ⚠️ **Beaucoup plus clairs que ce que portait le socle précédent.**
     `ohos_id_color_subheading_separator` vaut l'encre à **3 %** — un filet
     qu'on devine plutôt qu'on ne le lit. Le socle du 07/08 employait #E3E8EB,
     soit trois fois plus dense : c'est ce qui donnait aux écrans leur aspect
     quadrillé, très loin de Huawei.

       ohos_id_color_subheading_separator  #08182431   (3 %)
       ohos_id_color_component_normal      #19182431   (10 %) */
  --trait: rgba(24, 36, 49, .09);
  --trait-2: rgba(24, 36, 49, .05);
  --remplissage: rgba(24, 36, 49, .06);          /* le creux d'un champ */
  --remplissage-fort: rgba(24, 36, 49, .1);      /* ohos_id_color_component_normal */

  /* ── Accent — le rouge brique de la marque ────────────────────────────
     Décision de Daniel, 07/08 : reprendre le design de dsdrenov.com.

       .main_button { background-color: #BE3734; color: #FAFAFA;
                      border-radius: 30px/40px; text-transform: uppercase }

     Il occupe la place de `ohos_id_color_emphasize` (#007DFF chez Huawei) :
     une seule couleur d'emphase dans tout le système, et elle ne signale que
     ce qui engage. Employée partout, elle ne signalerait plus rien.

     ⛔ **`text-transform: uppercase` n'est PAS repris, et c'est délibéré.**
     Huawei ne met jamais un libellé de bouton en capitales — ni sur le site,
     ni dans HarmonyOS. Les capitales étaient la seule chose du bouton
     dsdrenov qui ne se conciliait pas avec la demande « faire pareil que
     Huawei » : la capsule, elle, se concilie très bien — `ButtonType.Capsule`
     est le type **par défaut** du bouton ArkUI. Reste donc du site : la
     teinte, l'encre #FAFAFA, la capsule. Part : la casse. */
  --accent: #BE3734;
  --accent-vif: #A62E2C;
  --accent-doux: rgba(190, 55, 52, .08);
  --accent-trait: rgba(190, 55, 52, .24);
  --accent-encre: #FAFAFA;   /* le blanc cassé du site, jamais #FFF pur */

  /* ── États ─────────────────────────────────────────────────────────────
     ⛔ **Le rouge de la marque et le rouge du blocage ne peuvent pas être le
     même signal.** Une alerte bloquante empêche d'émettre un devis ; un
     bouton d'action invite à le faire. Deux sens sur une même teinte, et le
     plus grave des deux se perd.

     Résolu par la **forme**, pas par la teinte : l'action est une capsule
     pleine, le blocage un panneau à filet clair. Le rouge du blocage est en
     outre plus sombre et plus désaturé — il n'attire pas, il arrête. */
  --ok: #1D6B45;      --ok-fond: #E9F5EE;      --ok-trait: #C2DECE;
  --alerte: #855400;  --alerte-fond: #FDF4DE;  --alerte-trait: #EFDCA9;
  --danger: #7E1D14;  --danger-fond: #F7E9E7;  --danger-trait: #E0BDB8;
  --info: #1B5E8C;    --info-fond: #EAF3F9;    --info-trait: #C4DCEC;

  /* ── Typographie ──────────────────────────────────────────────────────
     L'échelle et ses NOMS sont ceux de HarmonyOS, à la valeur près :

       ohos_id_text_size_headline9 … 6   18 · 20 · 24 · 30 vp
       ohos_id_text_size_sub_title1…3    18 · 16 · 14 fp
       ohos_id_text_size_body1 … 3       16 · 14 · 12 fp
       ohos_id_text_size_button1 … 3     16 · 14 · 12 fp
       ohos_id_text_size_caption1        10 fp

     ✅ **La famille est HarmonyOS Sans depuis le 09/08**, servie par nos
     serveurs et jamais par un tiers — voir le bloc `@font-face` en tête de ce
     fichier et `polices/NOTICE.txt`. La pile système reste derrière : c'est
     elle qui s'affiche pendant le chargement, et c'est elle qui reste si la
     police n'arrive pas.

     ⚠️ **Cela ne remplace pas la charte du groupe.** Le jour où Daniel la
     donne, elle l'emporte : une police de fabricant de téléphones n'est pas
     l'identité d'une maison de restauration patrimoniale. */
  --serif: 'Iowan Old Style', 'Palatino Linotype', Palatino, Georgia, serif;
  --ui: 'HarmonyOS Sans', ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
  --mono: ui-monospace, 'SF Mono', SFMono-Regular, Menlo, Consolas, monospace;

  --t-titre: 30px;      /* headline6  — le titre d'une vue */
  --t-titre-s: 24px;    /* headline7  — le titre d'une section */
  --t-sous-titre: 16px; /* sub_title2 — le titre d'une carte */
  --t-corps: 14px;      /* body2      — le texte courant */
  --t-corps-s: 12px;    /* body3      — la mention secondaire */
  --t-legende: 10px;    /* caption1   — l'étiquette d'un repère */

  /* ── Rayons — l'échelle nommée de HarmonyOS ──────────────────────────
     ⚠️ Le socle du 07/08 en déclarait trois, choisis à l'œil (8 · 12 · 18).
     Deux tombaient juste par hasard ; le 8 n'existe pas dans l'échelle, où
     l'on descend à 6.

       ohos_id_corner_radius_default_xs · s · m · l · xl   6 · 12 · 18 · 24 · 36 vp

     Et les rayons NOMMÉS, qui ne se déduisent pas de l'échelle — c'est
     précisément ce que « la nomenclature » veut dire : */
  --r-xs: 6px;
  --r-s: 12px;          /* default_s */
  --r: 18px;            /* default_m */
  --r-l: 24px;          /* default_l — corner_radius_card, _dialog */
  --r-xl: 36px;         /* default_xl */
  --r-capsule: 999px;

  --r-carte: 24px;      /* ohos_id_corner_radius_card */
  --r-dialogue: 24px;   /* ohos_id_corner_radius_dialog */
  --r-menu: 20px;       /* ohos_id_corner_radius_menu */
  --r-bouton: 20px;     /* ohos_id_corner_radius_button */
  --r-bouton-s: 14px;   /* ohos_id_corner_radius_small_button */
  --r-champ: 20px;      /* ohos_id_corner_radius_text_field */
  --r-bulle: 18px;      /* ohos_id_corner_radius_tips_tips */
  --r-icone: 8px;       /* ohos_id_corner_radius_icon */
  --r-marque: 4px;      /* ohos_id_corner_radius_mark, _check_box */

  /* ⛔ **La cible tactile minimale.** Le relevé terrain s'utilise sur un toit,
     debout, souvent avec des gants : une cible de 32 px s'y manque une fois
     sur trois. 48 px est la recommandation des deux plateformes mobiles, et
     c'est la seule valeur de ce socle qui existe pour une contrainte physique
     et non pour une raison esthétique.

     ⚠️ Elle était employée par l'écran de relevé sous le nom `--tap` **sans
     avoir jamais été déclarée nulle part** : la propriété était donc invalide,
     et les boutons n'avaient aucune hauteur minimale. Trouvé le 09/08 en
     unifiant les palettes. */
  --tap: 48px;

  /* ── Ombres — basses et diffuses, jamais un contour dur ───────────────
     Chez Huawei, ce qui sépare deux plans est l'ombre et l'espace, pas une
     bordure de plus. Une carte n'a **pas** de contour : elle a une ombre. */
  --ombre: 0 1px 2px rgba(24, 36, 49, .03), 0 4px 16px rgba(24, 36, 49, .05);
  --ombre-haute: 0 2px 8px rgba(24, 36, 49, .06), 0 16px 40px rgba(24, 36, 49, .1);

  /* ── Rythme — les marges nommées de HarmonyOS ────────────────────────
       ohos_id_max_padding_start / _end        24 vp   la marge d'une vue
       ohos_id_card_margin_start / _end / _middle  12 vp   entre deux cartes
       ohos_id_elements_margin_vertical_l / _m  16 / 8 vp
       ohos_id_elements_margin_horizontal_l / _m  16 / 8 vp */
  --pas: 4px;
  --marge-vue: 24px;
  --marge-carte: 12px;
  --marge-l: 16px;
  --marge-m: 8px;
  --menu-large: 232px;
  --barre-haute: 56px;
}

@media (prefers-color-scheme: dark) {
  /* ⚠️ HarmonyOS ne noircit pas ses gris : il **inverse l'encre** et garde les
     mêmes taux de contenu — `ohos_id_color_primary_dark` est le blanc à 90 %,
     comme l'encre claire est le #182431 à 90 %. Une seule règle à tenir dans
     les deux modes, au lieu de deux palettes qui divergent.

       ohos_id_alpha_content_primary_dark  0.86  (et non 0.9 : le blanc sur
       fond sombre éblouit plus vite que le noir sur fond clair) */
  :root {
    --fond: #000000;             /* ohos_id_color_sub_background_dark */
    --surface: #191919;          /* ohos_id_color_background_dark */
    --surface-2: #202020;
    --surface-3: #2A2A2A;
    --encre-source: 255, 255, 255;
    /* Même déviation qu'en clair, et pour la même raison. Le blanc sur fond
       sombre atteint la norme un peu plus bas que l'inverse : 0,86 · 0,7 · 0,6. */
    --encre:   rgba(255, 255, 255, .86);
    --encre-2: rgba(255, 255, 255, .7);
    --encre-3: rgba(255, 255, 255, .6);
    --encre-4:     rgba(255, 255, 255, .34);
    --encre-icone: rgba(255, 255, 255, .4);
    --trait: rgba(255, 255, 255, .1);
    --trait-2: rgba(255, 255, 255, .06);
    --remplissage: rgba(255, 255, 255, .08);
    --remplissage-fort: rgba(255, 255, 255, .12);
    --accent: #D9524E;
    --accent-vif: #E56763;
    --accent-doux: rgba(217, 82, 78, .16);
    --accent-trait: rgba(217, 82, 78, .34);
    --accent-encre: #FAFAFA;
    --ok: #63BC8B;      --ok-fond: #11251A;      --ok-trait: #23422F;
    --alerte: #DBAE50;  --alerte-fond: #272013;  --alerte-trait: #48391C;
    --danger: #E9776B;  --danger-fond: #2A1614;  --danger-trait: #4C2621;
    --info: #74B4DD;    --info-fond: #12222C;    --info-trait: #23404F;
    --ombre: 0 1px 2px rgba(0, 0, 0, .4), 0 4px 16px rgba(0, 0, 0, .3);
    --ombre-haute: 0 2px 8px rgba(0, 0, 0, .5), 0 16px 40px rgba(0, 0, 0, .45);
  }
}

/* ═══════════════════════════════════════════════════════════════════════════
   La coque — barre, menu, vue

   Une grille de deux colonnes et deux rangées. Le menu et la barre tiennent
   seuls ; c'est la vue qui défile. Sur un CRM, on passe la journée dans le
   même écran : le menu ne doit jamais disparaître sous le défilement.
   ═══════════════════════════════════════════════════════════════════════════ */

.coque {
  display: grid;
  grid-template-columns: var(--menu-large) 1fr;
  grid-template-rows: var(--barre-haute) 1fr;
  grid-template-areas: 'marque barre' 'menu vue';
  min-height: 100vh;
  background: var(--fond);
  color: var(--encre);
  font-family: var(--ui);
  font-size: 14px;
  line-height: 1.5;
}

/* ── La marque, au-dessus du menu ─────────────────────────────────────
   **Daniel, 09/08 : « même les logos ».** Le bloc portait un nom en serif de
   17 px suivi d'une baseline en capitales interlettrées — la signature d'un
   cabinet de conseil, pas d'un produit Huawei.

   Ce que fait Huawei d'une marque dans une interface : un mot, une seule
   graisse, aucune capitale forcée, aucun interlettrage, et **beaucoup de vide
   autour**. La marque n'a pas à se défendre : elle est déjà chez elle.

   ⚠️ Le serif reste réservé aux pièces contractuelles — devis, CCTP. Il n'a
   rien à faire dans une coque d'application. */
.coque-marque {
  grid-area: marque;
  display: flex;
  align-items: baseline;
  gap: 8px;
  padding: 0 var(--marge-vue);
  background: var(--surface);
  text-decoration: none;
  color: inherit;
}
.coque-marque b {
  font-family: var(--ui);
  font-size: var(--t-sous-titre);
  font-weight: 600;
  letter-spacing: -.01em;
  color: var(--encre);
}
.coque-marque span {
  font-size: var(--t-corps-s);
  font-weight: 400;
  color: var(--encre-3);
}

/* ── La barre du haut ─────────────────────────────────────────────────── */
/* ⚠️ Ni la barre ni le menu ne portent de filet. Trois filets qui se croisent
   au coin supérieur gauche découpent l'écran en cases ; Huawei sépare par la
   couleur du plan — la coque est blanche, la vue est #F1F3F5 — et par le vide. */
.coque-barre {
  grid-area: barre;
  display: flex;
  align-items: center;
  gap: var(--marge-l);
  padding: 0 var(--marge-vue);
  background: var(--surface);
}
.coque-titre {
  font-size: var(--t-sous-titre);
  font-weight: 500;
  color: var(--encre);
}
.coque-barre-fin {
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: 14px;
  color: var(--encre-3);
  font-size: 13px;
}

/* Pastille d'état. Elle dit que la page est vivante, jamais qu'un chiffrage
   est bon — les alertes du devis ont leur propre place, dans la vue. */
.coque-etat {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  font-size: 12.5px;
}
.coque-etat::before {
  content: '';
  width: 7px; height: 7px;
  border-radius: var(--r-capsule);
  background: var(--ok);
}
.coque-etat.hors::before { background: var(--alerte); }
.coque-etat.hors { color: var(--alerte); }

.coque-compte {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  color: var(--encre-2);
  font-weight: 500;
}
.coque-pastille {
  width: 28px; height: 28px;
  border-radius: var(--r-capsule);
  background: var(--accent-doux);
  color: var(--accent);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: .02em;
}

/* ── Le menu latéral ──────────────────────────────────────────────────── */
.coque-menu {
  grid-area: menu;
  background: var(--surface);
  padding: var(--marge-m) 12px var(--marge-l);
  display: flex;
  flex-direction: column;
  gap: 2px;
  overflow-y: auto;
}

/* Un intitulé de groupe se lit en `body3`, encre tertiaire, casse normale —
   comme les sections des réglages HarmonyOS. */
.coque-menu-groupe {
  padding: var(--marge-l) 12px 6px;
  font-size: var(--t-corps-s);
  font-weight: 400;
  color: var(--encre-3);
}

.coque-lien {
  display: flex;
  align-items: center;
  gap: 11px;
  padding: 10px 14px;
  border-radius: var(--r-menu);   /* ohos_id_corner_radius_menu — 20 vp */
  color: var(--encre-2);
  text-decoration: none;
  font-size: var(--t-corps);
  font-weight: 400;
  transition: background-color .2s ease, color .2s ease;
}
.coque-lien:hover { background: var(--remplissage); color: var(--encre); }
/* Le pictogramme du menu — 24 px, c'est la taille des icônes de liste
   HarmonyOS. Il prend l'encre du lien, donc l'accent sur la section courante. */
.coque-lien .p-picto { width: 22px; height: 22px; color: var(--encre-icone); }

/* La section courante. Le seul endroit du menu où l'accent paraît : il
   répond à « où suis-je », qui est la question que ce menu existe pour
   régler. */
.coque-lien[aria-current='page'] {
  background: var(--accent-doux);
  color: var(--accent);
  font-weight: 500;
}
.coque-lien[aria-current='page'] .p-picto { color: var(--accent); }

/* ⚠️ Un lien qui change de nom d'hôte le dit. Le paramétrage vit derrière un
   certificat client, sur son propre hôte : le clic peut échouer chez qui n'a
   pas le certificat, et l'utilisateur doit savoir que la porte est ailleurs. */
.coque-lien-externe::after {
  content: '↗';
  margin-left: auto;
  font-size: 12px;
  color: var(--encre-4);
}

.coque-menu-pied {
  margin-top: auto;
  padding: 12px;
  font-size: var(--t-corps-s);
  color: var(--encre-3);
  border-top: 1px solid var(--trait-2);
}
/* ⛔ La mention exigée par l'article 2.1 de la licence HarmonyOS Sans. Elle
   est discrète, jamais cachée : `display: none` ou une couleur égale au fond
   nous mettraient hors licence aussi sûrement que de la supprimer.

   ⚠️ Elle était en `--encre-4` — 2,3:1, illisible. « Prominent notice » et
   « contraste 2,3 » ne vont pas ensemble : une mention qu'on ne peut pas lire
   ne remplit pas l'obligation qu'elle prétend remplir. Encre de texte, et
   `--t-corps-s` plutôt que `--t-legende` : 10 px à faible contraste, c'était
   deux défauts qui se renforçaient. */
.coque-mention {
  display: block;
  margin-top: 4px;
  font-size: var(--t-corps-s);
  color: var(--encre-3);
  line-height: 1.4;
}

/* ── La vue ───────────────────────────────────────────────────────────── */
.coque-vue {
  grid-area: vue;
  padding: 28px 32px 64px;
  overflow-y: auto;
  max-width: 1400px;
  width: 100%;
}

/* ── Étroit : le menu passe en barre horizontale ──────────────────────── */
@media (max-width: 860px) {
  .coque {
    grid-template-columns: 1fr;
    grid-template-rows: var(--barre-haute) auto 1fr;
    grid-template-areas: 'barre' 'menu' 'vue';
  }
  .coque-marque { display: none; }
  .coque-menu {
    flex-direction: row;
    overflow-x: auto;
    border-right: none;
    border-bottom: 1px solid var(--trait);
    padding: 8px 12px;
    scrollbar-width: none;
  }
  .coque-menu::-webkit-scrollbar { display: none; }
  .coque-menu-groupe, .coque-menu-pied { display: none; }
  .coque-lien { white-space: nowrap; }
  .coque-lien-externe::after { margin-left: 4px; }
  .coque-vue { padding: 20px 16px 48px; }
}

@media print {
  .coque-barre, .coque-menu, .coque-marque { display: none; }
  .coque { display: block; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   Éléments partagés
   ═══════════════════════════════════════════════════════════════════════════ */

/* ⚠️ `headline6` — 30 vp. Le titre de vue faisait 22 px : chez Huawei, un
   titre de page est GRAND et léger. C'est lui qui porte la respiration de
   l'écran, et un titre timide fait une page dense même quand elle ne l'est
   pas. La graisse descend de 600 à 500 : la taille suffit à hiérarchiser. */
.p-titre-vue {
  font-size: var(--t-titre);
  font-weight: 500;
  letter-spacing: -.02em;
  line-height: 1.2;
  margin: 0 0 6px;
}
.p-sous-titre {
  color: var(--encre-3);
  font-size: var(--t-corps);
  margin: 0 0 var(--marge-vue);
}

/* ⛔ Une carte n'a PAS de contour : elle a une ombre et un rayon de 24.
   `ohos_id_corner_radius_card` = 24 vp, `ohos_id_max_padding_start` = 24 vp.
   Le contour et l'ombre ensemble donnent le cadre épais des interfaces de
   gestion — exactement ce que Daniel ne reconnaissait pas comme du Huawei. */
.p-carte {
  background: var(--surface);
  border-radius: var(--r-carte);
  box-shadow: var(--ombre);
  padding: var(--marge-vue);
}

/* ⚠️ Le titre de carte n'est PAS une capitale espacée. Huawei titre en
   `sub_title2` (16 fp), poids moyen, encre principale — la hiérarchie vient
   de la taille et de l'espace, jamais d'un traitement de casse. */
.p-carte-titre {
  font-size: var(--t-sous-titre);
  font-weight: 500;
  color: var(--encre);
  margin: 0 0 var(--marge-l);
}

.p-grille {
  display: grid;
  gap: 16px;
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
}

/* ── Tuile de chiffre ──────────────────────────────────────────────────
   Le chiffre en grand et léger, son libellé au-dessus en petit : c'est la
   hiérarchie de ce langage, et elle se lit d'un mètre.

   ⚠️ Les chiffres sont tabulaires. Une colonne de montants qui ne s'aligne
   pas se relit mal, et c'est sur ces colonnes qu'on décide. */
.p-tuile {
  background: var(--surface);
  border-radius: var(--r-l);
  box-shadow: var(--ombre);
  padding: 20px 22px;
}
.p-tuile-libelle {
  font-size: var(--t-corps-s);
  font-weight: 400;
  color: var(--encre-3);
}
.p-tuile-valeur {
  font-size: 30px;
  font-weight: 300;
  letter-spacing: -.02em;
  margin-top: 8px;
  font-variant-numeric: tabular-nums;
  color: var(--encre);
}
.p-tuile-valeur.accent { color: var(--accent); }
.p-tuile-note {
  font-size: 12px;
  color: var(--encre-3);
  margin-top: 4px;
}

/* ── Boutons — capsule, un seul accentué par écran ────────────────────── */
/* ── Boutons ──────────────────────────────────────────────────────────
   ⛔ **La capsule vient des DEUX sources à la fois, et c'est ce qui rend la
   décision de Daniel du 07/08 compatible avec celle du 09/08.** Le bouton de
   dsdrenov.com est une capsule ; `ButtonType.Capsule` est le type **par
   défaut** du bouton ArkUI, dont le rayon vaut la moitié de la hauteur. Il
   n'y a rien à arbitrer sur la forme.

   ⛔ **Les capitales, elles, ne se concilient pas.** Huawei n'écrit jamais un
   libellé de bouton en capitales — ni sur consumer.huawei.com, ni dans
   HarmonyOS. Elles sont retirées ; la teinte, l'encre #FAFAFA et la capsule
   du site restent. C'est le seul point du bouton dsdrenov qui tombe, et il
   se rétablit en une ligne si Daniel le préfère.

   Le bouton secondaire n'a PAS de contour : il a un remplissage. Un écran
   qui aligne six boutons cerclés se lit comme un formulaire ; six boutons
   remplis se lisent comme une barre d'actions.
     ohos_id_color_component_normal  #182431 à 10 %
     ohos_id_text_size_button2       14 fp */
.p-bouton {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--marge-m);
  padding: 10px 20px;
  border-radius: var(--r-capsule);
  border: 0;
  background: var(--remplissage);
  color: var(--encre);
  font-family: var(--ui);
  font-size: var(--t-corps);
  font-weight: 500;
  cursor: pointer;
  transition: background-color .2s ease, opacity .2s ease;
}
.p-bouton:hover { background: var(--remplissage-fort); }
.p-bouton:disabled { opacity: .38; cursor: not-allowed; }
.p-bouton:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

.p-bouton.accent {
  background: var(--accent);
  color: var(--accent-encre);
  font-weight: 500;
  padding: 10px 24px;
}
.p-bouton.accent:hover { background: var(--accent-vif); }

/* Le bouton de texte — l'action tertiaire de HarmonyOS : ni fond, ni contour,
   seulement l'emphase. Il porte les actions qu'on ne veut pas mettre en
   avant, sans les cacher. */
.p-bouton.texte {
  background: none;
  color: var(--accent);
  padding: 10px 12px;
}
.p-bouton.texte:hover { background: var(--accent-doux); }

/* ── Champs ───────────────────────────────────────────────────────────── */
/* ── Champs de saisie ─────────────────────────────────────────────────
   ⛔ **C'est la signature la plus reconnaissable de ce langage, et le socle
   du 07/08 ne l'avait pas.** Un champ HarmonyOS est **rempli et sans
   contour**, avec un grand rayon : `ohos_id_corner_radius_text_field` vaut
   20 vp, et le fond est `ohos_id_color_component_normal`, l'encre à 10 %.

   Un champ cerclé de 1 px à rayon 8, c'est le formulaire d'administration
   que Daniel a reconnu au premier coup d'œil comme n'étant pas du Huawei.

   Le contour n'apparaît qu'au foyer, et il porte l'accent : dans ce langage,
   le cadre est un état, pas une décoration permanente. */
.p-champ {
  width: 100%;
  padding: 11px 16px;
  border-radius: var(--r-champ);
  border: 0;
  box-shadow: inset 0 0 0 1px transparent;
  background: var(--remplissage);
  color: var(--encre);
  font-family: var(--ui);
  font-size: var(--t-corps);
  transition: background-color .2s ease, box-shadow .2s ease;
}
.p-champ::placeholder { color: var(--encre-3); }
.p-champ:hover { background: var(--remplissage-fort); }
.p-champ:focus {
  outline: none;
  background: var(--surface);
  box-shadow: inset 0 0 0 1px var(--accent), 0 0 0 3px var(--accent-doux);
}
.p-champ:disabled { opacity: .38; cursor: not-allowed; }

/* Une zone de texte garde le remplissage, mais pas le rayon de 20 : sur
   quatre lignes, un rayon de capsule mange le premier mot. */
textarea.p-champ { border-radius: var(--r-s); line-height: 1.55; resize: vertical; }

.p-etiquette-champ {
  display: block;
  font-size: var(--t-corps-s);
  font-weight: 400;
  color: var(--encre-2);
  margin-bottom: 6px;
  padding-left: 4px;
}

/* ── Étiquettes d'état ────────────────────────────────────────────────── */
.p-etiquette {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: .02em;
  padding: 3px 10px;
  border-radius: var(--r-capsule);
  background: var(--surface-3);
  color: var(--encre-3);
}
.p-etiquette.ok      { background: var(--ok-fond);      color: var(--ok); }
.p-etiquette.alerte  { background: var(--alerte-fond);  color: var(--alerte); }
.p-etiquette.danger  { background: var(--danger-fond);  color: var(--danger); }
.p-etiquette.info    { background: var(--info-fond);    color: var(--info); }
.p-etiquette.accent  { background: var(--accent-doux);  color: var(--accent); }

/* ── Tableaux ─────────────────────────────────────────────────────────── */
.p-tableau {
  width: 100%;
  border-collapse: collapse;
  font-size: 13.5px;
}
/* ⚠️ Ni capitales ni interlettrage : `body3` (12 fp) en encre tertiaire.
   L'en-tête de colonne se distingue par sa légèreté, pas par son insistance. */
.p-tableau th {
  text-align: left;
  font-size: var(--t-corps-s);
  font-weight: 500;
  color: var(--encre-3);
  padding: 0 12px 10px;
  border-bottom: 1px solid var(--trait);
  white-space: nowrap;
}
.p-tableau td {
  padding: 12px;
  border-bottom: 1px solid var(--trait-2);
  color: var(--encre-2);
}
.p-tableau tr:last-child td { border-bottom: none; }
.p-tableau tbody tr:hover td { background: var(--surface-2); }
/* Les colonnes de montants et de quantités s'alignent au chiffre. */
.p-tableau .num {
  text-align: right;
  font-variant-numeric: tabular-nums;
  color: var(--encre);
}

/* ── Message vide ─────────────────────────────────────────────────────── */
.p-vide {
  text-align: center;
  padding: 40px 24px;
  color: var(--encre-3);
  font-size: 13.5px;
}

/* ── Bandeau de réserve ────────────────────────────────────────────────
   Une réserve non levée se montre ; la taire ferait passer un chiffrage
   provisoire pour un chiffrage arrêté. */
/* ⚠️ Elle GARDE son filet, contre la règle « pas de contour » ci-dessus.
   Une réserve arrête ; elle a le droit d'être la seule chose encadrée de
   l'écran. C'est ce qui la distingue d'une carte au premier coup d'œil. */
.p-reserve {
  border-radius: var(--r);
  padding: 14px 18px;
  font-size: 13px;
  background: var(--alerte-fond);
  color: var(--alerte);
  border: 1px solid var(--alerte-trait);
}
.p-reserve.danger { background: var(--danger-fond); color: var(--danger); border-color: var(--danger-trait); }
.p-reserve.info   { background: var(--info-fond);   color: var(--info);   border-color: var(--info-trait); }

/* ═══════════════════════════════════════════════════════════════════════════
   Les onglets d'une fiche
   ═══════════════════════════════════════════════════════════════════════════

   **Demande de Daniel, 09/08 : « dans la fiche client il faut un menu avec les
   fonctionnalités, le design doit reprendre Huawei dans ses menus ».**

   Le principe Huawei tenu ici : une barre claire, très aérée, sans cadre ni
   fond — la section courante se marque par un **filet d'accent sous le
   libellé**, jamais par une pastille colorée. L'accent reste rare : il ne
   marque qu'une chose à la fois sur l'écran.

   ⛔ Ce composant vit dans le socle, jamais dans un écran. Deux écrans qui
   dessinent chacun leurs onglets finissent par ne pas avoir les mêmes — c'est
   exactement ce que la demande n° 5 veut supprimer. */

.p-onglets {
  display: flex; gap: 4px; flex-wrap: wrap;
  border-bottom: 1px solid var(--trait);
  margin: 0 0 24px;
}

.p-onglet {
  appearance: none; background: none; border: 0; cursor: pointer;
  font: inherit; font-size: 14px; font-weight: 550; color: var(--encre-3);
  padding: 12px 16px; border-radius: var(--r-s) var(--r-s) 0 0;
  /* Le filet est toujours là, transparent : sans lui le libellé sauterait de
     deux pixels au changement d'onglet. */
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
  transition: color .12s ease, border-color .12s ease, background-color .12s ease;
}

.p-onglet:hover { color: var(--encre); background: var(--surface-2); }

.p-onglet[aria-selected="true"] {
  color: var(--encre);
  border-bottom-color: var(--accent);
}

/* ⚠️ Le foyer se voit, et il ne se confond pas avec la sélection : qui navigue
   au clavier doit savoir où il est avant d'appuyer. */
.p-onglet:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: -2px;
}

/* Un compteur discret dans l'onglet — « Documents 4 ». Il dit ce qu'il y a
   dedans sans qu'on ait à l'ouvrir. */
.p-onglet-compte {
  display: inline-block; margin-left: 8px; padding: 1px 7px;
  border-radius: var(--r-capsule); background: var(--surface-3);
  color: var(--encre-3); font-size: 12px; font-weight: 600;
}
.p-onglet[aria-selected="true"] .p-onglet-compte {
  background: var(--accent-doux); color: var(--accent-vif);
}

.p-panneau { display: none; }
.p-panneau.actif { display: block; }

@media (max-width: 640px) {
  /* Sur un téléphone la barre défile plutôt que de s'empiler : trois lignes
     d'onglets repoussent le contenu hors de l'écran. */
  .p-onglets { flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none; }
  .p-onglets::-webkit-scrollbar { display: none; }
  .p-onglet { white-space: nowrap; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   L'infobulle de contexte
   ═══════════════════════════════════════════════════════════════════════════

   **Demande de Daniel, 09/08 : « tu rédiges trop d'informations dans toutes
   les pages. Il serait plus pratique de faire des fenêtres de contexte qui
   s'affichent quand on survole et qu'on reste dessus. Toutes ces informations
   ne devraient pas être affichées directement, ça fait de la pollution
   visuelle. »**

   Il a raison : l'écran de paramétrage portait neuf paragraphes d'explication
   et sept réserves entières, soit plus de mots que de champs. Une explication
   qu'on lit une fois occupe la place tous les jours.

   ── Ce que ce composant fait, et ce qu'il ne fera jamais ──────────────────

   ⛔ **Ce qui ENGAGE reste affiché.** Une explication se range ici ; un
   avertissement, jamais. Un blocage à l'émission, une réserve non tranchée, un
   refus de droit : ces mentions doivent se voir sans geste. Une alerte derrière
   un survol est une alerte que personne ne lit — et sur un écran tactile, il
   n'y a pas de survol du tout. Ce qui se range ici, c'est le *développement* de
   la mention, jamais son existence.

   ── Pourquoi un bouton, et pas un `title=` ni un `<div>` ──────────────────

   ⚠️ L'attribut `title` du navigateur n'est atteignable ni au clavier, ni au
   doigt, et son délai d'apparition n'est pas réglable. Un `<div>` survolable
   ne l'est pas davantage. Le déclencheur est donc un vrai `<button>` : il
   prend le foyer au clavier, il répond au doigt, et le lecteur d'écran annonce
   son contenu par `aria-describedby`.

   ⚠️ **La bulle est enfant du déclencheur, sans espace entre les deux.** C'est
   ce qui permet « on survole ET on reste dessus » : le pointeur passe du
   bouton à la bulle sans jamais quitter la zone de survol. Une bulle décollée
   de deux pixels disparaîtrait dès qu'on tente de la lire. */

.p-info {
  position: relative;
  display: inline-flex;
  vertical-align: middle;
  margin-left: 6px;
}

/* Le repère : un disque rempli, sans contour — `ohos_id_color_component_normal`.
   Un cercle cerclé au milieu d'un texte fait une pastille de formulaire ;
   rempli, il se lit comme une icône. */
.p-info-declencheur {
  appearance: none; cursor: help;
  display: inline-flex; align-items: center; justify-content: center;
  width: 16px; height: 16px; padding: 0;
  border: 0; border-radius: var(--r-capsule);
  background: var(--remplissage-fort); color: var(--encre-3);
  font: inherit; font-size: 11px; font-weight: 600; line-height: 1;
  font-family: var(--serif); font-style: italic;
  transition: color .2s ease, background-color .2s ease;
}

.p-info-declencheur:hover,
.p-info:focus-within .p-info-declencheur,
.p-info.ouvert .p-info-declencheur {
  color: var(--accent-encre);
  background: var(--accent);
}

.p-info-declencheur:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* ⚠️ Sur un écran tactile, une cible de 17 px est intouchable. La surface
   sensible est agrandie par un pseudo-élément plutôt que par la taille visible :
   le repère reste discret, la cible respecte le minimum. */
@media (pointer: coarse) {
  .p-info-declencheur::after {
    content: ''; position: absolute;
    top: 50%; left: 50%; transform: translate(-50%, -50%);
    width: var(--tap); height: var(--tap);
  }
}

.p-info-bulle {
  position: absolute; z-index: 60;
  top: calc(100% + 2px); left: 50%; transform: translateX(-50%);
  width: max-content; max-width: min(34rem, calc(100vw - 32px));
  padding: var(--marge-l) 18px;
  background: var(--surface); color: var(--encre-2);
  /* ⚠️ Pas de contour : `ohos_id_corner_radius_tips_tips` = 18 vp, et ce qui
     détache la bulle du fond est l'ombre. Un contour + une ombre, c'est
     l'infobulle d'un intranet des années 2010. */
  border: 0; border-radius: var(--r-bulle);
  box-shadow: var(--ombre-haute);
  font-size: var(--t-corps); font-weight: 400; line-height: 1.6; text-align: left;
  white-space: normal;
  /* Cachée sans être retirée : un `display: none` interromprait le survol au
     moment même où le pointeur descend du bouton vers la bulle. */
  opacity: 0; visibility: hidden;
  transition: opacity .12s ease, visibility .12s ease;
}

/* Le pont invisible entre le bouton et la bulle — deux pixels de vide
   suffiraient à faire disparaître la bulle qu'on essaie d'atteindre. */
.p-info-bulle::before {
  content: ''; position: absolute;
  top: -6px; left: 0; right: 0; height: 6px;
}

.p-info:hover .p-info-bulle,
.p-info:focus-within .p-info-bulle,
.p-info.ouvert .p-info-bulle {
  opacity: 1; visibility: visible;
}

/* Près du bord droit, la bulle centrée sortirait de l'écran. */
.p-info.a-gauche .p-info-bulle { left: auto; right: 0; transform: none; }
.p-info.a-droite .p-info-bulle { left: 0; right: auto; transform: none; }

.p-info-bulle b, .p-info-bulle strong { color: var(--encre); font-weight: 650; }

@media (max-width: 640px) {
  /* Sur un téléphone, une bulle ancrée sur un bouton de 17 px déborde toujours.
     Elle s'ancre alors sur la largeur de l'écran. */
  .p-info { position: static; }
  .p-info-bulle {
    left: 16px; right: 16px; transform: none;
    width: auto; max-width: none;
  }
}

/* Le survol n'existe pas partout : sans lui, seul le clic ouvre la bulle. Le
   composant fonctionne déjà ainsi — `.ouvert` est posé par `info.js`. */
@media (prefers-reduced-motion: reduce) {
  .p-info-bulle, .p-info-declencheur { transition: none; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   Les pictogrammes du système
   ═══════════════════════════════════════════════════════════════════════════

   **Daniel, 09/08 : « … bouton, picto… tout ».** Vingt-sept SVG du dépôt
   `openharmony/applications_settings`, sous licence Apache 2.0, servis tels
   que publiés — voir `pictos/NOTICE.txt`.

   ⛔ **Employés en MASQUE, jamais insérés dans la page.** Trois raisons, et
   ce sont elles qui expliquent la forme inhabituelle de ce composant :

   1. ces fichiers portent un `fill="#000000"` en dur. Inséré tel quel, un
      pictogramme resterait noir en mode sombre — invisible sur fond noir.
      En masque, la couleur vient de `currentColor`, donc de l'encre du
      texte, donc du mode ;
   2. ils portent des identifiants internes (`path-1`, `mask-2`) **identiques
      d'un fichier à l'autre**. Deux pictogrammes insérés dans la même page,
      et le second afficherait la forme du premier. En masque, chaque fichier
      reste un document séparé : ses identifiants ne rencontrent jamais ceux
      d'un autre ;
   3. le masque n'exige aucune retouche du fichier — ce qui laisse
      l'attribution Apache 2.0 simple : rien n'a été modifié.

   ⚠️ `mask` ET `-webkit-mask` : Safari n'a toujours pas la propriété nue. */

.p-picto {
  display: inline-block;
  width: 20px; height: 20px;
  flex: none;
  background-color: currentColor;
  -webkit-mask-position: center; mask-position: center;
  -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
  -webkit-mask-size: contain; mask-size: contain;
  vertical-align: -.2em;
}

.p-picto.grand { width: 24px; height: 24px; }
.p-picto.geant { width: 28px; height: 28px; }

/* ── Le chevron d'arborescence ─────────────────────────────────────────────
   C'est LE signe des réglages HarmonyOS : chaque ligne qui mène ailleurs le
   porte, à droite, en encre quaternaire. Une ligne qui ne l'a pas ne mène
   nulle part — et c'est ainsi qu'on lit un écran de réglages sans le lire. */
.p-chevron {
  width: 12px; height: 24px;
  color: var(--encre-icone);
  margin-left: auto;
}

/* ═══════════════════════════════════════════════════════════════════════════
   La grille d'accueil — le bureau d'un téléphone
   ═══════════════════════════════════════════════════════════════════════════

   **Daniel, 09/08 : « je veux que l'accueil ressemble au menu d'un téléphone
   avec des icônes, le même menu que Huawei. »**

   Le bureau HarmonyOS : de grandes tuiles carrées à coins très arrondis, le
   pictogramme en blanc sur un fond plein, le libellé DESSOUS et hors de la
   tuile, beaucoup d'air entre les tuiles. Le rayon d'une icône d'application
   vaut environ 22 % de son côté — c'est le « squircle » de HarmonyOS. */

.p-bureau {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(96px, 1fr));
  gap: 28px 16px;
  margin: 0; padding: 0;
  list-style: none;
}

.p-appli {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  text-decoration: none;
  color: var(--encre);
  border-radius: var(--r-s);
  padding: 4px 0;
}
.p-appli:focus-visible { outline: 2px solid var(--accent); outline-offset: 4px; }

.p-appli-icone {
  position: relative;
  width: 64px; height: 64px;
  border-radius: 14px;               /* ≈ 22 % du côté — le squircle HarmonyOS */
  display: flex; align-items: center; justify-content: center;
  background: var(--accent);
  color: var(--accent-encre);
  box-shadow: var(--ombre);
  transition: transform .18s cubic-bezier(.2,.8,.2,1), box-shadow .18s ease;
}
/* ⚠️ L'appui enfonce l'icône plutôt que de la colorer : c'est le retour
   tactile de HarmonyOS, et il fonctionne au doigt comme à la souris. */
.p-appli:hover .p-appli-icone { transform: translateY(-2px); box-shadow: var(--ombre-haute); }
.p-appli:active .p-appli-icone { transform: scale(.94); }

.p-appli-libelle {
  font-size: var(--t-corps-s);
  font-weight: 400;
  text-align: center;
  line-height: 1.35;
  color: var(--encre-2);
}

/* La pastille de comptage, en haut à droite de l'icône — le badge du bureau. */
.p-appli-badge {
  position: absolute; top: -5px; right: -5px;
  min-width: 20px; height: 20px; padding: 0 6px;
  border-radius: var(--r-capsule);
  background: var(--danger); color: #FFF;
  font-size: 11px; font-weight: 500;
  display: flex; align-items: center; justify-content: center;
  box-shadow: 0 0 0 2px var(--fond);
}

/* ⛔ Les teintes de tuile. L'accent de la marque reste RARE : il ne marque
   que l'action principale du bureau. Les autres tuiles prennent une teinte
   neutre dérivée de l'encre — jamais l'arc-en-ciel d'un bureau grand public,
   qui ferait ressembler un outil de chiffrage à un téléphone personnel. */
.p-appli-icone.sourd  { background: var(--remplissage-fort); color: var(--encre); box-shadow: none; }
.p-appli-icone.encre  { background: var(--encre); color: var(--surface); }

/* ═══════════════════════════════════════════════════════════════════════════
   L'arborescence de réglages — la liste des Paramètres HarmonyOS
   ═══════════════════════════════════════════════════════════════════════════

   **Daniel, 09/08 : « idem pour le paramétrage, fais en sorte de reprendre la
   même arborescence que Huawei. »**

   La forme des Paramètres HarmonyOS : des groupes de lignes dans une carte
   blanche à grand rayon ; chaque ligne porte son pictogramme à gauche, son
   libellé, sa valeur courante en encre secondaire, et le chevron à droite.
   **Le filet de séparation ne va pas jusqu'au bord** : il commence à
   l'aplomb du texte, ce qui fait lire le groupe comme un bloc et non comme
   un tableau. C'est un détail, et c'est celui qui se remarque quand il
   manque. */

.p-liste-reglages {
  background: var(--surface);
  border-radius: var(--r-carte);
  box-shadow: var(--ombre);
  overflow: hidden;
  margin-bottom: var(--marge-carte);
}

.p-ligne-reglage {
  display: flex;
  align-items: center;
  gap: var(--marge-l);
  width: 100%;
  min-height: 60px;
  padding: 12px var(--marge-vue);
  background: none; border: 0;
  font: inherit; font-size: var(--t-corps);
  color: var(--encre);
  text-align: left;
  text-decoration: none;
  cursor: pointer;
  position: relative;
  transition: background-color .15s ease;
}
.p-ligne-reglage:hover { background: var(--remplissage); }
.p-ligne-reglage:active { background: var(--remplissage-fort); }
.p-ligne-reglage:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }

/* Le filet, décalé à l'aplomb du texte — et jamais sous la dernière ligne. */
.p-ligne-reglage + .p-ligne-reglage::before {
  content: '';
  position: absolute; top: 0; left: calc(var(--marge-vue) + 24px + var(--marge-l));
  right: 0; height: 1px;
  background: var(--trait);
}

.p-ligne-icone {
  width: 24px; height: 24px;
  color: var(--encre-2);
}

.p-ligne-corps { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.p-ligne-titre { font-weight: 400; }
.p-ligne-aide  { font-size: var(--t-corps-s); color: var(--encre-3); }

/* La valeur courante, à droite avant le chevron. C'est elle qui permet de
   lire tout un écran de réglages sans en ouvrir un seul. */
.p-ligne-valeur {
  margin-left: auto;
  color: var(--encre-3);
  font-size: var(--t-corps);
  white-space: nowrap;
  overflow: hidden; text-overflow: ellipsis; max-width: 45%;
}
.p-ligne-valeur + .p-chevron { margin-left: 8px; }

/* Le titre d'un groupe, au-dessus de sa carte — jamais dedans. */
.p-groupe-titre {
  font-size: var(--t-corps-s);
  font-weight: 400;
  color: var(--encre-3);
  margin: var(--marge-vue) 4px var(--marge-m);
}

/* ── L'en-tête d'une sous-page ────────────────────────────────────────────
   Retour à gauche, titre au centre de la ligne, rien d'autre. HarmonyOS ne
   met jamais d'action à droite d'un en-tête de réglages : ce qui agit est
   dans la page. */
.p-entete-page {
  display: flex; align-items: center; gap: var(--marge-m);
  margin-bottom: var(--marge-vue);
}
.p-retour {
  display: inline-flex; align-items: center; justify-content: center;
  width: var(--tap); height: var(--tap);
  border: 0; border-radius: var(--r-capsule);
  background: none; color: var(--encre); cursor: pointer;
  margin-left: -12px;
  transition: background-color .15s ease;
}
.p-retour:hover { background: var(--remplissage); }
.p-entete-page h1 { font-size: var(--t-titre-s); font-weight: 500; margin: 0; }

/* ── Le nom de métier de chaque pictogramme ──────────────────────────────
   ⛔ Un nom de MÉTIER, et le fichier d'origine en regard. `ic_users_accounts`
   ne dit rien à qui lit `clients.html` ; `pi-clients` si. Le fichier reste
   nommé comme chez OpenHarmony — c'est lui qui porte l'attribution.

   ⚠️ `mask-image` passe par `--picto` : une seule règle porte le
   comportement, et chaque classe ne déclare qu'une URL. */

.p-picto { -webkit-mask-image: var(--picto); mask-image: var(--picto); }

.pi-accueil { --picto: url('/commun/pictos/ic_settings_system.svg'); }
.pi-clients { --picto: url('/commun/pictos/ic_users_accounts.svg'); }
.pi-affaires { --picto: url('/commun/pictos/ic_public_todo.svg'); }
.pi-devis { --picto: url('/commun/pictos/ic_public_edit.svg'); }
.pi-releve { --picto: url('/commun/pictos/ic_public_mark.svg'); }
.pi-chantier { --picto: url('/commun/pictos/ic_settings_application.svg'); }
.pi-assistant { --picto: url('/commun/pictos/ic_public_notify.svg'); }
.pi-parametrage { --picto: url('/commun/pictos/ic_public_settings.svg'); }
.pi-bibliotheque { --picto: url('/commun/pictos/ic_settings_storage.svg'); }
.pi-comptes { --picto: url('/commun/pictos/ic_user_portrait.svg'); }
.pi-droits { --picto: url('/commun/pictos/ic_settings_privacy.svg'); }
.pi-journal { --picto: url('/commun/pictos/ic_settings_about.svg'); }
.pi-affichage { --picto: url('/commun/pictos/ic_settings_display.svg'); }
.pi-theme { --picto: url('/commun/pictos/ic_settings_theme.svg'); }
.pi-horloge { --picto: url('/commun/pictos/ic_settings_clock.svg'); }
.pi-avance { --picto: url('/commun/pictos/ic_settings_developer.svg'); }
.pi-impression { --picto: url('/commun/pictos/ic_printer.svg'); }
.pi-chevron { --picto: url('/commun/pictos/ic_public_arrow_right.svg'); }
.pi-retour { --picto: url('/commun/pictos/ic_public_back.svg'); }
.pi-recherche { --picto: url('/commun/pictos/ic_public_search.svg'); }
.pi-ajouter { --picto: url('/commun/pictos/ic_add_norm.svg'); }
.pi-supprimer { --picto: url('/commun/pictos/ic_public_delete.svg'); }
.pi-modifier { --picto: url('/commun/pictos/ic_public_pencil.svg'); }
.pi-valider { --picto: url('/commun/pictos/ic_public_ok.svg'); }
.pi-annuler { --picto: url('/commun/pictos/ic_public_cancel.svg'); }
.pi-detail { --picto: url('/commun/pictos/ic_public_detail.svg'); }
.pi-plus { --picto: url('/commun/pictos/ic_public_more.svg'); }
