diff --git a/.github/workflows/check-pr.yml b/.github/workflows/check-pr.yml new file mode 100644 index 0000000..becdeb1 --- /dev/null +++ b/.github/workflows/check-pr.yml @@ -0,0 +1,69 @@ +name: Vérification des pull requests (build et PDF) + +# Mêmes étapes de construction que le déploiement, sans déploiement ni secret : +# le site et les PDF du livre blanc sont validés avant fusion, et les PDF joints en artefact pour relecture. + +on: + pull_request: + branches: ["main"] + +concurrency: + group: "check-pr-${{ github.event.pull_request.number }}" + cancel-in-progress: true + +permissions: + contents: read + +jobs: + check: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + persist-credentials: false + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: "3.12" + cache: pip + + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -r requirements.txt -r requirements-pdf.txt + sudo apt-get update + sudo apt-get install -y libpango-1.0-0 libpangoft2-1.0-0 poppler-utils + + - name: Build documentation + run: mkdocs build --strict + + - name: Export whitepaper PDF + run: python scripts/export_pdf.py + + - name: Cache veraPDF + uses: actions/cache@v4 + with: + path: ~/.cache/verapdf + key: verapdf-1.30.2 + + - name: Validate PDF/UA-1 + run: bash scripts/check_pdf_ua.sh + + # Polices embarquées : Inter pour le texte ; toute autre police signale un glyphe absent d'Inter + - name: List embedded fonts + run: | + for pdf in site/livre-blanc/otspi-livre-blanc.pdf site/white-paper/otspi-white-paper.pdf; do + echo "== $pdf" + pdffonts "$pdf" + done + + - name: Upload PDF + uses: actions/upload-artifact@v4 + with: + name: livre-blanc-pdf + path: | + site/livre-blanc/otspi-livre-blanc.pdf + site/white-paper/otspi-white-paper.pdf + retention-days: 14 diff --git a/docs/assets/fonts/inter/OFL.txt b/docs/assets/fonts/inter/OFL.txt new file mode 100644 index 0000000..40589da --- /dev/null +++ b/docs/assets/fonts/inter/OFL.txt @@ -0,0 +1,93 @@ +Copyright 2016 The Inter Project Authors (https://github.com/rsms/inter) Inter-Italic[opsz,wght].ttf: Copyright 2016 The Inter Project Authors (https://github.com/rsms/inter) + +This Font Software is licensed under the SIL Open Font License, Version 1.1. +This license is copied below, and is also available with a FAQ at: +http://scripts.sil.org/OFL + + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. diff --git a/docs/assets/fonts/inter/inter-latin-300-normal.woff2 b/docs/assets/fonts/inter/inter-latin-300-normal.woff2 new file mode 100644 index 0000000..ece952c Binary files /dev/null and b/docs/assets/fonts/inter/inter-latin-300-normal.woff2 differ diff --git a/docs/assets/fonts/inter/inter-latin-400-italic.woff2 b/docs/assets/fonts/inter/inter-latin-400-italic.woff2 new file mode 100644 index 0000000..9e98286 Binary files /dev/null and b/docs/assets/fonts/inter/inter-latin-400-italic.woff2 differ diff --git a/docs/assets/fonts/inter/inter-latin-400-normal.woff2 b/docs/assets/fonts/inter/inter-latin-400-normal.woff2 new file mode 100644 index 0000000..f15b025 Binary files /dev/null and b/docs/assets/fonts/inter/inter-latin-400-normal.woff2 differ diff --git a/docs/assets/fonts/inter/inter-latin-600-normal.woff2 b/docs/assets/fonts/inter/inter-latin-600-normal.woff2 new file mode 100644 index 0000000..d189794 Binary files /dev/null and b/docs/assets/fonts/inter/inter-latin-600-normal.woff2 differ diff --git a/docs/assets/fonts/inter/inter-latin-700-italic.woff2 b/docs/assets/fonts/inter/inter-latin-700-italic.woff2 new file mode 100644 index 0000000..48b6e5b Binary files /dev/null and b/docs/assets/fonts/inter/inter-latin-700-italic.woff2 differ diff --git a/docs/assets/fonts/inter/inter-latin-700-normal.woff2 b/docs/assets/fonts/inter/inter-latin-700-normal.woff2 new file mode 100644 index 0000000..a68fb10 Binary files /dev/null and b/docs/assets/fonts/inter/inter-latin-700-normal.woff2 differ diff --git a/docs/assets/fonts/inter/inter-latin-800-normal.woff2 b/docs/assets/fonts/inter/inter-latin-800-normal.woff2 new file mode 100644 index 0000000..74a16d4 Binary files /dev/null and b/docs/assets/fonts/inter/inter-latin-800-normal.woff2 differ diff --git a/docs/assets/logo-vertical-dark.svg b/docs/assets/logo-vertical-dark.svg index 93009c3..ceab211 100644 --- a/docs/assets/logo-vertical-dark.svg +++ b/docs/assets/logo-vertical-dark.svg @@ -1,11 +1,5 @@ - - - - - - + fill-rule="evenodd" /> + + @@ -29,10 +25,10 @@ stroke-width="14.40" stroke-linecap="round" stroke-linejoin="round" /> - + OTSPI - + OPEN TRUSTED SERVICE PROVIDER INITIATIVE diff --git a/docs/cadrage/index.md b/docs/cadrage/index.md index f03d2d2..59896ee 100644 --- a/docs/cadrage/index.md +++ b/docs/cadrage/index.md @@ -6,7 +6,7 @@ Ce dossier rassemble l'ensemble des documents de cadrage stratégique, réglemen --- -## 🏛️ Le Socle de Conformité Initial (Corpus d'Audit) +## Le socle de conformité initial (corpus d'audit) 1. **[Cadre Général des Politiques de Certification et Pratiques (CP/CPS)](cp-cps-cadre.md)** : - Document maître conforme à la **RFC 3647**, à l'**ETSI EN 319 401**, à l'**ETSI EN 319 411-1 / 411-2** et aux exigences **WebTrust / CA/Browser Forum** ; @@ -28,7 +28,7 @@ Ce dossier rassemble l'ensemble des documents de cadrage stratégique, réglemen --- -## 🧭 Documents Complémentaires de Cadrage +## Documents complémentaires de cadrage - **[Livre blanc](../livre-blanc/index.md)** : vision et modèle d'intérêt général à but non lucratif inspiré de l'ISRG / Let's Encrypt appliqué aux services qualifiés eIDAS. - **[Manifeste pour une identité numérique libre et ouverte](https://www.otspi.org/manifeste.html)** : dix principes ouverts à la signature des personnes et des organisations. @@ -37,7 +37,7 @@ Ce dossier rassemble l'ensemble des documents de cadrage stratégique, réglemen --- -## 🔒 Principes d'Auditabilité et Sécurité +## Principes d'auditabilité et de sécurité - Tous les documents de cadrage normatifs sont publics et consultables en libre accès dans le cadre de la redevabilité publique intégrale ; - Les seules exceptions concernent les secrets cryptographiques matériels (clés sous séquestre HSM) et les embargos temporaires de sécurité sur les vulnérabilités non corrigées (*Coordinated Vulnerability Disclosure*). diff --git a/docs/index.md b/docs/index.md index 7f54fdb..18242f1 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,106 +1,95 @@ --- title: "OTSPI — Open Trusted Service Provider Initiative" description: "Portail officiel de gouvernance, statuts, conformité et documentation d'intérêt général pour la confiance numérique européenne." +template: home.html hide: - navigation - toc --- -
+ -:material-shield-check: Association d'intérêt général (loi 1901) en cours de constitution +
-# Open Trusted Service Provider Initiative +
+:material-bank-outline:{ .otspi-feature__icon } -

-Construire, opérer et pérenniser des infrastructures de confiance numérique ouvertes, souveraines et universellement accessibles, conformes aux standards eIDAS 2.0, ETSI et WebTrust sous gouvernance strictement désintéressée. -

+

100 % intérêt général

-
-[:material-book-open-page-variant: Consulter le projet de statuts](statuts/statuts-association.md){ .md-button .md-button--primary } -[:material-draw-pen: Signer le Manifeste](https://www.otspi.org/manifeste.html){ .md-button } -[:material-github: Dépôt GitHub](https://github.com/otspi/organisation){ .md-button target="_blank" } +Gestion désintéressée, bénévolat strict des dirigeants, inaliénabilité des logiciels libres et des marques.
-
+
+:material-certificate-outline:{ .otspi-feature__icon } -
+

eIDAS 2.0 et ETSI

-
-🏛️ -
100% Intérêt Général
-

Gestion désintéressée, bénévolat strict des dirigeants, inaliénabilité des logiciels libres et des marques.

+Services de confiance qualifiés : horodatage, signature, scellement et archivage probatoire sous audit CAB.
-
-🇪🇺 -
eIDAS 2.0 & ETSI
-

Services de confiance qualifiés : horodatage, signature, scellement et archivage probatoire sous audit CAB.

-
+
+:material-scale-balance:{ .otspi-feature__icon } -
-⚖️ -
Séparation des Devoirs
-

Indépendance absolue du Comité des Politiques de Confiance (CPC) vis-à-vis du Bureau exécutif.

-
+

Séparation des devoirs

-
-🔍 -
Redevabilité Intégrale
-

Transparence totale des PV, budgets prévisionnels, rapports d'audit et politiques de certification (CP/CPS).

+Indépendance absolue du Comité des Politiques de Confiance (CPC) vis-à-vis du Bureau exécutif.
+
+:material-magnify-scan:{ .otspi-feature__icon } + +

Redevabilité intégrale

+ +Transparence totale des PV, budgets prévisionnels, rapports d'audit et politiques de certification (CP/CPS).
---- +
-## 📚 Explorer la Documentation et les Textes Fondateurs +## Explorer la documentation et les textes fondateurs -
+
-- :material-scale-balance:{ .lg .middle } __Statuts & Gouvernance__ +- :material-scale-balance:{ .lg .middle } __Statuts et gouvernance__ --- Le projet de statuts constitutifs, soumis au vote de l'assemblée générale constitutive, fondé sur l'intérêt général (CGI art. 200 & 238 bis), la gestion désintéressée et la séparation stricte des devoirs. [:octicons-arrow-right-24: Consulter le projet de statuts](statuts/statuts-association.md) - [:octicons-arrow-right-24: Charte d'Éthique & Déontologie](gouvernance/charte-ethique.md) - [:octicons-arrow-right-24: Organisation Technique & CPC](gouvernance/comite-technique.md) + [:octicons-arrow-right-24: Charte d'éthique et de déontologie](gouvernance/charte-ethique.md) + [:octicons-arrow-right-24: Organisation technique et CPC](gouvernance/comite-technique.md) -- :material-book-open-page-variant:{ .lg .middle } __Règlement Intérieur__ +- :material-book-open-page-variant:{ .lg .middle } __Règlement intérieur__ --- Fonctionnement opérationnel : cursus d'habilitation des Officiers d'Autorité, clés matérielles FIPS/ANSSI et règles de fonctionnement de l'association. - [:octicons-arrow-right-24: Règlement Intérieur](reglement-interieur/reglement-interieur.md) + [:octicons-arrow-right-24: Règlement intérieur](reglement-interieur/reglement-interieur.md) -- :material-certificate:{ .lg .middle } __Socle de Conformité (TSP / PKI)__ +- :material-certificate:{ .lg .middle } __Socle de conformité (TSP / PKI)__ --- Le référentiel d'audit initial conforme aux normes eIDAS, ETSI et WebTrust : Cadre CP/CPS (RFC 3647), Politique de Sécurité (PSSI) et Fin d'Activité. - [:octicons-arrow-right-24: Cadre Général CP/CPS](cadrage/cp-cps-cadre.md) - [:octicons-arrow-right-24: Politique de Sécurité (PSSI ISO 27001)](cadrage/pssi.md) - [:octicons-arrow-right-24: Plan de Fin d'Activité (Termination Plan)](cadrage/termination-plan.md) + [:octicons-arrow-right-24: Cadre général CP/CPS](cadrage/cp-cps-cadre.md) + [:octicons-arrow-right-24: Politique de sécurité (PSSI ISO 27001)](cadrage/pssi.md) + [:octicons-arrow-right-24: Plan de fin d'activité (Termination Plan)](cadrage/termination-plan.md) -- :material-file-document-outline:{ .lg .middle } __Démarches Légales & Fiscales__ +- :material-file-document-outline:{ .lg .middle } __Démarches légales et fiscales__ --- Dossier juridique complet : Procès-Verbal de l'AG Constitutive, demande formelle de rescrit fiscal mécénat DGFIP et guide d'immatriculation. - [:octicons-arrow-right-24: Procès-Verbal Constitutif (Modèle)](administratif/pv-ag-constitutive-modele.md) - [:octicons-arrow-right-24: Dossier de Rescrit Fiscal DGFIP](administratif/rescrit-fiscal-mecenat.md) - [:octicons-arrow-right-24: Guide Préfecture (RNA, SIRET)](administratif/declaration-prefecture.md) + [:octicons-arrow-right-24: Procès-verbal constitutif (modèle)](administratif/pv-ag-constitutive-modele.md) + [:octicons-arrow-right-24: Dossier de rescrit fiscal DGFIP](administratif/rescrit-fiscal-mecenat.md) + [:octicons-arrow-right-24: Guide préfecture (RNA, SIRET)](administratif/declaration-prefecture.md)
---- - -## 🏛️ La Confiance Numérique comme Bien Commun +## La confiance numérique comme bien commun L'association **« Open Trusted Service Provider Initiative » (OTSPI)**, en cours de constitution, a pour but d'intérêt général de lever les barrières économiques, techniques, administratives et éducatives à la sécurité, à la confidentialité et à la confiance numérique dans les communications électroniques mondiales. @@ -110,57 +99,32 @@ L'association **« Open Trusted Service Provider Initiative » (OTSPI)**, en cou * **Gestion strictement désintéressée** : Bénévolat strict des dirigeants, inaliénabilité des dépôts logiciels libres et des marques, absence de distribution d'actifs et réinvestissement intégral des excédents dans la mission d'intérêt général. * **Garantie de continuité opérationnelle** : Un fonds de réserve sanctuarisé garantit l'exécution intégrale du plan de fin d'activité (*Termination Plan*, maintien des listes de révocation CRL/OCSP pendant au moins 10 ans). ---- - -## ⚖️ Architecture de Gouvernance et Ségrégation des Fonctions +## Architecture de gouvernance et ségrégation des fonctions La gouvernance d'OTSPI applique une séparation stricte des devoirs conformément aux normes ETSI EN 319 401 et WebTrust : -```mermaid -flowchart TD - AG["Assemblée Générale (Titulaires & Sympathisants)"] --> CA["Conseil d'Administration (2 à 9 membres)"] - AG -.->|"Confirmation des nominations"| CPC["Comité des Politiques de Confiance (CPC / PMA)"] - CA --> Bureau["Bureau (Direction Opérationnelle - Executive Management)
Président, Trésorier, Secrétaire Général"] - - subgraph Normatif["Autorité Normative Cryptographique (Indépendante)"] - CPC -->|"Avis conforme CP/CPS & Cérémonies"| TSC["Comité Technique & Ingénierie (TSC)"] - CPC -->|"Désignation (1 an)"| RSSI["RSSI / CISO"] - CPC -->|"Habilitation & Contrôle"| OA["Officiers d'Autorité & Key Custodians"] - end - - subgraph Operationnel["Direction Opérationnelle & Exploitation"] - Bureau -->|"Mise en œuvre PSSI & Moyens"| TSC - Bureau -->|"Relations de gouvernance"| ANSSI["Autorités de Contrôle & Auditeurs (CAB)"] - end - - classDef blue fill:#2563eb,stroke:#1d4ed8,color:#fff; - classDef green fill:#059669,stroke:#047857,color:#fff; - classDef orange fill:#d97706,stroke:#b45309,color:#fff; - class AG,CA,Bureau blue; - class CPC,RSSI,OA green; - class TSC,ANSSI orange; -``` + +
+Organisation de la gouvernance d'OTSPIL'assemblée générale élit le conseil d'administration, qui désigne le bureau (direction opérationnelle) ; le bureau assure les relations avec les autorités de contrôle et les auditeurs. L'assemblée générale confirme aussi les nominations au comité des politiques de confiance (CPC), autorité normative indépendante du bureau, qui désigne le RSSI pour un an, habilite et contrôle les officiers d'autorité et rend un avis conforme sur les travaux du comité technique ; le bureau fournit à ce comité ses moyens.DIRECTION OPÉRATIONNELLEAUTORITÉ NORMATIVE INDÉPENDANTEconfirmation des nominationsAssemblée généraletitulaires et sympathisantsConseil d'administration2 à 9 membresBureauprésidence · trésorerie · secrétariatAutorités de contrôleet auditeurs (CAB)Comité des politiques de confianceCPC / PMAComité technique (TSC)avis CPC · moyens du BureauRSSI / CISOdésigné par le CPC, 1 anOfficiers d'autoritéet gardiens de clés +
+ 1. **Direction Opérationnelle (*Executive Management*)** : Assurée par le Bureau issu du Conseil d'Administration. Il porte la responsabilité juridique et financière, alloue les ressources de sécurité et assure les relations de gouvernance. 2. **Comité des Politiques de Confiance (CPC / PMA)** : Organe collégial indépendant garant de la rigueur cryptographique et normative. Il approuve les CP/CPS, valide les cérémonies de clés, supervise l'habilitation des Officiers d'Autorité et désigne le RSSI. **L'appartenance au Bureau est strictement incompatible avec le CPC.** 3. **Officiers d'Autorité & Gardiens de Clés (*Key Custodians*)** : Opérateurs habilités assurant sous contrôle à quatre yeux (*Dual Control*) les cérémonies de clés et disposant d'un pouvoir autonome de **révocation d'urgence** sans délai. ---- - -## 🔍 Redevabilité Publique Intégrale (*Public Accountability*) +## Redevabilité publique intégrale (*Public Accountability*) OTSPI applique un principe de **transparence radicale et d'auditabilité publique** : + - Ordres du jour, débats et comptes-rendus publics des réunions (CA, Bureau, Assemblées Générales, comités techniques) ; - Budgets prévisionnels, comptes annuels certifiés, rapports moraux et rapports d'évaluation d'audit (ETSI / eIDAS / WebTrust) ; - Dépôt public de l'ensemble des sources et des documents de gouvernance sur [GitHub : `otspi/organisation`](https://github.com/otspi/organisation). -> [!NOTE] -> **Réserves de protection légitimes :** -> Conformément à notre projet de statuts, les seules exceptions à la publication intégrale concernent la **protection des données personnelles (RGPD)** de nos membres et votants (données nominatives caviardées), les **secrets cryptographiques matériels** (clés protégées sous HSM) et l'**embargo temporaire de sécurité** lors du traitement coordonné de vulnérabilités critiques (*Coordinated Vulnerability Disclosure — CVD*). - ---- +!!! note "Réserves de protection légitimes" + Conformément à notre projet de statuts, les seules exceptions à la publication intégrale concernent la **protection des données personnelles (RGPD)** de nos membres et votants (données nominatives caviardées), les **secrets cryptographiques matériels** (clés protégées sous HSM) et l'**embargo temporaire de sécurité** lors du traitement coordonné de vulnérabilités critiques (*Coordinated Vulnerability Disclosure — CVD*). -## 📬 Contact & Adresses Officielles +## Contact et adresses officielles - **Contact unique (Informations, Partenariats, Sécurité)** : `contact@otspi.org` *(Pour le signalement de vulnérabilités / CVD : indiquer `[Sécurité]` en objet ou utiliser les [GitHub Private Security Advisories](https://github.com/otspi/organisation/security/advisories))* diff --git a/docs/livre-blanc/index.md b/docs/livre-blanc/index.md index a4cfc38..13b32da 100644 --- a/docs/livre-blanc/index.md +++ b/docs/livre-blanc/index.md @@ -7,7 +7,7 @@ description: "Livre blanc de l'Open Trusted Service Provider Initiative : défai
-![OTSPI](../assets/logo-vertical.svg){ .wp-cover-logo } +![OTSPI](../assets/logo-vertical-dark.svg){ .wp-cover-logo }

Livre blanc

Une infrastructure de services de confiance qualifiés d'utilité publique pour eIDAS 2.0

@@ -25,6 +25,8 @@ description: "Livre blanc de l'Open Trusted Service Provider Initiative : défai

La version PDF est balisée et validée au format PDF/UA-1 par l'outil de contrôle veraPDF ; cette validation automatique ne remplace pas un test avec un lecteur d'écran. La présente page (HTML) reste la version accessible de référence.

+
+ | | | |---|---| | **Émetteur** | Initiative « Open Trusted Service Provider Initiative » (OTSPI), association loi 1901 en cours de constitution | @@ -34,6 +36,8 @@ description: "Livre blanc de l'Open Trusted Service Provider Initiative : défai | **Licence** | Creative Commons Attribution 4.0 International (CC-BY-4.0) | | **Contact** | [contact@otspi.org](mailto:contact@otspi.org) | +
+ !!! note "Nature du document" Le présent livre blanc expose une intention et une architecture cible. Il ne constitue ni une Politique d'Horodatage, ni une Déclaration des Pratiques de Certification (DPC), ni un engagement contractuel de service. Les références à des produits ou fournisseurs sont données à titre indicatif ; leur sélection définitive relèvera de procédures de mise en concurrence et de l'approbation du Comité des Politiques de Confiance (CPC). @@ -376,8 +380,9 @@ Tout éditeur de solution de signature, commercial ou libre, peut s'appuyer sur ### 4.1. Hiérarchie de certification -
+
Hiérarchie de certification qualifiée d'OTSPIL'AC racine OTSPI, hors ligne et sous quorum, certifie l'AC intermédiaire d'horodatage, qui certifie les unités d'horodatage TSU-1 (site A) et TSU-2 (site B). Elle certifiera aussi de futures AC qualifiées de cachet, de signature et d'attestations.AC racine OTSPIhors ligne · air-gap · quorum M-de-NAC intermédiaire Horodatagehors ligne ou en ligne restreinteAC qualifiées futurescachet · signature · attestationsUnité d'horodatage TSU-1HSM en ligne — site AUnité d'horodatage TSU-2HSM en ligne — site B +
Figure 1 — Hiérarchie de certification qualifiée d'OTSPI
@@ -385,11 +390,12 @@ Tout éditeur de solution de signature, commercial ou libre, peut s'appuyer sur - Chaque **unité d'horodatage (TSU)** dispose d'une clé propre, exclusivement réservée à la signature de jetons d'horodatage, générée et conservée dans un module cryptographique certifié. - La période d'utilisation des clés TSU est inférieure à la durée de validité de leur certificat, conformément à l'ETSI EN 319 421, afin de garantir la vérifiabilité des jetons émis en fin de période. - Les futures **AC qualifiées** de cachet, de signature et d'attestations (cf. § 6.1, phase 5) seront rattachées à cette même racine qualifiée, chacune sous une AC intermédiaire dédiée à un seul usage. -- Le futur service de certificats TLS (cf. § 2.4) repose sur **deux racines distinctes** de la racine qualifiée d'horodatage : une **racine WebTrust**, destinée aux magasins de confiance des systèmes d'exploitation et des navigateurs, et une **racine QWAC**, inscrite sur la liste de confiance européenne. Elles appliquent les mêmes principes de gouvernance (air-gap, quorum, cérémonies) et ne partagent aucune clé avec les AC d'horodatage, de cachet ou de signature. +- Le futur service de certificats TLS (cf. § 2.4) repose sur **deux racines distinctes** de la racine qualifiée d'horodatage ([figure 2](#figure-2)) : une **racine WebTrust**, destinée aux magasins de confiance des systèmes d'exploitation et des navigateurs, et une **racine QWAC**, inscrite sur la liste de confiance européenne. Elles appliquent les mêmes principes de gouvernance (air-gap, quorum, cérémonies) et ne partagent aucune clé avec les AC d'horodatage, de cachet ou de signature. -
+
Hiérarchies de certification TLS d'OTSPIDeux racines distinctes : une racine WebTrust pour les magasins des navigateurs, une racine QWAC inscrite sur la liste de confiance européenne. La racine WebTrust certifie une sous-AC DV, qui émet des certificats serveur DV par ACME instantané. Une sous-AC hybride OV / QWAC, à clé unique, est certifiée par la racine WebTrust et, par signature croisée, par la racine QWAC ; elle émet des certificats OV / QWAC.signature croiséeRacine WebTrustmagasins OS et navigateursRacine QWACliste de confiance européenneSous-AC DVWebTrust uniquement · HSM standardSous-AC hybride OV / QWACune clé · deux certificats d'ACCertificats serveur DVusage Web · ACME instantanéCertificats serveur OV / QWACDSP2, eIDAS · ACME avec liaison de compte +
Figure 2 — Hiérarchies de certification TLS d'OTSPI
diff --git a/docs/reunions/index.md b/docs/reunions/index.md index 341658d..7cd1ae1 100644 --- a/docs/reunions/index.md +++ b/docs/reunions/index.md @@ -8,7 +8,7 @@ Toutes les réunions formelles de gouvernance font l'objet d'un ordre du jour pr --- -## 🏛️ Typologie des Réunions +## Typologie des réunions 1. **Assemblées Générales (AG)** : - Assemblée Générale Ordinaire (AGO) : Approbation des comptes, rapport moral, budget, renouvellement du CA, confirmation des membres du CPC. @@ -22,7 +22,7 @@ Toutes les réunions formelles de gouvernance font l'objet d'un ordre du jour pr --- -## 🛡️ Règles de Publication et Protection RGPD / Sécurité +## Règles de publication et protection RGPD / sécurité Avant toute publication publique d'un compte-rendu : @@ -35,7 +35,7 @@ Avant toute publication publique d'un compte-rendu : --- -## 📝 Modèle Type de Compte-Rendu Public +## Modèle type de compte-rendu public ```markdown # Compte-Rendu : [Conseil d'Administration / CPC / AG / TSC] du [AAAA-MM-JJ] diff --git a/docs/stylesheets/extra.css b/docs/stylesheets/extra.css index 817e9a0..bb576cc 100644 --- a/docs/stylesheets/extra.css +++ b/docs/stylesheets/extra.css @@ -1,228 +1,364 @@ /* ========================================================================== - OTSPI Custom Styling — Modern, Trustworthy & Accessible + OTSPI — charte du portail + Bleu nuit du logo (#0b1120), bleu institutionnel, bleu ciel et jaune d'accent. ========================================================================== */ :root { + --otspi-navy: #0b1120; + --otspi-navy-2: #111a33; --otspi-primary: #1e40af; --otspi-primary-light: #3b82f6; - --otspi-accent: #0ea5e9; - --otspi-success: #10b981; - --otspi-warning: #f59e0b; + --otspi-sky: #38bdf8; + --otspi-gold: #fbbf24; --otspi-card-bg: #ffffff; - --otspi-card-border: rgba(226, 232, 240, 0.8); - --otspi-card-shadow: 0 4px 20px -2px rgba(0, 0, 0, 0.05); - --otspi-card-hover-shadow: 0 12px 28px -4px rgba(30, 64, 175, 0.12); + --otspi-card-border: #e2e8f0; + --otspi-card-shadow: 0 1px 2px rgba(15, 23, 42, 0.04), 0 4px 16px -6px rgba(15, 23, 42, 0.08); + --otspi-card-hover-shadow: 0 10px 28px -8px rgba(30, 64, 175, 0.22); +} + +/* Palette personnalisée de Material (primary: custom, accent: custom) */ +:root > * { + --md-primary-fg-color: #1e40af; + --md-primary-fg-color--light: #3b82f6; + --md-primary-fg-color--dark: #0b1120; + --md-primary-bg-color: #ffffff; + --md-primary-bg-color--light: rgba(255, 255, 255, 0.72); + --md-accent-fg-color: #0369a1; + --md-accent-fg-color--transparent: rgba(3, 105, 161, 0.1); + --md-typeset-a-color: #1d4ed8; } [data-md-color-scheme="slate"] { - --otspi-card-bg: #1e293b; - --otspi-card-border: rgba(51, 65, 85, 0.7); - --otspi-card-shadow: 0 4px 20px -2px rgba(0, 0, 0, 0.25); - --otspi-card-hover-shadow: 0 12px 28px -4px rgba(14, 165, 233, 0.15); + --md-hue: 225; + --otspi-card-bg: #161f36; + --otspi-card-border: rgba(148, 163, 184, 0.18); + --otspi-card-shadow: 0 4px 20px -6px rgba(0, 0, 0, 0.4); + --otspi-card-hover-shadow: 0 12px 28px -6px rgba(56, 189, 248, 0.18); +} + +[data-md-color-scheme="slate"] > * { + --md-accent-fg-color: #38bdf8; + --md-accent-fg-color--transparent: rgba(56, 189, 248, 0.12); } /* -------------------------------------------------------------------------- - Hero Section + En-tête et onglets : bleu nuit du logo -------------------------------------------------------------------------- */ +.md-header, +.md-tabs { + background-color: var(--otspi-navy); +} + +.md-header { + box-shadow: none; + border-bottom: 1px solid rgba(148, 163, 184, 0.14); +} + +.md-header--shadow { + box-shadow: 0 2px 12px rgba(2, 6, 23, 0.35); +} + +.md-header__button.md-logo { + display: flex !important; + align-items: center; + margin-right: 0.5rem; +} + +.md-header__button.md-logo img, +.md-header__button.md-logo svg { + height: 1.6rem !important; + width: auto !important; +} + +.md-tabs__link { + font-weight: 500; + opacity: 0.78; +} + +.md-tabs__item--active .md-tabs__link, +.md-tabs__link:hover { + opacity: 1; +} + +.md-tabs__item--active .md-tabs__link { + color: #ffffff; + box-shadow: inset 0 -2px 0 var(--otspi-sky); +} + +.md-search__form { + background-color: rgba(148, 163, 184, 0.14); + border-radius: 8px; +} + +/* -------------------------------------------------------------------------- + Titres : hiérarchie nette, sans le gris clair et la graisse légère de Material + -------------------------------------------------------------------------- */ +.md-typeset h1 { + color: var(--md-default-fg-color); + font-weight: 800; + line-height: 1.2; + letter-spacing: -0.02em; +} + +.md-typeset h2 { + font-weight: 700; + letter-spacing: -0.01em; +} + +.md-typeset h3 { + font-weight: 700; +} + +/* -------------------------------------------------------------------------- + Accueil — bandeau pleine largeur (overrides/home.html) + -------------------------------------------------------------------------- */ +/* Fond uni : le logo, qui porte son propre fond #0b1120, s'y fond sans cadre visible */ .otspi-hero { - text-align: center; - padding: clamp(2rem, 5vw, 3.5rem) 1rem clamp(1.5rem, 4vw, 2.5rem); - margin-bottom: 1.5rem; - position: relative; + background: var(--otspi-navy); + color: #e2e8f0; } -.otspi-badge { - display: inline-flex; +[data-md-color-scheme="slate"] .otspi-hero { + border-bottom: 1px solid rgba(148, 163, 184, 0.16); +} + +.otspi-hero__inner { + display: grid; + grid-template-columns: minmax(0, 1fr) auto; + gap: 2rem; align-items: center; - gap: 0.5rem; - padding: 0.35rem 0.9rem; - border-radius: 9999px; - font-size: clamp(0.72rem, 2vw, 0.82rem); - font-weight: 600; - letter-spacing: 0.025em; - background-color: rgba(59, 130, 246, 0.1); - color: var(--otspi-primary-light); - border: 1px solid rgba(59, 130, 246, 0.25); - margin-bottom: 1.25rem; + padding: clamp(2.2rem, 6vw, 4rem) 0.8rem clamp(2.4rem, 6vw, 4.2rem); +} + +.otspi-hero__kicker { + margin: 0 0 1rem; + color: var(--otspi-sky); + font-size: 0.68rem; + font-weight: 700; + letter-spacing: 0.16em; text-transform: uppercase; - max-width: 100%; } -.otspi-hero h1 { - font-size: clamp(1.65rem, 5vw + 0.3rem, 2.5rem) !important; - font-weight: 800 !important; - line-height: 1.25 !important; - margin-bottom: 1rem !important; - letter-spacing: -0.02em; +.otspi-hero__title { + margin: 0; + color: #ffffff; + font-size: clamp(1.7rem, 4.2vw, 2.7rem); + font-weight: 800; + line-height: 1.12; + letter-spacing: -0.025em; } -.otspi-hero .subtitle { - font-size: clamp(0.95rem, 2vw + 0.2rem, 1.15rem); - line-height: 1.6; - max-width: 48rem; - margin: 0 auto 1.5rem; - color: var(--md-default-fg-color--light); +.otspi-hero__title::after { + content: ""; + display: block; + width: 3.2rem; + height: 0.22rem; + margin-top: 1.1rem; + border-radius: 1px; + background: var(--otspi-gold); +} + +.otspi-hero__lead { + max-width: 38rem; + margin: 1.2rem 0 0; + color: #cbd5e1; + font-size: clamp(0.85rem, 1.6vw, 0.98rem); + line-height: 1.65; } -.otspi-hero-actions { +.otspi-hero__lead strong { + color: #ffffff; +} + +.otspi-hero__actions { display: flex; - justify-content: center; - gap: 0.85rem; flex-wrap: wrap; - margin-top: 1.25rem; + gap: 0.7rem; + margin-top: 1.8rem; +} + +/* Hors de .md-typeset, Material ne donne aucun style de bouton : on les pose ici */ +.otspi-hero .md-button { + display: inline-block; + margin: 0; + border: 0.1rem solid rgba(226, 232, 240, 0.45); + color: #ffffff; + font-size: 0.72rem; + line-height: 1.4; + text-decoration: none; +} + +.otspi-hero .md-button:hover, +.otspi-hero .md-button:focus-visible { + border-color: #ffffff; + background-color: rgba(255, 255, 255, 0.08); + color: #ffffff; } -@media screen and (max-width: 600px) { - .otspi-hero-actions { - flex-direction: column; - align-items: stretch; - max-width: 300px; - margin: 1.25rem auto 0; +.otspi-hero .md-button--primary { + border-color: var(--otspi-sky) !important; + background-color: var(--otspi-sky) !important; + color: var(--otspi-navy) !important; + box-shadow: none !important; +} + +.otspi-hero .md-button--primary:hover, +.otspi-hero .md-button--primary:focus-visible { + border-color: #7dd3fc !important; + background-color: #7dd3fc !important; +} + +.otspi-hero__logo { + width: 13rem; + height: auto; +} + +@media screen and (max-width: 59.9844em) { + .otspi-hero__inner { + grid-template-columns: minmax(0, 1fr); } - .otspi-hero-actions .md-button { - width: 100%; + + .otspi-hero__logo { + display: none; + } +} + +@media screen and (max-width: 29.9844em) { + .otspi-hero__actions .md-button { + flex: 1 1 100%; text-align: center; - justify-content: center; } } /* -------------------------------------------------------------------------- - Key Stats / Value Pillars + Accueil — quatre engagements -------------------------------------------------------------------------- */ -.otspi-stats-grid { +.otspi-features { display: grid; - grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); - gap: 1.25rem; - margin: 2.5rem 0 3.5rem; + grid-template-columns: repeat(auto-fit, minmax(min(100%, 12rem), 1fr)); + gap: 1rem; + margin: 0.4rem 0 2.6rem; } -.otspi-stat-card { - background: var(--otspi-card-bg); +.md-typeset .otspi-feature { + padding: 1.2rem 1.2rem 1rem; border: 1px solid var(--otspi-card-border); border-radius: 12px; - padding: 1.5rem 1.25rem; - text-align: center; + background: var(--otspi-card-bg); box-shadow: var(--otspi-card-shadow); - transition: transform 0.2s ease, border-color 0.2s ease, box-shadow 0.2s ease; + font-size: 0.72rem; + line-height: 1.55; } -.otspi-stat-card:hover { - transform: translateY(-3px); - border-color: var(--otspi-primary-light); - box-shadow: var(--otspi-card-hover-shadow); +.md-typeset .otspi-feature p { + margin: 0; + color: var(--md-default-fg-color--light); } -.otspi-stat-icon { - font-size: 1.75rem; - margin-bottom: 0.5rem; - display: inline-block; +.md-typeset .otspi-feature .otspi-feature__icon { + display: inline-flex; + width: 2.2rem; + height: 2.2rem; + margin-bottom: 0.8rem; + padding: 0.45rem; + border-radius: 10px; + background: var(--md-accent-fg-color--transparent); + color: var(--otspi-primary); } -.otspi-stat-title { - font-size: 1.05rem; - font-weight: 700; - margin-bottom: 0.35rem; - color: var(--md-default-fg-color); +.md-typeset .otspi-feature .otspi-feature__icon svg { + width: 100%; + height: 100%; + max-height: none; } -.otspi-stat-desc { +.md-typeset .otspi-feature p.otspi-feature__title { + margin: 0 0 0.35rem; + color: var(--md-default-fg-color); font-size: 0.85rem; - line-height: 1.4; - color: var(--md-default-fg-color--light); - margin: 0; + font-weight: 700; +} + +[data-md-color-scheme="slate"] .md-typeset .otspi-feature .otspi-feature__icon { + color: var(--otspi-sky); +} + +/* Titres de section de l'accueil */ +.md-content:has(.otspi-features) .md-typeset h2 { + margin-top: 2.4rem; + padding-top: 1.6rem; + border-top: 1px solid var(--md-default-fg-color--lightest); +} + +.md-content:has(.otspi-features) .md-typeset .otspi-features + h2 { + border-top: none; + padding-top: 0; +} + +/* Cartes de documentation : deux colonnes au plus, pas de carte orpheline */ +.md-typeset .grid.cards.otspi-docs { + grid-template-columns: repeat(auto-fit, minmax(min(100%, 20rem), 1fr)); } /* -------------------------------------------------------------------------- - Material for MkDocs Cards Customization + Cartes Material -------------------------------------------------------------------------- */ .md-typeset .grid.cards > ul > li { background: var(--otspi-card-bg); border: 1px solid var(--otspi-card-border); - border-radius: 14px; - padding: 1.75rem; + border-radius: 12px; + padding: 1.4rem 1.5rem; box-shadow: var(--otspi-card-shadow); - transition: transform 0.25s cubic-bezier(0.16, 1, 0.3, 1), - box-shadow 0.25s cubic-bezier(0.16, 1, 0.3, 1), - border-color 0.25s ease; - position: relative; + transition: box-shadow 0.2s ease, border-color 0.2s ease; } .md-typeset .grid.cards > ul > li:hover { - transform: translateY(-4px); box-shadow: var(--otspi-card-hover-shadow); border-color: var(--otspi-primary-light); } .md-typeset .grid.cards > ul > li > hr { - margin: 1rem 0; - opacity: 0.2; + margin: 0.8rem 0; + opacity: 0.4; +} + +.md-typeset .grid.cards .lg { + color: var(--otspi-primary); +} + +[data-md-color-scheme="slate"] .md-typeset .grid.cards .lg { + color: var(--otspi-sky); } /* -------------------------------------------------------------------------- - Custom Buttons + Boutons -------------------------------------------------------------------------- */ .md-button { border-radius: 8px !important; font-weight: 600 !important; letter-spacing: 0.01em; - padding: 0.65em 1.5em !important; - transition: all 0.2s ease !important; + padding: 0.6em 1.3em !important; + transition: background-color 0.15s ease, border-color 0.15s ease, color 0.15s ease !important; } .md-button--primary { background-color: var(--otspi-primary) !important; border-color: var(--otspi-primary) !important; - box-shadow: 0 4px 14px rgba(30, 64, 175, 0.25) !important; } .md-button--primary:hover { - background-color: var(--otspi-primary-light) !important; - border-color: var(--otspi-primary-light) !important; - transform: translateY(-1px); - box-shadow: 0 6px 20px rgba(30, 64, 175, 0.35) !important; + background-color: #1e3a8a !important; + border-color: #1e3a8a !important; } /* -------------------------------------------------------------------------- - Mermaid Diagrams & Admonitions + Encadrés : Material les compose plus petit que le corps du texte -------------------------------------------------------------------------- */ -.mermaid { - background: var(--otspi-card-bg); - border: 1px solid var(--otspi-card-border); - border-radius: 12px; - padding: 1.5rem 1rem; - box-shadow: var(--otspi-card-shadow); - margin: 1.5rem 0 !important; - overflow-x: auto; - -webkit-overflow-scrolling: touch; - max-width: 100%; -} - -.md-typeset .admonition { +.md-typeset .admonition, +.md-typeset details { border-radius: 10px; - box-shadow: var(--otspi-card-shadow); -} - -/* -------------------------------------------------------------------------- - Navigation & Header Refinements - -------------------------------------------------------------------------- */ -.md-header { - box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05), 0 1px 2px rgba(0, 0, 0, 0.1); -} - -.md-header__button.md-logo { - display: flex !important; - align-items: center; - margin-right: 0.5rem; -} - -.md-header__button.md-logo img, -.md-header__button.md-logo svg { - height: 1.6rem !important; - width: auto !important; -} - -.md-tabs { - border-bottom: 1px solid rgba(255, 255, 255, 0.1); + box-shadow: none; + font-size: 0.72rem; } /* -------------------------------------------------------------------------- @@ -262,6 +398,88 @@ } } +/* -------------------------------------------------------------------------- + Livre blanc — en-tête, métadonnées et hiérarchie des titres + (la page de garde .wp-cover, masquée à l'écran, identifie la page du livre blanc) + -------------------------------------------------------------------------- */ +.md-typeset .wp-cover ~ h1 { + margin-bottom: 0.4em; + color: var(--otspi-primary); + font-size: 0.8rem; + font-weight: 700; + letter-spacing: 0.16em; + text-transform: uppercase; +} + +.md-typeset .wp-cover ~ h1 + h2 { + margin-top: 0; + padding-left: 0.8rem; + border-left: 4px solid var(--otspi-primary); + color: var(--md-default-fg-color); + font-size: 1.6em; + font-weight: 700; + line-height: 1.3; + letter-spacing: -0.01em; +} + +[data-md-color-scheme="slate"] .md-typeset .wp-cover ~ h1 { + color: #9cc0ff; +} + +[data-md-color-scheme="slate"] .md-typeset .wp-cover ~ h1 + h2 { + border-left-color: #8fb4ff; +} + +.md-typeset:has(> .wp-cover) h2 { + font-weight: 700; + letter-spacing: -0.01em; +} + +.md-typeset:has(> .wp-cover) h3 { + font-weight: 700; +} + +.md-typeset:has(> .wp-cover) h4 { + font-weight: 700; + color: var(--md-default-fg-color--light); +} + +/* Fiche d'identification du document : tableau clé / valeur sans ligne d'en-tête */ +.md-typeset .wp-meta thead { + display: none; +} + +.md-typeset .wp-meta table:not([class]) { + border: none; + border-top: 2px solid var(--otspi-primary); + border-radius: 0; + box-shadow: none; + font-size: 0.72rem; +} + +.md-typeset .wp-meta table:not([class]) td { + padding: 0.55em 0.9em; + border-top: 1px solid var(--md-default-fg-color--lightest); + vertical-align: top; +} + +.md-typeset .wp-meta table:not([class]) td:first-child { + width: 11em; + color: var(--md-default-fg-color--light); + white-space: nowrap; +} + +.md-typeset .wp-meta table:not([class]) tr:hover { + box-shadow: none; +} + +@media screen and (max-width: 44.9375em) { + .md-typeset .wp-meta table:not([class]) td:first-child { + width: auto; + white-space: normal; + } +} + /* -------------------------------------------------------------------------- Livre blanc — chiffres clés -------------------------------------------------------------------------- */ @@ -301,6 +519,20 @@ overflow-x: auto; } +.md-typeset .wp-diagram figcaption { + max-width: 820px; + margin: 0.8em auto 0; + color: var(--md-default-fg-color--light); + font-size: 0.72rem; + font-style: normal; + text-align: center; +} + +.md-typeset .wp-fig-num { + color: var(--md-default-fg-color); + font-weight: 700; +} + .md-typeset .wp-svg { display: block; width: 100%; @@ -310,6 +542,23 @@ margin: 0 auto; } +.md-typeset .wp-svg--wide { + max-width: 940px; +} + +/* Regroupements de l'organigramme de gouvernance (accueil) */ +.wp-svg .dg-group { + fill: var(--md-default-fg-color--lightest); + stroke: none; +} + +.wp-svg .dg-glabel { + fill: var(--md-default-fg-color--light); + font-size: 11px; + font-weight: 700; + letter-spacing: 0.08em; +} + .wp-svg .dg-box { fill: var(--md-default-bg-color); stroke: var(--md-default-fg-color--lighter); @@ -429,10 +678,11 @@ --md-typeset-a-color: #8fb4ff; } -[data-md-color-scheme="slate"] .otspi-badge { - color: #9cc0ff; +[data-md-color-scheme="slate"] .md-typeset .wp-meta table:not([class]) { + border-top-color: #8fb4ff; } + [data-md-color-scheme="slate"] .md-typeset a:not(.md-button):not(.headerlink):not(.md-annotation__index) { color: #8fb4ff; } diff --git a/docs/stylesheets/fonts.css b/docs/stylesheets/fonts.css new file mode 100644 index 0000000..fdbdd91 --- /dev/null +++ b/docs/stylesheets/fonts.css @@ -0,0 +1,68 @@ +/* ========================================================================== + Police Inter (SIL Open Font License 1.1, voir assets/fonts/inter/OFL.txt), + servie par le portail lui-même : aucune requête vers un service tiers. + Sous-ensemble latin (français, anglais) de la distribution Fontsource 5.3.0. + Le PDF du livre blanc l'embarque aussi : son rendu ne dépend plus des polices + installées sur la machine qui le génère. + ========================================================================== */ + +@font-face { + font-family: "Inter"; + font-style: normal; + font-weight: 300; + font-display: swap; + src: url("../assets/fonts/inter/inter-latin-300-normal.woff2") format("woff2"); +} + +@font-face { + font-family: "Inter"; + font-style: normal; + font-weight: 400; + font-display: swap; + src: url("../assets/fonts/inter/inter-latin-400-normal.woff2") format("woff2"); +} + +@font-face { + font-family: "Inter"; + font-style: italic; + font-weight: 400; + font-display: swap; + src: url("../assets/fonts/inter/inter-latin-400-italic.woff2") format("woff2"); +} + +@font-face { + font-family: "Inter"; + font-style: normal; + font-weight: 600; + font-display: swap; + src: url("../assets/fonts/inter/inter-latin-600-normal.woff2") format("woff2"); +} + +@font-face { + font-family: "Inter"; + font-style: normal; + font-weight: 700; + font-display: swap; + src: url("../assets/fonts/inter/inter-latin-700-normal.woff2") format("woff2"); +} + +@font-face { + font-family: "Inter"; + font-style: italic; + font-weight: 700; + font-display: swap; + src: url("../assets/fonts/inter/inter-latin-700-italic.woff2") format("woff2"); +} + +@font-face { + font-family: "Inter"; + font-style: normal; + font-weight: 800; + font-display: swap; + src: url("../assets/fonts/inter/inter-latin-800-normal.woff2") format("woff2"); +} + +/* Material compose le texte avec --md-text-font, suivi des polices du système en repli */ +:root { + --md-text-font: "Inter"; +} diff --git a/docs/stylesheets/print.css b/docs/stylesheets/print.css index 55ddffb..3ed4482 100644 --- a/docs/stylesheets/print.css +++ b/docs/stylesheets/print.css @@ -23,35 +23,51 @@ @bottom-right { content: counter(page) " / " counter(pages); - font: 8pt Roboto, "Helvetica Neue", Arial, sans-serif; + font: 8pt Inter, "Helvetica Neue", Arial, sans-serif; color: #64748b; } } /* Gabarit nommé du livre blanc : pied de page identifiant le document */ @page whitepaper { + @top-right { + content: string(section); + font: 8pt Inter, "Helvetica Neue", Arial, sans-serif; + color: #64748b; + } + @bottom-left { content: "OTSPI — Livre blanc · document de consultation v0.9 · CC-BY-4.0"; - font: 8pt Roboto, "Helvetica Neue", Arial, sans-serif; + font: 8pt Inter, "Helvetica Neue", Arial, sans-serif; color: #64748b; } } @page whitepaper:first { + margin: 0; + @top-right { content: none; } @bottom-left { content: none; } @bottom-right { content: none; } } /* Gabarit anglais du livre blanc */ @page whitepaper-en { + @top-right { + content: string(section); + font: 8pt Inter, "Helvetica Neue", Arial, sans-serif; + color: #64748b; + } + @bottom-left { content: "OTSPI — White paper · public consultation v0.9 · CC-BY-4.0"; - font: 8pt Roboto, "Helvetica Neue", Arial, sans-serif; + font: 8pt Inter, "Helvetica Neue", Arial, sans-serif; color: #64748b; } } @page whitepaper-en:first { + margin: 0; + @top-right { content: none; } @bottom-left { content: none; } @bottom-right { content: none; } } @@ -84,6 +100,11 @@ padding: 0 !important; } + /* Espaceur de Material en tête d'article : il décalerait la page de garde à fond perdu */ + .md-content__inner::before { + display: none !important; + } + .md-grid { max-width: none !important; } @@ -124,7 +145,6 @@ .md-typeset .admonition, .md-typeset details, .md-typeset pre, - .md-typeset .mermaid, .md-typeset tr, .md-typeset img { break-inside: avoid; @@ -147,13 +167,17 @@ page: whitepaper-en; } - .wp-cover { - display: flex; - flex-direction: column; - justify-content: center; - align-items: center; - min-height: 245mm; - text-align: center; + /* Page de garde à fond perdu, aux couleurs du logo en version claire + (son fond #0b1120 se confond avec celui de la page) */ + .md-typeset .wp-cover { + display: block; + position: relative; + box-sizing: border-box; + height: 297mm; + margin: 0; + padding: 22mm 24mm 20mm; + background: #0b1120; + color: #f8fafc; break-after: page; } @@ -162,38 +186,59 @@ } .md-typeset .wp-cover .wp-cover-logo { - width: 55mm; - margin-bottom: 18mm; + display: block; + width: 58mm; + margin: 0 0 0 -8mm; } .md-typeset .wp-cover .wp-cover-kicker { + margin-top: 32mm; + margin-bottom: 7mm; + color: #38bdf8; font-size: 11pt; font-weight: 700; - letter-spacing: 0.2em; + letter-spacing: 0.24em; text-transform: uppercase; - color: var(--otspi-primary); - margin-bottom: 6mm; } .md-typeset .wp-cover .wp-cover-title { - font-size: 22pt; - font-weight: 700; - line-height: 1.25; - color: #0f172a; max-width: 150mm; - margin-bottom: 14mm; + color: #ffffff; + font-size: 30pt; + font-weight: 800; + line-height: 1.15; + letter-spacing: -0.015em; + } + + .md-typeset .wp-cover .wp-cover-title::after { + content: ""; + display: block; + width: 28mm; + height: 1.5mm; + margin-top: 11mm; + background: #fbbf24; } + /* Mentions ancrées en bas de page (l'ordre de lecture reste celui du document) */ .md-typeset .wp-cover .wp-cover-meta { + position: absolute; + right: 24mm; + bottom: 30mm; + left: 24mm; + padding-top: 6mm; + border-top: 0.5pt solid #334155; + color: #cbd5e1; font-size: 10.5pt; - color: #334155; line-height: 1.7; } .md-typeset .wp-cover .wp-cover-license { - margin-top: 24mm; + position: absolute; + right: 24mm; + bottom: 20mm; + left: 24mm; + color: #94a3b8; font-size: 8.5pt; - color: #64748b; } /* Le titre et le sous-titre écran sont remplacés par la page de garde */ @@ -224,20 +269,186 @@ .wp-cover ~ hr { display: none; } + + /* Typographie du livre blanc */ + /* Trait d'union ASCII pour la césure : le trait typographique (U+2010) manque à la police */ + .md-typeset:has(> .wp-cover) { + color: #1e293b; + hyphenate-character: "-"; + } + + .md-typeset:has(> .wp-cover) p, + .md-typeset:has(> .wp-cover) li { + text-align: justify; + hyphens: auto; + } + + /* Colonnes étroites et page de garde : le justifié y creuserait des blancs */ + .md-typeset .wp-cover p, + .md-typeset .grid.cards.wp-figures p, + .md-typeset .grid.cards.wp-figures li { + text-align: left; + hyphens: manual; + } + + .md-typeset .wp-cover ~ h2 { + margin: 0 0 6mm; + padding-bottom: 2.5mm; + border-bottom: 1.5pt solid var(--otspi-primary); + color: #0f2a6b; + font-size: 18pt; + font-weight: 700; + line-height: 1.25; + letter-spacing: -0.01em; + string-set: section content(); + } + + /* Le sous-titre masqué ne doit pas alimenter l'en-tête courant */ + .md-typeset .wp-cover ~ h1 + h2 { + string-set: section ""; + } + + .md-typeset .wp-cover ~ h3 { + margin: 7mm 0 2.5mm; + color: var(--otspi-primary); + font-size: 12.5pt; + font-weight: 700; + line-height: 1.3; + } + + .md-typeset .wp-cover ~ h4 { + margin: 5mm 0 2mm; + color: #1e293b; + font-size: 10.5pt; + font-weight: 700; + } + + /* Les titres ne restent jamais seuls en bas de page */ + .md-typeset .wp-cover ~ h3, + .md-typeset .wp-cover ~ h4 { + break-after: avoid; + break-inside: avoid; + } + + /* Encadrés : filet de couleur, sans ombre ni arrondi */ + .md-typeset:has(> .wp-cover) .admonition, + .md-typeset:has(> .wp-cover) details { + margin: 5mm 0; + border-width: 0 0 0 2.5pt; + border-radius: 0; + box-shadow: none; + font-size: 9pt; + } + + .md-typeset:has(> .wp-cover) .admonition-title, + .md-typeset:has(> .wp-cover) summary { + font-size: 9pt; + } + + /* Tableaux */ + .md-typeset:has(> .wp-cover) table:not([class]) { + border: none; + border-top: 1.5pt solid var(--otspi-primary); + border-bottom: 0.75pt solid #94a3b8; + border-radius: 0; + box-shadow: none; + } + + .md-typeset:has(> .wp-cover) table:not([class]) th { + background: #eef2fb; + color: #0f2a6b; + font-weight: 700; + } + + .md-typeset:has(> .wp-cover) table:not([class]) th, + .md-typeset:has(> .wp-cover) table:not([class]) td { + padding: 1.6mm 2.5mm; + border-top: 0.5pt solid #e2e8f0; + text-align: left; + hyphens: auto; + } + + .md-typeset:has(> .wp-cover) table:not([class]) thead { + display: table-header-group; + } + + .md-typeset:has(> .wp-cover) table:not([class]) tbody tr:nth-child(even) { + background: #f8fafc; + } + + .md-typeset .wp-meta table:not([class]) { + font-size: 9pt; + } + + /* Notes de bas de page */ + .md-typeset:has(> .wp-cover) .footnote { + font-size: 8pt; + color: #334155; + } + + .md-typeset:has(> .wp-cover) .footnote li { + text-align: left; + } + + /* Sommaire */ + .md-typeset .wp-toc h3 { + margin: 0 0 8mm; + padding-bottom: 2.5mm; + border-bottom: 1.5pt solid var(--otspi-primary); + color: #0f2a6b; + font-size: 18pt; + font-weight: 700; + } + + .md-typeset .wp-toc li { + margin: 0; + padding: 2.2mm 0; + border-bottom: 0.5pt solid #e2e8f0; + font-size: 10.5pt; + text-align: left; + } + + .md-typeset .wp-toc a { + color: #1e293b; + text-decoration: none !important; + } } /* Grille des chiffres clés du livre blanc */ @media print { + /* La grille porte sur la liste : posée sur le conteneur, elle tasserait les six cartes + dans la première colonne. */ .md-typeset .grid.cards.wp-figures { + display: block; + } + + .md-typeset .grid.cards.wp-figures > ul { display: grid; - grid-template-columns: repeat(2, 1fr); - gap: 0.6rem; + grid-template-columns: repeat(3, 1fr); + gap: 4mm; + margin: 0; + padding: 0; + list-style: none; } - .md-typeset .grid.cards.wp-figures > ul > li, - .md-typeset .grid.cards.wp-figures li { + .md-typeset .grid.cards.wp-figures > ul > li { + margin: 0; + padding: 3.5mm 4mm; + border: 0.5pt solid #cbd5e1; + border-top: 2.5pt solid var(--otspi-primary); + border-radius: 0; + box-shadow: none; + background: #f8fafc; + font-size: 8.5pt; + line-height: 1.4; break-inside: avoid; } + + .md-typeset .grid.cards.wp-figures .wp-value { + color: var(--otspi-primary); + font-size: 17pt; + line-height: 1.15; + } } /* Schémas SVG du livre blanc : ne pas les couper d'une page à l'autre */ @@ -250,4 +461,14 @@ .md-typeset .wp-svg { min-width: 0; } + + .md-typeset .wp-diagram figcaption { + margin-top: 3mm; + color: #475569; + font-size: 8.5pt; + } + + .md-typeset .wp-fig-num { + color: #0f2a6b; + } } diff --git a/docs/white-paper/index.md b/docs/white-paper/index.md index 29eb7a4..4c5e3af 100644 --- a/docs/white-paper/index.md +++ b/docs/white-paper/index.md @@ -8,7 +8,7 @@ description: "White paper of the Open Trusted Service Provider Initiative: marke
-![OTSPI](../assets/logo-vertical.svg){ .wp-cover-logo } +![OTSPI](../assets/logo-vertical-dark.svg){ .wp-cover-logo }

White paper

A public-interest qualified trust service infrastructure for eIDAS 2.0

@@ -26,6 +26,8 @@ description: "White paper of the Open Trusted Service Provider Initiative: marke

The PDF is tagged and validated as PDF/UA-1 by the veraPDF checker; this automated validation does not replace testing with a screen reader. This page (HTML) remains the accessible reference version.

+
+ | | | |---|---| | **Issuer** | Open Trusted Service Provider Initiative (OTSPI), non-profit association under the French law of 1901, currently being formed | @@ -35,6 +37,8 @@ description: "White paper of the Open Trusted Service Provider Initiative: marke | **Licence** | Creative Commons Attribution 4.0 International (CC-BY-4.0) | | **Contact** | [contact@otspi.org](mailto:contact@otspi.org) | +
+ !!! note "Nature of this document" This white paper sets out an intention and a target architecture. It is neither a Time-Stamping Policy, nor a Certification Practice Statement (CPS), nor a contractual service commitment. References to products or suppliers are given for information only; their final selection will be subject to competitive procedures and to the approval of the Trust Policy Committee (CPC). @@ -377,8 +381,9 @@ Any vendor of a signing solution, commercial or free, can rely on the service to ### 4.1. Certification hierarchy -
+
OTSPI qualified certification hierarchyThe offline OTSPI root CA, under a quorum, certifies the time-stamping intermediate CA, which certifies time-stamping units TSU-1 (site A) and TSU-2 (site B). It will also certify future qualified CAs for seals, signatures and attestations.OTSPI root CAoffline · air-gapped · M-of-N quorumTime-stamping intermediate CAoffline or restricted onlineFuture qualified CAsseal · signature · attestationsTime-stamping unit TSU-1online HSM — site ATime-stamping unit TSU-2online HSM — site B +
Figure 1 — OTSPI qualified certification hierarchy
@@ -386,11 +391,12 @@ Any vendor of a signing solution, commercial or free, can rely on the service to - Each **time-stamping unit (TSU)** has its own key, reserved exclusively for signing time-stamp tokens, generated and stored in a certified cryptographic module. - The usage period of TSU keys is shorter than the validity of their certificate, in accordance with ETSI EN 319 421, so that tokens issued at the end of the period remain verifiable. - The future **qualified CAs** for seals, signatures and attestations (see § 6.1, phase 5) will be attached to this same qualified root, each under an intermediate CA dedicated to a single use. -- The future TLS certificate service (see § 2.4) relies on **two roots distinct** from the qualified time-stamping root: a **WebTrust root**, intended for the trust stores of operating systems and browsers, and a **QWAC root**, listed on the European trusted list. They apply the same governance principles (air gap, quorum, ceremonies) and share no key with the time-stamping, seal or signature CAs. +- The future TLS certificate service (see § 2.4) relies on **two roots distinct** from the qualified time-stamping root ([figure 2](#figure-2)): a **WebTrust root**, intended for the trust stores of operating systems and browsers, and a **QWAC root**, listed on the European trusted list. They apply the same governance principles (air gap, quorum, ceremonies) and share no key with the time-stamping, seal or signature CAs. -
+
OTSPI TLS certification hierarchiesTwo separate roots: a WebTrust root for browser stores, and a QWAC root listed on the European trusted list. The WebTrust root certifies a DV sub-CA, which issues DV server certificates through instant ACME. A hybrid OV / QWAC sub-CA, holding a single key, is certified by the WebTrust root and, through cross-signing, by the QWAC root; it issues OV / QWAC certificates.cross-signingWebTrust rootOS and browser storesQWAC rootEuropean trusted listDV sub-CAWebTrust only · standard HSMHybrid OV / QWAC sub-CAone key · two CA certificatesDV server certificatesgeneral Web use · instant ACMEOV / QWAC server certificatesPSD2, eIDAS · ACME with account binding +
Figure 2 — OTSPI TLS certification hierarchies
diff --git a/mkdocs.yml b/mkdocs.yml index f72dab9..90031b7 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -16,20 +16,21 @@ theme: name: material custom_dir: overrides language: fr + # Couleurs de la charte OTSPI (bleu nuit du logo) : voir docs/stylesheets/extra.css palette: # Mode clair - media: "(prefers-color-scheme: light)" scheme: default - primary: indigo - accent: indigo + primary: custom + accent: custom toggle: icon: material/brightness-7 name: Passer au mode sombre # Mode sombre - media: "(prefers-color-scheme: dark)" scheme: slate - primary: indigo - accent: indigo + primary: custom + accent: custom toggle: icon: material/brightness-4 name: Passer au mode clair @@ -37,7 +38,8 @@ theme: favicon: assets/favicon.svg icon: repo: fontawesome/brands/github - # Polices du système : aucune requête vers Google Fonts (l'adresse IP du visiteur y serait transmise) + # Pas de Google Fonts (l'adresse IP du visiteur y serait transmise) : la police Inter est + # auto-hébergée (stylesheets/fonts.css) font: false features: - navigation.tabs @@ -61,6 +63,7 @@ extra_javascript: - javascripts/analytics.js?v=2 extra_css: + - stylesheets/fonts.css - stylesheets/extra.css - stylesheets/print.css @@ -79,11 +82,7 @@ markdown_extensions: emoji_index: !!python/name:material.extensions.emoji.twemoji emoji_generator: !!python/name:material.extensions.emoji.to_svg - pymdownx.details - - pymdownx.superfences: - custom_fences: - - name: mermaid - class: mermaid - format: !!python/name:pymdownx.superfences.fence_code_format + - pymdownx.superfences - pymdownx.highlight: anchor_linenums: true - pymdownx.inlinehilite @@ -98,6 +97,8 @@ markdown_extensions: permalink: true extra: + # Pas de mention « Made with Material for MkDocs » en pied de page + generator: false social: - icon: fontawesome/brands/github link: https://github.com/otspi/organisation @@ -111,30 +112,30 @@ extra: nav: - Accueil: index.md - - Livre Blanc: + - Livre blanc: - Livre blanc (FR): livre-blanc/index.md - White Paper (EN): white-paper/index.md - Historique des versions: livre-blanc/historique.md - - Statuts & Gouvernance: + - Statuts et gouvernance: - Projet de statuts: statuts/statuts-association.md - - Charte d'Éthique: gouvernance/charte-ethique.md - - Organisation Technique & CPC: gouvernance/comite-technique.md - - Règlement Intérieur: - - Règlement Intérieur: reglement-interieur/reglement-interieur.md - - Démarches Administratives: - - Procès-Verbal Constitutif (Modèle): administratif/pv-ag-constitutive-modele.md - - Demande de Rescrit Fiscal DGFIP: administratif/rescrit-fiscal-mecenat.md + - Charte d'éthique: gouvernance/charte-ethique.md + - Organisation technique et CPC: gouvernance/comite-technique.md + - Règlement intérieur: + - Règlement intérieur: reglement-interieur/reglement-interieur.md + - Démarches administratives: + - Procès-verbal constitutif (modèle): administratif/pv-ag-constitutive-modele.md + - Demande de rescrit fiscal DGFIP: administratif/rescrit-fiscal-mecenat.md - Dossier de constitution: administratif/dossier-constitution.md - Résolution d'amorçage (CPC et Bureau): administratif/resolution-transitoire.md - - Guide Démarches Préfecture (RNA, SIRET): administratif/declaration-prefecture.md - - Socle Technique & Audit (TSP / PKI): + - Démarches en préfecture (RNA, SIRET): administratif/declaration-prefecture.md + - Socle technique et audit (TSP / PKI): - Vue d'ensemble: cadrage/index.md - Cadre CP/CPS (RFC 3647): cadrage/cp-cps-cadre.md - - Politique de Sécurité des SI (PSSI): cadrage/pssi.md - - Plan de Fin d'Activité (Termination Plan): cadrage/termination-plan.md + - Politique de sécurité des SI (PSSI): cadrage/pssi.md + - Plan de fin d'activité (Termination Plan): cadrage/termination-plan.md - Arc d'OID et numéro IANA: cadrage/oid-arc.md - Demandes de devis (audit, HSM, hébergement): cadrage/demandes-de-devis.md - Transparence: - Hébergements: reunions/hebergements.md - Hosting transparency (EN): reunions/hosting.md - - Registre des Réunions & PV: reunions/index.md + - Registre des réunions et PV: reunions/index.md diff --git a/overrides/home.html b/overrides/home.html new file mode 100644 index 0000000..39b6507 --- /dev/null +++ b/overrides/home.html @@ -0,0 +1,30 @@ +{% extends "main.html" %} + +{#- Page d'accueil : bandeau pleine largeur sous l'en-tête, puis le contenu de docs/index.md + sans le titre automatique ni les boutons d'édition. -#} + +{% block hero %} +
+
+
+

Association d'intérêt général (loi 1901) en cours de constitution

+

Open Trusted Service Provider Initiative

+

+ Construire, opérer et pérenniser des infrastructures de confiance numérique + ouvertes, souveraines et universellement accessibles, conformes aux standards + eIDAS 2.0, ETSI et WebTrust, sous une gouvernance strictement désintéressée. +

+ +
+ +
+
+{% endblock %} + +{% block content %} + {{ page.content }} +{% endblock %} diff --git a/scripts/build_diagrams.py b/scripts/build_diagrams.py index a9cc949..dc1cced 100644 --- a/scripts/build_diagrams.py +++ b/scripts/build_diagrams.py @@ -1,7 +1,8 @@ #!/usr/bin/env python3 # SPDX-License-Identifier: EUPL-1.2 -"""Génère les deux schémas du livre blanc (hiérarchie qualifiée, hiérarchies TLS) en SVG intégré, -en français et en anglais, et les insère entre les marqueurs des pages du livre blanc. +"""Génère les schémas du portail en SVG intégré et les insère entre les marqueurs des pages : +les deux schémas du livre blanc (hiérarchie qualifiée, hiérarchies TLS), en français et en anglais, +et l'organigramme de gouvernance de la page d'accueil. Les schémas n'utilisent aucun script : ils remplacent des blocs Mermaid, dont la bibliothèque (environ 950 Ko, chargée depuis un service tiers) ralentissait fortement la page. @@ -112,8 +113,62 @@ def tls(t, uid): return "".join(parts) -def figure(svg): - return f'
\n{svg}\n
' +GOVERNANCE = { + "title": "Organisation de la gouvernance d'OTSPI", + "desc": "L'assemblée générale élit le conseil d'administration, qui désigne le bureau (direction opérationnelle) ; " + "le bureau assure les relations avec les autorités de contrôle et les auditeurs. L'assemblée générale confirme " + "aussi les nominations au comité des politiques de confiance (CPC), autorité normative indépendante du bureau, " + "qui désigne le RSSI pour un an, habilite et contrôle les officiers d'autorité et rend un avis conforme sur les " + "travaux du comité technique ; le bureau fournit à ce comité ses moyens.", + "ag": ("Assemblée générale", "titulaires et sympathisants"), + "ca": ("Conseil d'administration", "2 à 9 membres"), + "bureau": ("Bureau", "présidence · trésorerie · secrétariat"), + "cab": ("Autorités de contrôle", "et auditeurs (CAB)"), + "cpc": ("Comité des politiques de confiance", "CPC / PMA"), + "tsc": ("Comité technique (TSC)", "avis CPC · moyens du Bureau"), + "rssi": ("RSSI / CISO", "désigné par le CPC, 1 an"), + "oa": ("Officiers d'autorité", "et gardiens de clés"), + "left": "Direction opérationnelle", + "right": "Autorité normative indépendante", + "confirm": "confirmation des nominations", +} + + +def governance(t, uid): + parts = [ + f'', + f'{escape(t["title"])}{escape(t["desc"])}', + defs(uid), + '', + f'{escape(t["left"].upper())}', + '', + f'{escape(t["right"].upper())}', + f'', + f'', + f'{escape(t["confirm"])}', + f'', + f'', + f'', + f'', + f'', + f'', + box(330, 10, 240, 64, t["ag"], "dg-root"), + box(40, 110, 240, 64, t["ca"], "dg-box"), + box(30, 230, 260, 64, t["bureau"], "dg-box"), + box(30, 366, 260, 64, t["cab"], "dg-box"), + box(500, 230, 260, 64, t["cpc"], "dg-root"), + box(342, 366, 186, 64, t["tsc"], "dg-box"), + box(538, 366, 186, 64, t["rssi"], "dg-box"), + box(734, 366, 186, 64, t["oa"], "dg-box"), + '', + ] + return "".join(parts) + + +def figure(svg, number, title): + """Enveloppe un schéma dans une figure légendée et numérotée, ancrée sur #figure-N pour les renvois.""" + return (f'
\n{svg}\n' + f'
Figure {number} — {escape(title)}
\n
') def replace_block(text, name, block): @@ -126,11 +181,17 @@ def main(): for lang, path in (("fr", "docs/livre-blanc/index.md"), ("en", "docs/white-paper/index.md")): page = ROOT / path text = page.read_text(encoding="utf-8") - text = replace_block(text, "hierarchy", figure(hierarchy(TEXT[lang], f"{lang}-h"))) - text = replace_block(text, "tls", figure(tls(TEXT[lang], f"{lang}-t"))) + text = replace_block(text, "hierarchy", figure(hierarchy(TEXT[lang], f"{lang}-h"), 1, TEXT[lang]["h_title"])) + text = replace_block(text, "tls", figure(tls(TEXT[lang], f"{lang}-t"), 2, TEXT[lang]["t_title"])) page.write_text(text, encoding="utf-8") print(f"{path} : schémas régénérés") + home = ROOT / "docs/index.md" + text = replace_block(home.read_text(encoding="utf-8"), "governance", + f'
\n{governance(GOVERNANCE, "home-g")}\n
') + home.write_text(text, encoding="utf-8") + print("docs/index.md : organigramme régénéré") + if __name__ == "__main__": main() diff --git a/scripts/export_pdf.py b/scripts/export_pdf.py index 0c429e7..291ccde 100644 --- a/scripts/export_pdf.py +++ b/scripts/export_pdf.py @@ -71,7 +71,7 @@ def print_pdf(url, output): f"--user-data-dir={profile}", "--no-pdf-header-footer", "--generate-pdf-document-outline", - # Laisse le temps au rendu des diagrammes Mermaid + # Laisse le temps au chargement complet de la page (polices, scripts) "--virtual-time-budget=20000", "--run-all-compositor-stages-before-draw", f"--print-to-pdf={output}", @@ -88,15 +88,15 @@ def print_pdf(url, output): .dg-box{fill:#fff;stroke:#b8bcc4;stroke-width:1.5} .dg-root{fill:#e8eefc;stroke:#1a3d8f;stroke-width:2} .dg-future{fill:none;stroke:#6b7280;stroke-width:1.5;stroke-dasharray:6 5} -.dg-t{fill:#1f2937;font-size:12.5px;font-weight:700;font-family:sans-serif} -.dg-s{fill:#4b5563;font-size:12px;font-family:sans-serif} +.dg-t{fill:#1f2937;font-size:12.5px;font-weight:700;font-family:Inter,sans-serif} +.dg-s{fill:#4b5563;font-size:12px;font-family:Inter,sans-serif} .dg-edge,.dg-cross{fill:none;stroke-width:1.8} .dg-edge{stroke:#4b5563} .dg-dash{stroke-dasharray:5 5} .dg-cross{stroke:#1a3d8f;stroke-dasharray:7 5} .dg-arrow{fill:#4b5563} .dg-arrow-cross{fill:#1a3d8f} -.dg-label{fill:#1a3d8f;font-size:12px;font-weight:700;font-family:sans-serif} +.dg-label{fill:#1a3d8f;font-size:12px;font-weight:700;font-family:Inter,sans-serif} """ diff --git a/scripts/pdf-weasyprint.css b/scripts/pdf-weasyprint.css index d86eb10..5cd7079 100644 --- a/scripts/pdf-weasyprint.css +++ b/scripts/pdf-weasyprint.css @@ -40,6 +40,8 @@ body { width: 1px !important; height: 1px !important; overflow: hidden !important; + padding: 0 !important; + border: 0 !important; break-before: auto !important; } @@ -65,17 +67,8 @@ body { padding-left: 0.6rem !important; } -/* Grille des chiffres clés : WeasyPrint ne gère pas la grille automatique de Material. */ -.md-typeset .grid.cards.wp-figures > ul { - display: grid !important; - grid-template-columns: repeat(2, 1fr) !important; - gap: 0.6rem !important; -} - -.md-typeset .grid.cards.wp-figures > ul > li { - margin: 0 !important; -} - +/* Grille des chiffres clés (trois colonnes, voir print.css) : WeasyPrint ne gère pas la grille + automatique de Material ni ses largeurs minimales. */ .md-typeset .grid.cards.wp-figures, .md-typeset .grid.cards.wp-figures > ul { width: 100% !important; @@ -83,19 +76,11 @@ body { box-sizing: border-box !important; } -.md-typeset .grid.cards.wp-figures > ul { - margin: 0 !important; - padding: 0 !important; - list-style: none !important; -} - .md-typeset .grid.cards.wp-figures > ul > li { - padding: 0.6rem 0.7rem !important; min-width: 0 !important; } .md-typeset .grid.cards.wp-figures .wp-value { - font-size: 1.25rem !important; overflow-wrap: anywhere; } @@ -127,3 +112,33 @@ body { .footnote li > p:first-child { display: inline !important; } + +/* Sommaire : numéro de page de chaque section, précédé de points de conduite. */ +.md-typeset .wp-toc a::after { + content: leader(".") target-counter(attr(href url), page); + color: #64748b; +} + +/* Signets du PDF : sections et annexes au premier niveau, sous-sections repliées. Le titre et le + sous-titre masqués n'en produisent pas : la page de garde et le titre du document en tiennent lieu. */ +.wp-cover ~ h1, +.wp-cover ~ h1 + h2 { + bookmark-level: none !important; +} + +.md-typeset .wp-toc h3, +.md-typeset .wp-cover ~ h2 { + bookmark-level: 1; +} + +.md-typeset .wp-cover ~ h2 { + bookmark-state: closed; +} + +.md-typeset .wp-cover ~ h3 { + bookmark-level: 2; +} + +.md-typeset .wp-cover ~ h4 { + bookmark-level: 3; +}