| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479 |
- /*
- * ZenQuality — client handover stylesheet
- * Used to render LIVRAISON.md / HANDOVER.md as a branded HTML/PDF.
- * Source brand tokens: zenquality.fr (CSS custom properties extracted from
- * the live site) — Inter (body) + Playfair Display (headings), green palette.
- */
- @import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=Playfair+Display:wght@400;600;700&display=swap');
- :root {
- --green-dark: #1A3A25;
- --green-forest: #2D5A3D;
- --green-moss: #4A7C59;
- --green-sage: #87A878;
- --black-deep: #0A0A0A;
- --black-soft: #1A1A1A;
- --gray-dark: #2A2A2A;
- --gray-mid: #666666;
- --gray-light: #B0B0B0;
- --white-cream: #F5F0EB;
- --white-pure: #FFFFFF;
- --status-ok: #2D5A3D;
- --status-warn: #b58900;
- --status-fail: #a83232;
- }
- @page {
- size: A4;
- margin: 22mm 18mm 22mm 18mm;
- @top-right {
- content: string(doctitle);
- font-family: 'Inter', sans-serif;
- font-size: 8.5pt;
- color: var(--green-moss);
- }
- @bottom-right {
- content: counter(page) " / " counter(pages);
- font-family: 'Inter', sans-serif;
- font-size: 8.5pt;
- color: var(--gray-mid);
- }
- @bottom-left {
- content: "ZenQuality — zenquality.fr";
- font-family: 'Inter', sans-serif;
- font-size: 8.5pt;
- color: var(--gray-mid);
- }
- }
- @page :first {
- margin: 0;
- @top-right { content: ""; }
- @bottom-right { content: ""; }
- @bottom-left { content: ""; }
- }
- * { box-sizing: border-box; }
- html, body {
- margin: 0;
- padding: 0;
- font-family: 'Inter', system-ui, -apple-system, sans-serif;
- font-size: 10.5pt;
- line-height: 1.6;
- color: var(--black-deep);
- background: var(--white-pure);
- }
- /* ============ COVER PAGE ============ */
- .cover {
- page-break-after: always;
- height: 297mm;
- width: 210mm;
- padding: 35mm 22mm 22mm 22mm;
- background:
- radial-gradient(ellipse at top right, rgba(135, 168, 120, 0.18) 0%, transparent 55%),
- radial-gradient(ellipse at bottom left, rgba(45, 90, 61, 0.06) 0%, transparent 55%),
- var(--white-pure);
- color: var(--black-deep);
- position: relative;
- display: flex;
- flex-direction: column;
- justify-content: space-between;
- page: cover;
- }
- .cover-header {
- display: flex;
- align-items: flex-start;
- justify-content: space-between;
- }
- .cover-logo {
- width: 55mm;
- height: auto;
- max-height: 30mm;
- object-fit: contain;
- }
- .cover-tagline {
- font-family: 'Playfair Display', Georgia, serif;
- font-size: 10pt;
- font-style: italic;
- color: var(--green-forest);
- text-align: right;
- max-width: 70mm;
- margin-top: 6mm;
- }
- .cover-body {
- flex: 1;
- display: flex;
- flex-direction: column;
- justify-content: center;
- margin: -10mm 0 0 0;
- }
- .cover-eyebrow {
- font-family: 'Inter', sans-serif;
- font-size: 9pt;
- font-weight: 600;
- text-transform: uppercase;
- letter-spacing: 0.18em;
- color: var(--green-forest);
- margin-bottom: 6mm;
- }
- .cover-title {
- font-family: 'Playfair Display', Georgia, serif;
- font-size: 34pt;
- font-weight: 700;
- color: var(--black-deep);
- line-height: 1.1;
- margin: 0 0 6mm 0;
- letter-spacing: -0.015em;
- }
- .cover-subtitle {
- font-family: 'Playfair Display', Georgia, serif;
- font-size: 16pt;
- font-weight: 400;
- font-style: italic;
- color: var(--green-forest);
- margin: 0 0 18mm 0;
- max-width: 140mm;
- }
- .cover-meta {
- font-family: 'Inter', sans-serif;
- font-size: 10.5pt;
- color: var(--black-deep);
- line-height: 1.9;
- border-left: 2px solid var(--green-forest);
- padding-left: 5mm;
- }
- .cover-meta strong {
- color: var(--green-forest);
- font-weight: 600;
- display: inline-block;
- min-width: 25mm;
- }
- .cover-meta a {
- color: var(--black-deep);
- text-decoration: underline;
- text-decoration-color: rgba(45, 90, 61, 0.6);
- }
- .cover-footer {
- font-family: 'Inter', sans-serif;
- font-size: 9pt;
- color: var(--green-forest);
- border-top: 1px solid rgba(45, 90, 61, 0.4);
- padding-top: 5mm;
- display: flex;
- justify-content: space-between;
- }
- .cover-footer a {
- color: var(--black-deep);
- text-decoration: none;
- font-weight: 500;
- }
- .cover-footer a:hover { color: var(--green-forest); }
- /* ============ DOCUMENT BODY ============ */
- .content {
- string-set: doctitle attr(data-title);
- }
- h1 {
- font-family: 'Playfair Display', Georgia, serif;
- font-size: 22pt;
- font-weight: 700;
- color: var(--green-dark);
- margin: 0 0 6mm 0;
- page-break-after: avoid;
- string-set: doctitle content();
- }
- h2 {
- font-family: 'Playfair Display', Georgia, serif;
- font-size: 17pt;
- font-weight: 600;
- color: var(--green-forest);
- margin: 12mm 0 4mm 0;
- padding-bottom: 2.5mm;
- border-bottom: 2px solid var(--green-sage);
- page-break-before: always;
- page-break-after: avoid;
- }
- .content > h2:first-of-type,
- h2.no-break,
- h2.continue {
- page-break-before: auto;
- }
- h3 {
- font-family: 'Playfair Display', Georgia, serif;
- font-size: 13.5pt;
- font-weight: 600;
- color: var(--green-forest);
- margin: 8mm 0 3mm 0;
- page-break-after: avoid;
- }
- h4 {
- font-family: 'Inter', sans-serif;
- font-size: 10pt;
- font-weight: 600;
- color: var(--green-moss);
- margin: 6mm 0 2mm 0;
- text-transform: uppercase;
- letter-spacing: 0.06em;
- page-break-after: avoid;
- }
- p { margin: 0 0 3mm 0; }
- p, li { orphans: 3; widows: 3; }
- ul, ol { margin: 0 0 3mm 0; padding-left: 6mm; }
- ul li, ol li { margin: 0 0 1.5mm 0; }
- ul li::marker { color: var(--green-moss); }
- ol li::marker { color: var(--green-moss); font-weight: 600; }
- /* ============ PAGE-BREAK HARDENING ============ */
- /* Keep each list item intact across pages — prevents the bullet/marker
- from staying on the previous page while the text reflows to the next
- (historical cause of "trailing word + leading bullet" superposition). */
- li {
- page-break-inside: avoid;
- break-inside: avoid;
- }
- /* Tie the first block after a heading to the heading itself so a page
- break never splits "heading + intro" or "heading + first list item"
- across two pages. */
- h1 + p, h1 + ul, h1 + ol,
- h2 + p, h2 + ul, h2 + ol,
- h3 + p, h3 + ul, h3 + ol,
- h4 + p, h4 + ul, h4 + ol {
- page-break-before: avoid;
- break-before: avoid;
- }
- strong { color: var(--green-dark); font-weight: 600; }
- em { color: var(--green-forest); font-style: italic; }
- blockquote {
- border-left: 3px solid var(--green-moss);
- padding: 3mm 5mm;
- margin: 4mm 0;
- background: var(--white-cream);
- color: var(--gray-dark);
- font-style: italic;
- page-break-inside: avoid;
- }
- blockquote p:last-child { margin-bottom: 0; }
- a { color: var(--green-forest); text-decoration: underline; text-decoration-thickness: 0.5pt; text-underline-offset: 1.5pt; }
- a:hover { color: var(--green-dark); }
- code {
- font-family: 'JetBrains Mono', 'Fira Code', Menlo, monospace;
- font-size: 9pt;
- background: var(--white-cream);
- padding: 0.5mm 1.5mm;
- border-radius: 1mm;
- color: var(--green-dark);
- }
- pre {
- background: var(--white-cream);
- padding: 4mm 5mm;
- border-radius: 1.5mm;
- border-left: 3px solid var(--green-moss);
- font-size: 8.5pt;
- line-height: 1.45;
- white-space: pre-wrap;
- word-wrap: break-word;
- page-break-inside: avoid;
- margin: 4mm 0;
- }
- pre code { background: none; padding: 0; color: var(--black-deep); font-size: inherit; }
- /* ============ TABLES ============ */
- table {
- width: 100%;
- border-collapse: collapse;
- margin: 4mm 0;
- font-size: 9.5pt;
- page-break-inside: avoid;
- }
- th {
- font-family: 'Inter', sans-serif;
- background: var(--green-forest);
- color: var(--white-pure);
- text-align: left;
- padding: 2.5mm 3mm;
- font-weight: 600;
- font-size: 9pt;
- text-transform: uppercase;
- letter-spacing: 0.04em;
- border-bottom: 0;
- }
- td {
- padding: 2.5mm 3mm;
- border-bottom: 1px solid var(--green-sage);
- vertical-align: top;
- }
- tr:nth-child(even) td { background: rgba(245, 240, 235, 0.55); }
- /* Numeric / status cols of score tables auto-detected via header text */
- table th:nth-child(2),
- table th:nth-child(3),
- table th:nth-child(4),
- table td:nth-child(2),
- table td:nth-child(3),
- table td:nth-child(4) {
- text-align: right;
- font-variant-numeric: tabular-nums;
- }
- table th:last-child,
- table td:last-child {
- text-align: center;
- }
- /* ============ CHECKLISTS ============ */
- ul.checklist,
- ul.task-list {
- list-style: none;
- padding-left: 0;
- }
- ul.checklist li,
- ul.task-list li {
- padding-left: 8mm;
- position: relative;
- margin-bottom: 2.5mm;
- }
- ul.checklist li::before,
- ul.task-list li::before,
- li.task-list-item::before {
- content: "☐";
- position: absolute;
- left: 0;
- color: var(--green-moss);
- font-size: 12pt;
- line-height: 1;
- }
- /* Pandoc GFM emits <li><input disabled type="checkbox"> text...</li> with
- no wrapper class. Render the native checkbox inline (small, green) and
- leave inline elements (<a>, <code>, <strong>) that follow it untouched.
- Earlier rule `li input[type="checkbox"] + *` mistakenly absolutely-
- positioned the first element sibling after the checkbox, yanking links
- and code spans out of flow and overlapping adjacent content. */
- li > input[type="checkbox"] {
- appearance: none;
- -webkit-appearance: none;
- display: inline-block;
- width: 3mm;
- height: 3mm;
- margin: 0 1.5mm 0 0;
- border: 0.4mm solid var(--green-moss);
- border-radius: 0.5mm;
- vertical-align: middle;
- background: transparent;
- }
- li > input[type="checkbox"]:checked {
- background: var(--green-forest);
- border-color: var(--green-forest);
- }
- /* ============ CALLOUTS ============ */
- .callout {
- padding: 4mm 6mm;
- margin: 4mm 0;
- border-radius: 2mm;
- page-break-inside: avoid;
- font-size: 10pt;
- }
- .callout.info {
- background: var(--white-cream);
- border-left: 4px solid var(--green-moss);
- }
- .callout.warn {
- background: #fdf6e3;
- border-left: 4px solid var(--status-warn);
- }
- .callout.success {
- background: rgba(135, 168, 120, 0.14);
- border-left: 4px solid var(--green-forest);
- }
- .callout-title {
- font-family: 'Inter', sans-serif;
- font-weight: 600;
- font-size: 10pt;
- color: var(--green-dark);
- margin-bottom: 2mm;
- text-transform: uppercase;
- letter-spacing: 0.04em;
- }
- /* ============ SECTION DIVIDERS ============ */
- hr {
- border: none;
- border-top: 1px solid var(--green-sage);
- margin: 8mm 0;
- }
- /* ============ STATUS PILLS (used by text replacement) ============ */
- .status-ok { color: var(--status-ok); font-weight: 600; }
- .status-warn { color: var(--status-warn); font-weight: 600; }
- .status-fail { color: var(--status-fail); font-weight: 600; }
- /* ============ LINK BEHAVIOR IN PRINT ============ */
- @media print {
- a[href^="http"]::after {
- content: " (" attr(href) ")";
- font-size: 7.5pt;
- color: var(--gray-mid);
- font-style: italic;
- font-weight: 400;
- }
- a[href^="#"]::after,
- a[href^="mailto:"]::after,
- a[href^="tel:"]::after,
- a.bare-url::after,
- .cover a::after,
- table a::after { content: ""; }
- /* Belt-and-braces: prevent the ::after URL pseudo-element from breaking
- across pages or columns and overlapping the next block (root cause of
- historical "text superposition" bugs on long URLs). */
- a[href^="http"]::after {
- white-space: nowrap;
- page-break-before: avoid;
- page-break-inside: avoid;
- break-before: avoid;
- break-inside: avoid;
- }
- }
|