chore(clean): dedup CV/index CSS, drop dead directives (tour F1-F8)

CV: shared block for xp/project/edu headers + date chips + roles + tags,
2 identical inline style attrs -> .inline-link class, no-op body margin/
padding removed, stray blank collapsed. Proven behavior-preserving: PDF
text-hash + per-page render-hash + full byte-identity vs committed PDF.
index: .stack-note/.theme-list code grouped, 2 no-op .formation overrides
removed. nginx.conf: dead 'deny all' after return 404 removed (nginx -t +
dotfile-404 oracle PASS). .dockerignore: phantom nginx.conf.bak entry.
Snippet comment: CV style attrs no longer exist. CSP hash unchanged.
This commit is contained in:
Bastien Chanot
2026-07-05 22:52:39 +02:00
parent 1aa97f0af0
commit 613bfc0d49
5 changed files with 45 additions and 99 deletions
-1
View File
@@ -11,7 +11,6 @@ docker-compose.yml
.dockerignore .dockerignore
.env .env
.env.example .env.example
nginx.conf.bak
# Editor / OS noise # Editor / OS noise
*.swp *.swp
+41 -82
View File
@@ -40,8 +40,6 @@
background: var(--page); background: var(--page);
font-family: var(--sans); font-family: var(--sans);
-webkit-font-smoothing: antialiased; -webkit-font-smoothing: antialiased;
margin: 0;
padding: 0;
} }
.page { .page {
@@ -174,15 +172,46 @@
background: var(--rule); background: var(--rule);
} }
/* ── XP ── */ /* ── SHARED (xp/project/edu headers, date chips, roles, tags, links) ── */
.xp-block { margin-bottom: 6px; } .xp-header, .project-header, .edu-header {
.xp-header {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
align-items: baseline; align-items: baseline;
margin-bottom: 1px;
} }
.xp-header, .project-header { margin-bottom: 1px; }
.xp-dates, .project-dates, .edu-dates {
font-family: var(--mono);
color: var(--ink-3);
background: var(--tag);
padding: 1px 6px;
border-radius: 2px;
}
.xp-role, .edu-degree {
font-size: 10pt;
font-weight: 500;
color: var(--g700);
margin-bottom: 3px;
}
.lang-item, .interest-tag {
font-family: var(--mono);
font-size: 8.5pt;
color: var(--g900);
background: var(--g100);
padding: 2px 8px;
border-radius: 10px;
}
.inline-link {
color: var(--g500);
text-decoration: none;
border-bottom: 1px solid var(--g300);
}
/* ── XP ── */
.xp-block { margin-bottom: 6px; }
.xp-company { .xp-company {
font-family: var(--mono); font-family: var(--mono);
@@ -191,22 +220,7 @@
color: var(--ink-1); color: var(--ink-1);
} }
.xp-dates { .xp-dates { font-size: 8.5pt; white-space: nowrap; }
font-family: var(--mono);
font-size: 8.5pt;
color: var(--ink-3);
white-space: nowrap;
background: var(--tag);
padding: 1px 6px;
border-radius: 2px;
}
.xp-role {
font-size: 10pt;
font-weight: 500;
color: var(--g700);
margin-bottom: 3px;
}
.xp-loc { .xp-loc {
font-size: 7.5pt; font-size: 7.5pt;
@@ -259,13 +273,6 @@
/* ── PROJECTS ── */ /* ── PROJECTS ── */
.project-block { margin-bottom: 5px; } .project-block { margin-bottom: 5px; }
.project-header {
display: flex;
justify-content: space-between;
align-items: baseline;
margin-bottom: 1px;
}
.project-name { .project-name {
font-family: var(--mono); font-family: var(--mono);
font-size: 10.5pt; font-size: 10.5pt;
@@ -280,15 +287,7 @@
font-style: italic; font-style: italic;
} }
.project-dates { .project-dates { font-size: 8pt; white-space: nowrap; }
font-family: var(--mono);
font-size: 8pt;
color: var(--ink-3);
white-space: nowrap;
background: var(--tag);
padding: 1px 6px;
border-radius: 2px;
}
.project-desc { .project-desc {
font-size: 10pt; font-size: 10pt;
@@ -328,12 +327,6 @@
/* ── EDU ── */ /* ── EDU ── */
.edu-block { margin-bottom: 5px; } .edu-block { margin-bottom: 5px; }
.edu-header {
display: flex;
justify-content: space-between;
align-items: baseline;
}
.edu-school { .edu-school {
font-family: var(--mono); font-family: var(--mono);
font-size: 11.5pt; font-size: 11.5pt;
@@ -341,21 +334,7 @@
color: var(--ink-1); color: var(--ink-1);
} }
.edu-dates { .edu-dates { font-size: 7.2pt; }
font-family: var(--mono);
font-size: 7.2pt;
color: var(--ink-3);
background: var(--tag);
padding: 1px 6px;
border-radius: 2px;
}
.edu-degree {
font-size: 10pt;
font-weight: 500;
color: var(--g700);
margin-bottom: 3px;
}
.edu-detail { .edu-detail {
font-size: 10pt; font-size: 10pt;
@@ -373,15 +352,6 @@
.lang-row { display: flex; gap: 4px; flex-wrap: wrap; } .lang-row { display: flex; gap: 4px; flex-wrap: wrap; }
.lang-item {
font-family: var(--mono);
font-size: 8.5pt;
color: var(--g900);
background: var(--g100);
padding: 2px 8px;
border-radius: 10px;
}
.lang-item .level { .lang-item .level {
color: var(--ink-3); color: var(--ink-3);
font-size: 7.5pt; font-size: 7.5pt;
@@ -389,15 +359,6 @@
.interests { display: flex; flex-wrap: wrap; gap: 4px; } .interests { display: flex; flex-wrap: wrap; gap: 4px; }
.interest-tag {
font-family: var(--mono);
font-size: 8.5pt;
color: var(--g900);
background: var(--g100);
padding: 2px 8px;
border-radius: 10px;
}
/* ── FOOTER ── */ /* ── FOOTER ── */
.footer-bar { .footer-bar {
background: var(--dark); background: var(--dark);
@@ -427,7 +388,6 @@
background: background:
url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='6' height='6'%3E%3Ccircle cx='1' cy='1' r='0.6' fill='rgba(27,94,59,0.05)'/%3E%3C/svg%3E"), url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='6' height='6'%3E%3Ccircle cx='1' cy='1' r='0.6' fill='rgba(27,94,59,0.05)'/%3E%3C/svg%3E"),
linear-gradient(160deg, var(--page) 0%, var(--tag) 55%, var(--page) 100%); linear-gradient(160deg, var(--page) 0%, var(--tag) 55%, var(--page) 100%);
padding: 0;
} }
.page { background: transparent; } .page { background: transparent; }
.cv-header { padding: 18px 14mm 14px; } .cv-header { padding: 18px 14mm 14px; }
@@ -488,7 +448,6 @@
</head> </head>
<body> <body>
<div class="page"> <div class="page">
<div class="cv-header"> <div class="cv-header">
@@ -525,7 +484,7 @@
<span class="xp-company">ZenQuality</span> <span class="xp-company">ZenQuality</span>
<span class="xp-dates">Apr 2026 - present</span> <span class="xp-dates">Apr 2026 - present</span>
</div> </div>
<div class="xp-role">Développeur indépendant <span class="xp-loc">· Yerres · <a href="https://zenquality.fr" style="color:var(--g500);text-decoration:none;border-bottom:1px solid var(--g300);">zenquality.fr</a></span></div> <div class="xp-role">Développeur indépendant <span class="xp-loc">· Yerres · <a href="https://zenquality.fr" class="inline-link">zenquality.fr</a></span></div>
<ul class="bullets"> <ul class="bullets">
<li>Mission SEO et conformité légale RGPD pour PME service (Île-de-France) — audit technique Core Web Vitals + Schema.org + NAP, refonte CGV B2B/B2C, RGPD, mentions légales, mise en conformité médiateur CM2C. Plan d'action 12 sprints.</li> <li>Mission SEO et conformité légale RGPD pour PME service (Île-de-France) — audit technique Core Web Vitals + Schema.org + NAP, refonte CGV B2B/B2C, RGPD, mentions légales, mise en conformité médiateur CM2C. Plan d'action 12 sprints.</li>
<li>Site vitrine WordPress (<span class="tag">Gutenverse</span>) pour PME esthétique — conception, intégration, déploiement et support continu (hébergement client).</li> <li>Site vitrine WordPress (<span class="tag">Gutenverse</span>) pour PME esthétique — conception, intégration, déploiement et support continu (hébergement client).</li>
@@ -582,7 +541,7 @@
<div class="project-desc"> <div class="project-desc">
Configuration Claude Code, dotfiles, projets bas-niveau (42, expérimentations C/Rust) — accessibles publiquement. Mirror automatique vers GitHub via push hook. Configuration Claude Code, dotfiles, projets bas-niveau (42, expérimentations C/Rust) — accessibles publiquement. Mirror automatique vers GitHub via push hook.
</div> </div>
<div class="project-link"><a href="https://git.bchanot.fr/bchanot" style="color:var(--g500);text-decoration:none;border-bottom:1px solid var(--g300);">git.bchanot.fr/bchanot</a></div> <div class="project-link"><a href="https://git.bchanot.fr/bchanot" class="inline-link">git.bchanot.fr/bchanot</a></div>
</div> </div>
<div class="project-block"> <div class="project-block">
+3 -14
View File
@@ -502,16 +502,16 @@
gap: 8px; gap: 8px;
flex-wrap: wrap; flex-wrap: wrap;
} }
.stack-note code { .stack-note code, .theme-list code {
font-family: var(--mono); font-family: var(--mono);
font-size: 12px; font-size: 12px;
font-weight: 500; font-weight: 500;
color: var(--g700); color: var(--g700);
background: var(--g050); background: var(--g050);
border: 1px solid var(--g100); border: 1px solid var(--g100);
padding: 2px 8px;
border-radius: var(--r-sm); border-radius: var(--r-sm);
} }
.stack-note code { padding: 2px 8px; }
@media (min-width: 768px) { .stack-grid { grid-template-columns: repeat(2, 1fr); } } @media (min-width: 768px) { .stack-grid { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1200px) { .stack-grid { grid-template-columns: repeat(3, 1fr); } } @media (min-width: 1200px) { .stack-grid { grid-template-columns: repeat(3, 1fr); } }
@@ -697,8 +697,6 @@
/* ── FORMATION ── */ /* ── FORMATION ── */
.formation { background: var(--g050); } .formation { background: var(--g050); }
.formation .timeline { border-left-color: var(--g100); }
.formation .timeline-item::before { box-shadow: 0 0 0 4px var(--g050); }
.formation-school-desc { .formation-school-desc {
font-family: var(--serif); font-family: var(--serif);
@@ -758,16 +756,7 @@
line-height: 1.55; line-height: 1.55;
color: var(--ink-2); color: var(--ink-2);
} }
.theme-list code { .theme-list code { padding: 1px 7px; }
font-family: var(--mono);
font-size: 12px;
font-weight: 500;
color: var(--g700);
background: var(--g050);
border: 1px solid var(--g100);
padding: 1px 7px;
border-radius: var(--r-sm);
}
.formation-tsrit-list { .formation-tsrit-list {
list-style: none; list-style: none;
+1 -1
View File
@@ -8,7 +8,7 @@ add_header X-Content-Type-Options "nosniff" always;
add_header X-Frame-Options "SAMEORIGIN" always; add_header X-Frame-Options "SAMEORIGIN" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always; add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Permissions-Policy "geolocation=(), microphone=(), camera=(), payment=()" always; add_header Permissions-Policy "geolocation=(), microphone=(), camera=(), payment=()" always;
# CSP: inline CSS allowed (style attributes in the CV + single-file convention); # CSP: inline CSS allowed (single-file convention: inline <style> element);
# the inline script is HASH-pinned (no script unsafe-inline). INVARIANT: after # the inline script is HASH-pinned (no script unsafe-inline). INVARIANT: after
# ANY edit to index.html's inline <script>, recompute the hash (command in # ANY edit to index.html's inline <script>, recompute the hash (command in
# CLAUDE.md) and update it here — a stale hash silently disables the JS. # CLAUDE.md) and update it here — a stale hash silently disables the JS.
-1
View File
@@ -64,7 +64,6 @@ server {
# Block access to dotfiles (defense-in-depth — none are shipped anyway). # Block access to dotfiles (defense-in-depth — none are shipped anyway).
location ~ /\. { location ~ /\. {
deny all;
return 404; return 404;
} }