
Weasyprint
- 5 installs
- 2 repo stars
- Updated June 11, 2026
- thedivergentai/divergent-skills
Helps with ai & agent building tasks during AI-assisted development.
About
weasyprint is a Claude Code skill for ai & agent building. It helps solo builders move faster with AI-assisted coding.
- weasyprint
- AI & Agent Building
- AI-coding skill
Weasyprint by the numbers
- 5 all-time installs (skills.sh)
- Ranked #13,065 of 16,546 AI & Agent Building skills by installs in the Skillselion catalog
- Data as of Aug 5, 2026 (Skillselion catalog sync)
npx skills add https://github.com/thedivergentai/divergent-skills --skill weasyprintAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 5 |
|---|---|
| repo stars | ★ 2 |
| Last updated | June 11, 2026 |
| Repository | thedivergentai/divergent-skills ↗ |
What it does
Helps with ai & agent building tasks during AI-assisted development.
Files
WeasyPrint
Pagination-first CSS engine (Python + Pango). Not headless Chrome: no JS, no RTL/bidi, print media default.
MANDATORY — read first when scope is unclear: `references/resource-matrix.md`
Load one flat expert lesson from references/ root (e.g. security-untrusted-html.md, css-paged-media.md). Do not open full-docs/ unless the matrix sends you there as last resort.
Before You Act
1. Trust — Untrusted HTML/CSS? → security-untrusted-html.md + security-url-fetcher.md (before code). 2. Runtime — CLI one-off (cli-basics.md), batch, or embedded Python (python-instantiation.md)? 3. Output — Plain PDF, PDF/A/UA/X (pdf-*.md), Factur-X, fillable forms? 4. Wrong tool? — JS layout, RTL, live DOM, pixel-perfect screen CSS → Puppeteer, not WeasyPrint.
Debug Bisect (wrong output)
1. `debug-pipeline.md` — enable logging; unsupported CSS fails silently by default. 2. `css-browser-vs-print.md` — print vs browser gaps? 3. Closest sample from `resource-matrix.md` Examples catalog — ≤120 lines of relevant .css. 4. Still blocked? One matching flat lesson from the matrix. `full-docs/` only as last resort (≤120 lines/§).
NEVER
- NEVER use positional string HTML or omit
base_urlonHTML(string=...)— seepython-instantiation.md. - NEVER enable
presentational_hintson untrusted HTML — CVE-2026-49452; seesecurity-untrusted-html.md. - NEVER expose untrusted HTML without process limits + fetcher blocking
file://. - NEVER set page size via imagined CLI flags — only
@pageor-s; seecli-basics.md. - NEVER assume PDF/A validity without
image-rendering: crisp-edges+ user-side validation — seepdf-a-archival.md. - NEVER expect
:hover,:focus,:visitedto match; NEVER rely on RTL/bidi — seecss-browser-vs-print.md. - NEVER use
zoom != 1casually — scales all units includingcmandA4. - NEVER bulk-load
full-docs/or example.pdffiles. - NEVER load
full-docs/contribute.mdorfull-docs/support.md.
Common Failures → Fix
| Symptom | Lesson |
|---|---|
cannot load library 'pango...' | install-windows.md or install-macos.md + install-troubleshooting.md |
| Tofu / blank text | css-fonts.md |
| Broken relative assets | python-instantiation.md (base_url=) |
| Styles ≠ browser | css-browser-vs-print.md |
| Auth assets 404 | web-flask-django.md |
| PDF/A rejected | pdf-a-archival.md |
| SSRF / file read | security-url-fetcher.md |
| Slow batch renders | web-performance.md |
Platform Quick Pointers
| Platform | Start here |
|---|---|
| Linux | install-linux.md |
| Windows | install-windows.md |
| macOS | install-macos.md |
| Any install failure | install-troubleshooting.md |
Expert Notes
- Versions: major bumps change rendering — see
debug-version-upgrades.md; visual diff PDFs on upgrade. - Performance: cascade cost ∝ selectors × elements; multi-page tables are slow — see
web-performance.md. - Defaults:
presentational_hints=False;finisher(document, pdf)hooks pydyf before trailer.
WeasyPrint — acknowledgments
Thank you to Kozea and the WeasyPrint team for the library, documentation, and official samples this skill packages. Professional support and maintenance by CourtBouillon.
Agents: do not load this file. Credit is in skill metadata only.
WeasyPrint CLI Basics
When to load: One-off PDF from HTML/URL, shell scripts, CI smoke tests, or debugging before embedding the Python API.
Expert lesson
The CLI shape is fixed: weasyprint [options] <input> <output>. Input is a URL, file path, or - for stdin; output is a path or - for stdout. There is no separate “page size” or “margin” flag — layout is entirely CSS.
Page geometry, margins, headers/footers, and named pages all belong in a stylesheet passed with -s / --stylesheet. Repeat -s for multiple user sheets (same as Python stylesheets=[...]). Quick experiments on bash/zsh can pipe CSS without a file:
weasyprint report.html out.pdf \
-s <(echo '@page { size: A4 landscape; margin: 2cm; }')Default @media is print (-m print). Use -m screen only when you intentionally want screen rules. Relative URLs in stdin HTML need -u <base-url> — without it, resolution falls back to the current working directory, not the HTML file’s directory.
Sanity check after install: weasyprint --info (Pango, Python, library paths). Version only: --version.
High-value flags beyond -s:
| Flag | Expert use |
|---|---|
-u / --base-url | Required for stdin or when assets are relative to another directory |
-m / --media-type | print (default) vs screen |
-t / --timeout | HTTP fetch timeout (seconds); default 10 |
--allowed-protocols | Coarse SSRF guard, e.g. https,data |
--fail-on-http-errors | Fail closed on 4xx/5xx instead of silent missing assets |
--pdf-variant | PDF/A, PDF/UA, PDF/X — must match your compliance checklist |
--pdf-tags | Tagged PDF for accessibility |
-p / --presentational-hints | Trusted HTML only — legacy attrs become CSS (see security-untrusted-html.md) |
-c / --cache-folder | Disk cache for repeated renders (batch invoices) |
-D / --dpi, -j / --jpeg-quality, --optimize-images | Size/quality tradeoffs for embedded images |
Stderr warnings about unsupported CSS are normal; they do not fail the process unless you add HTTP/error policies above.
For many documents in one process, prefer the Python API — CLI pays full startup + font/Pango init every invocation.
Related example
weasyprint https://weasyprint.org /tmp/site.pdf \
-s page.css \
-t 20 \
--custom-metadataTraps
- No `-size` / `-margin` flags — agents invent them constantly; only
@pagevia-sor embedded CSS works. - Stdin without `-u` —
./images/logo.pngresolves against CWD, not your project tree. - `presentational_hints` on untrusted HTML — CVE-2026-49452; keep off for user content.
- Assuming failure on CSS warnings — unsupported properties log and skip; check stderr when output looks wrong.
- PDF/A from CLI alone — variant flag is necessary but not sufficient; raster images often need
image-rendering: crisp-edgesin CSS.
---
Further research
Official stable documentation: Command-Line, Description (manpage)
Browser vs Print: Diagnosing CSS Gaps
Use this lesson when CSS looks correct in a browser but fails or differs in WeasyPrint PDF output.
First Diagnostic Checklist
1. Media type — WeasyPrint defaults to print, not screen. Rules inside @media screen are ignored unless you pass -m screen or media_type='screen'. Put print-specific rules in @media print or leave them unqualified. 2. Presentational hints — Legacy HTML may rely on attributes (width, align, bgcolor). Enable once with --presentational-hints or presentational_hints=True only on trusted input (untrusted HTML + hints is a security risk; see CVE-2026-49452). 3. Unsupported features — Before rewriting layout, confirm the property is implemented. Many “bugs” are spec gaps (see sections below). 4. Logs — Run with verbose logging; missing glyphs, fetch failures, and font warnings appear in stderr.
Hard Unsupported (CSS 2.1)
| Feature | Impact |
|---|---|
visibility: collapse on tables | Use hidden or restructure |
| Min/max width/height on table boxes | Avoid on <table>, rows, cells |
| Min/max on page-margin boxes | Fixed margin-box sizing only |
Spec-conforming font-family matching | Passed raw to Pango — test with fc-match |
| RTL / bidi text | No right-to-left layout |
| System colors / system fonts | Deprecated; use explicit values |
Selectors That Never Match
PDF is not interactive. These parse as valid CSS but never match:
:hover, :active, :focus, :target, :visited
Selectors Level 4 gaps: no :dir, no input pseudo-classes (:valid, :invalid…), no column selectors (||, :nth-col).
Text Module Gaps
Not supported: line-break, match-parent for text-align, text-indent, hanging-punctuation, Text 4 spacing/wrap properties (text-wrap, text-spacing, etc.).
Hyphenation requires both hyphens: auto and lang on <html> for a Pyphen dictionary. Disable locally with hyphens: manual where needed (e.g. URLs in ::after content).
Other Common Surprises
- Transforms — 2D only (
translate,rotate,scale,skew). No 3D,perspective, orbackface-visibility. - Color — CSS Color 4 fully supported except system colors. Level 5:
light-dark(),device-cmyk(),@color-profileyes;color-mix()/contrast-color()no. - Tables — Multi-page tables are a known slow path; prefer block layout when performance matters.
- Box shadow —
box-shadownot supported in stable releases. - Intrinsic sizing —
min-content,max-content,fit-content()not supported.
Paged Media: Where WeasyPrint Excels
Unlike browsers, WeasyPrint fully implements @page, margin boxes, running elements, footnotes, named strings, target-counter() / target-text(), leaders, and PDF bookmarks. If screen layout “works” but print headers/TOC fail, you likely need paged-media CSS — not a flexbox rewrite.
Limits: element() `start` parameter not supported; footnote-display: compact not supported.
Migration Strategy
1. Confirm media type and check logs. 2. Map the failing property to the supported-features matrix in `full-docs/api_reference.md` § Supported Features. 3. Replace unsupported layout (e.g. box-shadow, complex grid) with print-native alternatives. 4. Use official samples from `resource-matrix.md` Examples catalog for TOC, headers, and @page patterns.
Further research
Flexbox & Grid in WeasyPrint
Both modules work for simple layouts. Neither is as battle-tested as block flow or paged media. Validate every PDF — do not assume browser parity.
Flexbox (Level 1)
"Works for simple use cases but is not deeply tested."
Supported: all flex-* properties, align-*, justify-*, order, plus flex and flex-flow shorthands.
Reliable patterns
- Single-row toolbars, ticket stubs, invoice line items
display: flexwith explicit widths on children- Simple
flex-direction: columnstacks
The ticket sample uses flex for a compact landscape layout — see `examples/ticket/ticket.css`.
Risk areas
- Deeply nested flex with
flex-grow/flex-shrinkacross page breaks min-content/max-content/fit-content()sizing (unsupported globally)- Complex wrapping combined with fragmentation — test page breaks explicitly
- Flex items containing images with intrinsic sizing edge cases
Fallback: for multi-page documents, prefer block flow + floats or tables for tabular data.
Grid (Level 2)
"Works for simple cases, but has some limitations."
Supported
display: grid(notinline-grid)grid-template-*,grid-auto-*, allgrid-*shorthandsfrunits, line names,grid-template-areas- Auto rows/columns,
repeat(N, *),minmax() align-*,justify-*,gap/*-gap, dense auto-flow,order- Margins, borders, padding on containers and items
- Fragmentation between rows
Unsupported or untested
| Feature | Notes |
|---|---|
display: inline-grid | Use grid |
| Auto content size for containers | Set explicit grid-template |
grid-auto-flow: column | Use row flow |
| Subgrids | Not implemented |
repeat(auto-fill/fit, *) | Use fixed repeat(N, …) |
| Auto margins on grid items | Set explicit alignment |
span with line names / flexible tracks | Simplify track definitions |
safe / unsafe alignments | Use default alignment |
| Baseline alignment | Use start / center |
| Grid items with intrinsic size (images) | Set explicit dimensions |
| Items larger than container | Constrain with fixed tracks |
min/max-width/height on grid items | Avoid or test carefully |
| Absolutely positioned / floating grid items | Keep items in normal flow |
| Fragmentation within rows | Breaks between rows only |
Decision Guide
Need headers/footers/TOC? → Paged media (not flex/grid)
Simple horizontal bar? → Flexbox (test once)
Fixed-column invoice table? → Table or grid with explicit tracks
Multi-page complex dashboard? → Block flow; avoid grid until simplifiedDebugging Checklist
1. Simplify to a minimal grid/flex — does the PDF improve? 2. Replace auto-fill / auto-fit with fixed repeat(). 3. Give images explicit width / height. 4. Remove min-content / max-content from track sizes. 5. If layout spans pages badly, switch affected sections to block flow.
Further research
Fonts in WeasyPrint
WeasyPrint renders text through Pango → Fontconfig → HarfBuzz. CSS font properties are supported, but font resolution differs from browsers.
System Fonts
Any font Pango finds on the system is available. List fonts with fc-list; test a pattern with fc-match "Family Name". Install locally by copying to ~/.local/share/fonts (Linux) or OS font directories.
Fonts are embedded and subset in PDF output (glyphs used in the document only). Subsetting uses hb-subset when available, fontTools as fallback.
CLI flags: --full-fonts embeds unmodified font files; --hinting keeps hinting data.
@font-face
Declare web fonts in CSS as usual:
@font-face {
font-family: "My Serif";
src: url("fonts/MySerif-Regular.woff2") format("woff2");
font-weight: 400;
}Python API: @font-face rules require a shared FontConfiguration instance passed to both CSS() and HTML.write_pdf() / render():
from weasyprint import HTML, CSS
from weasyprint.text.fonts import FontConfiguration
font_config = FontConfiguration()
css = CSS("styles.css", font_config=font_config)
HTML("doc.html").write_pdf("out.pdf", stylesheets=[css], font_config=font_config)Reuse the same FontConfiguration for all stylesheets in one document.
Samples with @font-face: `examples/report/`, `examples/book/`, `examples/letter/fonts/`.
Supported Font Properties
From CSS Fonts 3: font-size, font-stretch, font-style, font-weight, font-kerning, font-variant-*, font-feature-settings, font-language-override, shorthand font / font-variant, @font-face.
From Level 4: font-variation-settings only.
Not supported: @font-feature-values; font-variant-alternates beyond normal and historical-forms.
Fontconfig Quirks
Fontconfig applies system-wide rules: fallbacks for missing glyphs, aliases (serif, monospace), emoji variants. These can override CSS expectations.
When fonts behave unexpectedly:
1. Run fc-match on your font-family string. 2. Check whether a system alias substitutes a different face. 3. Disable or override Fontconfig rules if you need pixel-exact CSS control. 4. Prefer explicit @font-face with local file paths for reproducible PDFs.
font-family is passed as-is to Pango, not via the CSS 2.1 font-matching algorithm. Common stacks work; exotic fallback chains may differ from Chrome.
Tofu (.notdef Glyphs)
When no font covers a Unicode code point, Pango renders the font's `.notdef` glyph (often a box — "tofu") and logs a warning.
Known quirk: the .notdef glyph may have an incorrect advance width; surrounding glyph positions remain correct. Text search/selection behave as if the character existed.
Fixes:
- Embed a font that covers the script (
@font-face+FontConfiguration) - Add fallback families in
font-family - Verify
langattribute for hyphenation/dictionary coverage (separate from glyph coverage)
Debugging Checklist
1. Check stderr for "Glyph … missing" warnings. 2. fc-list | grep -i "family" — is the font installed? 3. Confirm base_url resolves relative url() in @font-face. 4. Pass the same font_config to CSS() and HTML.write_pdf(). 5. For production PDFs, ship fonts with the project instead of relying on system installs.
Further research
CSS Paged Media in WeasyPrint
WeasyPrint treats each PDF page as a CSS page box. Paged Media is a core strength — most browser engines barely implement it.
The @page Rule
@page {
size: A4;
margin: 2.5cm 2cm;
@top-center { content: "Report Title"; }
@bottom-right { content: counter(page); }
}Page selectors: :left, :right, :first, :blank, and GCPM :nth() — e.g. @page :nth(1 of chapter) for first page of each named chapter.
Page properties: size, bleed, marks, margins, borders, padding. Page-based counters have known issues (#93) — test on your document.
Named Pages
@page chapter { @top-center { content: string(heading); } }
h2 { page: chapter; break-before: right; }Report sample: page: chapter / page: no-chapter for cover vs body (`examples/report/report.css`). Book sample: page: full, page: clean, :blank with left/right margin boxes (`examples/book/book.css`).
Margin Boxes
Sixteen positions (@top-left … @bottom-right). Content uses counter(), string(), element(), and literal content.
Limits: no min/max on margin boxes; element() works but `start` parameter not supported.
Running Elements & Footnotes
.header { position: running(header); }
@page { @top-center { content: element(header); } }Footnotes: float: footnote with ::footnote-marker, ::footnote-call, footnote-display, footnote-policy. footnote-display: compact not supported.
Fragmentation & Units
break-before/after/inside work for pages (not columns). orphans, widows, margin-break supported.
pvw / pvh = whole page including margins; vw / cm / px = page area inside margins.
Sample Index
| Task | Sample |
|---|---|
| Cover + body | `examples/report/report.css` |
| Book left/right | `examples/book/book.css` |
| Invoice footer | `examples/invoice/invoice.css` |
Humans preview PDFs via scripts/render-courtbouillon-sample.sh — see `resource-matrix.md` Examples section.
Further research
Tables of Contents, Running Headers & Cross-References
WeasyPrint implements CSS Generated Content Level 3 features that browsers ignore — the foundation for professional PDF navigation.
Named Strings (string-set)
Capture text for reuse in margin boxes:
h2 { string-set: heading content(); }
@page chapter { @top-center { content: string(heading); } }Strings can embed static text, counters, cross-references, content, and attributes. Pair with named pages so headers update per chapter — see `examples/book/book.css`.
Cross-References & TOC
Link TOC entries to section headings; pull page numbers and titles from targets:
#contents a::after {
content: leader(dotted) " " target-counter(attr(href), page);
}Also available: target-text(attr(href)) for heading text, and custom counters:
h2 { counter-increment: h2-counter; }
#contents a::before { content: target-counter(attr(href), h2-counter) '. '; }
#contents a::after { content: target-counter(attr(href), page); }Classical dotted TOC — `examples/book/book-classical.css`:
#contents a::after {
content: target-text(attr(href)) ' ' leader('.') ' ' target-counter(attr(href), page);
}Leaders
leader(dotted), leader('.'), and other styles fill space between TOC title and page number in ::before / ::after content.
PDF Bookmarks
Control PDF outline (sidebar) with bookmark-level, bookmark-label, bookmark-state. UA stylesheet auto-bookmarks <h1>–<h6>; exclude with bookmark-level: none.
End-to-End Samples
| Pattern | File |
|---|---|
| Report TOC + running header | `examples/report/report.css` |
| Book headers + TOC counters | `examples/book/book.css` |
| Classical dotted TOC | `examples/book/book-classical.css` |
weasyprint report/report.html report/report.pdf
weasyprint -s book/book.css book/book.html book/book.pdfNot supported: content: open-quote / close-quote.
Further research
Debug: Logging & Render Pipeline
Use when PDF output is wrong, incomplete, or differs from browser preview — start here before diving into full API docs.
Silent CSS Failures (Check First)
Most unsupported CSS and missing resources are non-fatal. WeasyPrint logs warnings and keeps rendering — output may look "almost right" with no exception.
CLI: warnings go to stderr by default.
Library: logs are disabled by default. Configure explicitly:
import logging
logger = logging.getLogger("weasyprint")
logger.setLevel(logging.WARNING)
logger.addHandler(logging.StreamHandler())Progress feedback uses weasyprint.progress (CLI: --verbose / --debug).
Raise FatalURLFetchingError in a custom fetcher when missing stylesheets must abort render — see `security-url-fetcher.md`.
Bisect Workflow
1. Enable WARNING-level logging — scan for ignored properties, missing images, font issues. 2. Check `css-browser-vs-print.md` — print media defaults, unsupported selectors, RTL gaps. 3. Isolate: render with user CSS only, then add HTML, then external assets. 4. Compare against a minimal example from `resource-matrix.md` Examples catalog.
Seven Pipeline Stages
Knowing where a bug lives narrows the search:
| Step | What happens | Key modules |
|---|---|---|
| 1. Parse HTML | DOM-like element tree | HTML class |
| 2. Parse CSS | tinycss2; unknown props → warnings | CSS class, css.validation |
| 3. Cascade | Selectors, specificity, inheritance | css package |
| 4. Formatting structure | Elements → boxes (display, UA stylesheet) | formatting_structure.build |
| 5. Layout | Breaks, page boxes, used values | layout (largest complexity) |
| 6. Stacking & draw | z-index, paint to PDF page | stacking, draw |
| 7. Metadata | Links, attachments, PDF/A fields | pdf |
Rule of thumb: if coordinates or breaks are wrong → layout (step 5). If styles never apply → cascade (step 3) or silent CSS parse (step 2). If elements missing entirely → formatting structure (step 4).
CSS Parse Details (Step 2)
During pre-processing:
- Unknown/unsupported declarations are ignored with warnings (easy to miss without logging).
- Shorthands expand (
margin→ four sides). - Hyphens become underscores in internal property names.
- Selectors pre-compile via cssselect2.
Common Log Clues
| Message pattern | Likely cause |
|---|---|
| Unsupported property | See css-browser-vs-print.md; property ignored |
| Missing image / fetch error | URL fetcher, auth, or blocked protocol |
.notdef glyph / font warning | Missing font file or FontConfiguration |
| No output at all | Check HTML(string=...) vs positional filename trap |
Further research
Debug: Version Upgrades & Visual Regression
Use when upgrading WeasyPrint changes PDF appearance, breaks custom fetchers, or triggers security advisories.
Upgrade Priority (Recent Security)
| Version | CVE | Action |
|---|---|---|
| 69.0 (2026-06-02) | CVE-2026-49452 | Upgrade if --presentational-hints / presentational_hints=True on untrusted HTML |
| 68.0 (2026-01-19) | CVE-2025-68616 | Upgrade if custom code wraps default_url_fetcher or uses allowed_protocols on it |
Both are security releases — treat lagging versions as active risk on server deployments.
69.0 — Breaking & Notable Changes
Security: presentational hints no longer inject CSS on untrusted HTML with restricted stylesheets.
API migrations:
--srgb→--output-intent=srgb(alsodevice-cmyk,@color-profileidentifiers)srgbboolean in default options →output_intentstring
Features that may shift layout:
- Logical properties support
- Viewport units (
vw,vh, etc.) - SVG transform angle units
- Redirect-loop detection in URL fetcher (fewer hung fetches)
Bug fixes worth retesting: grid endless loops, flex overflow clipping, RTL auto-width alignment, table break retry after padding overflow, calc() in logical properties.
68.1 — Patch Release (2026-02-06)
Focused bug fixes — retest if you hit:
- SVG clip paths outside
<defs> - Transparency with Acrobat / Edge
calc()on many properties- URL scheme pattern detection
URLFetcherResponsecompatibility withaddinfourl
68.0 — URL Fetcher Refactor
Migrate: default_url_fetcher() → URLFetcher class. Custom fetchers that delegated to the old function must call super().fetch() on the class instead.
Security: HTTP redirects always route through the fetcher (SSRF hardening).
Other: DocumentMetadata.generate_rdf_metadata is now an overridable method, not a constructor parameter (Factur-X workflows).
Visual Diff Guidance
WeasyPrint is not pixel-stable across versions — Pango, fontconfig, and layout fixes change metrics.
Before upgrading production:
1. Pin old and new versions in separate venvs or containers. 2. Render a golden set of representative PDFs (invoices, tables, multi-page, SVG, custom fonts). 3. Diff with a visual tool (ImageMagick compare, diff-pdf, or PDF rasterize + perceptual hash) — not raw byte comparison. 4. Triage diffs:
- Intentional (bug fix, security) — update golden files.
- Font drift — embed fonts via
@font-face+FontConfiguration; disable fontconfig surprises. - Layout shift — check changelog for grid/flex/table fixes; adjust CSS if you relied on old buggy behavior.
CI pattern: store hashed PNG renders of key pages; fail build on unexpected delta above a threshold.
Quick Compatibility Checklist
- [ ] Custom
URLFetcher(not deprecateddefault_url_fetcher) - [ ]
presentational_hintsonly on trusted HTML - [ ]
output_intentreplacessrgbboolean - [ ] Golden PDF set re-rendered and reviewed
- [ ] Server security controls from `security-untrusted-html.md` still in place
Further research
/* Fonts */
@font-face {
font-family: SourceSerifPro;
src: url("fonts/SourceSerifPro-Regular.ttf") format('truetype');
}
/* Page rules */
@page {
size: 110mm 170mm;
}
@page :left {
margin: 20mm 10mm 12mm 15mm;
@top-left { content: counter(page) }
@top-right { content: string(heading); font-variant: small-caps }
}
@page :right {
margin: 20mm 15mm 12mm 10mm;
@top-left { content: string(heading); font-variant: small-caps }
@top-right { content: counter(page) }
}
@page :blank {
@top-right { content: none }
@top-left { content: none }
}
@page clean {
@top-right { content: none }
@top-left { content: none }
}
/* Style */
html {
font-family: SourceSerifPro;
font-size: 10pt;
}
body {
margin: 0;
}
section {
break-after: right;
padding-top: 25mm;
}
aside {
display: none;
}
h1 {
break-after: right;
font-size: 2.6em;
font-weight: normal;
margin: 3em 0;
page: clean;
}
h2 {
font-size: 1em;
font-variant: small-caps;
font-weight: normal;
margin: 0 0 2em;
page: clean;
string-set: heading content();
text-align: center;
}
img {
display: none;
}
p {
hyphens: auto;
margin: 0;
text-align: justify;
text-indent: 1em;
}
dd {
margin: 0 0 0 1em;
}
br::after {
content: '';
display: inline-block;
width: 0.78em;
}
#authors {
page: clean;
p {
text-indent: 0;
}
}
#contents {
page: clean;
p {
margin: 2em 0;
text-indent: 0;
}
ul {
display: block;
margin: 1em 0;
padding: 0;
li {
display: block;
}
}
a {
color: inherit;
text-decoration: none;
&::before {
content: target-text(attr(href)) ' ' leader('.') ' ' target-counter(attr(href), page);
}
}
}
.fullpage {
display: none;
}
/* Fonts */
@font-face {
font-family: OpenDyslexic;
font-weight: bold;
src: url(fonts/OpenDyslexic-Bold.otf);
}
@font-face {
font-family: OpenDyslexic;
font-weight: normal;
src: url(fonts/OpenDyslexic-Regular.otf);
}
/* Page rules */
@page {
margin: 2cm 2cm 3cm 2cm;
size: 148mm 210mm;
}
@page :left {
@bottom-left {
content: counter(page);
position: absolute;
z-index: -1;
}
@bottom-right {
content: string(heading);
position: absolute;
z-index: -1;
}
}
@page :right {
@bottom-left {
content: string(heading);
position: absolute;
z-index: -1;
}
@bottom-right {
content: counter(page);
position: absolute;
z-index: -1;
}
}
@page full {
@bottom-right {
content: none;
}
@bottom-left {
content: none;
}
background: black;
margin: 0;
}
@page :blank {
@bottom-right {
content: none;
}
@bottom-left {
content: none;
}
}
@page clean {
@bottom-right {
content: none;
}
@bottom-left {
content: none;
}
}
/* Style */
html {
counter-reset: h2-counter;
font-family: OpenDyslexic;
font-size: 10pt;
}
body {
margin: 0;
}
p {
line-height: 2;
text-align: justify;
}
img {
display: block;
margin: 2em auto;
max-width: 70%;
}
h1 {
position: absolute;
visibility: hidden;
}
h2 {
color: white;
counter-increment: h2-counter;
display: flex;
flex-direction: column;
font-family: OpenDyslexic;
font-size: 3em;
height: 6cm;
justify-content: flex-end;
margin: 0;
string-set: heading content();
text-align: center;
&::before {
content: "Chapitre " counter(h2-counter) " ";
display: block;
font-size: 1.2rem;
font-weight: normal;
line-height: 1;
}
}
section {
break-after: right;
}
aside {
display: flex;
justify-content: center;
figure {
flex: none;
margin: 0;
padding: 1em;
text-align: center;
}
img {
border: 0.4mm solid white;
border-radius: 50%;
margin: 0 auto;
max-width: 14mm;
}
}
.character {
break-after: avoid;
margin: auto;
max-width: 14mm;
}
#authors {
padding-top: 10em;
page: clean;
text-align: center;
img {
display: block;
margin: auto;
width: 75%;
}
p {
font-size: 1.3em;
margin: 5em 0 1em;
text-align: center;
}
dl {
display: flex;
flex-wrap: wrap;
justify-content: center;
dt {
display: block;
font-size: 0.8em;
line-height: 2rem;
width: 100%;
}
dd {
margin: 0 0.5em;
padding: 0;
}
}
}
#contents {
page: clean;
p {
font-size: 2em;
}
ul {
display: block;
margin: 1em 0;
padding: 0;
li {
display: block;
}
}
a {
color: inherit;
text-decoration: none;
&::before {
content: target-counter(attr(href), h2-counter) '. ' target-text(attr(href));
}
&::after {
content: target-counter(attr(href), page);
float: right;
}
}
}
.chapitre::before {
background: center / cover;
border-radius: 0 0 50% 50% / 0 0 15mm 15mm;
content: "";
display: block;
height: 90mm;
left: -30mm;
position: absolute;
top: -20mm;
width: 168mm;
z-index: -1;
}
#chapitre-1::before {
background-image: url("img/couv1.jpg");
}
#chapitre-2::before {
background-image: url("img/couv2.jpg");
}
#chapitre-3::before {
background-image: url("img/couv3.jpg");
}
#chapitre-4::before {
background-image: url("img/couv4.jpg");
}
.outro {
border-radius: 50% 50% 0 0 / 15mm 15mm 0 0;
display: block;
height: 90mm;
left: -30mm;
max-width: none;
object-fit: cover;
position: absolute;
top: 120mm;
width: 168mm;
z-index: -1;
}
.fullpage {
page: full;
img {
bottom: 0;
height: 210mm;
left: 0;
margin: 0;
max-width: none;
object-fit: cover;
position: absolute;
width: 148mm;
z-index: 1;
}
&:last-child {
break-before: left;
}
}
<!doctype html>
<html lang="fr">
<meta charset="utf-8">
<meta name="author" content="Madcats">
<title>All Cats Are Beautiful</title>
<h1>All Cats Are Beautiful</h1>
<section class="fullpage">
<img src="img/affiche.jpg" alt="Affiche">
</section>
<section id="authors">
<img src="img/logo-intro.png" alt="Intro">
<p>
Écritures collaboratives
</p>
<dl>
<dt>Écrivain·e·s</dt>
<dd>Antoine Cénet</dd>
<dd>Tzara Auffray</dd>
<dd>Alban Haouaci</dd>
<dd>Alexandre Masson</dd>
<dd>Jérémie Richard</dd>
</dl>
</section>
<section id="contents">
<p>Table des matières</p>
<ul>
<li><a href="#chapitre-1-h2"></a></li>
<li><a href="#chapitre-2-h2"></a></li>
<li><a href="#chapitre-3-h2"></a></li>
<li><a href="#chapitre-4-h2"></a></li>
</ul>
</section>
<section id="chapitre-1" class="chapitre">
<h2 id="chapitre-1-h2">La course</h2>
<aside>
<figure>
<img src="img/poire.png" alt="Poire">
<figcaption>Poire</figcaption>
</figure>
</aside>
<p>
Et dire que je dois encore me lever, courir après mon repas, porter le
coup fatal et déguster… Mais je déguste, là aussi. Le soleil est au
zénith, une légère brise s'est installée, c’est le pied.
</p>
<p>
Il faut dire que les derniers jours, c'était pas ça. Un tout petit
moineau à peine sorti du nid et quelques rats mal en point, ça ne rend
pas un chat en forme. Courir, courir, toujours courir. Les proies ne
peuvent-elles pas s’offrir à moi ? Non, la ville m'a bien appris qu'il
fallait se battre pour ses besoins. Et plus que jamais, j'ai besoin de
manger maintenant.
</p>
<p>
Il est temps, la faim est trop grande. Je fais glisser une dernière
fois ma joue contre le béton chaud et descends de la cheminée. Mes
frères et sœurs avaient toujours trouvé ça drôle, chasser. Pour eux,
tuer était un jeu. Un jeu sans règles, ça ne m'a jamais amusé.
</p>
<p>
Tiens, cette gouttière n'en a plus pour longtemps, il va falloir que je
trouve un nouveau spot pour me dorer la pilule, c’est le seul accès.
Cette ville détruite est un ramassis de labyrinthes désorganisés où les
cachettes sont infinies. Trouver un endroit où se cacher, c'est le nerf
de la guerre.
</p>
<p>
Malgré les belles histoires que me racontait ma mère, la réalité
reprend vite le dessus et je vis dans une guerre permanente. Chacun
protège son territoire et ce serait une vraie boucherie s’il me venait
l’idée de me balader trop loin.
</p>
<p>
Mon territoire ? Il a toujours été le même depuis ma naissance. À quoi
bon chercher à s'étendre. J'ai même parfois laissé quelques uns prendre
leurs aises, je ne suis pas du genre à pinailler pour un coin de
litière. Les autres ont tendance à être le total opposé, accrochés
farouchement à défendre un espace qui n'a aucun sens au final.
Déterminés à honnir quiconque oserait fouler de la patte le mauvais
trottoir.
</p>
<p>
Ca bouge !
</p>
<p>
Mes sens sont en éveil, je suis surpris à chaque fois. D'où est-ce que
ça peut venir ? Là aussi je laisse couler, temps que cela m'aide à
courir le moins possible. Mon instinct se confirme, je m'élance sans
hésitation. Un vieux rat visiblement. J’espère juste pas trop vieux,
sinon ils ont un goût de poussière. Il renverse tout sur son passage
pour entamer sa fuite perdue d'avance. Mes pattes sont rouillées et
rongées par la flemme, mais je les rappelle à l'ordre.
</p>
<p>
Au bout de quelques mètres dans la ruelle, il tente une embardée pour
accéder à un sous-sol. Sans succès, je gagne un peu de terrain. Il est
vif, sûrement plein de bonnes vitamines. J'occupe l’espace sur sa
droite pour le diriger un peu. Il ne se laisse pas impressionner, il
bifurque quand même. Les rues défilent et je le tiens serré pour ne pas
qu'il se faufile. Paniqué il en oublie les recoins.
</p>
<p>Bien.</p>
<p> Il tente un tuyau qui traîne. Trop petit pour moi, je tourne en rond
autour de lui et ronronne d’impatience. Quelques miaulements et
griffures pour servir l'ambiance, en plein dans le mille. Il ne résiste
pas à la pression et sort de sa cachette pour courir de plus belle.<br>
Mince ! Pensant avoir gagné, je ne l'ai pas joué stratège. Il se dirige vers l'arbre de non retour. Passé ce point, je ne suis plus chez moi. La perspective même de devoir recommencer ma chasse me ramollit. Tant pis, je suis si proche, personne ne me verra. Je dois juste faire vite. Très vite.
</p>
<p> S'il tourne dans cette ruelle, il sera acculé. Le mur est haut et les
sorties inexistantes.</p>
<p>
Il tourne !</p>
<p>
Plus qu'une foulée.</p>
<p>
Avec ma fierté féline qui crève le plafond, je plante enfin mes crocs
dans le cou de la bestiole. J'ai bien fait, il a bon goût. Enfin.<br>
Allez, je dois filer maintenant. Bien que mon repas soit lourd, je devrais pouvoir rejoindre mon fief.
</p>
<p>
“Le dîner est servi.”</p>
<p>
Une voix rocailleuse s'élève derrière moi. En un instant, je me
retrouve dans la peau du rat que je tiens dans la gueule.
</p>
<p>Le mur est haut et les sorties sont inexistantes…</p>
<img class="outro" src="img/outro1.png" alt="Outro">
</section>
<section id="chapitre-2" class="chapitre">
<h2 id="chapitre-2-h2">Dos au mur</h2>
<aside>
<figure>
<img src="img/poire.png" alt="Poire">
<figcaption>Poire</figcaption>
</figure>
<figure>
<img src="img/john.png" alt="John">
<figcaption>John McMiaou</figcaption>
</figure>
</aside>
<p>
D’habitude à cette heure, tout est très calme. Mais ce soir c’est
différent, j’entends du bruit venant de la rue de derrière. Je vais aller
voir, de toute manière j’ai pas grand chose de mieux à faire.
</p>
<p>
Je reconnais la voix de Gros Bouchon. Ce gros con de Gros Bouchon. J’ai
jamais pu le sentir ce chat là… Il y a des nuits de cela, il a chassé
ses propres frères et sœurs du territoire afin d’en avoir l’exclusivité.
J’entends un deuxième chat. Je ne le reconnais pas… Ils ont plus l’air
d’avoir envie d’en découdre que de trouver un terrain d’entente. Revoilà
ce foutu oiseau. Les poubelles valsent, je ferais mieux d’aller voir ce
qui se passe. Ce foutu piaf attendra.
</p>
<p>
C’est bien ce que je pensais… C’est la bagarre là-bas. Gros Bouchon n’a
pas volé son nom. Qu’est ce qu’il est gros ! Ces deux-là ne jouent
définitivement pas dans la même catégorie. De toute évidence, ce ne sera
pas un beau combat. Je devrais peut-être empêcher Gros Bouchon de toucher
ce pauvre petit gars.
</p>
<p>
Le p’tit a un regard qu’il ne m’avait jamais été donné de voir. Pas le
regard de celui qui a peur, non ! Plutôt le regard de celui qui accepte
la fatalité. Le regard de celui qui est tétanisé et qui ne laisse
apercevoir aucune autre fin que LA fin. J’avais pas laissé un assommeur
dans le coin ? Gros Bouchon n’a pas l’air d’en être bien loin.
</p>
<p>
Je devrais pas avoir trop de mal à viser Gros Bouchon : il est si
massif… J’ai jamais trop compris pourquoi on trouvait des plantes dans
des boites. Mais là, faute de compréhension, ça avait au moins le mérite
de m’être utile. Je sais quel bruit fait le bois, mais j’ai aucune idée
de quel bruit fait le bois sur un énorme chat. Allez, salut l’ami !</p>
<p>J’arrive pas à savoir si p’tit père passe maintenant le plus beau jour
de sa vie ou s’il espérait quand même pouvoir en placer une ou deux.</p>
<p>Bon… je ferais bien de trouver un moyen de descendre d’ici moi… Je
me demande si le piaf est encore dans le coin.</p>
<img class="character" src="img/poire.png" alt="Poire">
<p>Le silence. Après ce chaos incroyable, tant dans ma tête qu'autour de moi, plus un bruit. En un instant, le monstre est étalé sur le sol. La poussière remplit la rue, mon esprit, lui, se vide. Pétrifié d'abord par ce monstre puis par ma chance, le rat a pu s’enfuir. Peu importe ! Comme lui, je l'ai échappé belle. Dire que je me le disais pendant ma poursuite : “tu vas trop loin”. Je vais toujours trop loin de toute façon. Je m'en fous, il faut que je bouge.</p>
<p>Le rat s’est déjà barré, et moi je peine à m’activer. Comme d’hab, dés
que l’émotion me gagne je suis tétanisé. Cette fois-ci je ne raisonne pas
mes pattes. Pas moyen, elles sont tétanisées. Il a du courage ce rat, lui
au moins à défaut de courir, il essaye. Et moi ? Je reste bêtement là,
comme si mon histoire s'était terminée quelques secondes plus tôt, face à
la bête.</p>
<p>J’entends bouger.</p>
<p>Mes pattes me trahissent, mais pas mes sens. Toujours surpris. Le
bruit a dû attirer du monde, je dois m’activer. Mon ouïe laisse place à
ma vision, une silhouette descend du toit.</p>
<img class="character" src="img/john.png" alt="John">
<p>
La nuit tombe, je me demande ce qui m’a pris le plus de temps
finalement. Est-ce que c’est cette gouttière ou ce match perdu d’avance
et gagné par surprise ? Bon, quoi qu’il en soit c’est l’heure où les
petits poilus sortent. C’est un bon timing.</p>
<p>P’tit père n’a pas l’air de s’être tiré. Qu’est-ce qu’il fait encore là lui ?</p>
<p>— Allez ! Tire toi !<br>
— Je respire un peu et je m’en vais.<br>
— Qu’est-ce qui t’a pris de t’aventurer ici ?<br>
— La chasse, tout simplement. Je pensais faire vite et disparaître. Maintenant j’ai tout perdu, je ne sais pas ce que je vais manger.</p>
<p>Devant moi, je vois son vieux rat agonisant qui essaie de s’enfuir. Il devait vraiment avoir faim p’tit père…</p>
<p>— C’est ça que tu cherches ? lui demandais-je en rattrapant son amuse-gueule<br>
— Merci.</p>
<p>Il ne peut s’empêcher de commencer à manger.</p>
<p>— C’est toi qui as fait tomber ces caisses sur ce dingue ? C’était impressionnant, j’ai bien cru que j’allais y passer. Je n’en peux plus de ce danger permanent, mon enfance me manque.</p>
<p>Je sais pas trop ce qu’il me raconte mais là, la nuit tombe, j’ai faim et… C’est quoi ce bruit ? Encore ce Piaf, un jour je t’aurai…</p>
<p>— Est-ce que je peux rester ? il reprend.</p>
<p>L’oiseau s’envole…</p>
<p>— Sans toi, j’aurais servi de repas. Laisse moi te remercier, je t’aiderai pour ton territoire, pour la chasse. Tu mangeras toujours en premier.</p>
<p>Impossible pour p’tit père de cacher son ronron à ce moment précis.</p>
<p>— Et puis je suis loin de chez moi maintenant, la seule idée de rentrer seul à cette heure du jour après ce qui s’est passé me donne le tournis.</p>
<p>L’idée même de me le coltiner me rebute, mais lui refiler les corvées me séduit assez.</p>
<p>— Si tu veux rester avec moi, c’est seulement parce que TU le veux, souviens t’en !<br>
— Compris !</p>
<p>C’est de loin le chat le plus inoffensif que je rencontre. Il devrait pas prendre trop de place.</p>
<p>— Reste mais fais-toi petit !</p>
<p>Les ronrons de p’tit père me montent déjà à la tête.</p>
<img src="img/pheromones.png" alt="Pheromones">
<p>
Je ne sais même pas pourquoi je lui ai demandé ça. J'ai passé ma vie à
éviter soigneusement les autres et à me faire discret. Et voilà qu'au
premier Shérif venu, je lui offre mes services. Ce doit être la
fatigue. La fatigue d'affronter chaque jour un monde qui n'accepte
personne et qui rejette tout le monde. C’est sûrement ça.
</p>
<p>
Je suis encore plus abasourdi qu'il accepte. Je dois paraître bien
faible à ses yeux. Pauvre chat incapable de se défendre tout seul. Ha !
Elle est loin la fierté de ma course poursuite effrénée !
</p>
<p>
Mais un sentiment de soulagement m'envahit. Je ne suis plus seul
maintenant.
</p>
<img class="character" src="img/john.png" alt="John">
<p>Ça fait des semaines que Poire et moi on traîne ensemble. Il apprend vite, mais qu’est ce qu’il parle… Je crois qu’il commence à assimiler la technique de l’assommoir par le toit.</p>
<p>— Poire, tu peux venir ?</p>
<p>Poire descend de la cheminée et se dirige vers moi.</p>
<p>— Tu as vu ce panneau à l’angle du toit bleu et du toit jaune ?<br>
— Non.<br>
— C’est un grand rectangle. On y voit deux bipèdes et un chat vivre ensemble. Il a l’air tellement heureux.<br>
— Plus qu’avec la cataire ?<br>
— Oui.<br>
— Plus qu’avec le thym ?<br>
— Oui.<br>
— Plus qu’avec le carton ?<br>
— Ta gueule Poire…<br>
— Ma mère me racontait des histoires sur ces bipèdes. Mais je n’y crois plus vraiment.<br>
— J’suis sûr qu’ils sont encore parmi nous Poire…</p>
<p>Ça fait des jours que j’ai pas vu ce foutu oiseau. Cela fait même des semaines que les “récoltes” sont de plus en plus faiblardes. Est-ce inconscient de quitter le territoire ? J'en sais rien… Une chose est sûre, il reste à peine de quoi manger sur le territoire pour un chat seul… Alors deux chats… En fait, c’est soit je mange Poire, soit on se tire d’ici.</p>
<p>— Poire ?<br>
— Oui ?<br>
— Demain matin, nous partons d’ici.<br>
— Pourquoi ?<br>
— Tu as mangé ce soir ?<br>
— Non.<br>
— Et hier ?<br>
— Non.<br>
— On commence à être à court, on doit trouver de la nourriture ailleurs Poire.<br>
— Mais tu veux aller où ?<br>
— Tu sais quand je te parlais des deux bipèdes et du chat à l’angle de la rue ? Je suis quasiment sûr d’avoir déjà vu l’endroit où ils sont.<br>
— Et tu penses que les choses seront meilleures qu’ici ?</p>
<p>Il commence à peine à prendre confiance en lui, je n’ai pas envie de le trahir.</p>
<p>— Oui.</p>
<p>Je n’en sais rien, je mens, et à Poire, et à moi-même.</p>
<img class="outro" src="img/outro2.jpg" alt="Outro">
</section>
<section id="chapitre-3" class="chapitre">
<h2 id="chapitre-3-h2">Le temple</h2>
<aside>
<figure>
<img src="img/poire.png" alt="Poire">
<figcaption>Poire</figcaption>
</figure>
<figure>
<img src="img/john.png" alt="John">
<figcaption>John McMiaou</figcaption>
</figure>
<figure>
<img src="img/frihet.png" alt="Frihet">
<figcaption>Frihet</figcaption>
</figure>
</aside>
<p>
Quatre jours sans se dorer les moustaches à l’aise au soleil ça peut
paraître long. Mais ça fait aussi quatre jours que je m’affûte, que je
comprends mieux mon instinct. Et puis… chasser à la volée sans avoir à
se soucier des limites imposées par son territoire, c’est pas mal. John
est impressionnant. Quelle que soit la situation, il a le bon réflexe,
la bonne réaction. Toujours à l’affût, toujours prêt mais jamais drôle.
J’ai pourtant essayé plusieurs fois de le dérouiller, mais rien n’y
fait. Je l’aurai à l’usure. Il croit que je ne l’entends pas, mais il
est en boucle sur un foutu oiseau. Je me dis qu’il a la mécanique qui
se détraque. J’ai jamais vu d’oiseau ! Je me demande si la rouille
n’est pas allée un peu trop loin. Mais c’était lui ou personne. Je me
suis laissé porter et pour le moment, pas de regret.
</p>
<img class="character" src="img/john.png" alt="John">
<p>
Il me surprend le petit père. Il est doué, malin et rapide. Mais encore
un peu lourdingue dans ses déplacements. C’était comme s’il s’était
résigné à ce que les choses s’imposent sans avoir d’autre choix que de
les accepter. Accepter… oui pourquoi pas, quand on est seul et qu’on ne
dépend que de nous ! Le monde continue de tourner, tout le monde ici se
bat pour survivre. Quand la recette ne fonctionne pas, on change les
ingrédients. Il n’y avait plus rien à manger sur notre territoire. Tôt
ou tard on se serait retrouvés à court, ou on aurait fini par se faire
évincer. Ici, comme tout le monde est à croc, ça aurait mal fini. Mais
c’était lui ou personne. Je me suis laissé porter et pour le moment
aucun regret !
</p>
<p>
Tandis que nous avançons sur ce large parterre d’asphalte, les maisons
ont cédé leurs places à un horizon incroyablement vide. Sur le chemin
nous apercevons des rangées entières de colosses d’aciers, ces mêmes
colosses qu’on trouvait de part et d’autres de la chaussée à la
jonction des territoires. Je ne sais pas si je l’ai rêvé ou si c’est
réellement arrivé, mais j’ai l’impression d’en avoir déjà vu bouger. Et
avec quel vacarme ! Je ne sais pas de quoi ces bêtes se nourrissent
mais ça doit être difficile de faire le plein quand on est aussi
bruyant. Sorti de nulle part, l’oiseau est juste là, devant moi,
trônant fièrement sur un géant d’acier bien plus imposant que les
autres.<br>
— Ne bouge plus !
— Alors tu disais vrai ! Il est magnifique ! me sort-il d’un air bipède.<br>
— J’irai pas jusque-là. Il a l’air appétissant mais j’en ai déjà vu des plus beaux.<br>
— Et pourquoi vouloir l’attraper ?<br>
— Ça fait au moins six ans que je suis dans le coin, six ans qu’il est là, toujours collé à mes basques. Six ans, que peu importe où je me rends, il est là, à me regarder et à me narguer. J’ai besoin de personne et certainement pas d’un oiseau à mes côtés. Je suis né seul, je me suis fait seul et je finirai seul.
— T’as décidé de finir seul, mais en attendant je suis là !<br>
— Merci de me le rappeler…Et tu comptes m’aider à l’attraper pour autant ?
</p>
<img class="character" src="img/frihet.png" alt="Frihet">
<p>
Cinglant. Mais pas de place à la discute, John se lance. Il a attendu
que le piaf tourne la tête, c’est pour ça qu’il ne me laisse pas le
temps de répondre. Allez ! je le suis et cette fois je le tiens. John
ondule avec ses sauts à travers les obstacles, c’est fluide. On sent
qu’il gagne du terrain, la patte est sûre à mille pour cent. Et ça,
sans lâcher l’oiseau du regard. Lui, il vole. Mais il fatigue. Pas un
gros voyageur visiblement. Alors que John repasse au sol pour la jouer
discrètement, l’oiseau se pose. C’est bien vu, le gros colosse lui
cache la vue. John est devenu invisible.
</p>
<img class="character" src="img/john.png" alt="John">
<p>
Je bondis sur le museau du petit colosse afin de gagner de la hauteur
et de pouvoir accéder au museau du plus gros, celui sur lequel l’oiseau
trône. Alors que je prends l’ultime appui, je sors mes griffes et
envisage déjà les endroits où celles-ci lui feront un beau collier.
Cette fois-ci, c’est la bonne. Je suis en l’air, tout se passe comme
prévu, mais j’entends un bruit parasite qui capte mon attention. Je
tourne la tête pour regarder et je réalise immédiatement la connerie
que je viens de faire. Je m’écrase contre la vitre du géant de métal
dans un vacarme assourdissant.
</p>
<img class="character" src="img/poire.png" alt="Poire">
<p>
Non ! Impossible de me retenir, je ris aux éclats. Je sais qu’il sera
vexé, mais quelle action ! C’est rare. Rare qu’il se plante de la
sorte. En même temps, il est pas net cet oiseau. Il a quelque chose.
Dans son air, sa posture, je ne sais pas. On a l’impression qu’il
savait que John glisserait. Sans rien dire, en boitillant à peine, John
suit l’oiseau en direction de ce gros bâtiment bleu.Bleu. J’aime bien
le bleu.
</p>
<img class="character" src="img/john.png" alt="John">
<p>
Tout est allé trop vite, je fatigue, j’ai chaud, mais j’ai encore une
chance. Pas le temps d’attendre Poire ! Qu’il se bouge !
</p>
<img class="character" src="img/frihet.png" alt="Frihet">
<p>
Le paradis, miiiiiiahahahou, j’adore mon territoire. Il est vaste,
complexe. Idéal pour la chasse. Seul un petit trou permet d’entrer ou
de sortir vers le monde dangereux.C’est par ce trou que je suis entrée
avec ma mère et que je l’ai vu partir pour la dernière fois. C’est
aussi par ici que ma nourriture vient à moi. Malheureusement, c’est
aussi par là qu’ils entrent : les autres…
</p>
<p>
Jusqu’à présent, je ne suis tombée que sur des chats amincis par la
faim, des faibles du dehors, des ombres pathétiques. Les plus malins
ont fui en sentant que le ter-ritoire était occupé. D’autre, j’imagine,
regrettent le jour où se retrouvant face à mes yeux brillants et mes
griffes affûtées, n’ont pu que prendre leurs pattes à leur cou tout en
récoltant au passage de nouvelles cicatrices. Mais il arrive que, de
temps en temps, certains mâles ridiculement fiers, malgré leur évidente
infériorité, tentent de me prendre MON merveilleux territoire. J’ai dû
tristement mettre un terme à leur misérable vie. J’ai eu de la chance
jusqu’à présent, aucun ne s’est révélé être un véritable danger. Car si
un jour il entre ici un monstre que je ne peux maîtriser, alors je
devrai fuir et ressortir par le petit trou.
</p>
<p>
Je n’aime guère tuer mes congénères, mais j’adore chasser, ça oui.
Miiihahahouu ! Je suis faite pour ça, j’ai les plus belles griffes du
monde. Affûtées, brillantes et incroyablement efficaces pour tuer.
C’est de l’entretien c’est sûr, des heures à détruire les nombreuses
“boites moelleuses”, les beaux dessins de murs en papier. Mais rien ne
me satisfait plus que de mettre en lambeaux les tissus suspendus !
Miiiihahahaou !! Je suis la Reine de ces lieux. Je connais les moindres
recoins de ce labyrinthe insensé et si je le souhaite, je peux avancer
ici sans jamais mettre une patte au sol. Seul un oiseau pourrait
m’échapper. Et du perchoir le plus haut de mon temple, je vois tout.
D’ailleurs, c’est parti.
</p>
<p>
Voilà maintenant quelques minutes que j’ai repéré l’intrus : une
salamandre inconsciente venue se reposer à l’ombre de ma demeure. Elle
ne sait pas encore qu’elle vient de devenir ma proie. Je me décide à
l’approcher doucement, elle est au sol et je la domine de plusieurs
étagères. J’avance à pattes de velours en évitant de faire tomber
quelque chose susceptible de me faire repérer.
</p>
<img src="img/seance-de-chasse.jpg" alt="Chasse">
<p>
Aplatie au maximum, dans l’ombre d’une fausse plante, elle ne m’a pas
vu la dépasser et me placer en embuscade. Désormais, la proie
s’approche de moi, s’en est fini d’elle. Je bondis sur elle alors que
dans un ultime mouve-ment de désespoir elle tente une embardée. Mais
toutes griffes dehors, mon coup précis et puissant la ramène tout droit
en direction du sol. Gagné ! Miiiiahahaou ! Me voici triomphante,
dominant l’animal qui cesse petit à petit de s’agiter, son sang coulant
le long de mes griffes. Je ne lui ai laissé aucune chance. Triste
destin pour cette proie qui cherchait juste un endroit de repos. La
voici sur le sol, se reposant pour l’éternité.
</p>
<p>
Je n’ai même pas très faim, les salamandres ont généralement un goût
atroce. Je croque un morceau, après l’avoir fait passer de gauche à
droite entre mes pattes, lui don-nant l’air d’un pantin désarticulé.
Cette victoire a le goût de ce lézard, amère. J’entends les oiseaux
dehors, au travers du petit trou. Je me souviens de moins en moins de
l’extérieur, je suis arrivée ici je n’étais qu’un chaton. Mais très
vite, j’ai adoré l’endroit. Ma mère m’a tout appris : la chasse,
l’affûtage des griffes, le marquage de territoire, tout ! Et puis un
jour elle est partie. Perché à l’entrée du Temple, un oiseau flamboyant
l’attendait. Elle m’a dit de ne pas bouger, s’est avancée, il s’est
envolé, elle l’a suivi.
</p>
<img class="character" src="img/poire.png" alt="Poire">
<p>
C’est sombre à l’intérieur. Un petit trou, unique moyen pour entrer
dans le bâtiment bleu, laisse passer un trait de soleil à travers la
façade. Mais après être rentré, ma vue s’adapte vite et je vois de
l’espace, beaucoup d’espace. On est haut aussi, je distingue mal le
sol. John est devant moi, on avance discrètement. Un enchaînement de
métal plus tard, il se met en idée de traverser ce câble.<br>
— T’es sûr ? Je le sens pas.<br>
— Allez ma biche, n’ai pas peur. Il a le don pour me les froisser, je
le sens pas j’ai dit ! Trop tard il est déjà de l’autre côté et continue d’avancer.
</p>
<img class="character" src="img/john.png" alt="John">
<p>
Un bruit de glissement me fait dire que j’ai peut-être surestimé la
courbe de progression de Poire. Je me retourne, je ne le vois plus
derrière moi. À tout les coups ce nigot a loupé son saut ! Bon… je vais
essayer de retourner sur mes pas, la grille est suffisemment haute pour
qu’il lui soit arrivé quelque chose…
</p>
<img class="character" src="img/poire.png" alt="Poire">
<p>
J’avais bien dit que je le sentais pas ! Je chute. Et maintenant le
plus important : l’atterrissage.
</p>
<p>
Trois, deux un.
</p>
<p>
Du mou ! Je me suis étalé du ciel, sur du mou ! J’en avais croisé
quelques-uns, mais jamais d’aussi agréables. Une texture épaisse,
incroyable, je ronronne immédiatement.
</p>
<img class="character" src="img/john.png" alt="John">
<p>
Mais qu’est ce que j’ai mérité pour me traîner un boulet pareil. Règle
n°1 : “fais toi discret !” Et voila que je l’entends ronronner ! La
bonne nouvelle, c’est qu’il n’a rien. La mauvaise ? C’est que s’il y a
qui que ce soit ici, il saura qu’on est là, bien avant même qu’on s’en
apperçoive.
</p>
<img class="character" src="img/frihet.png" alt="Frihet">
<p>
Évidemment que je l’ai vu descendre ce gros lourdingue, eh mais
attend ? C’est sur ma sainte boîte qu’il se prélasse ? Mais pour qui il
se prend ? Et il sort d’où cet abruti ? Cette boîte c’est la seule que
je n’ai pas détruite, je la garde pour mes vieux jours, c’est la plus
belle, la plus confortable et la seule sans odeur. Mmmh… ça explique
pourquoi il ne m’a pas encore repérée, enfin, l’endroit entier doit
empester ma présence. Peut-être que son odorat est défaillant, ou que
l’intrus est trop occupé à détruire Ma propriété ! Il ne paie rien pour
attendre, j’aimerais le réduire en bouillie, mais ce n’est pas ma
méthode. Prudence, on observe et on avise. Il est volumineux et je ne
voudrais pas me retrouver en difficulté. J’ai l’intuition que quelque
chose m’échappe… Je reste à distance suffisante pour ne pas être prise
de court mais visible. À sa réaction je saurais s’il est dangereux ou
juste débile. Regarde-moi, allez… re-gar-de moi.
</p>
<img class="character" src="img/john.png" alt="John">
<p>
Je vois Poire… Il est là insouciant pour pas dire inconscient ! J’en
viens à me demander s’il me dit qu’il comprend, juste pour que je lui
fiche la paix. J’entends un bruit qui vient d’en face. Poire n’a même
pas l’air d’avoir remarqué. Est-ce qu’il retiendra plus s’il se
retrouve devant les problèmes qu’il a lui-même provoqué ? J’suis sûr
que non. Je reste en position, voyons comment les choses se trament, je
vais pas passer chacune de mes journées à lui sauver le popotin !
</p>
<img class="character" src="img/poire.png" alt="Poire">
<p>
Qu’est-ce que c’est bon ! Toute cette matière, tout ce mou ! Je suis
sur un nuage, j’oublie presque que j’ai fais le grand saut. Où est John
d’ailleurs ? Il faut absolument qu’il voit ça. Je miaule un coup pour
l’appeler. Et j’entends immédiatement gronder derrière moi. “John ! Tu
dois ab-solument te couché la dess…”
</p>
<img class="character" src="img/frihet.png" alt="Frihet">
<p>
— Salut, je te dérange pas ? Cet idiot lève en fin la tête. Tu as deux
minutes pour déguerpir. Affolé, le voilà qui cherche de l’aide du
regard.
</p>
<img class="character" src="img/poire.png" alt="Poire">
<p>
Encore ! Décidément tout le monde m’en veut de ma présence.<br>
— Tu as gagné !
</p>
<img class="character" src="img/frihet.png" alt="Frihet">
<p>
— Hein ?<br>
Mais qu’est ce que c’est que ce chat ? Quelque chose ne va pas,
j’ai les vibrisses qui s’agitent. D’habitude tout est clair, qui
vient sur mon territoire, termine en charpie. Il est marrant celui-là,
j’ai rien gagné du tout ! J’ai même pas eu à lui courir après. Je
suis à deux griffes de m’en faire un tapis.
</p>
<img class="outro" src="img/outro3.jpg" alt="Outro">
</section>
<section id="chapitre-4" class="chapitre">
<h2 id="chapitre-4-h2">Le grondement</h2>
<aside>
<figure>
<img src="img/poire.png" alt="Poire">
<figcaption>Poire</figcaption>
</figure>
<figure>
<img src="img/john.png" alt="John">
<figcaption>John McMiaou</figcaption>
</figure>
<figure>
<img src="img/frihet.png" alt="Frihet">
<figcaption>Frihet</figcaption>
</figure>
</aside>
<p>
— Je ne veux pas me battre.<br>
— Qu’est ce que tu fais là ?<br>
— Je suis tombé du plafond, je me suis retrouvé ici en un instant.<br>
Je ne peux pas tout lui dire, si elle apprend que John est ici elle pourrait
m’achever avant qu’il arrive.<br>
— Quoi qu’il en soit, ce canapé est très mou. C’est sympa ici !
</p>
<img class="character" src="img/john.png" alt="John">
<p>
— Partez de chez moi, toi et celui que je peux sentir d’ici.<br>
Comment peut-elle savoir ? Moi même je n’ai pas vu John depuis ma chute.<br>
— De qui parles-tu ? Je suis arrivé seul ici.
</p>
<img class="character" src="img/frihet.png" alt="Frihet">
<p>
Son stress est puant. On le ressent à 2 kilomètres. Il ne tient pas en place et
regarde partout. ll n’est pas seul j’en suis sûre mais il ne sait pas
où est son acolyte.<br>
— Montre toi, je sais que tu es là. Sinon je mange ton copain.<br>
Une ombre se profile derrière le paravent, j’avais correctement anticipé d’où il viendrait.
J’aurais sûrement fait pareil.<br>
— Du calme, on ne te veut aucun mal.<br>
Un chat roux beaucoup plus assuré s’avance vers moi, ses nombreuses cicatrices me
font douter de sa sympathie. Je me tourne vers l’autre, le fusille du regard,
son ronronnement s’arrête instantanément.<br>
— J’avais trop peur, j’ai menti… On ne cherche qu’un peu à manger.<br>
— On a quitté notre territoire. Nous sommes des chats qui voyageons.
On s’est arrêtés ici pensant qu’il n’y avait personne.<br>
— Eh bien il y’a quelqu’un et la nourriture ici lui appartient. Toi ! Descend de
ma boite moelleuse ! Et toi reste où tu es !<br>
J’ai un vrai problème, je ne pourrai pas les faire sortir de force. À deux contre un
et sans effet de surprise, c’est la défaite assurée. Il va falloir la jouer fine.<br>
— Recommençons, moi c’est Poire, je suis gros, vachement gentil. Et j’aime le mou !
Et le bleu ! On traîne ensemble avec John depuis quelques temps,
je sais qu’il peut faire peur mais il m’a sauvé plusieurs fois les moustaches !
Il a la couleur de son tempérament, un vrai caramel. Dur d’abord puis mou dedans.<br>
Il va falloir que je garde l’œil ouvert. Au moindre faux pas, je descends
le caramel en premier.<br>
— Tu n’es pas une adversaire, nous ne prendrions pas le temps de discuter…<br>
— Une nuit pas plus, et pas de chasse sans mon autorisation sur mon territoire.
Je prendrai la plus grosse part, et vous dormirez là où je vous le dirai.
</p>
<img class="character" src="img/john.png" alt="John">
<p>
Poire la suit sans hésiter, mais je préfère garder mes distances. Je
vois bien qu’elle ne nous fait pas confiance. Est-ce-qu’elle prévoit de
nous tuer dans notre sommeil ? Quoi qu’il en soit restons prudents.
</p>
<img src="img/inter42.png" alt="Inter">
<p>
— Depuis quand es-tu ici ?<br>
— Depuis presque toujours.<br>
Poire multiplie les questions et j’en profite pour prendre un peu
plus de distance pour repérer les lieux.Des meubles, des meubles partout…
Ils sont comme dans les habitations, mais là, ils sont sans vie et
s’étendent à perte de vue. Pourquoi en fabriquer autant ? Il n’y a
pas assez de chats pour tous les griffer.Leur voix s’éloignent, je
ne dois pas laisser Poire seul trop longtemps.<br>
— … et c’est comme ça que je me suis retrouvée seule ici.<br>
— Tu sais tu pourrais nous accompagner. D’après John, cet endroit est parfait pour les chats.<br>
— Je ne vous accompagnerai pas, je suis très bien ici. Cet endroit, dont tu m’as parlé,
tu n’es pas le premier à l’évoquer. Ceux qui ont eu l’audace de passer par ici
suivaient cette route. Ils appelaient ça « LEUZO ».<br>
— Et tu sais comment y aller ?<br>
— Non. Je ne m’aventure pas en dehors de mon Temple, c’est dangereux.
Je n’en ai jamais vu revenir de la bas. Peut-être qu’ils y sont bien.<br>
— C’est sûrement pour ça !
</p>
<img class="character" src="img/frihet.png" alt="Frihet">
<p>
Il est si naïf… mais je l’aime bien. Il n’est clairement pas une
menace, et a l’air d’avoir le cœur sur la patte. John, en revanche, il
a pas l’air net, il est chez moi et il agit comme si il pouvait faire
ce qu’il veut. D’ailleurs, où est-il ?Un bruit. ZBREYMPuis un autre.
KRRRKRRKRKRKRUn fracas assourdissant s’élève du fond de mon royaume. Je
vois au loin un panneau tomber, et un nuage de poussière se lever du
sol. C’est John, en pleine frénésie, qui renverse tout sur son passage.
Et plus haut, je n’en crois pas mes yeux…
</p>
<img class="character" src="img/john.png" alt="John">
<p>
Je savais qu’il était toujours à l’intérieur. Il n’a qu’une seule
sortie. Cet oiseau est à moi.
</p>
<img class="character" src="img/frihet.png" alt="Frihet">
<p>
Alors là, certainement pas ! Cet oiseau est sacré ! Je me lance à sa
poursuite, espérant que l’agilité de l’oiseau me laisse un peu de temps
pour rattraper John avant qu’il ne l’éventre. Je saute de boites en
étagères, et reprends rapidement du terrain.
</p>
<img class="character" src="img/poire.png" alt="Poire">
<p>
Ils jouent ? Finalement ils s’entendent bien. Je vais les suivre, il
m’expliqueront les règles en route. Décidément les relations entre
chats me dépassent.
</p>
<img class="character" src="img/john.png" alt="John">
<p>
— Laisse cet oiseau tranquille !<br>
À peine je réalise que Frihet me poursuit, que ses griffes viennent
se planter dans ma croupe. Nous roulons en ren-versant absolument
tout sur notre passage. Je me débat pour qu’elle me lâche, mais son
étreinte est beaucoup trop forte, elle me fait miauler de douleur.<br>
— Ça n’a rien à voir avec toi ! je lui dis en la repoussant de mes pattes arrières.<br>
— Bien sûr que si ! Tu es trop borné pour comprendre !<br>
Elle prend son élan et me percute la tête en avant. Je suis projeté
en arrière sous la puissance du choc. Mon dos heurte la paroi et
dans le même mouvement, avec une rage totale, Frihet me plaque contre le mur.<br>
— Cet oiseau est sacré pour ma mère, jamais je ne te laisserai lui faire du mal !<br>
— Je ne te laisserai pas te mettre sur mon chemin, même si tu penses devoir protéger cet oiseau.<br>
— Je vais te tuer !<br>
Sa rage vient heurter violemment mon museau.
</p>
<img class="character" src="img/poire.png" alt="Poire">
<p>
J’arrive à peine et j’entends Frihet hurler sur John complètement
maîtrisé. Son rugissement semble sorti d’une autre espèce, plus
puissante et plus grande que les chats. Sa colère est saisissante, mais
plus impressionnant encore, le sol se met soudainement à trembler sous
mes coussinets. D’abord légères, les secousses s’intensifient à chaque
seconde. Mon instinct me somme de déguerpir, la pression est
insupportable. Je dois absolument sauver John de cette furie.
</p>
<img class="character" src="img/frihet.png" alt="Frihet">
<p>
Je n’ai jamais été aussi enragée, j’étais prête à le couper en deux.
Mais sans savoir pourquoi, mon instinct remplace instantanément toute
rage par de la peur. Le sol vibre sous mes pattes, les murs commencent
à grincer.
</p>
<img class="character" src="img/john.png" alt="John">
<p>
Frihet relâche doucement son emprise et détourne le regard vers le
vide. C’est elle qui fait trembler le sol ? Je n’ai jamais vu un chat
faire ça. Non, ce doit être autre chose. Je vois Poire redescendre à
toute vitesse vers nous. Il fonce sur Frihet. Mais avant de
l’atteindre, dans un bruit assourdissant, un immense morceau de métal
s’effondre sur le sol. Manquant ainsi d’aplatir Poire. L’élan coupé, je
le distingue au travers de la fumée, tétanisé.<br>
— Frihet ! L’endroit tombe en morceaux ! Lâche moi !
</p>
<img class="character" src="img/poire.png" alt="Poire">
<p>
— Mais que ce passe-t-il ?! C’est un morceaux du plafond ?<br>
Le sol n’en finit pas de trembler et ça monte en puissance. Une
fois remis de mon absence, je contourne l’obstacle pour rejoindre John.<br>
— Qu’avez vous fait ? Hurle Frihet à John, effarée.<br>
Je me glisse entre les deux pour ramener Frihet à la raison.<br>
— Lâche-le Frihet ! Il faut partir !
</p>
<img class="character" src="img/frihet.png" alt="Frihet">
<p>
Mon monde s’effondre. Et je ne bouge pas. Ma maison tombe en ruine et
je ne peux rien y faire. Je distingue le plafond se plier et je sens
chaque mur se disloquer. Rien ne résiste à cette vibration venue du
sol, mes muscles sont paralysés alors que tout est en mouvement.
</p>
<img class="character" src="img/poire.png" alt="Poire">
<p>
Je la pousse avec ma tête pour qu’elle se mette en mouvement mais rien
n’y fait, elle est clouée au sol. Alors que le mur au dessus de nous
penche dangereusement. Elle bouge enfin. Je retrouve John du regard, il
est déjà près de la sortie.
</p>
<img class="character" src="img/frihet.png" alt="Frihet">
<p>
Tout est si flou. Je ne me souviens que de formes abstraites s’étalant
le long de mon champ de vision. Mes muscles sont tendus, comme si je
venais de faire un effort incroyable, mais aucun souvenir. Rien, juste
un monde en deux couleurs, bleu et blanc, un ensemble brouillon de
métal et la silhouette de deux chats se découpant dans l’horizon.
</p>
<img class="character" src="img/john.png" alt="John">
<p>
Il fallait que cette catastrophe arrive en pleine nuit. Nous voilà déjà
dehors alors que le froid revient. Est ce que c’est ma faute si on en
est là maintenant ? J’espère que non, ça aurait pu mal finir. Ce ne
doit pas être simple pour Frihet. Se faire sortir de la boite, c’est
jamais agréable.
</p>
<img src="img/inter42.png" alt="Inter">
<p>
— Je vois que tu es réveillée.<br>
Je tournais autour d’elle depuis un petit moment et même si je ne tournais plus,
je gardais un œil sur elle.<br>
— Nous nous en sommes sortis, c’était moins une. Je suis terriblement
désolé pour ton Temple bleu.<br>
Je ne peux pas compter sur John pour ce genre d’attention, il est mal
à l’aise. Alors comme c’est important, je m’en occupe. Et maintenant, Frihet
elle fait partie de la bande,je crois.<br>
— C’est donc bien mon temple que je vois écroulé devant mes yeux.<br>
— Oui… Mais nous nous sommes rencontrés, tu n’as qu’à nous suivre !<br>
— Et bah voyons ! Vous avez fait tomber ma maison pour me forcer à
vous accompagner !<br>
— Non Frihet, nous n’avons pas ce pouvoir…<br>
John sort d’un buisson proche et s’avance vers nous l’air concerné.<br>
— Nous devrions partir, le coin est en effervescence après les secousses. Frihet, tu es avec nous ?
</p>
<img class="character" src="img/frihet.png" alt="Frihet">
<p>
Quel choix ai-je ? Cette bande de chats fous m’ont eue.<br>
— Je n’ai pas d’autre choix. Sache que…<br>
Le sol tremble de nouveau. Cette fois c’est instantané, le choc est lourd.
Poire vacille sur ses pattes et tombe maladroitement. Un son incroyable
sors du sol et envahit l’espace.<br>
Comme étouffée, la voix de John ressort au loin :<br>
— Partons tout de suite !<br>
Poire m’incite à les suivre alors que John prend déjà un pas de course, au revoir chez moi.
</p>
<img class="character" src="img/poire.png" alt="Poire">
<p>
Quelle horreur ! Impossible de courir ! Mais petit à petit le bruit
assourdissant s’estompe. Le sol ne tremble plus, mais un son persiste.
J’entends comme des couinements, sortir de l’obscurité. L’ombre semble
vivante.
</p>
<img class="character" src="img/john.png" alt="John">
<p>
Dans un bruit de craquement, une vague noire surgit à la lumière de la
lune. Le son de cisaille que je percevais légèrement tout à l’heure
s’amplifie de plus en plus. Des rats. Cette mélasse, c’est des rats. Et
nous sommes sur leur chemin.<br>
— Prenez de la hauteur ! Vite !
</p>
<img class="character" src="img/poire.png" alt="Poire">
<p>
Cette fois sans aucune hésitation je suis les ordres de John. Frihet,
elle, avait déjà eu le réflexe, même peut-être avant John. Je déteste
les rats. Depuis Gros Bouchon je ne peux plus les voir.
</p>
<img class="character" src="img/frihet.png" alt="Frihet">
<p>
— D’où viennent tous ces rats ?<br>
— Aucune idée, le tremblement les a peut-etre fait sortir de leur nid.
Mais ils ont l’air de suivre une direction en particulier !
</p>
<p>
— Et si nous les suivions par les hauteurs ? Il y aura peut-être à
manger là où ils vont.<br>
— Bonne idée !<br>
Bonne idée, bonne idée, je suis pas vraiment d’accord. Il y en a
beaucoup quand même. Mais ils partent déjà. Je vais devoir m’imposer
si je ne veut pas me retrouver “suiveuse”. Enfin, l’idée de ne pas
avancer seule dans ce monde inconnu me réconforte. J’ai tout perdu mais je les ai trouvés.
</p>
<img class="outro" src="img/outro4.jpg" alt="Outro">
</section>
<section class="fullpage">
<img src="img/silhouettes_color.jpg" alt="Silhouettes">
</section>
</html>
/* Fonts */
@font-face {
font-family: Pacifico;
src: url(pacifico.ttf);
}
@font-face {
font-family: Source Sans Pro;
font-weight: 400;
src: url(SourceSans3-Regular.ttf);
}
@font-face {
font-family: Source Sans Pro;
font-weight: 700;
src: url(SourceSans3-Bold.ttf);
}
/* Variables */
:root {
--black: #14213d;
--green: #1ee494;
--grey: #a9a;
--white: #f6f6f6;
}
/* Page rules */
@page {
font-family: Pacifico;
margin: 3cm;
@bottom-left {
color: var(--green);
content: '♥ Thank you!';
}
@bottom-right {
color: var(--grey);
content: 'contact@courtbouillon.org | courtbouillon.org';
font-size: 9pt;
}
}
/* Style */
html {
color: var(--black);
font-family: Source Sans Pro;
font-size: 11pt;
line-height: 1.6;
}
body {
margin: 0;
}
h1 {
color: var(--green);
font-family: Pacifico;
font-size: 40pt;
margin: 0;
}
aside {
display: flex;
margin: 2em 0 4em;
address {
font-style: normal;
white-space: pre-line;
&#from {
color: var(--grey);
flex: 1;
}
&#to {
text-align: right;
}
}
}
dl {
position: absolute;
right: 0;
text-align: right;
top: 0;
dt, dd {
display: inline;
margin: 0;
}
dt {
color: var(--grey);
&::before {
content: '';
display: block;
}
&::after {
content: ':';
}
}
}
table {
border-collapse: collapse;
width: 100%;
&#total {
background: var(--white);
border-color: var(--white);
border-style: solid;
border-width: 2cm 3cm;
bottom: 0;
font-size: 20pt;
margin: 0 -3cm;
position: absolute;
width: 18cm;
}
th {
border-bottom: .2mm solid var(--grey);
color: var(--grey);
font-size: 10pt;
font-weight: 400;
padding-bottom: .25cm;
text-transform: uppercase;
}
td {
padding-top: 7mm;
&:last-of-type {
color: var(--green);
font-weight: bold;
text-align: right;
}
}
th, td {
text-align: center;
&:first-of-type {
text-align: left;
}
&:last-of-type {
text-align: right;
}
}
}
footer {
content: '';
display: block;
height: 6cm;
}
<html lang="en">
<head>
<meta charset="utf-8">
<link href="invoice.css" media="print" rel="stylesheet">
<title>Invoice</title>
<meta name="description" content="Invoice demo sample">
</head>
<body>
<h1>Invoice</h1>
<aside>
<address id="from">
WeasyPrint
26 rue Emile Decorps
69100 Villeurbanne
France
</address>
<address id="to">
Our awesome developers
From all around the world
Earth
</address>
</aside>
<dl id="informations">
<dt>Invoice number</dt>
<dd>12345</dd>
<dt>Date</dt>
<dd>March 31, 2018</dd>
</dl>
<table>
<thead>
<tr>
<th>Description</th>
<th>Price</th>
<th>Quantity</th>
<th>Subtotal</th>
</tr>
</thead>
<tbody>
<tr>
<td>Website design</td>
<td>€34.20</td>
<td>100</td>
<td>€3,420.00</td>
</tr>
<tr>
<td>Website development</td>
<td>€45.50</td>
<td>100</td>
<td>€4,550.00</td>
</tr>
<tr>
<td>Website integration</td>
<td>€25.75</td>
<td>100</td>
<td>€2,575.00</td>
</tr>
</tbody>
</table>
<footer>
<table id="total">
<thead>
<tr>
<th>Due by</th>
<th>Account number</th>
<th>Total due</th>
</tr>
</thead>
<tbody>
<tr>
<td>May 10, 2018</td>
<td>132 456 789 012</td>
<td>€10,545.00</td>
</tr>
</tbody>
</table>
</footer>
</body>
</html>
<html lang="fr">
<head>
<meta charset="utf-8">
<title>Bon de commande</title>
<link href="style.css" rel="stylesheet">
<meta name="description" content="Letter demo sample">
</head>
<body>
<header>
<div>
<img src="img/logo-couleurs.png" alt="Logo de Des Couleurs Dans l’Assiette">
</div>
</header>
<div>
<p>Cher Aurélien Leno,</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute
irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
<p>Estelle Carotte</p>
</div>
<hr>
<div>
<form method="post">
<fieldset>
<legend>Bon de commande</legend>
<label for="name">Nom :</label>
<input type="text" name="name" id="name">
<label for="firstname">Prénom :</label>
<input type="text" name="firstname" id="firstname">
<label for="address">Adresse :</label>
<textarea name="address" id="address" rows="2" cols="40"></textarea>
<label for="products">Produits souhaités :</label>
<textarea name="products" id="products" rows="4" cols="40"></textarea>
</fieldset>
<input type="submit" name="submit" value="Envoyer">
</form>
</div>
<footer>
<p>AMAP - Des couleurs dans l'assiette - 53 Avenue du Panier Rouge - 69005 Lyon</p>
</footer>
</body>
</html>
/* Fonts */
@font-face {
font-family: "pacifico";
src: url("fonts/Pacifico-Regular.ttf") format('truetype');
}
@font-face {
font-family: "soon";
src: url("fonts/ComingSoon-Regular.ttf") format('truetype');
}
/* Page rule */
@page {
margin: 0;
}
/* Style */
body {
font-family: "soon";
margin: 0;
> div {
margin: 0 auto;
padding: 0 12mm;
&:first-of-type, &:last-of-type {
margin: 2cm 0 1cm 0;
}
}
}
header {
background: no-repeat top left / 125% url('img/image-couleurs.png');
div {
height: 3cm;
padding: 5mm 5mm 12mm 5mm;
}
img {
width: 5cm;
}
}
hr {
border-top: 3px dashed gray;
border-bottom: none;
margin: 5mm 0;
}
p {
font-family: serif;
line-height: 18pt;
margin-top: 5mm;
}
label {
display: block;
margin-bottom: 2mm;
}
legend {
font-family: "pacifico", serif;
font-size: 18pt;
margin-bottom: 5mm;
}
input {
height: 1.5em;
}
textarea {
height: 4em;
}
input, textarea {
border: none;
display: block;
width: 100%;
}
input::before,
textarea::before,
textarea::after {
content: leader(dotted);
display: block;
}
footer p {
text-align: center;
}
@media print {
input[type="submit"] {
display: none;
}
}
/* Fonts */
@font-face {
font-family: ArchivoBlack;
src: url(archivoblack-regular.ttf);
}
/* Style */
html {
background: url(background.jpg);
background-size: cover;
font-family: ArchivoBlack;
color: white;
text-transform: uppercase;
}
#logo {
position: absolute;
z-index: -1;
}
#main-title p {
background-color: black;
display: inline;
}
#date {
border: 4px solid white;
padding-top: 0.5cm;
padding-bottom: 0.5cm;
article {
display: inline-block;
p {
margin: 0;
}
}
}
#sponsors ul {
align-items: center;
display: flex;
flex-wrap: wrap;
justify-content: center;
list-style: none;
padding: 0;
li {
margin: 0 1em;
}
}
#address {
letter-spacing: 0.15rem;
text-transform: none;
}
@import url(common.css);
/* Page rules */
@page {
margin: 3mm;
size: 100mm 140mm;
}
/* Style */
#logo {
left: 2.1cm;
top: 0.7cm;
width: 55%;
}
#top-line {
font-size: 1em;
margin-top: 0.2cm;
margin-left: 0.1cm;
}
#main-title {
font-size: 0.86em;
margin-left: -0.1cm;
margin-top: 5cm;
p {
padding: 0.25cm;
&:last-of-type {
margin-right: -0.2cm;
}
}
}
#description {
display: none;
}
#date {
margin-top: 0.7cm;
article {
margin-left: 0.8cm;
&:first-child {
> p:first-child {
font-size: 1.2em;
}
> p:last-of-type {
font-size: 2em;
}
}
&:last-of-type {
> p:first-child {
font-size: 0.9em;
}
> p:last-of-type {
font-size: 2.3em;
}
}
}
}
#sponsors img {
max-height: 40px;
max-width: 100px;
}
#address {
font-size: 0.6em;
text-align: center;
}
@import url(common.css);
/* Page rules */
@page {
margin: 10mm;
size: 278mm 388mm;
}
/* Style */
#logo {
left: 1.8cm;
top: 2cm;
width: 87%;
}
#top-line {
font-size: 2.9em;
margin-top: 0.6cm;
}
#main-title {
font-size: 2.5em;
margin-top: 20cm;
p {
padding: 0.35cm;
&:last-of-type {
margin-left: 0.3cm;
}
}
}
#description {
font-size: 1.5em;
letter-spacing: 0.1em;
margin: 2cm auto 0.2cm 1cm;
}
#date article {
margin-left: 1cm;
&:first-child {
> p:first-child {
font-size: 4.4em;
}
> p:last-of-type {
font-size: 7em;
}
}
&:last-of-type {
> p:first-child {
font-size: 3.2em;
}
> p:last-of-type {
font-size: 8em;
}
}
}
#sponsors{
margin-top: 1.2cm;
img {
max-height: 60px;
max-width: 150px;
}
}
#address {
font-weight: lighter;
margin-left: 0.8cm;
}
<html>
<head>
<meta charset="utf-8">
<!-- <link href="poster.css" rel="stylesheet"> -->
<title>Poster</title>
<meta name="description" content="Poster">
</head>
<body>
<img id="logo" src="gaming-affiche-logo.png" />
<p id="top-line">En live dans 50 villes de France</p>
<section id="main-title">
<p>e-sport live</p>
<p>Tournoi retro-gaming</p>
</section>
<p id="description">Participez à la première édition près de chez vous</p>
<section id="date">
<article>
<p>25 juin</p><p>2021</p>
</article>
<article>
<p>La souris verte</p><p>Épinal</p>
</article>
</section>
<section id="sponsors">
<ul>
<li><img src="logo-mc.png" /></li>
<li><img src="logo-stella.png" /></li>
<li><img src="logo-rhino.png" /></li>
<li><img src="logo-fleurexpo.png" /></li>
<li><img src="logo-fiac.png" /></li>
</ul>
</section>
<p id="address">La Souris Verte — 17 rue des États-Unis, 88000 Épinal — www.ticketrocknight.org</p>
</body>
</html>
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Calque_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 56.7 56.7" style="enable-background:new 0 0 56.7 56.7;" xml:space="preserve">
<style type="text/css">
.st0{fill:none;stroke:#231F20;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;}
</style>
<rect x="12.4" y="6.1" class="st0" width="31.9" height="44.5"/>
<line class="st0" x1="16.4" y1="10.8" x2="26.8" y2="10.8"/>
<line class="st0" x1="37" y1="10.8" x2="40.2" y2="10.8"/>
<g>
<rect x="-85.5" y="-13" class="st0" width="31.9" height="44.5"/>
<line class="st0" x1="-81.4" y1="-6.3" x2="-71.1" y2="-6.3"/>
<line class="st0" x1="-81.4" y1="-0.1" x2="-71.1" y2="-0.1"/>
<line class="st0" x1="-81.4" y1="6.1" x2="-71.1" y2="6.1"/>
<line class="st0" x1="-81.4" y1="12.3" x2="-71.1" y2="12.3"/>
<line class="st0" x1="-81.4" y1="18.6" x2="-71.1" y2="18.6"/>
<line class="st0" x1="-81.4" y1="24.8" x2="-71.1" y2="24.8"/>
<line class="st0" x1="-60.8" y1="-6.3" x2="-57.6" y2="-6.3"/>
<line class="st0" x1="-60.8" y1="-0.1" x2="-57.6" y2="-0.1"/>
<line class="st0" x1="-60.8" y1="6.1" x2="-57.6" y2="6.1"/>
<line class="st0" x1="-60.8" y1="12.3" x2="-57.6" y2="12.3"/>
<line class="st0" x1="-60.8" y1="18.6" x2="-57.6" y2="18.6"/>
<line class="st0" x1="-60.8" y1="24.8" x2="-57.6" y2="24.8"/>
</g>
</svg>
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Calque_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 56.7 56.7" style="enable-background:new 0 0 56.7 56.7;" xml:space="preserve">
<style type="text/css">
.st0{fill:none;stroke:#231F20;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;}
</style>
<rect x="12.4" y="6.1" class="st0" width="31.9" height="44.5"/>
<line class="st0" x1="16.4" y1="13.8" x2="26.8" y2="13.8"/>
<g>
<rect x="-85.5" y="-13" class="st0" width="31.9" height="44.5"/>
<line class="st0" x1="-81.4" y1="-6.3" x2="-71.1" y2="-6.3"/>
<line class="st0" x1="-81.4" y1="-0.1" x2="-71.1" y2="-0.1"/>
<line class="st0" x1="-81.4" y1="6.1" x2="-71.1" y2="6.1"/>
<line class="st0" x1="-81.4" y1="12.3" x2="-71.1" y2="12.3"/>
<line class="st0" x1="-81.4" y1="18.6" x2="-71.1" y2="18.6"/>
<line class="st0" x1="-81.4" y1="24.8" x2="-71.1" y2="24.8"/>
<line class="st0" x1="-60.8" y1="-6.3" x2="-57.6" y2="-6.3"/>
<line class="st0" x1="-60.8" y1="-0.1" x2="-57.6" y2="-0.1"/>
<line class="st0" x1="-60.8" y1="6.1" x2="-57.6" y2="6.1"/>
<line class="st0" x1="-60.8" y1="12.3" x2="-57.6" y2="12.3"/>
<line class="st0" x1="-60.8" y1="18.6" x2="-57.6" y2="18.6"/>
<line class="st0" x1="-60.8" y1="24.8" x2="-57.6" y2="24.8"/>
</g>
<line class="st0" x1="16.4" y1="20.9" x2="26.8" y2="20.9"/>
<line class="st0" x1="16.4" y1="28" x2="26.8" y2="28"/>
<line class="st0" x1="16.4" y1="35" x2="26.8" y2="35"/>
<line class="st0" x1="16.4" y1="42.1" x2="26.8" y2="42.1"/>
<g>
<path d="M38.1,12.5c0.2,0,0.3,0.1,0.4,0.2v1.2c0,0.2,0,0.3,0.1,0.4s0.1,0.1,0.2,0.1c0.1,0,0.2-0.1,0.3-0.2c0.1-0.2,0.1-0.4,0.1-0.8
c0-0.4-0.1-0.8-0.4-1c-0.3-0.2-0.6-0.4-1.1-0.4c-0.3,0-0.7,0.1-0.9,0.2c-0.3,0.1-0.4,0.4-0.6,0.6c-0.1,0.3-0.2,0.6-0.2,0.9
c0,0.5,0.1,1,0.4,1.3s0.7,0.5,1.2,0.5c0.2,0,0.3,0,0.5,0c0.2,0,0.3-0.1,0.5-0.1l0.2,0.5c-0.2,0.1-0.3,0.1-0.6,0.2
c-0.2,0-0.4,0.1-0.6,0.1c-0.5,0-0.9-0.1-1.3-0.3c-0.4-0.2-0.6-0.5-0.8-0.8c-0.2-0.3-0.3-0.8-0.3-1.2c0-0.4,0.1-0.8,0.3-1.2
s0.5-0.6,0.9-0.8s0.8-0.3,1.2-0.3c0.5,0,0.9,0.1,1.2,0.3s0.6,0.4,0.8,0.7c0.2,0.3,0.3,0.6,0.3,1c0,0.3,0,0.6-0.1,0.8
c-0.1,0.2-0.2,0.4-0.4,0.6c-0.2,0.1-0.4,0.2-0.6,0.2c-0.2,0-0.3-0.1-0.5-0.2s-0.2-0.2-0.2-0.4c-0.1,0.2-0.2,0.3-0.3,0.4
c-0.1,0.1-0.3,0.1-0.4,0.1c-0.3,0-0.5-0.1-0.7-0.3s-0.2-0.5-0.2-0.8c0-0.4,0.1-0.7,0.3-1c0.2-0.2,0.5-0.4,0.9-0.4
C37.9,12.5,38,12.5,38.1,12.5z M37.8,14.4c0.1,0,0.1-0.1,0.1-0.2V13c-0.1,0-0.2,0-0.2,0c-0.1,0-0.2,0.1-0.3,0.2s-0.1,0.4-0.1,0.7
c0,0.2,0,0.4,0.1,0.5c0,0.1,0.1,0.1,0.2,0.1C37.6,14.5,37.7,14.4,37.8,14.4z"/>
</g>
<g>
<path d="M38.1,19.6c0.2,0,0.3,0.1,0.4,0.2V21c0,0.2,0,0.3,0.1,0.4s0.1,0.1,0.2,0.1c0.1,0,0.2-0.1,0.3-0.2c0.1-0.2,0.1-0.4,0.1-0.8
c0-0.4-0.1-0.8-0.4-1c-0.3-0.2-0.6-0.4-1.1-0.4c-0.3,0-0.7,0.1-0.9,0.2c-0.3,0.1-0.4,0.4-0.6,0.6c-0.1,0.3-0.2,0.6-0.2,0.9
c0,0.5,0.1,1,0.4,1.3s0.7,0.5,1.2,0.5c0.2,0,0.3,0,0.5,0c0.2,0,0.3-0.1,0.5-0.1l0.2,0.5c-0.2,0.1-0.3,0.1-0.6,0.2
c-0.2,0-0.4,0.1-0.6,0.1c-0.5,0-0.9-0.1-1.3-0.3c-0.4-0.2-0.6-0.5-0.8-0.8c-0.2-0.3-0.3-0.8-0.3-1.2c0-0.4,0.1-0.8,0.3-1.2
s0.5-0.6,0.9-0.8s0.8-0.3,1.2-0.3c0.5,0,0.9,0.1,1.2,0.3s0.6,0.4,0.8,0.7c0.2,0.3,0.3,0.6,0.3,1c0,0.3,0,0.6-0.1,0.8
c-0.1,0.2-0.2,0.4-0.4,0.6c-0.2,0.1-0.4,0.2-0.6,0.2c-0.2,0-0.3-0.1-0.5-0.2s-0.2-0.2-0.2-0.4c-0.1,0.2-0.2,0.3-0.3,0.4
c-0.1,0.1-0.3,0.1-0.4,0.1c-0.3,0-0.5-0.1-0.7-0.3s-0.2-0.5-0.2-0.8c0-0.4,0.1-0.7,0.3-1c0.2-0.2,0.5-0.4,0.9-0.4
C37.9,19.6,38,19.6,38.1,19.6z M37.8,21.5c0.1,0,0.1-0.1,0.1-0.2v-1.2c-0.1,0-0.2,0-0.2,0c-0.1,0-0.2,0.1-0.3,0.2s-0.1,0.4-0.1,0.7
c0,0.2,0,0.4,0.1,0.5c0,0.1,0.1,0.1,0.2,0.1C37.6,21.6,37.7,21.5,37.8,21.5z"/>
</g>
<g>
<path d="M38.1,26.7c0.2,0,0.3,0.1,0.4,0.2v1.2c0,0.2,0,0.3,0.1,0.4s0.1,0.1,0.2,0.1c0.1,0,0.2-0.1,0.3-0.2c0.1-0.2,0.1-0.4,0.1-0.8
c0-0.4-0.1-0.8-0.4-1c-0.3-0.2-0.6-0.4-1.1-0.4c-0.3,0-0.7,0.1-0.9,0.2c-0.3,0.1-0.4,0.4-0.6,0.6C36.1,27.3,36,27.6,36,28
c0,0.5,0.1,1,0.4,1.3s0.7,0.5,1.2,0.5c0.2,0,0.3,0,0.5,0c0.2,0,0.3-0.1,0.5-0.1l0.2,0.5c-0.2,0.1-0.3,0.1-0.6,0.2
c-0.2,0-0.4,0.1-0.6,0.1c-0.5,0-0.9-0.1-1.3-0.3c-0.4-0.2-0.6-0.5-0.8-0.8c-0.2-0.3-0.3-0.8-0.3-1.2c0-0.4,0.1-0.8,0.3-1.2
s0.5-0.6,0.9-0.8s0.8-0.3,1.2-0.3c0.5,0,0.9,0.1,1.2,0.3s0.6,0.4,0.8,0.7c0.2,0.3,0.3,0.6,0.3,1c0,0.3,0,0.6-0.1,0.8
c-0.1,0.2-0.2,0.4-0.4,0.6c-0.2,0.1-0.4,0.2-0.6,0.2c-0.2,0-0.3-0.1-0.5-0.2s-0.2-0.2-0.2-0.4c-0.1,0.2-0.2,0.3-0.3,0.4
c-0.1,0.1-0.3,0.1-0.4,0.1c-0.3,0-0.5-0.1-0.7-0.3s-0.2-0.5-0.2-0.8c0-0.4,0.1-0.7,0.3-1c0.2-0.2,0.5-0.4,0.9-0.4
C37.9,26.7,38,26.7,38.1,26.7z M37.8,28.6c0.1,0,0.1-0.1,0.1-0.2v-1.2c-0.1,0-0.2,0-0.2,0c-0.1,0-0.2,0.1-0.3,0.2s-0.1,0.4-0.1,0.7
c0,0.2,0,0.4,0.1,0.5c0,0.1,0.1,0.1,0.2,0.1C37.6,28.6,37.7,28.6,37.8,28.6z"/>
</g>
<g>
<path d="M38.1,33.8c0.2,0,0.3,0.1,0.4,0.2v1.2c0,0.2,0,0.3,0.1,0.4s0.1,0.1,0.2,0.1c0.1,0,0.2-0.1,0.3-0.2c0.1-0.2,0.1-0.4,0.1-0.8
c0-0.4-0.1-0.8-0.4-1c-0.3-0.2-0.6-0.4-1.1-0.4c-0.3,0-0.7,0.1-0.9,0.2c-0.3,0.1-0.4,0.4-0.6,0.6c-0.1,0.3-0.2,0.6-0.2,0.9
c0,0.5,0.1,1,0.4,1.3s0.7,0.5,1.2,0.5c0.2,0,0.3,0,0.5,0c0.2,0,0.3-0.1,0.5-0.1l0.2,0.5c-0.2,0.1-0.3,0.1-0.6,0.2
c-0.2,0-0.4,0.1-0.6,0.1c-0.5,0-0.9-0.1-1.3-0.3c-0.4-0.2-0.6-0.5-0.8-0.8c-0.2-0.3-0.3-0.8-0.3-1.2c0-0.4,0.1-0.8,0.3-1.2
s0.5-0.6,0.9-0.8s0.8-0.3,1.2-0.3c0.5,0,0.9,0.1,1.2,0.3s0.6,0.4,0.8,0.7c0.2,0.3,0.3,0.6,0.3,1c0,0.3,0,0.6-0.1,0.8
c-0.1,0.2-0.2,0.4-0.4,0.6c-0.2,0.1-0.4,0.2-0.6,0.2c-0.2,0-0.3-0.1-0.5-0.2s-0.2-0.2-0.2-0.4c-0.1,0.2-0.2,0.3-0.3,0.4
c-0.1,0.1-0.3,0.1-0.4,0.1c-0.3,0-0.5-0.1-0.7-0.3s-0.2-0.5-0.2-0.8c0-0.4,0.1-0.7,0.3-1c0.2-0.2,0.5-0.4,0.9-0.4
C37.9,33.7,38,33.8,38.1,33.8z M37.8,35.7c0.1,0,0.1-0.1,0.1-0.2v-1.2c-0.1,0-0.2,0-0.2,0c-0.1,0-0.2,0.1-0.3,0.2s-0.1,0.4-0.1,0.7
c0,0.2,0,0.4,0.1,0.5c0,0.1,0.1,0.1,0.2,0.1C37.6,35.7,37.7,35.7,37.8,35.7z"/>
</g>
<g>
<path d="M38.1,40.9c0.2,0,0.3,0.1,0.4,0.2v1.2c0,0.2,0,0.3,0.1,0.4s0.1,0.1,0.2,0.1c0.1,0,0.2-0.1,0.3-0.2c0.1-0.2,0.1-0.4,0.1-0.8
c0-0.4-0.1-0.8-0.4-1c-0.3-0.2-0.6-0.4-1.1-0.4c-0.3,0-0.7,0.1-0.9,0.2c-0.3,0.1-0.4,0.4-0.6,0.6c-0.1,0.3-0.2,0.6-0.2,0.9
c0,0.5,0.1,1,0.4,1.3s0.7,0.5,1.2,0.5c0.2,0,0.3,0,0.5,0c0.2,0,0.3-0.1,0.5-0.1l0.2,0.5c-0.2,0.1-0.3,0.1-0.6,0.2
c-0.2,0-0.4,0.1-0.6,0.1c-0.5,0-0.9-0.1-1.3-0.3c-0.4-0.2-0.6-0.5-0.8-0.8c-0.2-0.3-0.3-0.8-0.3-1.2c0-0.4,0.1-0.8,0.3-1.2
s0.5-0.6,0.9-0.8s0.8-0.3,1.2-0.3c0.5,0,0.9,0.1,1.2,0.3s0.6,0.4,0.8,0.7c0.2,0.3,0.3,0.6,0.3,1c0,0.3,0,0.6-0.1,0.8
c-0.1,0.2-0.2,0.4-0.4,0.6c-0.2,0.1-0.4,0.2-0.6,0.2c-0.2,0-0.3-0.1-0.5-0.2s-0.2-0.2-0.2-0.4c-0.1,0.2-0.2,0.3-0.3,0.4
c-0.1,0.1-0.3,0.1-0.4,0.1c-0.3,0-0.5-0.1-0.7-0.3s-0.2-0.5-0.2-0.8c0-0.4,0.1-0.7,0.3-1c0.2-0.2,0.5-0.4,0.9-0.4
C37.9,40.8,38,40.9,38.1,40.9z M37.8,42.7c0.1,0,0.1-0.1,0.1-0.2v-1.2c-0.1,0-0.2,0-0.2,0c-0.1,0-0.2,0.1-0.3,0.2s-0.1,0.4-0.1,0.7
c0,0.2,0,0.4,0.1,0.5c0,0.1,0.1,0.1,0.2,0.1C37.6,42.8,37.7,42.8,37.8,42.7z"/>
</g>
</svg>
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Calque_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 56.7 56.7" style="enable-background:new 0 0 56.7 56.7;" xml:space="preserve">
<style type="text/css">
.st0{fill:none;stroke:#231F20;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;}
</style>
<rect x="12.4" y="6.1" class="st0" width="31.9" height="44.5"/>
<line class="st0" x1="16.4" y1="13.8" x2="26.8" y2="13.8"/>
<g>
<rect x="-85.5" y="-13" class="st0" width="31.9" height="44.5"/>
<line class="st0" x1="-81.4" y1="-6.3" x2="-71.1" y2="-6.3"/>
<line class="st0" x1="-81.4" y1="-0.1" x2="-71.1" y2="-0.1"/>
<line class="st0" x1="-81.4" y1="6.1" x2="-71.1" y2="6.1"/>
<line class="st0" x1="-81.4" y1="12.3" x2="-71.1" y2="12.3"/>
<line class="st0" x1="-81.4" y1="18.6" x2="-71.1" y2="18.6"/>
<line class="st0" x1="-81.4" y1="24.8" x2="-71.1" y2="24.8"/>
<line class="st0" x1="-60.8" y1="-6.3" x2="-57.6" y2="-6.3"/>
<line class="st0" x1="-60.8" y1="-0.1" x2="-57.6" y2="-0.1"/>
<line class="st0" x1="-60.8" y1="6.1" x2="-57.6" y2="6.1"/>
<line class="st0" x1="-60.8" y1="12.3" x2="-57.6" y2="12.3"/>
<line class="st0" x1="-60.8" y1="18.6" x2="-57.6" y2="18.6"/>
<line class="st0" x1="-60.8" y1="24.8" x2="-57.6" y2="24.8"/>
</g>
<line class="st0" x1="30.5" y1="13.8" x2="40.8" y2="13.8"/>
<line class="st0" x1="16.4" y1="20.9" x2="26.8" y2="20.9"/>
<line class="st0" x1="30.5" y1="20.9" x2="40.8" y2="20.9"/>
<line class="st0" x1="16.4" y1="28" x2="26.8" y2="28"/>
<line class="st0" x1="30.5" y1="28" x2="40.8" y2="28"/>
<line class="st0" x1="16.4" y1="35" x2="26.8" y2="35"/>
<line class="st0" x1="30.5" y1="35" x2="40.8" y2="35"/>
<line class="st0" x1="16.4" y1="42.1" x2="26.8" y2="42.1"/>
<line class="st0" x1="30.5" y1="42.1" x2="40.8" y2="42.1"/>
</svg>
/* Fonts */
@font-face {
font-family: Fira Sans;
font-weight: 400;
src: url(FiraSans-Regular.ttf);
}
@font-face {
font-family: Fira Sans;
font-style: italic;
font-weight: 400;
src: url(FiraSans-Italic.ttf);
}
@font-face {
font-family: Fira Sans;
font-weight: 300;
src: url(FiraSans-Light.ttf);
}
@font-face {
font-family: Fira Sans;
font-style: italic;
font-weight: 300;
src: url(FiraSans-LightItalic.ttf);
}
@font-face {
font-family: Fira Sans;
font-weight: 700;
src: url(FiraSans-Bold.ttf);
}
/* Variables */
:root {
--black: #393939;
--orange: #fbc847;
}
/* Page rules */
@page {
@top-left {
background: var(--orange);
content: counter(page);
height: 1cm;
text-align: center;
width: 1cm;
}
@top-center {
background: var(--orange);
content: '';
display: block;
height: .05cm;
opacity: .5;
width: 100%;
}
@top-right {
content: string(heading);
font-size: 9pt;
height: 1cm;
vertical-align: middle;
width: 100%;
}
}
@page :blank {
@top-left { background: none; content: '' }
@top-center { content: none }
@top-right { content: none }
}
@page no-chapter {
@top-left { background: none; content: none }
@top-center { content: none }
@top-right { content: none }
}
@page :first {
background: url(report-cover.jpg) no-repeat center;
background-size: cover;
margin: 0;
}
@page chapter {
background: var(--orange);
margin: 0;
@top-left { content: none }
@top-center { content: none }
@top-right { content: none }
}
/* Style */
html {
color: var(--black);
font-family: Fira Sans;
font-size: 11pt;
font-weight: 300;
line-height: 1.5;
}
body {
margin: 0;
}
h1 {
color: var(--orange);
font-size: 38pt;
margin: 5cm 2cm 0 2cm;
page: no-chapter;
width: 100%;
}
h2, h3, h4 {
color: black;
font-weight: 400;
}
h2 {
break-before: always;
font-size: 28pt;
string-set: heading content();
}
h3 {
font-weight: 300;
font-size: 15pt;
}
h4 {
font-size: 13pt;
}
#cover {
align-content: space-between;
display: flex;
flex-wrap: wrap;
height: 297mm;
address {
background: var(--orange);
flex: 1 50%;
margin: 0 -2cm;
padding: 1cm 0;
white-space: pre-wrap;
&:first-of-type {
padding-left: 3cm;
}
}
}
#contents {
break-before: right;
break-after: left;
page: no-chapter;
h2 {
font-size: 20pt;
font-weight: 400;
margin-bottom: 3cm;
}
h3 {
font-weight: 500;
margin: 3em 0 1em;
&::before {
background: var(--orange);
content: '';
display: block;
height: .08cm;
margin-bottom: .25cm;
width: 2cm;
}
}
ul {
list-style: none;
padding-left: 0;
li {
border-top: .25pt solid #c1c1c1;
margin: .25cm 0;
padding-top: .25cm;
&::before {
color: var(--orange);
content: '• ';
font-size: 40pt;
line-height: 16pt;
vertical-align: bottom;
}
a {
color: inherit;
text-decoration-line: inherit;
&::before {
content: target-text(attr(href));
}
&::after {
color: var(--orange);
content: target-counter(attr(href), page);
float: right;
}
}
}
}
}
#columns section {
columns: 2;
column-gap: 1cm;
padding-top: 1cm;
p {
text-align: justify;
&:first-of-type {
font-weight: 700;
}
}
}
#skills {
h3 {
background: var(--orange);
margin: 0 -3cm 1cm;
padding: 1cm 1cm 1cm 3cm;
width: 21cm;
}
section {
padding: .5cm 0;
h4 {
margin: 0;
}
p {
margin-top: 0;
}
&#table-content::before {
background: url(table-content.svg) no-repeat center var(--orange);
background-size: 50%;
content: '';
display: inline-block;
float: left;
height: 2cm;
margin-right: .5cm;
vertical-align: middle;
width: 2cm;
}
&#heading::before {
background: url(heading.svg) no-repeat center var(--orange);
background-size: 50%;
content: '';
display: inline-block;
float: left;
height: 2cm;
margin-right: .5cm;
vertical-align: middle;
width: 2cm;
}
&#multi-columns::before {
background: url(multi-columns.svg) no-repeat center var(--orange);
background-size: 50%;
content: '';
display: inline-block;
float: left;
height: 2cm;
margin-right: .5cm;
vertical-align: middle;
width: 2cm;
}
&#internal-links::before {
background: url(internal-links.svg) no-repeat center var(--orange);
background-size: 50%;
content: '';
display: inline-block;
float: left;
height: 2cm;
margin-right: .5cm;
vertical-align: middle;
width: 2cm;
}
&#style::before {
background: url(style.svg) no-repeat center var(--orange);
background-size: 50%;
content: '';
display: inline-block;
float: left;
height: 2cm;
margin-right: .5cm;
vertical-align: middle;
width: 2cm;
}
}
}
#offers {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
h2, h3 {
width: 100%;
}
section {
width: 30%;
h4 {
margin-bottom: 0;
}
ul {
list-style: none;
margin: 0;
padding-left: 0;
li:not(:last-of-type) {
margin: .5cm 0;
}
}
p {
background: var(--orange);
display: block;
font-size: 15pt;
font-weight: 700;
margin-bottom: 0;
padding: .25cm 0;
text-align: center;
}
}
}
#chapter {
align-items: center;
display: flex;
height: 297mm;
justify-content: center;
page: chapter;
}
#typography section {
display: flex;
flex-wrap: wrap;
margin: 1cm 0;
h4 {
border-top: 1pt solid;
flex: 1 25%;
margin: 0;
+ * {
flex: 1 75%;
margin: 0;
padding-left: .5cm;
}
}
p {
text-align: justify;
}
ul {
line-height: 2;
list-style: none;
}
&#small-caps p {
font-variant: small-caps;
}
&#ligatures dl {
display: flex;
flex-wrap: wrap;
dt {
font-weight: 400;
width: 30%;
}
dd {
flex: 1 70%;
margin: 0;
padding: 0;
}
.none {
font-variant-ligatures: none;
}
.common {
font-variant-ligatures: common-ligatures;
}
.discretionary {
font-variant-ligatures: discretionary-ligatures;
}
.contextual {
font-variant-ligatures: contextual;
}
}
&#numbers {
dl {
display: flex;
flex-wrap: wrap;
dt {
font-weight: 400;
width: 30%;
}
dd {
flex: 1 70%;
margin: 0;
padding: 0;
}
}
#fractions {
font-variant-numeric: diagonal-fractions;
}
#ordinals {
font-variant-numeric: ordinal;
}
#slashed {
font-variant-numeric: slashed-zero;
}
#super {
font-variant-position: super;
}
#sub {
font-variant-position: sub;
}
}
&#figures {
dl {
columns: 4;
dt {
font-weight: 400;
}
dd {
display: flex;
margin: 0;
padding: 0;
ul {
padding: 0 1em 0 0;
}
}
}
#oldstyle {
font-variant-numeric: oldstyle-nums;
}
#tabular {
font-variant-numeric: tabular-nums;
}
#old-tabular {
font-variant-numeric: oldstyle-nums tabular-nums;
}
}
}
<html lang="en">
<head>
<meta charset="utf-8">
<link href="report.css" rel="stylesheet">
<title>Report</title>
<meta name="description" content="Report example">
</head>
<body>
<article id="cover">
<h1>Report example</h1>
<address>
WeasyPrint
26 rue Emile Decorps
69100 Villeurbanne France
</address>
<address>
contact@courtbouillon.org
https://courtbouillon.org
</address>
</article>
<article id="contents">
<h2>Table of contents</h2>
<h3>Part one</h3>
<ul>
<li><a href="#columns-title"></a></li>
<li><a href="#skills-title"></a></li>
</ul>
<h3>Part two</h3>
<ul>
<li><a href="#offers-title"></a></li>
<li><a href="#chapter-title"></a></li>
<li><a href="#typography-title"></a></li>
</ul>
</article>
<article id="columns">
<h2 id="columns-title">Big title on left page, with text on columns</h2>
<h3>This is a little subtitle, here to explain what we are talking about</h3>
<section>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam volutpat faucibus vestibulum.
Mauris varius orci quam. Nam dui mauris, dictum at elementum at, mollis pulvinar est.
Nunc lobortis pharetra erat, id rutrum lorem malesuada in.
</p>
<p>
Phasellus id nisl nec arcu tempor ultricies non id tortor. Mauris ex nibh, viverra vitae nisi eget, placerat pharetra est.
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed id maximus diam. Cras molestie nisl vitae iaculis convallis.
Vivamus molestie vitae nisl sed interdum. Nunc aliquam massa rhoncus finibus convallis.
Vivamus sed vulputate risus. Nunc dignissim magna velit, quis lobortis ex volutpat eget.
Proin dictum mauris condimentum consequat faucibus.
</p>
<p>
Duis maximus mauris ac purus eleifend, sit amet blandit nulla lacinia.
Maecenas massa dolor, suscipit at erat eget, maximus dignissim dolor. Praesent consectetur maximus libero, eu facilisis ligula finibus et.
Cras rhoncus eros sit amet lorem auctor, a efficitur leo tincidunt. Sed viverra interdum odio, eget pulvinar tortor blandit lacinia.
Praesent consequat congue commodo. Phasellus eu massa feugiat, imperdiet nisi a, sagittis ipsum.
</p>
<p>
Suspendisse et gravida nunc. Quisque at felis nisl. Nam eget efficitur nunc.
Vivamus fermentum imperdiet massa, porttitor elementum mauris faucibus scelerisque.
Pellentesque ut metus tortor. Fusce vulputate ex at turpis consectetur, in vestibulum odio placerat.
Suspendisse tempor sapien rutrum, cursus sem a, tincidunt odio. Sed in consequat augue.
Proin finibus felis neque, ac hendrerit lorem consequat nec.
</p>
<p>
Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Fusce quam mi, dapibus et augue sit amet, porttitor volutpat orci.
Vestibulum ac ligula at justo placerat pulvinar vel non velit. Duis vel iaculis nibh, non tristique lectus.
Phasellus vel ex bibendum, accumsan tellus a, commodo nisi.
</p>
<p>
Mauris tincidunt dolor ligula, et egestas lectus rutrum consectetur. Donec ac ex mollis, vestibulum libero in, convallis risus.
</p>
</section>
</article>
<article id="skills">
<h2 id="skills-title">This is another big title, on a page full of work presentation</h2>
<h3>We present you some of WeasyPrint's features.</h3>
<section id="table-content">
<h4>Table of contents</h4>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi mi ante, tincidunt quis vehicula
sed, vehicula sed augue. Cras eget ante turpis.
</p>
</section>
<section id="heading">
<h4>Heading titles and page counters</h4>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi mi ante, tincidunt quis vehicula
sed, vehicula sed augue. Cras eget ante turpis.
</p>
</section>
<section id="multi-columns">
<h4>Multi-column text</h4>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi mi ante, tincidunt quis vehicula
sed, vehicula sed augue. Cras eget ante turpis.
</p>
</section>
<section id="internal-links">
<h4>Internal links</h4>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi mi ante, tincidunt quis vehicula
sed, vehicula sed augue. Cras eget ante turpis.
</p>
</section>
<section id="style">
<h4>Different page types</h4>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi mi ante, tincidunt quis vehicula
sed, vehicula sed augue. Cras eget ante turpis.
</p>
</section>
</article>
<article id="offers">
<h2 id="offers-title">Big title on the first right page</h2>
<h3>Display offers using flex layout</h3>
<section>
<h4>Offer #1</h4>
<p>€135</p>
<ul>
<li>Lorem ipsum dolor sit amet.</li>
<li>Nullam at diam eget urna consequat.</li>
<li>Sed fringilla quam at augue semper aliquam.</li>
<li>Cras nec lacus eu turpis finibus vulputate.</li>
</ul>
</section>
<section>
<h4>Offer #2</h4>
<p>€175</p>
<ul>
<li>Lorem ipsum dolor sit amet.</li>
<li>Nullam at diam eget urna consequat.</li>
<li>Sed fringilla quam at augue semper aliquam.</li>
<li>Mauris viverra nulla vel semper mollis.</li>
<li>Nulla quis massa eu urna suscipit vehicula.</li>
<li>Curabitur a odio id risus pharetra iaculis.</li>
</ul>
</section>
<section>
<h4>Offer #3</h4>
<p>€200</p>
<ul>
<li>Lorem ipsum dolor sit amet.</li>
<li>Nullam at diam eget urna consequat.</li>
<li>Sed fringilla quam at augue semper aliquam.</li>
<li>Mauris viverra nulla vel semper mollis.</li>
<li>Cras nec lacus eu turpis finibus vulputate.</li>
<li>Nulla quis massa eu urna suscipit vehicula.</li>
<li>Curabitur a odio id risus pharetra iaculis.</li>
<li>Mauris viverra nulla vel semper mollis.</li>
<li>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</li>
</ul>
</section>
</article>
<article id="chapter">
<h2 id="chapter-title">This is a chapter of a new section</h2>
</article>
<article id="typography">
<h2 id="typography-title">About some typography features</h2>
<h3>Here is a showcase of several typography features</h3>
<section>
<h4>Italic and Bold Text</h4>
<p>
Lorem ipsum dolor <em>sit amet, consectetur adipiscing elit.</em> Ut
pulvinar dolor <strong>ac orci finibus elementum. Praesent</strong>
sit amet ligula turpis.
</p>
</section>
<section id="small-caps">
<h4>Small Caps Text</h4>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut pulvinar
dolor ac orci finibus elementum.
</p>
</section>
<section id="ligatures">
<h4>Ligatures</h4>
<dl>
<dt>Classical</dt>
<dd><span class="none">Offer</span> → <span class="common">Offer</span></dd>
<dt>Discretionary</dt>
<dd><span class="none">Often</span> → <span class="discretionary">Often</span></dd>
<dt>Contextual</dt>
<dd><span class="none">#&</span> → <span class="contextual">#&</span></dd>
</dl>
</section>
<section id="numbers">
<h4>Numbers</h4>
<dl>
<dt>Fractions</dt>
<dd>421/42 → <span id="fractions">421/42</span></dd>
<dt>Ordinals</dt>
<dd>2a 3o → <span id="ordinals">2a 3o</span></dd>
<dt>Slashed zero</dt>
<dd>1000 → <span id="slashed">1000</span></dd>
<dt>Superscript</dt>
<dd>a2 → <span id="super">a2</span></dd>
<dt>Subscript</dt>
<dd>C8H10N4O2 → <span id="sub">C8H10N4O2</span></dd>
</dl>
</section>
<section id="figures">
<h4>Figures</h4>
<dl>
<dt>Lining</dt>
<dd>
<ul>
<li>409,280</li>
<li>367,112</li>
</ul>
</dd>
<dt>Old-Style</dt>
<dd>
<ul id="oldstyle">
<li>409,280</li>
<li>367,112</li>
</ul>
</dd>
<dt>Tabular</dt>
<dd>
<ul id="tabular">
<li>409,280</li>
<li>367,112</li>
</ul>
</dd>
<dt>Old & Tab.</dt>
<dd>
<ul id="old-tabular">
<li>409,280</li>
<li>367,112</li>
</ul>
</dd>
</dl>
</section>
</article>
</body>
</html>
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Calque_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 56.7 56.7" style="enable-background:new 0 0 56.7 56.7;" xml:space="preserve">
<style type="text/css">
.st0{fill:none;stroke:#231F20;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;}
</style>
<rect x="12.4" y="6.1" class="st0" width="31.9" height="44.5"/>
<line class="st0" x1="16.4" y1="13.8" x2="40.2" y2="13.8"/>
<g>
<rect x="-85.5" y="-13" class="st0" width="31.9" height="44.5"/>
<line class="st0" x1="-81.4" y1="-6.3" x2="-71.1" y2="-6.3"/>
<line class="st0" x1="-81.4" y1="-0.1" x2="-71.1" y2="-0.1"/>
<line class="st0" x1="-81.4" y1="6.1" x2="-71.1" y2="6.1"/>
<line class="st0" x1="-81.4" y1="12.3" x2="-71.1" y2="12.3"/>
<line class="st0" x1="-81.4" y1="18.6" x2="-71.1" y2="18.6"/>
<line class="st0" x1="-81.4" y1="24.8" x2="-71.1" y2="24.8"/>
<line class="st0" x1="-60.8" y1="-6.3" x2="-57.6" y2="-6.3"/>
<line class="st0" x1="-60.8" y1="-0.1" x2="-57.6" y2="-0.1"/>
<line class="st0" x1="-60.8" y1="6.1" x2="-57.6" y2="6.1"/>
<line class="st0" x1="-60.8" y1="12.3" x2="-57.6" y2="12.3"/>
<line class="st0" x1="-60.8" y1="18.6" x2="-57.6" y2="18.6"/>
<line class="st0" x1="-60.8" y1="24.8" x2="-57.6" y2="24.8"/>
</g>
<line class="st0" x1="16.4" y1="20.9" x2="40.2" y2="20.9"/>
<line class="st0" x1="16.4" y1="28" x2="40.2" y2="28"/>
<line class="st0" x1="16.4" y1="35" x2="40.2" y2="35"/>
<line class="st0" x1="16.4" y1="42.1" x2="40.2" y2="42.1"/>
</svg>
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Calque_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 56.7 56.7" style="enable-background:new 0 0 56.7 56.7;" xml:space="preserve">
<style type="text/css">
.st0{fill:none;stroke:#231F20;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;}
</style>
<rect x="12.4" y="6.1" class="st0" width="31.9" height="44.5"/>
<line class="st0" x1="16.4" y1="12.8" x2="26.8" y2="12.8"/>
<line class="st0" x1="16.4" y1="19" x2="26.8" y2="19"/>
<line class="st0" x1="16.4" y1="25.2" x2="26.8" y2="25.2"/>
<line class="st0" x1="16.4" y1="31.5" x2="26.8" y2="31.5"/>
<line class="st0" x1="16.4" y1="37.7" x2="26.8" y2="37.7"/>
<line class="st0" x1="16.4" y1="43.9" x2="26.8" y2="43.9"/>
<line class="st0" x1="37" y1="12.8" x2="40.2" y2="12.8"/>
<line class="st0" x1="37" y1="19" x2="40.2" y2="19"/>
<line class="st0" x1="37" y1="25.2" x2="40.2" y2="25.2"/>
<line class="st0" x1="37" y1="31.5" x2="40.2" y2="31.5"/>
<line class="st0" x1="37" y1="37.7" x2="40.2" y2="37.7"/>
<line class="st0" x1="37" y1="43.9" x2="40.2" y2="43.9"/>
</svg>
/* Fonts */
@font-face {
font-family: Libre Barcode;
src: url(librebarcode128-regular.ttf);
}
@font-face {
font-family: Barlow Condensed;
src: url(barlowcondensed-regular.otf);
}
@font-face {
font-family: Barlow Condensed;
font-weight: 300;
src: url(barlowcondensed-light.otf);
}
@font-face {
font-family: Barlow Condensed;
font-weight: 700;
src: url(barlowcondensed-bold.otf);
}
/* Colors */
:root {
--black: #2A3239;
--grey: #eef1f5;
--white: #fff;
}
/* Page rules */
@page {
margin: 0;
size: landscape;
}
/* Style */
html {
align-content: center;
align-items: center;
background: var(--grey);
display: flex;
font-family: Barlow Condensed, sans-serif;
height: 100%;
justify-content: center;
}
body {
background: var(--white);
box-sizing: border-box;
color: var(--black);
display: flex;
flex-wrap: wrap;
height: 8cm;
justify-content: space-between;
margin: 0;
width: 25cm;
}
section {
box-sizing: border-box;
}
dl {
columns: 4;
text-align: center;
dt {
font-size: 9pt;
font-weight: 700;
text-transform: uppercase;
}
dd {
margin-left: 0;
}
}
ul {
align-items: center;
display: flex;
list-style: none;
margin: 0;
padding-left: 0;
li {
font-weight: 700;
text-transform: uppercase;
}
}
#informations {
flex: 1;
padding: 0;
position: relative;
h1 {
display: inline-block;
font-size: 25pt;
font-weight: 300;
text-transform: uppercase;
}
#name {
margin-left: 1cm;
}
#destination {
position: absolute;
right: 1cm;
}
dl {
background: var(--black);
color: var(--white);
margin: 0;
padding: 1cm 0;
dd {
border-left: 1pt solid var(--white);
font-size: 35pt;
&:first-of-type {
border-left: 0;
}
}
}
ul {
margin-left: 1cm;
li {
font-weight: 300;
padding: 0.15cm;
&:first-of-type {
background: var(--black);
border-radius: 4pt;
color: var(--white);
}
&:last-of-type {
font-family: Libre Barcode, cursive;
font-size: 25pt;
margin-left: auto;
padding-right: 1cm;
padding-top: 0.5cm;
}
}
}
}
#ticket {
border-left: 1pt dashed var(--black);
display: flex;
flex-direction: column;
height: 8cm;
justify-content: space-around;
padding: 0 1cm;
h2 {
font-weight: 300;
margin: 0;
text-transform: uppercase;
}
p {
font-family: Libre Barcode, cursive;
font-size: 25pt;
margin: 0;
text-align: center;
}
dl {
margin: 0;
}
li {
margin: 0 0.25cm;
}
}
<html>
<head>
<meta charset="utf-8">
<link href="ticket.css" rel="stylesheet">
<title>Boarding ticket</title>
<meta name="description" content="Boarding ticket">
</head>
<body>
<section id="informations">
<h1 id="name">Théodore Marcelin</h1>
<h1 id="destination">CDG ✈ LFLL</h1>
<dl>
<dt>Flight</dt>
<dd>DL31</dd>
<dt>Gate</dt>
<dd>29</dd>
<dt>Seat</dt>
<dd>26E</dd>
<dt>Zone</dt>
<dd>4</dd>
</dl>
<ul>
<li>5:10pm</li>
<li>Dec 15, 2018</li>
<li>Coach</li>
<li>1257797706706</li>
</ul>
</section>
<section id="ticket">
<p>1257797706706</p>
<h2>Théodore Marcelin</h2>
<dl>
<dt>Flight</dt>
<dd>DL31</dd>
<dt>Gate</dt>
<dd>29</dd>
<dt>Seat</dt>
<dd>26E</dd>
<dt>Zone</dt>
<dd>4</dd>
</dl>
<ul>
<li>CDG ✈ LFLL</li>
<li>5:10pm</li>
</ul>
</section>
</body>
</html>
Contribute
Source: https://doc.courtbouillon.org/weasyprint/stable/contribute.html
Contribute
You want to add some code to WeasyPrint, launch its tests or improve its documentation? Thank you very much! Here are some tips to help you play with WeasyPrint in good conditions.
The first step is to clone the repository, create a virtual environment and install WeasyPrint dependencies:
git clone https://github.com/Kozea/WeasyPrint.git
cd WeasyPrint
python -m venv venv
venv/bin/pip install -e '.[doc,test]'You can then launch Python to test your changes:
venv/bin/pythonRunning WeasyPrint might look something like this:
venv/bin/python -m weasyprint example.html example.pdfCode & Issues
If you’ve found a bug in WeasyPrint, it’s time to report it, and to fix it if you can!
You can report bugs and feature requests on GitHub. If you want to add or fix some code, please fork the repository and create a pull request, we’ll be happy to review your work.
You can find more information about the code architecture in the Dive into the Source section.
Tests
Tests are stored in the tests folder at the top of the repository. They use the pytest library.
Tests require Ghostscript to be installed and available on the local path. You should also install all the DejaVu fonts if you’re on Linux.
You can launch tests using the following command:
venv/bin/python -m pytestWeasyPrint also uses ruff to check the coding style:
venv/bin/python -m ruff checkDocumentation
Documentation is stored in the docs folder at the top of the repository. It relies on the Sphinx library.
You can build the documentation using the following command:
venv/bin/sphinx-build docs docs/_buildThe documentation home page can now be found in the /path/to/weasyprint/docs/_build/index.html file. You can open this file in a browser to see the final rendering.
WeasyPrint Documentation (scraped archive)
- Upstream: https://doc.courtbouillon.org/weasyprint/stable/
- Version: WeasyPrint 69.0 (stable)
- Scraped: 2026-06-10
- Total: ~282 KB / ~7913 lines
Agent Load Policy
Prefer flat expert lessons at `references/` root (resource-matrix.md catalog). Use this archive only as last resort when a lesson is insufficient.
| Rule | Detail |
|---|---|
| NEVER bulk-load | One section at a time |
| Prefer lessons | cli-basics.md, css-paged-media.md, pdf-a-archival.md, etc. |
| changelog.md | Latest version block only, ≤80 lines — or use debug-version-upgrades.md |
| api_reference.md | One section, ≤120 lines |
| Excluded | contribute.md, support.md |
Pages
| File | Lines | Size | Agent use |
|---|---|---|---|
| api_reference.md | 1214 | 62 KB | Last resort, ≤120 lines/section |
| changelog.md | 4817 | 146 KB | Last resort — prefer debug-version-upgrades.md |
| common_use_cases.md | 568 | 21 KB | Last resort, ≤120 lines/section |
| contribute.md | 78 | 2 KB | Do not load |
| first_steps.md | 640 | 23 KB | Last resort, ≤120 lines/section |
| going_further.md | 223 | 11 KB | Last resort — prefer debug-pipeline.md |
| index.md | 196 | 8 KB | TOC only |
| manpage.md | 155 | 5 KB | Last resort — prefer cli-basics.md |
| support.md | 22 | 0 KB | Do not load |
Refresh: python .resources/weasyprint/scripts/scrape_weasyprint_docs.py