Some checks failed
Build & Deploy / build-and-deploy (push) Has been cancelled
Dockerfile (nginx alpine), K3s manifests (cv namespace, NodePort 30111), Gitea Actions workflow for build + rollout. Targets cv.arthurbarre.fr. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
1121 lines
46 KiB
HTML
1121 lines
46 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="fr">
|
||
<head>
|
||
<meta charset="UTF-8" />
|
||
<title>Arthur Barré — Fullstack Developer</title>
|
||
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
||
<link href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;500;700&family=Inter:wght@300;400;500;600&display=swap" rel="stylesheet" />
|
||
<style>
|
||
:root {
|
||
--bg: #F4F2EC;
|
||
--ink: #0A0A0A;
|
||
--muted: #6B6B66;
|
||
--accent: #FF4D00;
|
||
--line: #0A0A0A;
|
||
}
|
||
* { box-sizing: border-box; }
|
||
html, body {
|
||
margin: 0; padding: 0;
|
||
background: var(--bg);
|
||
color: var(--ink);
|
||
font-family: 'Inter', system-ui, sans-serif;
|
||
-webkit-font-smoothing: antialiased;
|
||
font-size: 9pt;
|
||
line-height: 1.45;
|
||
}
|
||
a { color: inherit; text-decoration: none; }
|
||
|
||
/* ---------- PAGE ---------- */
|
||
.page {
|
||
width: 210mm;
|
||
min-height: 297mm;
|
||
padding: 8mm;
|
||
margin: 0 auto;
|
||
background: var(--bg);
|
||
position: relative;
|
||
}
|
||
.frame {
|
||
border: 1px solid var(--ink);
|
||
min-height: calc(297mm - 16mm);
|
||
display: flex;
|
||
flex-direction: column;
|
||
}
|
||
|
||
/* ---------- TOPBAR ---------- */
|
||
.topbar {
|
||
display: grid;
|
||
grid-template-columns: 1fr 1fr 1fr 1fr;
|
||
border-bottom: 1px solid var(--ink);
|
||
font-family: 'JetBrains Mono', ui-monospace, monospace;
|
||
font-size: 7.5pt;
|
||
letter-spacing: 0.08em;
|
||
text-transform: uppercase;
|
||
color: var(--muted);
|
||
}
|
||
.topbar > div {
|
||
padding: 8px 12px;
|
||
border-right: 1px solid var(--ink);
|
||
}
|
||
.topbar > div:last-child { border-right: none; text-align: right; }
|
||
.topbar .val { color: var(--ink); display: block; margin-top: 2px; }
|
||
.topbar .accent { color: var(--accent); }
|
||
|
||
/* ---------- LABEL ---------- */
|
||
.label {
|
||
font-family: 'JetBrains Mono', ui-monospace, monospace;
|
||
font-size: 7.5pt;
|
||
letter-spacing: 0.08em;
|
||
text-transform: uppercase;
|
||
color: var(--muted);
|
||
}
|
||
|
||
/* ---------- HERO ---------- */
|
||
.hero {
|
||
display: grid;
|
||
grid-template-columns: 7fr 5fr;
|
||
border-bottom: 1px solid var(--ink);
|
||
}
|
||
.hero-left {
|
||
border-right: 1px solid var(--ink);
|
||
padding: 18px 22px;
|
||
}
|
||
.hero h1 {
|
||
font-family: 'Inter', sans-serif;
|
||
font-weight: 300;
|
||
font-size: 56pt;
|
||
line-height: 0.92;
|
||
letter-spacing: -0.04em;
|
||
margin: 10px 0 0;
|
||
}
|
||
.hero h1 em {
|
||
font-style: italic;
|
||
color: var(--accent);
|
||
font-weight: 300;
|
||
}
|
||
.hero-meta {
|
||
display: grid;
|
||
grid-template-columns: repeat(4, 1fr);
|
||
gap: 14px;
|
||
margin-top: 24px;
|
||
font-family: 'JetBrains Mono', ui-monospace, monospace;
|
||
font-size: 8pt;
|
||
letter-spacing: 0.06em;
|
||
text-transform: uppercase;
|
||
}
|
||
.hero-meta .k { color: var(--muted); margin-bottom: 3px; }
|
||
.hero-meta .v { color: var(--ink); }
|
||
.hero-meta .v.accent { color: var(--accent); }
|
||
|
||
.hero-right {
|
||
display: flex;
|
||
flex-direction: column;
|
||
}
|
||
.hero-cell {
|
||
padding: 14px 18px;
|
||
border-bottom: 1px solid var(--ink);
|
||
flex: 1;
|
||
display: flex;
|
||
flex-direction: column;
|
||
justify-content: space-between;
|
||
min-height: 90px;
|
||
}
|
||
.hero-cell:last-child { border-bottom: none; }
|
||
.hero-cell .tag {
|
||
font-family: 'JetBrains Mono', ui-monospace, monospace;
|
||
font-size: 8pt;
|
||
letter-spacing: 0.08em;
|
||
}
|
||
.hero-cell .big {
|
||
font-size: 22pt;
|
||
font-weight: 300;
|
||
letter-spacing: -0.02em;
|
||
margin-top: 8px;
|
||
}
|
||
.hero-cell .big .accent { color: var(--accent); }
|
||
|
||
/* Specimen photo */
|
||
.specimen-cell { padding: 12px 14px; flex: 0 0 auto; }
|
||
.specimen-header { display: flex; justify-content: space-between; align-items: flex-start; }
|
||
.specimen-photo-wrap {
|
||
position: relative;
|
||
margin-top: 8px;
|
||
border: 1px solid var(--ink);
|
||
overflow: hidden;
|
||
aspect-ratio: 1 / 1;
|
||
width: 100%;
|
||
background: #fff;
|
||
}
|
||
.specimen-photo {
|
||
width: 100%;
|
||
height: 100%;
|
||
object-fit: cover;
|
||
display: block;
|
||
filter: grayscale(0.15) contrast(1.02);
|
||
}
|
||
.specimen-corner {
|
||
position: absolute;
|
||
font-family: 'JetBrains Mono', ui-monospace, monospace;
|
||
font-size: 8pt;
|
||
letter-spacing: 0.08em;
|
||
background: var(--bg);
|
||
color: var(--ink);
|
||
padding: 2px 5px;
|
||
border: 1px solid var(--ink);
|
||
line-height: 1;
|
||
}
|
||
.specimen-corner.tl { top: 6px; left: 6px; }
|
||
.specimen-corner.br { bottom: 6px; right: 6px; color: var(--accent); border-color: var(--accent); }
|
||
|
||
/* ---------- SECTION HEADER ---------- */
|
||
.section-header {
|
||
display: grid;
|
||
grid-template-columns: 80px 1fr 160px 80px;
|
||
border-bottom: 1px solid var(--ink);
|
||
font-family: 'JetBrains Mono', ui-monospace, monospace;
|
||
font-size: 7.5pt;
|
||
letter-spacing: 0.08em;
|
||
text-transform: uppercase;
|
||
color: var(--muted);
|
||
}
|
||
.section-header > div {
|
||
padding: 10px 12px;
|
||
border-right: 1px solid var(--ink);
|
||
}
|
||
.section-header > div:last-child { border-right: none; text-align: right; }
|
||
.section-header .title { color: var(--ink); }
|
||
|
||
/* ---------- ROW (job / project) ---------- */
|
||
.row {
|
||
display: grid;
|
||
grid-template-columns: 80px 1fr 200px;
|
||
border-bottom: 1px solid var(--ink);
|
||
page-break-inside: avoid;
|
||
}
|
||
.row .num {
|
||
padding: 14px 12px;
|
||
border-right: 1px solid var(--ink);
|
||
font-family: 'JetBrains Mono', ui-monospace, monospace;
|
||
font-size: 10pt;
|
||
color: var(--ink);
|
||
}
|
||
.row .body {
|
||
padding: 14px 16px;
|
||
border-right: 1px solid var(--ink);
|
||
}
|
||
.row .body h3 {
|
||
margin: 0;
|
||
font-family: 'Inter', sans-serif;
|
||
font-weight: 400;
|
||
font-size: 14pt;
|
||
letter-spacing: -0.015em;
|
||
line-height: 1.1;
|
||
}
|
||
.row .body .company {
|
||
font-family: 'JetBrains Mono', ui-monospace, monospace;
|
||
font-size: 8pt;
|
||
text-transform: uppercase;
|
||
letter-spacing: 0.06em;
|
||
color: var(--accent);
|
||
margin-top: 4px;
|
||
}
|
||
.row .body .desc {
|
||
margin-top: 8px;
|
||
font-size: 8.5pt;
|
||
line-height: 1.45;
|
||
color: var(--ink);
|
||
max-width: 64ch;
|
||
}
|
||
.row .body ul {
|
||
margin: 6px 0 0;
|
||
padding-left: 14px;
|
||
font-size: 8.5pt;
|
||
line-height: 1.5;
|
||
}
|
||
.row .body ul li { margin: 2px 0; }
|
||
.row .body ul li b { font-weight: 600; }
|
||
.row .meta {
|
||
padding: 14px 14px;
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: 8px;
|
||
}
|
||
.row .meta .period {
|
||
font-family: 'JetBrains Mono', ui-monospace, monospace;
|
||
font-size: 8pt;
|
||
letter-spacing: 0.06em;
|
||
text-transform: uppercase;
|
||
color: var(--ink);
|
||
}
|
||
.row .meta .where {
|
||
font-family: 'JetBrains Mono', ui-monospace, monospace;
|
||
font-size: 7.5pt;
|
||
letter-spacing: 0.08em;
|
||
text-transform: uppercase;
|
||
color: var(--muted);
|
||
}
|
||
.stack-chips {
|
||
margin-top: 4px;
|
||
display: flex;
|
||
flex-wrap: wrap;
|
||
gap: 4px;
|
||
}
|
||
.chip {
|
||
display: inline-block;
|
||
border: 1px solid var(--ink);
|
||
border-radius: 999px;
|
||
padding: 1px 7px;
|
||
font-family: 'JetBrains Mono', ui-monospace, monospace;
|
||
font-size: 7pt;
|
||
letter-spacing: 0.04em;
|
||
text-transform: uppercase;
|
||
color: var(--ink);
|
||
}
|
||
.chip.accent { color: var(--accent); border-color: var(--accent); }
|
||
|
||
/* ---------- PITCH STRIP (compact) ---------- */
|
||
.pitch-strip {
|
||
display: grid;
|
||
grid-template-columns: 110px 1fr;
|
||
align-items: center;
|
||
border-bottom: 1px solid var(--ink);
|
||
padding: 10px 18px;
|
||
gap: 16px;
|
||
}
|
||
.pitch-strip .pitch-label {
|
||
font-family: 'JetBrains Mono', ui-monospace, monospace;
|
||
font-size: 7.5pt;
|
||
letter-spacing: 0.08em;
|
||
text-transform: uppercase;
|
||
color: var(--muted);
|
||
}
|
||
.pitch-strip .pitch-text {
|
||
margin: 0;
|
||
font-size: 9pt;
|
||
line-height: 1.45;
|
||
color: var(--ink);
|
||
}
|
||
.pitch-strip .pitch-text b { font-weight: 600; }
|
||
.pitch-strip .pitch-text .accent { color: var(--accent); font-weight: 500; }
|
||
|
||
/* ---------- ABOUT (legacy, no longer used) ---------- */
|
||
.about {
|
||
display: grid;
|
||
grid-template-columns: 3fr 4fr 5fr;
|
||
border-bottom: 1px solid var(--ink);
|
||
}
|
||
.about > div {
|
||
padding: 18px 20px;
|
||
border-right: 1px solid var(--ink);
|
||
}
|
||
.about > div:last-child { border-right: none; }
|
||
.about h2 {
|
||
margin: 12px 0 0;
|
||
font-family: 'Inter', sans-serif;
|
||
font-weight: 400;
|
||
font-size: 18pt;
|
||
letter-spacing: -0.015em;
|
||
line-height: 1.1;
|
||
}
|
||
.about p {
|
||
margin: 12px 0 0;
|
||
font-size: 9pt;
|
||
line-height: 1.55;
|
||
max-width: 46ch;
|
||
}
|
||
.stack-grid {
|
||
margin-top: 12px;
|
||
display: grid;
|
||
grid-template-columns: 1fr 1fr;
|
||
border-top: 1px solid var(--ink);
|
||
}
|
||
.stack-grid > div {
|
||
padding: 7px 10px;
|
||
border-bottom: 1px solid var(--ink);
|
||
font-family: 'JetBrains Mono', ui-monospace, monospace;
|
||
font-size: 7.5pt;
|
||
letter-spacing: 0.04em;
|
||
text-transform: uppercase;
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 8px;
|
||
}
|
||
.stack-grid > div:nth-child(2n+1) { border-right: 1px solid var(--ink); }
|
||
.dot { width: 6px; height: 6px; border-radius: 50%; background: var(--ink); flex: none; }
|
||
.dot.accent { background: var(--accent); }
|
||
|
||
/* ---------- EDU ---------- */
|
||
.edu-row {
|
||
display: grid;
|
||
grid-template-columns: 80px 1fr 1fr 200px;
|
||
border-bottom: 1px solid var(--ink);
|
||
page-break-inside: avoid;
|
||
}
|
||
.edu-row > div {
|
||
padding: 14px 14px;
|
||
border-right: 1px solid var(--ink);
|
||
}
|
||
.edu-row > div:last-child { border-right: none; }
|
||
.edu-row .num {
|
||
font-family: 'JetBrains Mono', ui-monospace, monospace;
|
||
font-size: 10pt;
|
||
}
|
||
.edu-row .degree {
|
||
font-family: 'JetBrains Mono', ui-monospace, monospace;
|
||
font-size: 8pt;
|
||
letter-spacing: 0.06em;
|
||
text-transform: uppercase;
|
||
color: var(--muted);
|
||
}
|
||
.edu-row h3 {
|
||
margin: 4px 0 0;
|
||
font-family: 'Inter', sans-serif;
|
||
font-weight: 400;
|
||
font-size: 13pt;
|
||
letter-spacing: -0.01em;
|
||
}
|
||
.edu-row .desc {
|
||
font-size: 8.5pt;
|
||
line-height: 1.45;
|
||
color: var(--ink);
|
||
}
|
||
.edu-row .meta-cell {
|
||
font-family: 'JetBrains Mono', ui-monospace, monospace;
|
||
font-size: 8pt;
|
||
letter-spacing: 0.06em;
|
||
text-transform: uppercase;
|
||
}
|
||
.edu-row .meta-cell .where { color: var(--accent); margin-top: 4px; display: block; }
|
||
|
||
/* ---------- HOBBIES ---------- */
|
||
.hobbies {
|
||
display: grid;
|
||
grid-template-columns: repeat(4, 1fr);
|
||
border-bottom: 1px solid var(--ink);
|
||
}
|
||
.hobbies > div {
|
||
padding: 16px 16px;
|
||
border-right: 1px solid var(--ink);
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: 6px;
|
||
}
|
||
.hobbies > div:last-child { border-right: none; }
|
||
.hobbies .h-title {
|
||
font-family: 'Inter', sans-serif;
|
||
font-size: 11pt;
|
||
font-weight: 400;
|
||
letter-spacing: -0.01em;
|
||
}
|
||
.hobbies .h-desc {
|
||
font-size: 8.5pt;
|
||
color: var(--ink);
|
||
line-height: 1.4;
|
||
}
|
||
.hobbies .h-time {
|
||
font-family: 'JetBrains Mono', ui-monospace, monospace;
|
||
font-size: 8pt;
|
||
letter-spacing: 0.06em;
|
||
text-transform: uppercase;
|
||
color: var(--accent);
|
||
margin-top: auto;
|
||
}
|
||
|
||
/* ---------- FOOTER ---------- */
|
||
.footer {
|
||
margin-top: auto;
|
||
display: grid;
|
||
grid-template-columns: 1fr 1fr 1fr 1fr;
|
||
font-family: 'JetBrains Mono', ui-monospace, monospace;
|
||
font-size: 7.5pt;
|
||
letter-spacing: 0.08em;
|
||
text-transform: uppercase;
|
||
color: var(--muted);
|
||
}
|
||
.footer > div {
|
||
padding: 10px 12px;
|
||
border-right: 1px solid var(--ink);
|
||
}
|
||
.footer > div:last-child { border-right: none; text-align: right; }
|
||
.footer .k { color: var(--ink); }
|
||
|
||
/* ---------- PROJECT URL ---------- */
|
||
.url-mono {
|
||
display: inline-block;
|
||
font-family: 'JetBrains Mono', ui-monospace, monospace;
|
||
font-size: 8pt;
|
||
color: var(--accent);
|
||
margin-top: 4px;
|
||
}
|
||
|
||
/* ---------- PRINT ---------- */
|
||
@page { size: A4; margin: 0; }
|
||
@media print {
|
||
body { background: var(--bg); -webkit-print-color-adjust: exact; print-color-adjust: exact; }
|
||
.page {
|
||
width: 210mm;
|
||
height: 297mm;
|
||
page-break-after: always;
|
||
break-after: page;
|
||
page-break-inside: avoid;
|
||
break-inside: avoid;
|
||
margin: 0;
|
||
overflow: hidden;
|
||
}
|
||
.page:last-child { page-break-after: auto; break-after: auto; }
|
||
.frame { height: calc(297mm - 16mm); }
|
||
.row, article, .section-header, .topbar, .hero { page-break-inside: avoid; break-inside: avoid; }
|
||
|
||
/* Global print compaction — all pages */
|
||
.hero h1 { font-size: 44pt; }
|
||
.hero-left { padding: 14px 18px; }
|
||
.hero-cell { padding: 10px 14px; min-height: 70px; }
|
||
.hero-cell .big { font-size: 18pt; margin-top: 4px; }
|
||
.about { padding: 10px 18px; }
|
||
.about h2 { font-size: 13pt; }
|
||
.about .stack-grid { gap: 4px 14px; }
|
||
.row .num { padding: 8px 12px; font-size: 9pt; }
|
||
.row .body { padding: 8px 16px; }
|
||
.row .meta { padding: 8px 14px; gap: 4px; }
|
||
.row .body h3 { font-size: 12pt; }
|
||
.row .body .company { margin-top: 2px; font-size: 7.5pt; }
|
||
.row .body ul { margin-top: 4px; line-height: 1.35; font-size: 8pt; padding-left: 14px; }
|
||
.row .body ul li { margin: 1px 0; }
|
||
.row .body .url-mono { font-size: 7.5pt; margin-top: 2px; }
|
||
.row .meta .period { font-size: 7.5pt; }
|
||
.row .meta .where { font-size: 7pt; }
|
||
.section-header { padding: 6px 14px; }
|
||
.edu-row > div { padding: 8px 14px; }
|
||
.edu-row h3 { font-size: 11pt; }
|
||
.edu-row .desc { font-size: 7.8pt; line-height: 1.35; }
|
||
.edu-row .degree { font-size: 7.5pt; }
|
||
.hobbies > div { padding: 8px 12px; gap: 3px; }
|
||
.hobbies .h-title { font-size: 9.5pt; }
|
||
.hobbies .h-desc { font-size: 7.5pt; line-height: 1.3; }
|
||
.hobbies .h-time { font-size: 7pt; }
|
||
.footer > div { padding: 5px 12px; }
|
||
.pitch-strip { padding: 8px 18px; }
|
||
.pitch-strip .pitch-text { font-size: 8.5pt; line-height: 1.35; }
|
||
|
||
.print-btn { display: none !important; }
|
||
a { color: inherit; }
|
||
}
|
||
|
||
/* ---------- DOWNLOAD BUTTON (screen only) ---------- */
|
||
.print-btn {
|
||
position: fixed;
|
||
bottom: 20px;
|
||
right: 20px;
|
||
z-index: 9999;
|
||
background: var(--accent);
|
||
color: #fff;
|
||
border: 1px solid var(--ink);
|
||
padding: 12px 18px;
|
||
font-family: 'JetBrains Mono', ui-monospace, monospace;
|
||
font-size: 9pt;
|
||
letter-spacing: 0.08em;
|
||
text-transform: uppercase;
|
||
cursor: pointer;
|
||
box-shadow: 4px 4px 0 var(--ink);
|
||
transition: transform 0.1s ease, box-shadow 0.1s ease;
|
||
}
|
||
.print-btn:hover { transform: translate(-2px, -2px); box-shadow: 6px 6px 0 var(--ink); }
|
||
.print-btn:active { transform: translate(2px, 2px); box-shadow: 1px 1px 0 var(--ink); }
|
||
.print-btn svg { vertical-align: middle; margin-right: 6px; }
|
||
|
||
/* VERSION SWITCHER (top-right, screen only) */
|
||
.switch-btn {
|
||
position: fixed;
|
||
top: 20px;
|
||
right: 20px;
|
||
z-index: 9999;
|
||
background: var(--bg);
|
||
color: var(--ink);
|
||
border: 1px solid var(--ink);
|
||
padding: 10px 16px;
|
||
font-family: 'JetBrains Mono', ui-monospace, monospace;
|
||
font-size: 8.5pt;
|
||
letter-spacing: 0.08em;
|
||
text-transform: uppercase;
|
||
text-decoration: none;
|
||
box-shadow: 4px 4px 0 var(--ink);
|
||
transition: transform 0.1s ease, box-shadow 0.1s ease, background 0.1s ease, color 0.1s ease;
|
||
display: inline-flex;
|
||
align-items: center;
|
||
gap: 8px;
|
||
}
|
||
.switch-btn:hover { background: var(--accent); color: #fff; transform: translate(-2px, -2px); box-shadow: 6px 6px 0 var(--ink); }
|
||
.switch-btn .arrow { display: inline-block; transition: transform 0.15s ease; }
|
||
.switch-btn:hover .arrow { transform: translateX(3px); }
|
||
@media print { .switch-btn { display: none !important; } }
|
||
|
||
/* LANG TOGGLE (bottom-right, left of download) */
|
||
.lang-toggle {
|
||
position: fixed;
|
||
bottom: 20px;
|
||
right: 220px;
|
||
z-index: 9999;
|
||
background: var(--bg);
|
||
color: var(--ink);
|
||
border: 1px solid var(--ink);
|
||
padding: 12px 16px;
|
||
font-family: 'JetBrains Mono', ui-monospace, monospace;
|
||
font-size: 9pt;
|
||
letter-spacing: 0.1em;
|
||
text-transform: uppercase;
|
||
cursor: pointer;
|
||
box-shadow: 4px 4px 0 var(--ink);
|
||
transition: transform 0.1s ease, box-shadow 0.1s ease;
|
||
display: inline-flex;
|
||
align-items: center;
|
||
gap: 6px;
|
||
}
|
||
.lang-toggle:hover { transform: translate(-2px, -2px); box-shadow: 6px 6px 0 var(--ink); }
|
||
.lang-toggle:active { transform: translate(2px, 2px); box-shadow: 1px 1px 0 var(--ink); }
|
||
.lang-toggle .lang-opt { opacity: 0.4; transition: opacity 0.1s ease, color 0.1s ease; }
|
||
.lang-toggle .lang-opt.active { opacity: 1; color: var(--accent); font-weight: 600; }
|
||
.lang-toggle .sep { color: var(--muted); opacity: 0.5; }
|
||
@media print { .lang-toggle { display: none !important; } }
|
||
</style>
|
||
</head>
|
||
<body>
|
||
|
||
<!-- ====================== PAGE 1 ====================== -->
|
||
<div class="page">
|
||
<div class="frame">
|
||
|
||
<!-- Topbar -->
|
||
<div class="topbar">
|
||
<div><span data-en="Document">Document</span><span class="val">CV / 2026</span></div>
|
||
<div><span data-en="Profile">Profil</span><span class="val">Fullstack Dev</span></div>
|
||
<div><span data-en="Based in">Basé à</span><span class="val accent">Marseille — FR</span></div>
|
||
<div><span data-en="Contact">Contact</span><span class="val">contact.arthurbarre@gmail.com</span></div>
|
||
</div>
|
||
|
||
<!-- Hero -->
|
||
<section class="hero">
|
||
<div class="hero-left">
|
||
<div class="label">[ A ] · Curriculum Vitae</div>
|
||
<h1>Arthur<br/>Barré —<br/><em>Fullstack</em><br/>Developer</h1>
|
||
|
||
<div class="hero-meta">
|
||
<div><div class="k">Role</div><div class="v">Fullstack Dev</div></div>
|
||
<div><div class="k">Years</div><div class="v" data-en="7+ years">7+ ans</div></div>
|
||
<div><div class="k">Focus</div><div class="v" data-en="SaaS · AI · Product">SaaS · IA · Produit</div></div>
|
||
<div><div class="k">Based</div><div class="v accent">Marseille</div></div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="hero-right">
|
||
<div class="hero-cell specimen-cell">
|
||
<div class="specimen-header">
|
||
<div class="tag">[ FIG. A ]</div>
|
||
</div>
|
||
<div class="specimen-photo-wrap">
|
||
<img class="specimen-photo" src="photo.jpg" alt="Arthur Barré" />
|
||
<span class="specimen-corner tl">A</span>
|
||
<span class="specimen-corner br">B</span>
|
||
</div>
|
||
</div>
|
||
<div class="hero-cell">
|
||
<div class="tag">[ COUNTER 01 ]</div>
|
||
<div>
|
||
<div class="big"><span class="accent">07</span></div>
|
||
<div class="label" data-en="Pro experience">Expériences pro</div>
|
||
</div>
|
||
</div>
|
||
<div class="hero-cell">
|
||
<div class="tag">[ COUNTER 02 ]</div>
|
||
<div>
|
||
<div class="big" data-en="05 PROJECTS">05 PROJETS</div>
|
||
<div class="label" data-en="Freelance & personal">Freelance & perso</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- Pitch strip — compact one-liner -->
|
||
<section class="pitch-strip">
|
||
<div class="pitch-label" data-en="[ 01 ] · Pitch">[ 01 ] · Pitch</div>
|
||
<p class="pitch-text" data-en="<b>7 years</b> shipping <span class='accent'>end-to-end</span> products — Node / Symfony / Python back-ends, polished React / Vue front-ends, self-hosted Proxmox / K3s infra. I ship, I measure, and I aim for <span class='accent'>product excellence</span>."><b>7 ans</b> à livrer des produits <span class='accent'>end-to-end</span> — back-ends Node / Symfony / Python, front-ends React / Vue ciselés, infra auto-hébergée Proxmox / K3s. Je livre, je mesure, et je vise <span class='accent'>l'excellence produit</span>.</p>
|
||
</section>
|
||
|
||
<!-- Expériences — header -->
|
||
<div class="section-header">
|
||
<div>[ 02 ]</div>
|
||
<div class="title" data-en="Work experience">Expériences professionnelles</div>
|
||
<div>2023 — 2026</div>
|
||
<div data-en="02 items">02 items</div>
|
||
</div>
|
||
|
||
<!-- Job 01 — Fogeron 3 -->
|
||
<article class="row">
|
||
<div class="num">01</div>
|
||
<div class="body">
|
||
<h3 data-en="Full Stack Developer">Développeur Full Stack</h3>
|
||
<div class="company" data-en="Fogeron 3 — Permanent">Fogeron 3 — CDI</div>
|
||
<ul data-en="<li><b>B2B SaaS</b> integrating advanced AI capabilities: <b>function calling</b>, LLM orchestration, business workflow automation.</li><li>Built <b>NestJS REST APIs</b>: business modules, auth, validation, fine-grained role management.</li><li><b>Angular</b> interfaces: reusable components, reactive forms, state management.</li><li>Contributed to <b>software architecture</b> decisions: domain modeling, module decomposition.</li><li>Worked on <b>prompt engineering</b>, LLM output control and inference cost optimization.</li>">
|
||
<li><b>SaaS B2B</b> intégrant des fonctionnalités IA avancées : <b>function calling</b>, orchestration de LLM, automatisation de workflows métier.</li>
|
||
<li>Développement d'<b>API REST en NestJS</b> : modules métier, auth, validation, gestion fine des rôles.</li>
|
||
<li>Interfaces <b>Angular</b> : composants réutilisables, formulaires réactifs, gestion d'état.</li>
|
||
<li>Contribution aux décisions d'<b>architecture logicielle</b> : modélisation des domaines, découpage des modules.</li>
|
||
<li>Travail sur le <b>prompt engineering</b>, le contrôle des sorties LLM et l'optimisation des coûts d'inférence.</li>
|
||
</ul>
|
||
</div>
|
||
<div class="meta">
|
||
<div class="period" data-en="Feb — Apr 2026">Fév — Avr 2026</div>
|
||
<div class="where">Marseille — FR</div>
|
||
<div class="stack-chips">
|
||
<span class="chip accent">NestJS</span>
|
||
<span class="chip accent">Angular</span>
|
||
<span class="chip">TypeScript</span>
|
||
<span class="chip">OpenAI</span>
|
||
<span class="chip">Postgres</span>
|
||
<span class="chip">Docker</span>
|
||
</div>
|
||
</div>
|
||
</article>
|
||
|
||
<!-- Job 02 — thecamp -->
|
||
<article class="row">
|
||
<div class="num">02</div>
|
||
<div class="body">
|
||
<h3 data-en="Full Stack Developer">Développeur Full Stack</h3>
|
||
<div class="company" data-en="thecamp — Permanent">thecamp — CDI</div>
|
||
<ul data-en="<li><b>Full-stack dev</b> on a multi-tech environment (TS, React, Vue, PHP/Symfony, Postgres, Docker, Linux).</li><li>Designed and built <b>internal tools</b> to streamline events and operations team workflows.</li><li>Shipped a connected <b>Building Management System (BMS)</b>: Python <b>IoT</b> gateway centralizing and translating equipment data, integrated into a Symfony app and interactive front-end.</li><li>Contributed to <b>software architecture</b> thinking: scalability, maintainability, observability, reliability.</li><li>Actively involved in <b>tech decisions</b> and rolling out engineering best practices.</li>">
|
||
<li><b>Développement full-stack</b> sur un environnement multi-technos (TS, React, Vue, PHP/Symfony, Postgres, Docker, Linux).</li>
|
||
<li>Conception et développement d'<b>outils internes</b> pour optimiser l'organisation des équipes événementielles et opérationnelles.</li>
|
||
<li>Mise en place d'un système de <b>Gestion Technique du Bâtiment (GTB)</b> connecté : passerelle <b>IoT en Python</b> centralisant et traduisant les données des équipements, intégrée dans une app Symfony et un frontend interactif.</li>
|
||
<li>Contribution aux réflexions d'<b>architecture logicielle</b> : scalabilité, maintenabilité, supervision, fiabilité.</li>
|
||
<li>Participation active aux <b>choix techniques</b> et à la mise en place de bonnes pratiques.</li>
|
||
</ul>
|
||
</div>
|
||
<div class="meta">
|
||
<div class="period">2023 — 2026</div>
|
||
<div class="where">Aix la Duranne — FR</div>
|
||
<div class="stack-chips">
|
||
<span class="chip accent">TypeScript</span>
|
||
<span class="chip accent">React.js</span>
|
||
<span class="chip">Vue.js</span>
|
||
<span class="chip">Symfony</span>
|
||
<span class="chip">Python</span>
|
||
<span class="chip">IoT</span>
|
||
<span class="chip">Docker</span>
|
||
<span class="chip">Linux</span>
|
||
</div>
|
||
</div>
|
||
</article>
|
||
|
||
<!-- Footer page 1 -->
|
||
<div class="footer">
|
||
<div>Arthur Barré</div>
|
||
<div>arthurbarre.fr</div>
|
||
<div>06 13 17 61 17</div>
|
||
<div class="k">Page 01 / 03</div>
|
||
</div>
|
||
|
||
</div>
|
||
</div>
|
||
|
||
<!-- ====================== PAGE 2 ====================== -->
|
||
<div class="page">
|
||
<div class="frame">
|
||
|
||
<div class="topbar">
|
||
<div><span data-en="Document">Document</span><span class="val">CV / 2026</span></div>
|
||
<div><span data-en="Section">Section</span><span class="val" data-en="Cont. experience + Education">Suite expériences + Formations</span></div>
|
||
<div><span data-en="Based in">Basé à</span><span class="val accent">Marseille — FR</span></div>
|
||
<div><span data-en="Page">Page</span><span class="val">02 / 03</span></div>
|
||
</div>
|
||
|
||
<div class="section-header">
|
||
<div>[ 02 ]</div>
|
||
<div class="title" data-en="Work experience (cont.)">Expériences (suite)</div>
|
||
<div>2019 — 2023</div>
|
||
<div data-en="03 items">03 items</div>
|
||
</div>
|
||
|
||
<!-- Job 03 — talents'in & between -->
|
||
<article class="row">
|
||
<div class="num">03</div>
|
||
<div class="body">
|
||
<h3 data-en="Full Stack Developer">Développeur Full Stack</h3>
|
||
<div class="company" data-en="talents'in & between — Apprenticeship">talents'in & between — Alternance</div>
|
||
<ul data-en="<li>Built <b>Java Spring Boot REST APIs</b> encoding complex business rules in the recruitment domain.</li><li>Consumed the <b>APIs from the front-end (Vue.js)</b> for clear end-to-end data flow ownership.</li><li>Contributed to <b>internal business tools</b> on a <b>PHP/Symfony + React + MySQL</b> stack.</li><li>Successful <b>transition</b> to a new stack post-acquisition by Between: <b>Spring Boot + Vue.js</b>.</li><li>Adapted the dev environment (local Docker ⇒ dedicated Linux VM).</li>">
|
||
<li>Développement d'<b>API REST en Java Spring Boot</b> intégrant des règles métiers complexes liées au secteur du recrutement.</li>
|
||
<li>Consommation des <b>API côté frontend (Vue.js)</b> pour une vision claire du flux end-to-end.</li>
|
||
<li>Contribution au développement d'<b>outils métiers internes</b> sur stack <b>PHP/Symfony + React + MySQL</b>.</li>
|
||
<li><b>Transition</b> réussie vers une nouvelle stack après le rachat par Between : <b>Spring Boot + Vue.js</b>.</li>
|
||
<li>Adaptation de l'environnement de dev (local Docker ⇒ VM Linux dédiée).</li>
|
||
</ul>
|
||
</div>
|
||
<div class="meta">
|
||
<div class="period">2021 — 2023</div>
|
||
<div class="where">Marseille — FR</div>
|
||
<div class="stack-chips">
|
||
<span class="chip accent">Spring Boot</span>
|
||
<span class="chip">Vue.js</span>
|
||
<span class="chip">React.js</span>
|
||
<span class="chip">Symfony</span>
|
||
<span class="chip">MySQL</span>
|
||
<span class="chip">K8s</span>
|
||
</div>
|
||
</div>
|
||
</article>
|
||
|
||
<!-- Job 04 — EasyMovie -->
|
||
<article class="row">
|
||
<div class="num">04</div>
|
||
<div class="body">
|
||
<h3 data-en="Frontend Developer">Développeur Frontend</h3>
|
||
<div class="company" data-en="EasyMovie — Apprenticeship">EasyMovie — Alternance</div>
|
||
<ul data-en="<li>Built and <b>maintained</b> a <b>React component library</b>.</li><li><b>Integrated</b> this library across various app pages (video project management, templates, admin).</li><li>Collaborated with <b>cross-functional teams</b> (PO, Design, iOS, Android, Backend, QA, DevOps) in a structured production cycle.</li><li>Full production cycle (Develop → Pre-Prod → Production) with systematic <b>peer code reviews</b>.</li><li>Strict adherence to standards (<b>guidelines</b>) within a demanding methodology.</li>">
|
||
<li>Développement et <b>maintenance</b> d'une <b>librairie de composants React</b>.</li>
|
||
<li><b>Intégration</b> de cette librairie dans différentes pages de l'application (gestion de projets vidéo, templates, administration).</li>
|
||
<li>Collaboration avec des <b>équipes pluridisciplinaires</b> (PO, Design, iOS, Android, Backend, QA, DevOps) dans un cycle de prod structuré.</li>
|
||
<li>Processus complet de mise en production (Develop → Pre-Prod → Production) avec <b>revues de code croisées</b> systématiques.</li>
|
||
<li>Respect rigoureux des standards (<b>guidelines</b>) dans un cadre méthodologique exigeant.</li>
|
||
</ul>
|
||
</div>
|
||
<div class="meta">
|
||
<div class="period">2019 — 2021</div>
|
||
<div class="where">Paris — FR</div>
|
||
<div class="stack-chips">
|
||
<span class="chip accent">React.js</span>
|
||
<span class="chip">TypeScript</span>
|
||
<span class="chip">Styled Comp.</span>
|
||
<span class="chip">Storybook</span>
|
||
<span class="chip">GraphQL</span>
|
||
<span class="chip">CircleCI</span>
|
||
</div>
|
||
</div>
|
||
</article>
|
||
|
||
<!-- Job 05 — WeFound -->
|
||
<article class="row">
|
||
<div class="num">05</div>
|
||
<div class="body">
|
||
<h3 data-en="Mobile Developer">Développeur mobile</h3>
|
||
<div class="company" data-en="WeFound — Internship">WeFound — Stage</div>
|
||
<ul data-en="<li>Designed a <b>React Native mobile app</b> for <b>Bluetooth Low Energy (BLE)</b> connectivity with electric vehicles.</li><li><b>Deep-dive into sorting algorithms</b> and re-learning of fundamentals (memory management, internals).</li><li>Built <b>JavaScript algorithms</b> to analyze battery health.</li><li>Worked with a <b>senior developer</b> in a startup environment.</li><li>Shipped a <b>working prototype</b> integrating an existing back-end with the mobile UI.</li>">
|
||
<li>Conception d'une <b>application mobile React Native</b> pour la connexion <b>Bluetooth Low Energy (BLE)</b> à un véhicule électrique.</li>
|
||
<li><b>Révision approfondie des algorithmes</b> de tri et réapprentissage des fondamentaux (gestion de la mémoire, fonctionnement interne).</li>
|
||
<li>Développement d'<b>algorithmes en JavaScript</b> pour analyser l'état de santé de la batterie.</li>
|
||
<li>Collaboration avec un <b>développeur senior</b> dans un environnement startup.</li>
|
||
<li>Livraison d'un <b>prototype fonctionnel</b> intégrant un backend existant et une interface mobile.</li>
|
||
</ul>
|
||
</div>
|
||
<div class="meta">
|
||
<div class="period">2019</div>
|
||
<div class="where">Paris — FR</div>
|
||
<div class="stack-chips">
|
||
<span class="chip accent">React Native</span>
|
||
<span class="chip">React.js</span>
|
||
<span class="chip">JavaScript</span>
|
||
<span class="chip">BLE</span>
|
||
</div>
|
||
</div>
|
||
</article>
|
||
|
||
<div class="section-header">
|
||
<div>[ 03 ]</div>
|
||
<div class="title" data-en="Education">Formations</div>
|
||
<div>2018 — 2023</div>
|
||
<div data-en="02 items">02 items</div>
|
||
</div>
|
||
|
||
<article class="edu-row">
|
||
<div class="num">01</div>
|
||
<div>
|
||
<div class="degree" data-en="Master's · 2021 — 2023">Master 2 · 2021 — 2023</div>
|
||
<h3 data-en="Software Architect">Architecte logiciel</h3>
|
||
</div>
|
||
<div class="desc" data-en="Project-based learning, application design, exploration of various programming languages like Java and Python. Projects focused on <b>artificial intelligence</b> and <b>big data</b>.">
|
||
Apprentissage par projet, conception d'applications, découverte de divers langages de programmation comme Java et Python. Projets orientés <b>intelligence artificielle</b> et <b>big data</b>.
|
||
</div>
|
||
<div class="meta-cell">
|
||
Epitech
|
||
<span class="where">Marseille — FR</span>
|
||
</div>
|
||
</article>
|
||
|
||
<article class="edu-row">
|
||
<div class="num">02</div>
|
||
<div>
|
||
<div class="degree" data-en="Bachelor's · 2018 — 2021">Bachelor · 2018 — 2021</div>
|
||
<h3 data-en="Multimedia Project Manager">Chef de projet multimédia</h3>
|
||
</div>
|
||
<div class="desc" data-en="Group projects: building websites, UX/UI redesigns, native JavaScript games. Use of <b>React</b> and <b>Vue</b>.">
|
||
Projets de groupe : création de sites internet, refonte de sites (UX/UI), création de jeux vidéo en JavaScript natif. Utilisation de <b>React</b> et <b>Vue</b>.
|
||
</div>
|
||
<div class="meta-cell">
|
||
Hetic
|
||
<span class="where">Paris — FR</span>
|
||
</div>
|
||
</article>
|
||
|
||
<!-- Hobbies -->
|
||
<div class="section-header">
|
||
<div>[ 04 ]</div>
|
||
<div class="title">Hobbies</div>
|
||
<div>Off-screen</div>
|
||
<div data-en="04 items">04 items</div>
|
||
</div>
|
||
|
||
<div class="hobbies">
|
||
<div>
|
||
<div class="label">[ A ]</div>
|
||
<div class="h-title">Open source & self hosting</div>
|
||
<div class="h-desc" data-en="Tech monitoring & experimenting with various programming tools.">Veille technologique & tests de divers outils de programmation.</div>
|
||
<div class="h-time" data-en="2 yrs">2 ans</div>
|
||
</div>
|
||
<div>
|
||
<div class="label">[ B ]</div>
|
||
<div class="h-title" data-en="App building">Création d'applications</div>
|
||
<div class="h-desc" data-en="Personal fullstack projects, from idea to production.">Projets fullstack persos, de l'idée à la mise en prod.</div>
|
||
<div class="h-time" data-en="3 yrs">3 ans</div>
|
||
</div>
|
||
<div>
|
||
<div class="label">[ C ]</div>
|
||
<div class="h-title">Do It Yourself</div>
|
||
<div class="h-desc" data-en="Wooden speaker builds & 3D printing.">Création d'enceintes en bois & impression 3D.</div>
|
||
<div class="h-time" data-en="3 yrs">3 ans</div>
|
||
</div>
|
||
<div>
|
||
<div class="label">[ D ]</div>
|
||
<div class="h-title">Scouts & Guides de France</div>
|
||
<div class="h-desc" data-en="Youth leadership and solidarity projects.">Animation d'enfants et projets solidaires.</div>
|
||
<div class="h-time" data-en="10 yrs">10 ans</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="footer">
|
||
<div>Arthur Barré</div>
|
||
<div>arthurbarre.fr</div>
|
||
<div>06 13 17 61 17</div>
|
||
<div class="k">Page 02 / 03</div>
|
||
</div>
|
||
|
||
</div>
|
||
</div>
|
||
|
||
<!-- ====================== PAGE 3 — PROJETS ====================== -->
|
||
<div class="page page-projects">
|
||
<div class="frame">
|
||
|
||
<div class="topbar">
|
||
<div><span data-en="Document">Document</span><span class="val">CV / 2026</span></div>
|
||
<div><span data-en="Section">Section</span><span class="val" data-en="Projects & Freelance">Projets & Freelance</span></div>
|
||
<div><span data-en="URL">URL</span><span class="val accent">arthurbarre.fr</span></div>
|
||
<div><span data-en="Page">Page</span><span class="val">03 / 03</span></div>
|
||
</div>
|
||
|
||
<div class="section-header">
|
||
<div>[ 05 ]</div>
|
||
<div class="title" data-en="Projects & freelance — Selected">Projets & freelance — Sélection</div>
|
||
<div>2023 — 2026</div>
|
||
<div data-en="05 items">05 items</div>
|
||
</div>
|
||
|
||
<!-- Project 01 — Rubis -->
|
||
<article class="row">
|
||
<div class="num">01</div>
|
||
<div class="body">
|
||
<h3>Rubis</h3>
|
||
<div class="company">SaaS B2B · Freelance · 2025 — 2026</div>
|
||
<a class="url-mono" href="https://rubis.pro">→ rubis.pro</a>
|
||
<ul data-en="<li><b>SaaS for automated dunning of unpaid invoices</b> for French SMBs, designed and built <b>end-to-end</b>.</li><li><b>AdonisJS v7</b> backend: Bearer auth, invoice & dunning plan models, scheduled jobs, Stripe webhooks, OCR, Resend integration.</li><li><b>React 19 + TanStack</b> SaaS and <b>Astro 6 SSR</b> landing/blog sharing a <b>Tailwind v4</b> design system in a Turborepo monorepo.</li><li><b>Self-hosted infrastructure</b> on Proxmox + K3s: deployment via Gitea CI, Traefik, managed PostgreSQL and MinIO.</li>">
|
||
<li>SaaS de <b>relance automatique de factures impayées</b> pour TPE-PME françaises, conçu et développé <b>end-to-end</b>.</li>
|
||
<li>Backend <b>AdonisJS v7</b> : auth Bearer, modèles factures & plans de relance, jobs programmés, webhooks Stripe, OCR, intégration Resend.</li>
|
||
<li>SaaS <b>React 19 + TanStack</b> et landing/blog <b>Astro 6 SSR</b> partageant un design system <b>Tailwind v4</b> en monorepo Turborepo.</li>
|
||
<li><b>Infrastructure auto-hébergée</b> sur Proxmox + K3s : déploiement via Gitea CI, Traefik, PostgreSQL et MinIO managés.</li>
|
||
</ul>
|
||
</div>
|
||
<div class="meta">
|
||
<div class="period" data-en="Ongoing">En cours</div>
|
||
<div class="where" data-en="SaaS · AI · OCR">SaaS · IA · OCR</div>
|
||
<div class="stack-chips">
|
||
<span class="chip accent">AdonisJS</span>
|
||
<span class="chip accent">React 19</span>
|
||
<span class="chip">Astro 6</span>
|
||
<span class="chip">Tailwind</span>
|
||
<span class="chip">Postgres</span>
|
||
<span class="chip">K3s</span>
|
||
<span class="chip">Stripe</span>
|
||
</div>
|
||
</div>
|
||
</article>
|
||
|
||
<!-- Project 02 — Rebours Studio -->
|
||
<article class="row">
|
||
<div class="num">02</div>
|
||
<div class="body">
|
||
<h3>Rebours Studio</h3>
|
||
<div class="company">E-commerce · Freelance</div>
|
||
<a class="url-mono" href="https://rebours.studio">→ rebours.studio</a>
|
||
<ul data-en="<li>Minimalist <b>showcase + e-commerce</b> site for a Paris-based contemporary art furniture studio (collection, detailed product pages, specifications, design notes).</li><li>Integrated a <b>Stripe checkout</b> and bespoke order flow tailored to art furniture (6–8 week lead times, unique pieces).</li><li>Managed <b>media APIs</b> for HD visuals and a contact form wired into <b>WhatsApp Business</b>.</li><li>Careful work on <b>visual identity</b> and performance, consistent with the premium positioning.</li>">
|
||
<li>Site <b>vitrine + e-commerce</b> minimaliste pour un atelier parisien de mobilier d'art contemporain (collection, fiches produit détaillées, spécifications, notes de conception).</li>
|
||
<li>Intégration d'un <b>tunnel de paiement Stripe</b> et d'un parcours de commande sur-mesure adapté au mobilier d'art (délais 6–8 semaines, pièces uniques).</li>
|
||
<li>Gestion d'<b>API media</b> pour les visuels HD et formulaire de contact relié à <b>WhatsApp Business</b>.</li>
|
||
<li>Travail soigné sur l'<b>identité visuelle</b> et la performance, en cohérence avec le positionnement haut de gamme.</li>
|
||
</ul>
|
||
</div>
|
||
<div class="meta">
|
||
<div class="period">2025</div>
|
||
<div class="where" data-en="Design · Limited edition">Design · Edition limitée</div>
|
||
<div class="stack-chips">
|
||
<span class="chip accent">Next.js</span>
|
||
<span class="chip">React</span>
|
||
<span class="chip">Tailwind</span>
|
||
<span class="chip">Stripe</span>
|
||
<span class="chip">API media</span>
|
||
</div>
|
||
</div>
|
||
</article>
|
||
|
||
<!-- Project 03 — Freedge -->
|
||
<article class="row">
|
||
<div class="num">03</div>
|
||
<div class="body">
|
||
<h3>Freedge.app</h3>
|
||
<div class="company" data-en="AI SaaS · Personal">SaaS IA · Perso</div>
|
||
<a class="url-mono" href="https://freedge.app">→ freedge.app</a>
|
||
<ul data-en="<li><b>AI-powered recipe generation</b> app, built end-to-end (frontend, backend, AI, infra, billing).</li><li><b>Fastify + Prisma + SQLite</b> API: <b>JWT & OAuth</b> auth, profile/recipe/prompt storage, <b>GPT-4 Turbo</b> and <b>DALL·E 3</b> integration.</li><li><b>Docker + MinIO + VPS + Nginx</b> reverse-proxy infra; <b>Stripe</b> billing with multi-tier subscriptions.</li><li>Deep work on <b>prompt engineering</b>, AI cost optimization and code maintainability.</li>">
|
||
<li>Application de <b>génération de recettes assistée par IA</b>, conçue end-to-end (frontend, backend, IA, infra, paiement).</li>
|
||
<li>API <b>Fastify + Prisma + SQLite</b> : auth <b>JWT & OAuth</b>, stockage profils/recettes/prompts, intégration <b>GPT-4 Turbo</b> et <b>DALL·E 3</b>.</li>
|
||
<li>Infra <b>Docker + MinIO + VPS + Nginx</b> reverse-proxy ; paiement <b>Stripe</b> avec abonnements multi-plans.</li>
|
||
<li>Travail approfondi sur le <b>prompt engineering</b>, l'optimisation des coûts IA et la maintenabilité du code.</li>
|
||
</ul>
|
||
</div>
|
||
<div class="meta">
|
||
<div class="period">2024</div>
|
||
<div class="where" data-en="AI · SaaS · Cooking">IA · SaaS · Cuisine</div>
|
||
<div class="stack-chips">
|
||
<span class="chip accent">Fastify</span>
|
||
<span class="chip accent">OpenAI</span>
|
||
<span class="chip">React</span>
|
||
<span class="chip">Prisma</span>
|
||
<span class="chip">Stripe</span>
|
||
<span class="chip">MinIO</span>
|
||
</div>
|
||
</div>
|
||
</article>
|
||
|
||
<!-- Project 04 — Portfolio Photographe -->
|
||
<article class="row">
|
||
<div class="num">04</div>
|
||
<div class="body">
|
||
<h3 data-en="Photographer Portfolio">Portfolio Photographe</h3>
|
||
<div class="company" data-en="Showcase site · Freelance">Site vitrine · Freelance</div>
|
||
<a class="url-mono" href="https://anne-sophie-rouault.vercel.app/">→ anne-sophie-rouault.vercel.app</a>
|
||
<ul data-en="<li><b>Responsive showcase site</b> for a professional photographer.</li><li>Set up a <b>headless CMS</b> (Sanity.io) for self-service gallery and content management.</li><li>Performance-optimized <b>Next.js</b> front-end: <b>SEO</b>, load times, <b>accessibility</b>.</li><li>Scalable deployment, DNS configuration and SEO optimization.</li>">
|
||
<li>Site <b>vitrine responsive</b> pour une photographe professionnelle.</li>
|
||
<li>Mise en place d'un <b>CMS headless</b> (Sanity.io) pour la gestion autonome des galeries et contenus.</li>
|
||
<li>Frontend <b>Next.js</b> optimisé pour la performance : <b>SEO</b>, temps de chargement, <b>accessibilité</b>.</li>
|
||
<li>Déploiement scalable, configuration DNS et optimisation SEO.</li>
|
||
</ul>
|
||
</div>
|
||
<div class="meta">
|
||
<div class="period">2024</div>
|
||
<div class="where">Portfolio · SEO</div>
|
||
<div class="stack-chips">
|
||
<span class="chip accent">Next.js</span>
|
||
<span class="chip">React</span>
|
||
<span class="chip">Sanity</span>
|
||
<span class="chip">Tailwind</span>
|
||
<span class="chip">Vercel</span>
|
||
</div>
|
||
</div>
|
||
</article>
|
||
|
||
<!-- Project 05 — Because Life Festival -->
|
||
<article class="row">
|
||
<div class="num">05</div>
|
||
<div class="body">
|
||
<h3>Because Life Festival</h3>
|
||
<div class="company" data-en="Event site · Freelance">Site événementiel · Freelance</div>
|
||
<span class="url-mono" data-en="→ temporary site — unavailable">→ site temporaire — indisponible</span>
|
||
<ul data-en="<li>Took part in <b>client meetings</b> to understand the festival's needs and goals.</li><li>Contributed to the <b>requirements spec</b> and expected feature set.</li><li>Designed the site <b>architecture</b> and <b>visual design</b>, focusing on readability and identity.</li><li>Built on <b>Webflow</b> for fast delivery, design flexibility and client-side autonomy.</li>">
|
||
<li>Participation aux <b>réunions clients</b> pour comprendre les besoins et les objectifs du festival.</li>
|
||
<li>Contribution au <b>cahier des charges</b> et aux fonctionnalités attendues.</li>
|
||
<li>Conception de l'<b>architecture</b> et du <b>design</b> du site, en mettant l'accent sur la lisibilité et l'identité visuelle.</li>
|
||
<li>Développement sur <b>Webflow</b> pour la rapidité de mise en œuvre, la flexibilité de design et l'autonomie de gestion côté client.</li>
|
||
</ul>
|
||
</div>
|
||
<div class="meta">
|
||
<div class="period">2023</div>
|
||
<div class="where" data-en="Events">Événementiel</div>
|
||
<div class="stack-chips">
|
||
<span class="chip accent">Webflow</span>
|
||
<span class="chip">DNS</span>
|
||
<span class="chip">Design</span>
|
||
</div>
|
||
</div>
|
||
</article>
|
||
|
||
<div class="footer">
|
||
<div>Arthur Barré</div>
|
||
<div>arthurbarre.fr</div>
|
||
<div>contact.arthurbarre@gmail.com</div>
|
||
<div class="k">Page 03 / 03</div>
|
||
</div>
|
||
|
||
</div>
|
||
</div>
|
||
|
||
<a class="switch-btn" href="cv-short.html" aria-label="Voir la version courte">
|
||
<span data-en="Short version · 1 page">Version courte · 1 page</span>
|
||
<span class="arrow">→</span>
|
||
</a>
|
||
|
||
<button class="lang-toggle" aria-label="Toggle language">
|
||
<span class="lang-opt" data-lang="en">EN</span>
|
||
<span class="sep">/</span>
|
||
<span class="lang-opt active" data-lang="fr">FR</span>
|
||
</button>
|
||
|
||
<button class="print-btn" onclick="window.print()" aria-label="Télécharger en PDF">
|
||
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="square" stroke-linejoin="miter">
|
||
<path d="M12 3v12m0 0l-5-5m5 5l5-5M5 21h14"/>
|
||
</svg>
|
||
<span data-en="Download PDF">Download PDF</span>
|
||
</button>
|
||
|
||
<script>
|
||
(function() {
|
||
const STORAGE_KEY = 'cv-lang';
|
||
const detect = () => {
|
||
const saved = localStorage.getItem(STORAGE_KEY);
|
||
if (saved === 'fr' || saved === 'en') return saved;
|
||
const nav = (navigator.language || 'fr').toLowerCase();
|
||
return nav.startsWith('fr') ? 'fr' : 'en';
|
||
};
|
||
let current = detect();
|
||
|
||
const apply = (lang) => {
|
||
document.documentElement.setAttribute('lang', lang);
|
||
document.querySelectorAll('[data-en]').forEach(el => {
|
||
if (!el.hasAttribute('data-fr')) el.setAttribute('data-fr', el.innerHTML);
|
||
el.innerHTML = lang === 'en' ? el.getAttribute('data-en') : el.getAttribute('data-fr');
|
||
});
|
||
document.querySelectorAll('.lang-toggle .lang-opt').forEach(o => {
|
||
o.classList.toggle('active', o.dataset.lang === lang);
|
||
});
|
||
};
|
||
|
||
document.addEventListener('DOMContentLoaded', () => {
|
||
apply(current);
|
||
const btn = document.querySelector('.lang-toggle');
|
||
if (!btn) return;
|
||
btn.addEventListener('click', () => {
|
||
current = current === 'fr' ? 'en' : 'fr';
|
||
localStorage.setItem(STORAGE_KEY, current);
|
||
apply(current);
|
||
});
|
||
});
|
||
})();
|
||
</script>
|
||
|
||
</body>
|
||
</html>
|