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 @@
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
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
-
+
+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.
-
+
+Figure 2 — Hiérarchies de certification TLS d'OTSPI
diff --git a/docs/stylesheets/extra.css b/docs/stylesheets/extra.css
index 817e9a0..68ecc64 100644
--- a/docs/stylesheets/extra.css
+++ b/docs/stylesheets/extra.css
@@ -262,6 +262,94 @@
}
}
+/* --------------------------------------------------------------------------
+ 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);
+}
+
+/* Encadrés lisibles : Material les compose plus petit que le corps du texte */
+.md-typeset:has(> .wp-cover) .admonition,
+.md-typeset:has(> .wp-cover) details {
+ font-size: 0.72rem;
+}
+
+/* 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 +389,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%;
@@ -429,6 +531,10 @@
--md-typeset-a-color: #8fb4ff;
}
+[data-md-color-scheme="slate"] .md-typeset .wp-meta table:not([class]) {
+ border-top-color: #8fb4ff;
+}
+
[data-md-color-scheme="slate"] .otspi-badge {
color: #9cc0ff;
}
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..06a3685 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;
}
@@ -147,13 +168,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 +187,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 +270,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 +462,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
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
-
+
+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.
-
+
+Figure 2 — OTSPI TLS certification hierarchies
diff --git a/mkdocs.yml b/mkdocs.yml
index f72dab9..e7f5a42 100644
--- a/mkdocs.yml
+++ b/mkdocs.yml
@@ -37,7 +37,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 +62,7 @@ extra_javascript:
- javascripts/analytics.js?v=2
extra_css:
+ - stylesheets/fonts.css
- stylesheets/extra.css
- stylesheets/print.css
diff --git a/scripts/build_diagrams.py b/scripts/build_diagrams.py
index a9cc949..debf1ed 100644
--- a/scripts/build_diagrams.py
+++ b/scripts/build_diagrams.py
@@ -112,8 +112,10 @@ def tls(t, uid):
return "".join(parts)
-def figure(svg):
- return f'\n{svg}\n'
+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,8 +128,8 @@ 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")
diff --git a/scripts/export_pdf.py b/scripts/export_pdf.py
index 0c429e7..a033bce 100644
--- a/scripts/export_pdf.py
+++ b/scripts/export_pdf.py
@@ -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;
+}