index.html: drop unused .reveal.d6 rule (markup uses d1-d5 only).
CV_Bastien_Chanot.html:
- remove dead `position: running(siteFooter)` — no `element()` consumer,
and .footer-bar is `display:none` in @media print (the @page
auto-numbered footer replaces it); on screen running() is an invalid
position value, ignored.
- remove no-op `box-shadow: none` on .page (weasyprint ignores box-shadow;
.page sets a shadow nowhere).
- remove dead `.skills-grid { font-size: 8.4pt }` (every direct child is a
.skill-label/.skill-values div that sets its own size; no bare text).
- normalize stray blank lines.
Behavior-preserving: PDF regenerated from the edited HTML is byte-identical
to the pre-edit baseline (text sha256 + per-page PNG render hash match),
so CV_Bastien_Chanot.pdf is unchanged and the PDF=HTML invariant holds.
CLAUDE.md palette now two enforceable lists (6 brand + 8 documented
neutrals — anything else is a violation); workflow gains the recompute-
CSP-hash-after-JS-edit invariant with the exact command. README points to
the neutrals list. TOUR.md follow-up: CLN-3/CLN-4/SEC-7 closed, INF-2
corrected (false positive — .gitignore exists).
Shared chrome/hover/head/title/tag blocks for stack/project/theme cards +
methode items; per-class blocks keep only specifics. Zero HTML change,
cascade-order verified (no interfering rules between shared and specific
blocks). Net -60 lines; the audit's ~421 estimate was overstated.
- 5x background:#fff -> var(--page) (stack/project/theme/methode cards +
CV body) per CLAUDE.md 'no pure white background' (user-approved strict
conformity; visual change: cards now blend with parchment, border-kept)
- prefers-reduced-motion now also kills transitions (universal rule)
- dead .screen-label rule removed (no matching element)
- PDF regenerated via weasyprint (must match HTML invariant)
- base image -> nginxinc/nginx-unprivileged:1.28-alpine, digest-pinned
(BREAKING for the docker path: container port 80 -> 8080; compose
mapping/healthcheck updated in the same change, cap_add dropped)
- nginx add_header inheritance fix: shared snippets file re-included in
every location that sets Cache-Control -- previously ALL security
headers were dropped on real responses (verified live before/after)
- server_tokens off; set_real_ip_from restricted to 127.0.0.1
- expires directives removed (duplicated Cache-Control); gzip_types
text/html redundancy removed (nginx -t warn)
Root cause + fix logged. New repo assets must be added to Dockerfile
COPY whitelist explicitly; future option = glob pattern if asset count
grows. Journal updated.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Dockerfile selectively COPYs files into /usr/share/nginx/html. Favicon
assets (favicon.svg, favicon-32.png, favicon.ico, apple-touch-icon.png)
were added to the repo in ef31fb3 but never wired into the Dockerfile,
so a rebuilt container served 404 for /favicon.svg and friends — broken
favicon in prod even after `docker compose up -d --build`.
nginx.conf gets a matching long-cache rule for icon/image assets
(30 days, immutable, access_log off) — they rarely change and the file
name is the cache key anyway.
Deploy: on the VPS, `docker compose up -d --build`.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Brand pulse-dot translated to favicon: dark rounded square (#0d1b12) +
inner green dot (#6ab98a) + faint outer ring (#2d7a4f @60%). Identical
visual language to .brand::before in the nav.
Assets:
- favicon.svg — vector primary (modern browsers, scales)
- favicon-32.png — PNG hint
- favicon.ico — legacy multi-size (16/24/32/48)
- apple-touch-icon.png — iOS home-screen 180x180
PIL-generated PNG/ICO at 8x supersample + Lanczos downscale for clean
antialiasing. No external dependency added (PIL already on system).
index.html: 4 <link> tags wired in <head> (SVG, PNG 32, ICO alternate,
apple-touch). CV HTML left untouched; browser auto-fetches /favicon.ico
from root as fallback — TODO logged to mirror the link block when the
user finalizes CV edits.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Section title now anchors the "bas niveau" thread across both schools.
- Section intro: drop <em> for consistency with other section-intro blocks.
- École 42 description rewritten to surface kernel/memory/shell/security focus.
- TSRIT: remove false claim about stage transformed into CDI at CareGame
(CareGame internship dates from 2018-2019 during 42, not 2015 TSRIT).
Co-Authored-By: Claude <noreply@anthropic.com>
- New <section id="formation"> between Parcours and Contact, reusing timeline
+ card visual components from the existing system (palette, typos, animations).
- École 42 (2015–2019): 3 theme cards (Systèmes & Kernel · Bas niveau & Outils
système · Sécurité & Algorithmie) with project list + concise technical proof
for each entry (no scolarisms).
- TSRIT — Next Formation (2013–2015): BTS + "Félicitations du jury" badge,
réseau/TCP-IP/admin Linux fundamentals, stage transformed into CareGame CDI.
- Nav: "Formation" link inserted between Parcours and Contact.
- Contact: removed the old <aside class="contact-side"> Formation block and
the now-unused .contact-side / .education / 2-col contact-grid CSS;
.contact-list becomes 2-col on >=768px to fill the freed space.
Co-Authored-By: Claude <noreply@anthropic.com>
Add Dockerfile (nginx:1.27-alpine), nginx.conf (gzip, cache, CSP and
security headers, no HSTS — left to outer proxy), and docker-compose
service `bchanot-web`. Host port is configurable via PORT env var
(default 8080) and bound to 127.0.0.1 so the container sits behind a
reverse proxy. Container hardened with read_only fs, cap_drop ALL,
no-new-privileges, and tmpfs for nginx runtime dirs. Healthcheck via
wget on /. Also adds .dockerignore and .env.example, and ignores .env.
Usage:
cp .env.example .env
docker compose up -d --build
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Single-page static site at bchanot.fr: landing (index.html) and CV
(HTML + PDF), pure HTML/CSS/JS, no build step. Includes project
conventions (CLAUDE.md), README, and .claude/ memory/tasks/audits
scaffolding.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>