/* ============================================================================
   theme.css — jeu de tokens de couleur de l'application
   ============================================================================

   PROPRIÉTAIRE UNIQUE DES TOKENS `--sv-*`.

   Aucun autre fichier CSS ne doit déclarer un `--sv-*` : les feuilles de page les
   consomment via `var(--sv-…)`, elles ne les redéfinissent jamais. Une feuille qui
   redéclarerait un token sous son propre scope se détacherait silencieusement du
   thème — c'est exactement le défaut de `landing.css`, qui déclare 23 custom
   properties `:root` non préfixées.

   Une feuille qui a besoin de valeurs qui lui sont propres (rayons, gouttières,
   largeur de rail) les préfixe autrement — `--sva-*` pour l'espace compte — et ces
   valeurs n'ont pas de variante sombre : elles sont invariantes par thème.

   LE THÈME CLAIR EST UNE EXTRACTION DE CE QUI EST EN PRODUCTION — mais pas
   intégralement à l'identique. Trois régimes, à ne pas confondre :

   1. EXTRAIT À L'IDENTIQUE — la valeur existe telle quelle dans les CSS actuels et
      porte sa source en commentaire : --sv-bg, --sv-ink, --sv-accent,
      --sv-accent-hover, --sv-accent-strong, --sv-focus, --sv-navbar. Ainsi que
      --sv-surface-2, --sv-ink-2, --sv-heading, --sv-line, --sv-accent-soft, --sv-ok,
      --sv-warn, --sv-danger, qui existent dans plusieurs fichiers sans source unique.

   2. CONVERGENCE — la notion existe en production sous plusieurs valeurs
      concurrentes, ramenées ici à une seule (cf. les 4 paires « succès » ci-dessous).
      Le pixel bouge sur certains écrans, c'est l'objet du chantier.

   3. ÉCART DÉLIBÉRÉ POUR L'ACCESSIBILITÉ — deux tokens seulement, et ils sont nommés :
      --sv-warn-soft (#f8efdc -> #fbf4e6) et --sv-ink-3 (#6b7280 -> #686e7c).
      Les valeurs d'origine tombaient sous le seuil AA (4,39:1) contre, respectivement,
      --sv-warn et --sv-surface-2. Aucune des deux valeurs d'origine n'était par
      ailleurs une couleur de TEXTE de production : seul le fond a bougé pour warn.
      ⚠️ La couleur de texte #b45309 (account-devices.css:123) est PRÉSERVÉE.

   Les valeurs sans équivalent en production (--sv-line-2, --sv-field-border, les
   *-soft sémantiques, --sv-vault, --sv-scrim, --sv-navbar-ink, --sv-accent-ink)
   sont nouvelles : elles nomment des notions que le CSS actuel exprimait au cas par cas.

   ⛔ PAS DE `@media (prefers-color-scheme: dark)` — PAS AVANT LA FIN DE LA CONVERSION.

   Une media-query bascule les tokens sur la seule préférence OS, sans que personne
   ne l'ait demandé. Tant que les 17 autres feuilles portent leurs couleurs en dur,
   un client en OS sombre verrait les fichiers DÉJÀ convertis passer en sombre et les
   autres rester clairs : cartes sombres sur page claire, texte hérité illisible.
   La conversion se fait fichier par fichier ; une bascule globale et automatique est
   incompatible avec ça.

   Le seul basculement actif est donc `[data-theme]`, posé sur `<html>` PAR LE SERVEUR.
   Il ne se déclenche que si le client l'a explicitement choisi, via le sélecteur de la
   navbar — lui-même derrière le flag `features.dark_theme`, ÉTEINT par défaut.

   Ce flag n'est pas un détail : tant que 16 feuilles sur 18 portent leurs couleurs en dur,
   basculer donnerait des cartes claires sur page sombre et du texte hérité invisible
   (1,03:1 à 1,14:1, mesuré). Il ne s'allume que lorsque `TokenCoverageTest` atteint 0 sur
   les feuilles chargées avec theme.css et 0 dans les attributs `style=` des templates.

   À RÉACTIVER en fin de conversion, avec le mode « système » : réintroduire un bloc
   `@media (prefers-color-scheme: dark)` AVANT les deux blocs `[data-theme]`, pour que
   le choix explicite prime dans les deux sens.

   PAS DE FLASH AU CHARGEMENT : l'attribut `data-theme` est posé sur `<html>` PAR LE
   SERVEUR, au rendu. Un script client qui l'appliquerait après coup produirait un
   flash blanc à chaque navigation.
   ============================================================================ */

:root {
    /* --- Fonds ------------------------------------------------------------ */
    --sv-bg: #f8f9fa;              /* style.css:58 */
    --sv-surface: #ffffff;
    --sv-surface-2: #f3f4f6;       /* fond secondaire, survol */
    /* Panneau volontairement SOMBRE dans les deux thèmes : pied de page, menu mobile
       de la navbar transparente. Il ne s'inverse pas — il s'assombrit. Son encre est
       --sv-navbar-ink, comme la navbar. */
    --sv-surface-inverse: #2c3e50;
    /* Chrome flottant quasi-opaque (flèche de rail musée) : suit --sv-surface, translucide
       pour laisser deviner le rail dessous. Distinct de --sv-surface-2 (opaque, teinte différente). */
    --sv-surface-veil: rgba(255, 255, 255, .95);
    /* Voile de chargement sur du CONTENU (pas du chrome flottant) : plus transparent que
       --sv-surface-veil, suit aussi --sv-surface. */
    --sv-surface-loading-veil: rgba(255, 255, 255, .55);

    /* --- Textes ----------------------------------------------------------- */
    --sv-ink: #333333;             /* style.css:59 */
    --sv-ink-2: #595959;
    --sv-ink-3: #686e7c;
    --sv-heading: #111827;

    /* --- Traits ----------------------------------------------------------- */
    --sv-line: #e5e7eb;
    --sv-line-2: #d3d9e2;
    --sv-field-border: #868c9c;    /* bordure de contrôle de saisie — WCAG 1.4.11 */

    /* --- Survol thématique (s'inverse) -------------------------------------
       Seule famille du fichier qui bascule réellement de couleur de base entre les 2 thèmes
       (contrairement aux voiles sur photo/navbar, invariants, et aux --sv-accent-*, qui suivent
       --sv-accent-ink). Assombrit en clair, éclaircit en sombre, même magnitude d'opacité. */
    --sv-hover-veil: rgba(0, 0, 0, .06); /* survol discret sur un fond neutre --sv-bg/--sv-surface */

    /* --- Accent de marque ------------------------------------------------- */
    --sv-accent: #5b6abf;          /* style.css:71 */
    --sv-accent-hover: #4a58a0;    /* style.css:76 */
    --sv-accent-soft: #eef0fb;
    --sv-accent-ink: #ffffff;      /* encre sur un aplat SATURÉ (accent, ok, warn, danger) */
    --sv-accent-strong: #4a58a0;   /* texte posé SUR --sv-accent-soft (style.css:76) */
    /* Quatrième bordure d'ALERTE (après ok/warn/danger), même rôle : le 3:1 de WCAG 1.4.11
       posé sur --sv-accent-soft. 3,10:1 — légèrement AU-DESSUS de ses frères (3,05 / 3,06 /
       3,07), pas « dans leur fourchette » ; idem en sombre, 3,57 contre 3,47 / 3,50 / 3,53.
       C'est le plus haut des quatre dans les deux palettes.
       Construction : désaturer --sv-accent et éclaircir (HSL 231,44%,55% -> 231,37%,62%).
       ⚠️ Le rapport de désaturation (x0,84) sort de la bande des frères (x0,59 à x0,77) et
       c'est un CHOIX ESTHÉTIQUE assumé, pas une contrainte arithmétique — ne pas le
       rationaliser après coup. La justification « --sv-accent part d'une saturation basse »
       ne tient pas : les 4 bases valent accent 43,9 %, ok 46,2 %, danger 66,4 %, warn 90,5 %
       — --sv-ok part PLUS HAUT qu'accent et a pourtant supporté x0,59 sans virer au gris.
       Et HSL(231,26%,60%) = #7e86b4, soit accent désaturé au ratio d'--sv-ok-border, mesure
       3,105:1, le MÊME ratio que la valeur retenue. Le choix de S=37 % préserve l'identité
       indigo à ratio équivalent, rien de plus. Corollaire : le Lot HTML.15 avait statué que
       c'est l'ÉCART de saturation qui se reproduit (-20 contre -19 et -15) ; ici l'écart est
       de -6,75 seulement (et -12 en sombre contre -29/-23/-46). Ce token suit la métrique du
       RATIO, pas celle de l'écart. Divergence assumée et signalée.
       « Dernière » serait imprudent (l'affirmation a déjà été fausse deux fois sur ce
       chantier) : elle ne vaut que pour les bordures d'alerte posées sur un fond tokenisé
       DANS LA MÊME RÈGLE, seul motif que le grep structurel sait voir. Trois réserves
       connues : (1) les filets sur fond HÉRITÉ lui échappent — style.css:2290,2332,
       séparateurs internes de .subscription-hero-card, #e0e3f0 à 1,13:1 sur --sv-accent-soft ;
       (2) --sv-vault-soft existe sans bordure dédiée (son unique site, documents/index.html:276,
       emprunte --sv-ok-border — 1 site, critère non rempli) ; (3) une famille « info » est
       latente à 2 sites (style.css .export-banner + telecharger.css .telecharger-location-help,
       #eff6ff/#bfdbfe identiques), hors critère tant que son fond n'est pas tokenisé.
       NE PAS confondre avec --sv-accent-strong, qui est l'ENCRE sur --sv-accent-soft
       (seuil 4,5:1) : deux rôles, deux seuils, deux tokens. Même teinte et même
       saturation (231,37%), seule la clarté sépare les deux (46 % contre 62 %).
       Les 3 valeurs qu'il unifie étaient toutes très pâles et sous le 3:1 EN CLAIR
       UNIQUEMENT : #d4d9f7 1,23:1 (style.css .doc-info-banner), #c7d2fe 1,31:1
       (regularisation.html .help-note), #d4d8f0 1,24:1 (style.css .subscription-hero-card
       et pricing.css .subscription-card — cette dernière règle n'est référencée par AUCUN
       template ni JS, elle ne rend aucun pixel : convertie par cohérence de feuille, pas
       pour corriger un défaut visible). En SOMBRE elles passaient très largement (10,37 /
       9,68 / 10,24 sur --sv-accent-soft #232842) : leur défaut y était esthétique — un filet
       blafard criard sur fond nuit — et la conversion y FAIT CHUTER le contraste à 3,57.
       Choix de design assumé, pas un gain d'accessibilité. */
    --sv-accent-border: #7a85c2;
    /* Ouvre la famille des ombres TEINTÉES accent, explicitement exclue du poste box-shadow
       (qui ne traitait que l'encre/noir) et différée depuis. Token COULEUR SEULE, composé avec
       sa propre géométrie — jamais un canon --sv-shadow-N imposé. Anneau de focus : en sombre
       l'accent s'éclaircit mais le fond aussi s'assombrit, l'alpha monte donc pour rester visible. */
    --sv-shadow-accent-color-1: rgba(91, 106, 191, .15);
    --sv-shadow-accent-color-2: rgba(91, 106, 191, .1);
    --sv-shadow-accent-color-3: rgba(91, 106, 191, .4);
    --sv-shadow-accent-color-4: rgba(91, 106, 191, .3);
    /* Variantes translucides de l'encre sur accent, ci-dessus : suivent SA valeur (blanc en clair,
       encre foncée en sombre), pas un blanc fixe — sinon illisible sur un aplat accent en sombre. */
    --sv-accent-ink-dim: rgba(255, 255, 255, .7);     /* texte secondaire sur aplat accent */
    --sv-accent-ink-strong: rgba(255, 255, 255, .85); /* texte proéminent sur aplat accent */
    --sv-accent-veil: rgba(255, 255, 255, .15);       /* survol sur aplat accent */
    --sv-accent-chip: rgba(255, 255, 255, .2);        /* puce statique sur aplat accent */
    --sv-accent-ring: rgba(255, 255, 255, .4);        /* bordure/anneau sur aplat accent */

    /* --- Focus ------------------------------------------------------------ */
    --sv-focus: #4a6fa5;           /* style.css:3 */

    /* --- Sémantique ------------------------------------------------------- */
    /* Trois rôles par famille : l'encre, le fond pastel, et la bordure. Cette dernière
       relève du 3:1 de WCAG 1.4.11 — sur un badge d'état, c'est elle qui distingue
       « en cours » de « terminé » pour qui ne perçoit pas la teinte du fond. */
    /* Quatre paires « succès » différentes coexistent aujourd'hui selon le fichier
       (#d4edda/#155724, #dcfce7/#166534, #d1fae5/#065f46, #e8f5e9/#2e7d32).
       Elles convergent ici sur une seule paire, puis un seul override sombre. */
    --sv-ok: #2e7d32;
    --sv-ok-soft: #e6f5ee;
    --sv-ok-border: #57986d;
    --sv-warn: #b45309;
    --sv-warn-soft: #fbf4e6;
    /* Troisième bordure d'ÉTAT (ok / warn / danger), même construction que --sv-ok-border
       et --sv-danger-border : --sv-warn désaturé et éclairci (HSL 26,90%,37% -> 28,70%,48%),
       3,07:1 sur --sv-warn-soft — aligné sur les 3,05:1 et 3,06:1 de ses deux frères.
       C'est l'ÉCART de saturation qui est reproduit (-20 pts, contre -19 et -15), pas le
       niveau : un ambre descendu à la saturation de --sv-ok-border (27%) virerait au beige.
       PAS la dernière bordure sémantique du projet : --sv-accent-border remplit déjà le
       critère (cf. TokenCoverageTest, style.css:4220 et regularisation.html .help-note).
       Les valeurs qu'il unifie, en palette CLAIRE, échouaient toutes au 3:1 sur leur propre
       fond : #f59e0b 1,96:1 (recuperation.html .warning-card), #ffc107 1,49:1 (photos.css
       .sync-banner.has-uploading), #fef08a 1,13:1 (account-devices.css .banner-yellow).
       En sombre il faut distinguer : les deux posées sur un fond DÉJÀ tokenisé passaient
       largement (#ffc107 9,04:1, #f59e0b 6,86:1) — leur défaut y était l'absence
       d'adaptation, un ambre criard sur fond sombre, pas le contraste. #fef08a en revanche
       avait un fond lui aussi en dur (#fefce8), donc invariant : il restait à 1,13:1 dans
       LES DEUX palettes. Deux défauts distincts, un seul token les corrige. */
    --sv-warn-border: #d07525;
    --sv-danger: #c62828;
    /* Survol d'un aplat --sv-danger, pendant exact de --sv-accent-hover : même rapport
       d'assombrissement (x0,67 en luminosité). 7,71:1 avec --sv-accent-ink. */
    --sv-danger-hover: #a02020;
    --sv-danger-soft: #fbecea;
    /* Symétrique de --sv-ok-border, construit de la même façon : --sv-danger désaturé
       et éclairci (HSL 0,66%,47% -> 0,51%,62%), calibré sur le 3:1 de WCAG 1.4.11 posé
       sur --sv-danger-soft (3,06:1, contre 3,05:1 pour --sv-ok-border).
       Il unifie TROIS valeurs qui ne se valaient pas sur ce fond : #fecaca (1,26:1) et
       #f5c6cb (1,32:1) échouaient au 3:1 — bordure invisible pour qui ne perçoit pas la
       teinte, défaut préexistant au thème sombre — mais #ef4444 le tenait déjà (3,28:1).
       Sur ce dernier site (recuperation.html .error-card) l'uniformisation coûte donc
       0,22 point de contraste, accepté : le bloc reste conforme, et #ef4444 était plus
       saturé que sa propre encre --sv-danger (#c62828), qu'il encadrait. */
    --sv-danger-border: #cf6b6b;

    /* --- Coffre souverain ------------------------------------------------- */
    /* --- Information (neutre, ni succes ni alerte) -------------------------
       Cinquieme famille semantique, la derniere annoncee comme latente. Elle nommait
       jusqu'ici une notion eparpillee sur 5 fichiers et 3 valeurs de fond concurrentes
       (#eff6ff, #dbeafe, #d1ecf1) : badge de statut « ouvert », encarts d'aide, banniere
       d'export, etat « present seulement en local ».
       Construction identique aux 3 autres familles : base 5,88:1 sur son -soft (les freres
       sont a 4,56 / 4,59 / 4,90), bordure calibree au 3:1 de WCAG 1.4.11.
       NE PAS confondre avec --sv-accent (marque) ni --sv-focus (anneau de focus) : les
       trois sont bleus et proches (1,36:1 et 1,31:1 entre eux), mais ce sont trois roles
       distincts, jamais adjacents. La proximite de valeur n'autorise aucune convergence —
       c'est le piege role-vs-valeur du chantier. */
    --sv-info: #1d4ed8;
    --sv-info-soft: #e8f1fd;
    --sv-info-border: #5a85dc;

    /* Posés SUR UNE PHOTO : invariants par thème, comme toute la famille --sv-scrim-*.
       Le fond est l'image, pas la page — il ne s'éclaircit ni ne s'assombrit avec le thème. */
    --sv-scrim-danger: rgba(231, 76, 60, .3);
    --sv-favorite: #f1c40f;
    --sv-favorite-stroke: #e0a800;

    /* Violet compagnon de l'accent, présent uniquement dans des DÉGRADÉS décoratifs
       (bandeaux d'en-tête). Il n'est jamais une couleur de texte ni de fond plein. */
    --sv-accent-violet: #8b5cf6;
    --sv-accent-violet-deep: #3d2b7a;
    /* Bandeau sombre en dégradé : sombre dans les DEUX thèmes, comme --sv-surface-inverse
       dont il est la variante dégradée. Bundlé en UN token, jamais en stops séparés. */
    --sv-panel-dark-gradient: linear-gradient(90deg, #1a1a2e 0%, #16213e 100%);
    /* Ombres à TEINTE NAVY, distinctes de --sv-navbar-shadow et de l'encre/noir des
       --sv-shadow-color-N : famille différée depuis le poste box-shadow, ouverte ici.
       Les alphas .1 et .08 sont fusionnés (écart 20 %, seuil retenu pour une fusion). */
    --sv-shadow-navy-color-1: rgba(31, 35, 86, .28);
    --sv-shadow-navy-color-2: rgba(31, 35, 86, .18);
    --sv-shadow-navy-color-3: rgba(31, 35, 86, .1);
    /* Alpha très bas de la famille accent : voile de survol à peine perceptible. */
    --sv-shadow-accent-color-5: rgba(91, 106, 191, .04);

    /* Sémantique posée sur un aplat INVARIANT sombre (page d'atterrissage de l'app, chrome
       de visionneuse). --sv-ok et --sv-info y seraient illisibles : ils sont calibrés pour un
       fond clair. Ces deux-là sont invariants, comme le fond qui les porte. */
    --sv-scrim-ok: #4ade80;
    --sv-scrim-info: #93c5fd;
    /* Fond de la page d'atterrissage mobile : dégradé bleu nuit à 3 arrêts, bundlé en UN
       token comme --sv-panel-dark-gradient. */
    --sv-hero-dark-gradient: linear-gradient(135deg, #1a1f3a 0%, #2c3e6b 50%, #1a1f3a 100%);

    --sv-vault: #1f7a52;
    --sv-vault-soft: #e6f5ee;

    /* --- Navbar ----------------------------------------------------------- */
    /* Déjà sombre en thème clair : en sombre il sera ASSOMBRI, pas inversé — sinon
       la navbar deviendrait plus claire que la page. */
    --sv-navbar: linear-gradient(110deg, #2a2f63 0%, #353b82 50%, #454da3 100%); /* style.css:80 */
    --sv-navbar-ink: #ffffff;
    /* La navbar reste sombre dans les deux thèmes (cf. ci-dessus) : ces blancs translucides
       aussi, même logique que --sv-navbar-ink. */
    --sv-navbar-hairline: rgba(255, 255, 255, .08);     /* filet de séparation */
    --sv-navbar-ink-dim: rgba(255, 255, 255, .85);       /* lien de nav au repos */
    --sv-navbar-veil: rgba(255, 255, 255, .12);          /* survol d'un lien/icône */
    --sv-navbar-veil-strong: rgba(255, 255, 255, .18);   /* lien actif */
    --sv-navbar-ring: rgba(255, 255, 255, .22);          /* liseré interne du lien actif */
    --sv-navbar-pill: rgba(255, 255, 255, .08);          /* fond d'une pastille (sélecteur de langue) */
    /* Ombre portée SOUS le lien actif, sur le fond de la navbar — toujours sombre elle aussi (cf.
       ci-dessus) : même encre, même logique d'invariance que le reste de cette famille. */
    --sv-navbar-shadow: rgba(0, 0, 0, .12);              /* style.css:224 — .navbar-nav a.active */

    /* --- Élévations ------------------------------------------------------- */
    /* Une ombre noire est invisible sur fond sombre : chaque niveau est redéfini
       en sombre avec une opacité accrue. */
    --sv-shadow-1: 0 1px 2px rgba(27, 35, 48, .05);
    --sv-shadow-2: 0 2px 8px rgba(27, 35, 48, .08);
    --sv-shadow-3: 0 8px 24px rgba(27, 35, 48, .12);
    /* Couleur SEULE, pour les box-shadow dont la géométrie (décalage/flou/étalement) ne matche
       aucun des 3 canons ci-dessus — la majorité des cas mesurés. Composer avec SA propre
       géométrie (ex. `box-shadow: 0 8px 20px var(--sv-shadow-color-1)`) pour préserver le rendu
       exact du thème clair : forcer une géométrie bespoke vers --sv-shadow-1/2/3 la changerait,
       une régression, pas une conversion. Même teinte que --sv-shadow-1/2/3 (rgba(27,35,48,α) en
       clair, rgba(0,0,0,α) en sombre) ; alpha propre à chaque cas, un nouvel index par valeur
       rencontrée, pas de tentative de les faire correspondre aux 3 index de --sv-shadow-1/2/3.
       EXCEPTION : si la géométrie d'un site DONNÉ matche EXACTEMENT (décalage+flou+étalement) l'un
       des 3 canons, réutiliser --sv-shadow-1/2/3 tel quel plutôt que d'ajouter un token couleur —
       une convergence d'alpha y est acceptable SI l'écart relatif à la plus petite des deux valeurs
       ne dépasse pas ~20 % (cf. pricing.css:27,757 → --sv-shadow-3, .1→.12, écart 20 %). Au-delà,
       garder un token couleur bespoke : factures.css:51,130,237 (0 2px 8px, géométrie identique à
       --sv-shadow-2) a son alpha à .05 contre .08 pour --sv-shadow-2, écart 60 % — aurait triplé
       l'intensité perçue sur 3 éléments de la même page, refusé, cf. --sv-shadow-color-2 ci-dessous.
       MÊME SEUIL pour fusionner deux tokens couleur-seule entre eux plutôt que d'en garder un par
       valeur d'alpha rencontrée (sans quoi la seule famille encre/noir explose vers ~13 tokens, cf.
       PÉRIMÈTRE ci-dessous) : --sv-shadow-color-2 fusionne .05 (factures.css) et .06 (pricing.css),
       écart 20 %, même rôle (ombre de carte au repos, discrète).
       RÈGLE DE RATIO clair->sombre (pour éviter de réinventer un chiffre à chaque lot) : reprendre
       le ratio du canon dont la géométrie est la plus proche en ordre de grandeur — ×8 si proche de
       --sv-shadow-1 (décalage ~1px/flou ~2px), ×6.25 si proche de --sv-shadow-2 (~2px/~8px), ×5 si
       proche de --sv-shadow-3 (~8px/~24px). Pas d'interpolation plus fine : la précision au pixel
       près n'a pas de sens ici, c'est une case à choisir, pas un calcul.
       ⚠️ PÉRIMÈTRE : cette famille (teinte encre/noir fixe) ne couvre qu'un sous-ensemble des
       box-shadow restants. Mesuré une fois pour toute la suite du poste (hors ce fichier) : ~53
       occurrences encre/noir (cette famille), mais aussi ~23 teintées --sv-accent littéral
       (rgba(91,106,191,α), ex. musee.css:55,186,222,325,459 ; style.css:1710,2195 — thématiques,
       suivraient --sv-accent, pas cette famille) et des ombres MULTI-COUCHES avec teinte bleu-nuit
       distincte (rgba(15,23,42,α), ex. musee.css:89,94,727 — deux rgba par déclaration, le modèle
       "géométrie propre + un seul var(--sv-shadow-color-N)" ne s'applique pas tel quel). Prévoir une
       famille de tokens séparée (ex. --sv-shadow-accent-color-N) pour l'accent avant de convertir
       ces cas — ne pas forcer vers cette famille-ci. */
    /* Fusion .12/.14/.15 (écarts 7 % et 17 %, tous < 20 %) : collections.css:71 (hover carte
       collection), photos.css (.photo-item:hover, .context-menu), style.css (.album-card:hover,
       .dt-toast, .doc-context-menu — seul à .12, un repos et non un survol, mais même famille
       « popup/carte élevée », cf. prompt de reprise pour le détail site par site), #legal-info-bar. */
    --sv-shadow-color-1: rgba(27, 35, 48, .14);
    /* Fusion .05/.06 (écart 20 %, même rôle « carte/tableau au repos ») : factures.css, pricing.css,
       photos.css, et 7 sites de style.css (.feature-card, .card, .stat-card, .device-card:hover,
       .table, .stat-card-mini, .doc-folder-card:hover — détail au prompt de reprise). Ratio ×6.25
       (canon --sv-shadow-2). */
    --sv-shadow-color-2: rgba(27, 35, 48, .06);
    --sv-shadow-color-3: rgba(27, 35, 48, .08); /* aide.css:146, style.css:868 (.qr-code-image) — carte au survol/repos, ratio ×6.25 (canon --sv-shadow-2) */
    /* Alpha .1, entre --sv-shadow-color-3 (.08) et le canon --sv-shadow-3 (.12) — ni l'un ni l'autre
       à moins de 20 % (25 % et 20 % pile, ce dernier hors géométrie de toute façon). Ratio ×5,5,
       interpolé entre celui de -3 (×6,25) et celui du canon --sv-shadow-3 (×5). 3 sites style.css :
       .btn-google:hover, .album-card, .dt-wrapper. */
    --sv-shadow-color-7: rgba(27, 35, 48, .1);
    /* Alpha .04, sous le seuil de tout token existant (écart 25 % même avec le plus proche, -1 canon
       .05). Ratio ×8, plafond déjà établi pour le bas de l'échelle (canon --sv-shadow-1). Site unique :
       style.css:1355 (.settings-card, ombre très discrète d'une carte de réglages). */
    --sv-shadow-color-8: rgba(27, 35, 48, .04);
    /* Alphas de départ nettement plus élevés (.2-.4, éléments spectaculaires : ghost de suppression,
       modale, popup flottant, canevas d'édition) que la famille -1/2/3 (.06-.14, élévation discrète
       de carte). Le barème de ratio ci-dessus (×5 à ×8, calé sur la géométrie des canons
       --sv-shadow-1/2/3) ferait dépasser 1 (ex. .3×5 = 1,5) : hors de son domaine de validité — il
       n'est PAS extrapolé ici (le point .05→×8 lui appartient, pas à cette famille couleur-seule,
       dont les ratios réels sont plus modestes : .06/.08→×6,25, .14→×5). Choix assumé, pas calculé :
       dark plafonne à .70, le max déjà en usage (--sv-shadow-color-1), quel que soit l'alpha clair de
       départ — cohérent avec une saturation perceptuelle (au-delà d'un certain point, une ombre déjà
       très marquée en clair n'a plus besoin d'être renforcée à due proportion en sombre), au prix
       d'une hiérarchie clair (.14 / .3 / .4) qui s'aplatit en sombre (.5-.7, proches). Accepté ici car
       ces sites ne sont jamais visibles côte à côte à l'écran. */
    --sv-shadow-color-4: rgba(27, 35, 48, .3);  /* photos.css et style.css:4021 — .fly-to-trash (règle dupliquée dans les 2 feuilles, alpha identique) ; photos.css .modal-content */
    /* Fusion .18/.2 (écart 11 %) : .filters-panel MOBILE (photos.css, media query, feuille modale
       plein écran) rejoint .floating-date-label/.toast (alpha .2 natif). Distinct du cas rejeté au
       Lot 3bis.10 sur .filters-overlay (le scrim plein écran de la MÊME feuille, .4→.5, écart 25 %,
       déjà hors seuil) : ici la propriété est le box-shadow du panneau (fine bande floue en bord de
       feuille, salience nettement plus faible qu'un aplat plein écran), pas son fond. Alpha .2 natif
       repris tel quel par 5 sites supplémentaires de style.css (.album-card-move/rename-btn,
       .doc-zip-panel [.18, même fusion], .modal-content documents, .doc-drag-count-badge,
       .wizard-modal) — détail au prompt de reprise. */
    --sv-shadow-color-5: rgba(27, 35, 48, .2);  /* photos.css — .floating-date-label, .toast, .filters-panel (mobile) */
    --sv-shadow-color-6: rgba(27, 35, 48, .4);  /* photos.css — .editor-canvas-wrapper canvas, alpha le plus élevé du poste */

    /* --- Voiles sur photo ------------------------------------------------- */
    /* INVARIANTS : posés sur une image, jamais sur du chrome. Ils ne basculent pas. */
    --sv-scrim: rgba(0, 0, 0, .55);
    --sv-scrim-soft: rgba(0, 0, 0, .25);

    /* Contrôles posés SUR un voile (barre du diaporama) : le voile reste sombre dans
       les deux thèmes, donc ces blancs translucides aussi — même logique que
       --sv-navbar-ink, pas --sv-accent-ink (qui s'éclaircit en sombre). */
    --sv-scrim-control: rgba(255, 255, 255, .12);         /* bouton au repos */
    --sv-scrim-control-active: rgba(255, 255, 255, .2);   /* bouton actif / lecture */
    --sv-scrim-control-hover: rgba(255, 255, 255, .28);   /* survol */
    --sv-scrim-track: rgba(255, 255, 255, .15);           /* piste de progression */
    --sv-scrim-fill: rgba(255, 255, 255, .85);            /* remplissage de progression */
    --sv-scrim-ink-dim: rgba(255, 255, 255, .65);         /* texte secondaire sur voile */
    --sv-scrim-ink-strong: rgba(255, 255, 255, .9);       /* lien/texte proéminent sur voile */

    /* Visionneuse musée (topbar + nav flottants sur la photo) */
    --sv-scrim-bar: rgba(0, 0, 0, .45);          /* fond topbar/nav, et ombre portée du titre */
    --sv-scrim-bar-hover: rgba(0, 0, 0, .7);      /* survol du nav */
    --sv-scrim-gradient: rgba(0, 0, 0, .72);      /* dégradé de assombrissement sous le hero */

    /* Grille de vignettes + lightbox photo (photos.css) */
    --sv-scrim-thumb: rgba(0, 0, 0, .6);          /* étiquette/badge flottant sur une vignette */
    --sv-scrim-panel: rgba(0, 0, 0, .3);          /* puce/bandeau compact sur fond invariant sombre */
    --sv-scrim-caption: rgba(0, 0, 0, .8);        /* dégradé sous la légende de la lightbox */
    --sv-scrim-backdrop: rgba(0, 0, 0, .92);      /* fond plein de la lightbox */
    --sv-scrim-modal: rgba(0, 0, 0, .5);          /* voile derrière une boîte de dialogue */
    --sv-scrim-sheet: rgba(0, 0, 0, .4);          /* voile derrière une feuille modale (bottom sheet) */
    --sv-scrim-ink-faint: rgba(255, 255, 255, .3); /* séparateur/texte très atténué sur voile */
    --sv-scrim-border: rgba(255, 255, 255, .4);    /* bordure translucide sur voile (survol) */

    /* Cartes de collections (photo de couverture + titre superposé) */
    --sv-card-scrim: linear-gradient(to top, rgba(0, 0, 0, .6) 0%, rgba(0, 0, 0, .1) 32%, rgba(0, 0, 0, 0) 60%);
    --sv-card-text-shadow: rgba(0, 0, 0, .4);     /* lisibilité du texte posé sur la photo */
}

/* Choix explicite du client — prime sur la préférence système, dans les deux sens. */

/* ============================================================================
   MODE « AUTOMATIQUE » — suit la préférence système, sans choix explicite du client.

   Réintroduit à la FIN de la conversion, comme prévu depuis le début. Tant que des
   feuilles portaient leurs couleurs en dur, cette media-query aurait rendu les
   fichiers déjà convertis sombres au milieu de pages restées claires. Ce n'est plus
   le cas : le cliquet est à zéro sur les trois surfaces (CSS, gabarits, JavaScript).

   ⚠️ ELLE DOIT RESTER AVANT LES DEUX BLOCS [data-theme], ET C'EST TESTÉ.
   Les deux ont la même spécificité de départ, donc c'est l'ORDRE qui décide. Placée
   après, elle écraserait le choix explicite du client : quelqu'un en OS sombre ayant
   demandé « clair » obtiendrait quand même du sombre. Le bug serait invisible pour
   quiconque n'est pas dans cette configuration précise.

   Le contenu est identique au bloc [data-theme="dark"] ci-dessous — c'est la même
   palette, atteinte par deux chemins : la préférence système ici, le choix explicite
   là. Toute modification doit porter sur LES DEUX (ThemeTokensTest le vérifie).
   ============================================================================ */
@media (prefers-color-scheme: dark) {
    :root {
        color-scheme: dark;

        --sv-bg: #12141d;
        --sv-surface: #1a1d29;
        --sv-surface-2: #232733;
        --sv-surface-inverse: #1b2430;
        --sv-surface-veil: rgba(26, 29, 41, .95); /* = --sv-surface #1a1d29 */
        --sv-surface-loading-veil: rgba(26, 29, 41, .55);

        --sv-ink: #eef0f6;
        --sv-ink-2: #b3bbcd;
        --sv-ink-3: #8b93a8;
        --sv-heading: #f5f7fb;

        --sv-line: #2b3040;
        --sv-line-2: #3a4055;
        --sv-field-border: #767e96;
        --sv-hover-veil: rgba(255, 255, 255, .06);

        --sv-accent: #8f9be0;
        --sv-accent-hover: #aab4ea;
        --sv-accent-soft: #232842;
        --sv-accent-ink: #12141d;
        --sv-accent-strong: #aab4ea;
        /* Miroir : --sv-accent désaturé et ASSOMBRI (HSL 231,57%,72% -> 231,45%,60%),
           3,57:1 sur --sv-accent-soft. Pas « même construction » au sens strict : l'écart de
           saturation est de -12, contre -29 / -23 / -46 pour ok / warn / danger. Calé sur le
           ratio, comme en clair. */
        --sv-accent-border: #6b79c7;
        --sv-shadow-accent-color-1: rgba(143, 155, 224, .3);
        --sv-shadow-accent-color-2: rgba(143, 155, 224, .22);
        --sv-shadow-accent-color-3: rgba(143, 155, 224, .55);
        --sv-shadow-accent-color-4: rgba(143, 155, 224, .45);
        --sv-accent-ink-dim: rgba(18, 20, 29, .7);
        --sv-accent-ink-strong: rgba(18, 20, 29, .85);
        --sv-accent-veil: rgba(18, 20, 29, .15);
        --sv-accent-chip: rgba(18, 20, 29, .2);
        --sv-accent-ring: rgba(18, 20, 29, .4);

        --sv-focus: #8fb0e0;

        --sv-ok: #5fd39b;
        --sv-ok-soft: #16302a;
        --sv-ok-border: #4d8a6e;
        --sv-warn: #e0b063;
        --sv-warn-soft: #302713;
        /* Même construction, miroir : --sv-warn désaturé et ASSOMBRI
           (HSL 37,67%,63% -> 37,44%,42%), 3,53:1 sur --sv-warn-soft. */
        --sv-warn-border: #9a763c;
        --sv-danger: #f0897a;
        /* Miroir : en sombre le survol ÉCLAIRCIT, comme --sv-accent-hover (x1,36). */
        --sv-danger-hover: #f5a196;
        --sv-danger-soft: #331c1a;
        /* Même construction qu'en clair, miroir : --sv-danger désaturé et ASSOMBRI
           (HSL 8,80%,71% -> 7,34%,51%), 3,50:1 sur --sv-danger-soft — aligné sur les
           3,47:1 de --sv-ok-border dans cette palette. */
        --sv-danger-border: #ad6157;

        --sv-info: #8ab4f8;
        --sv-info-soft: #16233a;
        --sv-info-border: #4f76c4;

        --sv-scrim-danger: rgba(231, 76, 60, .3);
        --sv-favorite: #f1c40f;
        --sv-favorite-stroke: #e0a800;

        --sv-accent-violet: #a78bfa;
        --sv-accent-violet-deep: #5b4a9e;
        --sv-panel-dark-gradient: linear-gradient(90deg, #12121f, #0f1729);
        --sv-shadow-navy-color-1: rgba(0, 0, 0, .6);
        --sv-shadow-navy-color-2: rgba(0, 0, 0, .5);
        --sv-shadow-navy-color-3: rgba(0, 0, 0, .35);
        --sv-shadow-accent-color-5: rgba(143, 155, 224, .1);

        --sv-scrim-ok: #4ade80;
        --sv-scrim-info: #93c5fd;
        --sv-hero-dark-gradient: linear-gradient(135deg, #1a1f3a 0%, #2c3e6b 50%, #1a1f3a 100%);

        --sv-vault: #4fd3b0;
        --sv-vault-soft: #12302c;

        --sv-navbar: linear-gradient(110deg, #1a1d3a 0%, #23264f 50%, #2c3163 100%);
        --sv-navbar-ink: #eef0f6;
        --sv-navbar-hairline: rgba(255, 255, 255, .08);
        --sv-navbar-ink-dim: rgba(255, 255, 255, .85);
        --sv-navbar-veil: rgba(255, 255, 255, .12);
        --sv-navbar-veil-strong: rgba(255, 255, 255, .18);
        --sv-navbar-ring: rgba(255, 255, 255, .22);
        --sv-navbar-pill: rgba(255, 255, 255, .08);
        --sv-navbar-shadow: rgba(0, 0, 0, .12);

        --sv-shadow-1: 0 1px 2px rgba(0, 0, 0, .40);
        --sv-shadow-2: 0 2px 8px rgba(0, 0, 0, .50);
        --sv-shadow-3: 0 8px 24px rgba(0, 0, 0, .60);
        --sv-shadow-color-1: rgba(0, 0, 0, .70);
        --sv-shadow-color-2: rgba(0, 0, 0, .38);
        --sv-shadow-color-3: rgba(0, 0, 0, .50);
        --sv-shadow-color-4: rgba(0, 0, 0, .60);
        --sv-shadow-color-5: rgba(0, 0, 0, .50);
        --sv-shadow-color-6: rgba(0, 0, 0, .70);
        --sv-shadow-color-7: rgba(0, 0, 0, .55);
        --sv-shadow-color-8: rgba(0, 0, 0, .32);

        --sv-scrim: rgba(0, 0, 0, .55);
        --sv-scrim-soft: rgba(0, 0, 0, .25);

        --sv-scrim-control: rgba(255, 255, 255, .12);
        --sv-scrim-control-active: rgba(255, 255, 255, .2);
        --sv-scrim-control-hover: rgba(255, 255, 255, .28);
        --sv-scrim-track: rgba(255, 255, 255, .15);
        --sv-scrim-fill: rgba(255, 255, 255, .85);
        --sv-scrim-ink-dim: rgba(255, 255, 255, .65);
        --sv-scrim-ink-strong: rgba(255, 255, 255, .9);

        --sv-scrim-bar: rgba(0, 0, 0, .45);
        --sv-scrim-bar-hover: rgba(0, 0, 0, .7);
        --sv-scrim-gradient: rgba(0, 0, 0, .72);

        --sv-scrim-thumb: rgba(0, 0, 0, .6);
        --sv-scrim-panel: rgba(0, 0, 0, .3);
        --sv-scrim-caption: rgba(0, 0, 0, .8);
        --sv-scrim-backdrop: rgba(0, 0, 0, .92);
        --sv-scrim-modal: rgba(0, 0, 0, .5);
        --sv-scrim-sheet: rgba(0, 0, 0, .4);
        --sv-scrim-ink-faint: rgba(255, 255, 255, .3);
        --sv-scrim-border: rgba(255, 255, 255, .4);

        --sv-card-scrim: linear-gradient(to top, rgba(0, 0, 0, .6) 0%, rgba(0, 0, 0, .1) 32%, rgba(0, 0, 0, 0) 60%);
        --sv-card-text-shadow: rgba(0, 0, 0, .4);
    }
}

:root[data-theme="dark"] {
    color-scheme: dark;

    --sv-bg: #12141d;
    --sv-surface: #1a1d29;
    --sv-surface-2: #232733;
    --sv-surface-inverse: #1b2430;
    --sv-surface-veil: rgba(26, 29, 41, .95); /* = --sv-surface #1a1d29 */
    --sv-surface-loading-veil: rgba(26, 29, 41, .55);

    --sv-ink: #eef0f6;
    --sv-ink-2: #b3bbcd;
    --sv-ink-3: #8b93a8;
    --sv-heading: #f5f7fb;

    --sv-line: #2b3040;
    --sv-line-2: #3a4055;
    --sv-field-border: #767e96;
    --sv-hover-veil: rgba(255, 255, 255, .06);

    --sv-accent: #8f9be0;
    --sv-accent-hover: #aab4ea;
    --sv-accent-soft: #232842;
    --sv-accent-ink: #12141d;
    --sv-accent-strong: #aab4ea;
    /* Miroir : --sv-accent désaturé et ASSOMBRI (HSL 231,57%,72% -> 231,45%,60%),
       3,57:1 sur --sv-accent-soft. Pas « même construction » au sens strict : l'écart de
       saturation est de -12, contre -29 / -23 / -46 pour ok / warn / danger. Calé sur le
       ratio, comme en clair. */
    --sv-accent-border: #6b79c7;
    --sv-shadow-accent-color-1: rgba(143, 155, 224, .3);
    --sv-shadow-accent-color-2: rgba(143, 155, 224, .22);
    --sv-shadow-accent-color-3: rgba(143, 155, 224, .55);
    --sv-shadow-accent-color-4: rgba(143, 155, 224, .45);
    --sv-accent-ink-dim: rgba(18, 20, 29, .7);
    --sv-accent-ink-strong: rgba(18, 20, 29, .85);
    --sv-accent-veil: rgba(18, 20, 29, .15);
    --sv-accent-chip: rgba(18, 20, 29, .2);
    --sv-accent-ring: rgba(18, 20, 29, .4);

    --sv-focus: #8fb0e0;

    --sv-ok: #5fd39b;
    --sv-ok-soft: #16302a;
    --sv-ok-border: #4d8a6e;
    --sv-warn: #e0b063;
    --sv-warn-soft: #302713;
    /* Même construction, miroir : --sv-warn désaturé et ASSOMBRI
       (HSL 37,67%,63% -> 37,44%,42%), 3,53:1 sur --sv-warn-soft. */
    --sv-warn-border: #9a763c;
    --sv-danger: #f0897a;
    /* Miroir : en sombre le survol ÉCLAIRCIT, comme --sv-accent-hover (x1,36). */
    --sv-danger-hover: #f5a196;
    --sv-danger-soft: #331c1a;
    /* Même construction qu'en clair, miroir : --sv-danger désaturé et ASSOMBRI
       (HSL 8,80%,71% -> 7,34%,51%), 3,50:1 sur --sv-danger-soft — aligné sur les
       3,47:1 de --sv-ok-border dans cette palette. */
    --sv-danger-border: #ad6157;

    --sv-info: #8ab4f8;
    --sv-info-soft: #16233a;
    --sv-info-border: #4f76c4;

    --sv-scrim-danger: rgba(231, 76, 60, .3);
    --sv-favorite: #f1c40f;
    --sv-favorite-stroke: #e0a800;

    --sv-accent-violet: #a78bfa;
    --sv-accent-violet-deep: #5b4a9e;
    --sv-panel-dark-gradient: linear-gradient(90deg, #12121f, #0f1729);
    --sv-shadow-navy-color-1: rgba(0, 0, 0, .6);
    --sv-shadow-navy-color-2: rgba(0, 0, 0, .5);
    --sv-shadow-navy-color-3: rgba(0, 0, 0, .35);
    --sv-shadow-accent-color-5: rgba(143, 155, 224, .1);

    --sv-scrim-ok: #4ade80;
    --sv-scrim-info: #93c5fd;
    --sv-hero-dark-gradient: linear-gradient(135deg, #1a1f3a 0%, #2c3e6b 50%, #1a1f3a 100%);

    --sv-vault: #4fd3b0;
    --sv-vault-soft: #12302c;

    --sv-navbar: linear-gradient(110deg, #1a1d3a 0%, #23264f 50%, #2c3163 100%);
    --sv-navbar-ink: #eef0f6;
    --sv-navbar-hairline: rgba(255, 255, 255, .08);
    --sv-navbar-ink-dim: rgba(255, 255, 255, .85);
    --sv-navbar-veil: rgba(255, 255, 255, .12);
    --sv-navbar-veil-strong: rgba(255, 255, 255, .18);
    --sv-navbar-ring: rgba(255, 255, 255, .22);
    --sv-navbar-pill: rgba(255, 255, 255, .08);
    --sv-navbar-shadow: rgba(0, 0, 0, .12);

    --sv-shadow-1: 0 1px 2px rgba(0, 0, 0, .40);
    --sv-shadow-2: 0 2px 8px rgba(0, 0, 0, .50);
    --sv-shadow-3: 0 8px 24px rgba(0, 0, 0, .60);
    --sv-shadow-color-1: rgba(0, 0, 0, .70);
    --sv-shadow-color-2: rgba(0, 0, 0, .38);
    --sv-shadow-color-3: rgba(0, 0, 0, .50);
    --sv-shadow-color-4: rgba(0, 0, 0, .60);
    --sv-shadow-color-5: rgba(0, 0, 0, .50);
    --sv-shadow-color-6: rgba(0, 0, 0, .70);
    --sv-shadow-color-7: rgba(0, 0, 0, .55);
    --sv-shadow-color-8: rgba(0, 0, 0, .32);

    --sv-scrim: rgba(0, 0, 0, .55);
    --sv-scrim-soft: rgba(0, 0, 0, .25);

    --sv-scrim-control: rgba(255, 255, 255, .12);
    --sv-scrim-control-active: rgba(255, 255, 255, .2);
    --sv-scrim-control-hover: rgba(255, 255, 255, .28);
    --sv-scrim-track: rgba(255, 255, 255, .15);
    --sv-scrim-fill: rgba(255, 255, 255, .85);
    --sv-scrim-ink-dim: rgba(255, 255, 255, .65);
    --sv-scrim-ink-strong: rgba(255, 255, 255, .9);

    --sv-scrim-bar: rgba(0, 0, 0, .45);
    --sv-scrim-bar-hover: rgba(0, 0, 0, .7);
    --sv-scrim-gradient: rgba(0, 0, 0, .72);

    --sv-scrim-thumb: rgba(0, 0, 0, .6);
    --sv-scrim-panel: rgba(0, 0, 0, .3);
    --sv-scrim-caption: rgba(0, 0, 0, .8);
    --sv-scrim-backdrop: rgba(0, 0, 0, .92);
    --sv-scrim-modal: rgba(0, 0, 0, .5);
    --sv-scrim-sheet: rgba(0, 0, 0, .4);
    --sv-scrim-ink-faint: rgba(255, 255, 255, .3);
    --sv-scrim-border: rgba(255, 255, 255, .4);

    --sv-card-scrim: linear-gradient(to top, rgba(0, 0, 0, .6) 0%, rgba(0, 0, 0, .1) 32%, rgba(0, 0, 0, 0) 60%);
    --sv-card-text-shadow: rgba(0, 0, 0, .4);
}

:root[data-theme="light"] {
    color-scheme: light;

    --sv-bg: #f8f9fa;
    --sv-surface: #ffffff;
    --sv-surface-2: #f3f4f6;
    --sv-surface-inverse: #2c3e50;
    --sv-surface-veil: rgba(255, 255, 255, .95);
    --sv-surface-loading-veil: rgba(255, 255, 255, .55);

    --sv-ink: #333333;
    --sv-ink-2: #595959;
    --sv-ink-3: #686e7c;
    --sv-heading: #111827;

    --sv-line: #e5e7eb;
    --sv-line-2: #d3d9e2;
    --sv-field-border: #868c9c;    /* bordure de contrôle de saisie — WCAG 1.4.11 */
    --sv-hover-veil: rgba(0, 0, 0, .06);

    --sv-accent: #5b6abf;
    --sv-accent-hover: #4a58a0;
    --sv-accent-soft: #eef0fb;
    --sv-accent-ink: #ffffff;
    --sv-accent-strong: #4a58a0;
    --sv-accent-border: #7a85c2;
    --sv-shadow-accent-color-1: rgba(91, 106, 191, .15);
    --sv-shadow-accent-color-2: rgba(91, 106, 191, .1);
    --sv-shadow-accent-color-3: rgba(91, 106, 191, .4);
    --sv-shadow-accent-color-4: rgba(91, 106, 191, .3);
    --sv-accent-ink-dim: rgba(255, 255, 255, .7);
    --sv-accent-ink-strong: rgba(255, 255, 255, .85);
    --sv-accent-veil: rgba(255, 255, 255, .15);
    --sv-accent-chip: rgba(255, 255, 255, .2);
    --sv-accent-ring: rgba(255, 255, 255, .4);

    --sv-focus: #4a6fa5;

    --sv-ok: #2e7d32;
    --sv-ok-soft: #e6f5ee;
    --sv-ok-border: #57986d;
    --sv-warn: #b45309;
    --sv-warn-soft: #fbf4e6;
    --sv-warn-border: #d07525;
    --sv-danger: #c62828;
    --sv-danger-hover: #a02020;
    --sv-danger-soft: #fbecea;
    --sv-danger-border: #cf6b6b;

    --sv-info: #1d4ed8;
    --sv-info-soft: #e8f1fd;
    --sv-info-border: #5a85dc;

    --sv-scrim-danger: rgba(231, 76, 60, .3);
    --sv-favorite: #f1c40f;
    --sv-favorite-stroke: #e0a800;

    --sv-accent-violet: #8b5cf6;
    --sv-accent-violet-deep: #3d2b7a;
    --sv-panel-dark-gradient: linear-gradient(90deg, #1a1a2e 0%, #16213e 100%);
    --sv-shadow-navy-color-1: rgba(31, 35, 86, .28);
    --sv-shadow-navy-color-2: rgba(31, 35, 86, .18);
    --sv-shadow-navy-color-3: rgba(31, 35, 86, .1);
    --sv-shadow-accent-color-5: rgba(91, 106, 191, .04);

    --sv-scrim-ok: #4ade80;
    --sv-scrim-info: #93c5fd;
    --sv-hero-dark-gradient: linear-gradient(135deg, #1a1f3a 0%, #2c3e6b 50%, #1a1f3a 100%);

    --sv-vault: #1f7a52;
    --sv-vault-soft: #e6f5ee;

    --sv-navbar: linear-gradient(110deg, #2a2f63 0%, #353b82 50%, #454da3 100%);
    --sv-navbar-ink: #ffffff;
    --sv-navbar-hairline: rgba(255, 255, 255, .08);
    --sv-navbar-ink-dim: rgba(255, 255, 255, .85);
    --sv-navbar-veil: rgba(255, 255, 255, .12);
    --sv-navbar-veil-strong: rgba(255, 255, 255, .18);
    --sv-navbar-ring: rgba(255, 255, 255, .22);
    --sv-navbar-pill: rgba(255, 255, 255, .08);
    --sv-navbar-shadow: rgba(0, 0, 0, .12);

    --sv-shadow-1: 0 1px 2px rgba(27, 35, 48, .05);
    --sv-shadow-2: 0 2px 8px rgba(27, 35, 48, .08);
    --sv-shadow-3: 0 8px 24px rgba(27, 35, 48, .12);
    --sv-shadow-color-1: rgba(27, 35, 48, .14);
    --sv-shadow-color-2: rgba(27, 35, 48, .06);
    --sv-shadow-color-3: rgba(27, 35, 48, .08);
    --sv-shadow-color-4: rgba(27, 35, 48, .3);
    --sv-shadow-color-5: rgba(27, 35, 48, .2);
    --sv-shadow-color-6: rgba(27, 35, 48, .4);
    --sv-shadow-color-7: rgba(27, 35, 48, .1);
    --sv-shadow-color-8: rgba(27, 35, 48, .04);

    --sv-scrim: rgba(0, 0, 0, .55);
    --sv-scrim-soft: rgba(0, 0, 0, .25);

    --sv-scrim-control: rgba(255, 255, 255, .12);
    --sv-scrim-control-active: rgba(255, 255, 255, .2);
    --sv-scrim-control-hover: rgba(255, 255, 255, .28);
    --sv-scrim-track: rgba(255, 255, 255, .15);
    --sv-scrim-fill: rgba(255, 255, 255, .85);
    --sv-scrim-ink-dim: rgba(255, 255, 255, .65);
    --sv-scrim-ink-strong: rgba(255, 255, 255, .9);

    --sv-scrim-bar: rgba(0, 0, 0, .45);
    --sv-scrim-bar-hover: rgba(0, 0, 0, .7);
    --sv-scrim-gradient: rgba(0, 0, 0, .72);

    --sv-scrim-thumb: rgba(0, 0, 0, .6);
    --sv-scrim-panel: rgba(0, 0, 0, .3);
    --sv-scrim-caption: rgba(0, 0, 0, .8);
    --sv-scrim-backdrop: rgba(0, 0, 0, .92);
    --sv-scrim-modal: rgba(0, 0, 0, .5);
    --sv-scrim-sheet: rgba(0, 0, 0, .4);
    --sv-scrim-ink-faint: rgba(255, 255, 255, .3);
    --sv-scrim-border: rgba(255, 255, 255, .4);

    --sv-card-scrim: linear-gradient(to top, rgba(0, 0, 0, .6) 0%, rgba(0, 0, 0, .1) 32%, rgba(0, 0, 0, 0) 60%);
    --sv-card-text-shadow: rgba(0, 0, 0, .4);
}

