| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607 |
- <!DOCTYPE html>
- <html lang="fr">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta name="description" content="Bastien Chanot — Développeur Systèmes · Embarqué · Backend. 7 ans en C, Rust, Linux kernel, AOSP, cloud gaming et GPU bare-metal en production.">
- <meta name="author" content="Bastien Chanot">
- <meta name="theme-color" content="#0d1b12">
- <title>Bastien Chanot — Développeur Systèmes · Embarqué · Backend</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;600;700&family=Fraunces:ital,wght@0,300;0,500;0,600;0,700;1,400&family=DM+Sans:wght@300;400;500;600&display=swap" rel="stylesheet">
- <style>
- :root {
- /* Palette — non négociable */
- --dark: #0d1b12;
- --dark-mid: #183325;
- --g900: #0e3320;
- --g700: #1b5e3b;
- --g500: #2d7a4f;
- --g300: #6ab98a;
- --g100: #dff0e7;
- --g050: #eef7f1;
- --ink-1: #111111;
- --ink-2: #1e1e1e;
- --ink-3: #636363;
- --page: #f5f3ec;
- --rule: #d8d4c8;
- --tag: #e6e2d8;
- /* Typographies */
- --mono: 'JetBrains Mono', ui-monospace, SFMono-Regular, monospace;
- --serif: 'Fraunces', Georgia, serif;
- --sans: 'DM Sans', system-ui, -apple-system, sans-serif;
- /* Échelle */
- --r-sm: 4px;
- --r-md: 6px;
- --r-pill: 999px;
- --shadow-sm: 0 1px 2px rgba(13, 27, 18, 0.06);
- --shadow-md: 0 6px 24px rgba(13, 27, 18, 0.08);
- --shadow-lg: 0 20px 60px rgba(13, 27, 18, 0.12);
- --nav-h: 64px;
- --max-w: 1100px;
- }
- *, *::before, *::after { margin: 0; padding: 0; box-sizing: border-box; }
- html { scroll-behavior: smooth; scroll-padding-top: calc(var(--nav-h) + 16px); }
- body {
- background: var(--page);
- color: var(--ink-2);
- font-family: var(--sans);
- font-size: 16px;
- line-height: 1.6;
- -webkit-font-smoothing: antialiased;
- -moz-osx-font-smoothing: grayscale;
- overflow-x: hidden;
- }
- ::selection { background: var(--g300); color: var(--dark); }
- a { color: var(--g700); text-decoration: none; transition: color .18s ease; }
- a:hover { color: var(--g500); }
- a:focus-visible { outline: 2px solid var(--g500); outline-offset: 3px; border-radius: 2px; }
- button, .btn { font-family: inherit; cursor: pointer; }
- /* ── NAV ── */
- .nav {
- position: fixed;
- top: 0; left: 0; right: 0;
- height: var(--nav-h);
- background: rgba(13, 27, 18, 0.92);
- backdrop-filter: saturate(140%) blur(10px);
- -webkit-backdrop-filter: saturate(140%) blur(10px);
- border-bottom: 1px solid rgba(106, 185, 138, 0.12);
- z-index: 50;
- }
- .nav-inner {
- max-width: var(--max-w);
- height: 100%;
- margin: 0 auto;
- padding: 0 24px;
- display: flex;
- align-items: center;
- justify-content: space-between;
- gap: 24px;
- }
- .brand {
- font-family: var(--mono);
- font-size: 14px;
- font-weight: 600;
- color: var(--g100);
- letter-spacing: 0.5px;
- display: inline-flex;
- align-items: center;
- gap: 8px;
- }
- .brand::before {
- content: "";
- width: 8px; height: 8px;
- border-radius: 50%;
- background: var(--g300);
- box-shadow: 0 0 0 0 rgba(106,185,138,.7);
- animation: pulse 2.4s infinite;
- }
- @keyframes pulse {
- 0% { box-shadow: 0 0 0 0 rgba(106,185,138,.5); }
- 70% { box-shadow: 0 0 0 10px rgba(106,185,138,0); }
- 100% { box-shadow: 0 0 0 0 rgba(106,185,138,0); }
- }
- .nav-links { display: flex; gap: 4px; list-style: none; }
- .nav-links a {
- font-family: var(--mono);
- font-size: 13px;
- color: rgba(223, 240, 231, 0.75);
- padding: 8px 12px;
- border-radius: var(--r-sm);
- transition: color .18s ease, background .18s ease;
- }
- .nav-links a:hover { color: var(--g100); background: rgba(106,185,138,0.08); }
- .nav-toggle { display: none; }
- @media (max-width: 768px) {
- .nav-links {
- position: absolute;
- top: var(--nav-h); left: 0; right: 0;
- flex-direction: column;
- gap: 0;
- background: var(--dark);
- border-bottom: 1px solid rgba(106,185,138,0.12);
- padding: 8px 0;
- transform: translateY(-200%);
- transition: transform .25s ease;
- }
- .nav-links.open { transform: translateY(0); }
- .nav-links a { padding: 14px 24px; border-radius: 0; }
- .nav-toggle {
- display: inline-flex;
- align-items: center;
- justify-content: center;
- width: 40px; height: 40px;
- margin-left: auto;
- background: transparent;
- border: 1px solid rgba(106,185,138,0.25);
- border-radius: var(--r-sm);
- color: var(--g100);
- }
- .nav-toggle svg { width: 18px; height: 18px; }
- }
- /* ── LAYOUT ── */
- main { padding-top: var(--nav-h); }
- section { padding: 96px 24px; }
- .container { max-width: var(--max-w); margin: 0 auto; }
- .section-label {
- display: inline-flex;
- align-items: center;
- gap: 10px;
- font-family: var(--mono);
- font-size: 12px;
- font-weight: 600;
- color: var(--g500);
- letter-spacing: 0.12em;
- text-transform: uppercase;
- margin-bottom: 18px;
- }
- .section-label::before {
- content: "";
- width: 24px; height: 1px; background: var(--g500);
- }
- .section-dark .section-label { color: var(--g300); }
- .section-dark .section-label::before { background: var(--g300); }
- h2.section-title {
- font-family: var(--serif);
- font-weight: 600;
- font-size: clamp(28px, 4vw, 40px);
- line-height: 1.1;
- color: var(--ink-1);
- letter-spacing: -0.02em;
- margin-bottom: 20px;
- }
- .section-dark h2.section-title { color: #fff; }
- .section-intro {
- font-family: var(--sans);
- font-size: 17px;
- color: var(--ink-2);
- max-width: 64ch;
- }
- .section-dark .section-intro { color: rgba(223, 240, 231, 0.85); }
- /* ── HERO ── */
- .hero {
- position: relative;
- min-height: calc(100vh - var(--nav-h));
- padding: 80px 24px 96px;
- display: flex;
- align-items: center;
- overflow: hidden;
- background:
- radial-gradient(ellipse 80% 60% at 80% 0%, rgba(45,122,79,0.10) 0%, transparent 60%),
- radial-gradient(ellipse 60% 50% at 0% 100%, rgba(27,94,59,0.08) 0%, transparent 55%),
- var(--page);
- }
- .hero-inner {
- max-width: var(--max-w);
- width: 100%;
- margin: 0 auto;
- display: grid;
- grid-template-columns: 1fr;
- gap: 28px;
- position: relative;
- }
- .hero-eyebrow {
- font-family: var(--mono);
- font-size: 13px;
- color: var(--g700);
- letter-spacing: 0.08em;
- display: inline-flex;
- align-items: center;
- gap: 10px;
- }
- .hero-eyebrow::before {
- content: "▍";
- color: var(--g500);
- font-weight: 700;
- }
- .hero-name {
- font-family: var(--serif);
- font-size: clamp(48px, 8vw, 96px);
- font-weight: 600;
- line-height: 0.95;
- letter-spacing: -0.04em;
- color: var(--ink-1);
- }
- .hero-name em {
- font-style: italic;
- font-weight: 400;
- color: var(--g700);
- }
- .hero-title {
- font-family: var(--mono);
- font-size: clamp(14px, 1.6vw, 17px);
- color: var(--ink-2);
- font-weight: 500;
- letter-spacing: 0.02em;
- }
- .hero-title .sep { color: var(--g500); margin: 0 8px; }
- .hero-tagline {
- font-family: var(--serif);
- font-style: italic;
- font-weight: 300;
- font-size: clamp(20px, 2.6vw, 28px);
- line-height: 1.35;
- color: var(--ink-2);
- max-width: 56ch;
- border-left: 3px solid var(--g500);
- padding-left: 20px;
- }
- .hero-cta {
- display: flex;
- gap: 14px;
- flex-wrap: wrap;
- margin-top: 12px;
- }
- .btn {
- display: inline-flex;
- align-items: center;
- gap: 10px;
- font-family: var(--mono);
- font-size: 14px;
- font-weight: 600;
- letter-spacing: 0.02em;
- padding: 14px 22px;
- border-radius: var(--r-md);
- border: 1px solid transparent;
- transition: transform .18s ease, background .18s ease, color .18s ease, border-color .18s ease, box-shadow .18s ease;
- text-decoration: none;
- }
- .btn-primary {
- background: var(--dark);
- color: var(--g100);
- border-color: var(--dark);
- box-shadow: var(--shadow-sm);
- }
- .btn-primary:hover {
- background: var(--g700);
- border-color: var(--g700);
- color: #fff;
- transform: translateY(-1px);
- box-shadow: var(--shadow-md);
- }
- .btn-secondary {
- background: transparent;
- color: var(--dark);
- border-color: var(--rule);
- }
- .btn-secondary:hover {
- border-color: var(--g500);
- color: var(--g700);
- background: var(--g050);
- transform: translateY(-1px);
- }
- .btn .arrow {
- width: 14px; height: 14px;
- transition: transform .18s ease;
- }
- .btn:hover .arrow { transform: translate(2px, -2px); }
- .hero-meta {
- display: flex;
- flex-wrap: wrap;
- gap: 24px;
- margin-top: 16px;
- font-family: var(--mono);
- font-size: 12px;
- color: var(--ink-3);
- letter-spacing: 0.04em;
- }
- .hero-meta span { display: inline-flex; align-items: center; gap: 8px; }
- .hero-meta .dot {
- display: inline-block;
- width: 6px; height: 6px;
- border-radius: 50%;
- background: var(--g500);
- }
- /* Stagger entrance */
- .reveal { opacity: 0; transform: translateY(14px); animation: rise .8s cubic-bezier(.2,.7,.2,1) forwards; }
- .reveal.d1 { animation-delay: .08s; }
- .reveal.d2 { animation-delay: .18s; }
- .reveal.d3 { animation-delay: .30s; }
- .reveal.d4 { animation-delay: .42s; }
- .reveal.d5 { animation-delay: .55s; }
- .reveal.d6 { animation-delay: .68s; }
- @keyframes rise {
- to { opacity: 1; transform: translateY(0); }
- }
- @media (prefers-reduced-motion: reduce) {
- .reveal { opacity: 1; transform: none; animation: none; }
- .brand::before { animation: none; }
- html { scroll-behavior: auto; }
- }
- /* ── ABOUT ── */
- .about {
- background: var(--dark);
- background-image:
- radial-gradient(ellipse 60% 50% at 100% 0%, rgba(45,122,79,0.16) 0%, transparent 55%),
- radial-gradient(ellipse 50% 40% at 0% 100%, rgba(27,94,59,0.12) 0%, transparent 60%);
- color: #fff;
- position: relative;
- }
- .about::before {
- content: ""; position: absolute; left: 0; top: 0; bottom: 0;
- width: 3px;
- background: linear-gradient(to bottom, var(--g300), var(--g700));
- }
- .about-grid {
- display: grid;
- grid-template-columns: 1fr;
- gap: 32px;
- align-items: start;
- }
- .about-text p {
- font-size: 18px;
- line-height: 1.65;
- color: rgba(223, 240, 231, 0.92);
- margin-bottom: 16px;
- max-width: 62ch;
- }
- .about-text strong { color: var(--g300); font-weight: 500; }
- .about-callout {
- border: 1px solid rgba(106,185,138,0.25);
- border-radius: var(--r-md);
- padding: 20px 22px;
- background: rgba(13, 27, 18, 0.4);
- }
- .about-callout dt {
- font-family: var(--mono);
- font-size: 11px;
- color: var(--g300);
- letter-spacing: 0.12em;
- text-transform: uppercase;
- margin-bottom: 6px;
- }
- .about-callout dd {
- font-family: var(--sans);
- font-size: 15px;
- color: var(--g100);
- margin-bottom: 14px;
- }
- .about-callout dd:last-child { margin-bottom: 0; }
- .about-callout a { color: var(--g300); }
- .about-callout a:hover { color: var(--g100); }
- @media (min-width: 768px) {
- .about-grid { grid-template-columns: 1.6fr 1fr; gap: 56px; }
- }
- /* ── STACK ── */
- .stack { background: var(--page); }
- .stack-grid {
- display: grid;
- grid-template-columns: 1fr;
- gap: 20px;
- margin-top: 40px;
- }
- .stack-card {
- background: #fff;
- border: 1px solid var(--rule);
- border-radius: var(--r-md);
- padding: 24px;
- transition: border-color .25s ease, transform .25s ease, box-shadow .25s ease;
- }
- .stack-card:hover {
- border-color: var(--g300);
- transform: translateY(-2px);
- box-shadow: var(--shadow-md);
- }
- .stack-card-head {
- display: flex;
- align-items: baseline;
- justify-content: space-between;
- margin-bottom: 16px;
- padding-bottom: 12px;
- border-bottom: 1px dashed var(--rule);
- }
- .stack-card h3 {
- font-family: var(--serif);
- font-weight: 600;
- font-size: 19px;
- color: var(--ink-1);
- letter-spacing: -0.01em;
- }
- .stack-card-tag {
- font-family: var(--mono);
- font-size: 11px;
- color: var(--g500);
- letter-spacing: 0.1em;
- }
- .pills {
- display: flex;
- flex-wrap: wrap;
- gap: 8px;
- list-style: none;
- }
- .pill {
- display: inline-block;
- font-family: var(--mono);
- font-size: 12px;
- font-weight: 500;
- color: var(--g900);
- background: var(--g050);
- border: 1px solid var(--g100);
- padding: 6px 12px;
- border-radius: var(--r-pill);
- transition: background .18s ease, border-color .18s ease, color .18s ease;
- }
- .pill:hover {
- background: var(--g100);
- border-color: var(--g300);
- color: var(--g700);
- }
- .pill-context {
- opacity: 0.65;
- font-weight: 400;
- margin-left: 3px;
- }
- .stack-note {
- margin-top: 14px;
- padding-top: 12px;
- border-top: 1px dashed var(--rule);
- font-family: var(--mono);
- font-size: 12px;
- color: var(--ink-3);
- letter-spacing: 0.02em;
- display: flex;
- align-items: center;
- gap: 8px;
- flex-wrap: wrap;
- }
- .stack-note code {
- font-family: var(--mono);
- font-size: 12px;
- font-weight: 500;
- color: var(--g700);
- background: var(--g050);
- border: 1px solid var(--g100);
- padding: 2px 8px;
- border-radius: var(--r-sm);
- }
- @media (min-width: 768px) { .stack-grid { grid-template-columns: repeat(2, 1fr); } }
- @media (min-width: 1200px) { .stack-grid { grid-template-columns: repeat(3, 1fr); } }
- /* ── EXPERIENCE ── */
- .experience { background: var(--g050); }
- .timeline {
- position: relative;
- margin-top: 40px;
- padding-left: 28px;
- border-left: 2px solid var(--g100);
- }
- .timeline-item {
- position: relative;
- padding: 0 0 36px 24px;
- }
- .timeline-item:last-child { padding-bottom: 0; }
- .timeline-item::before {
- content: "";
- position: absolute;
- left: -34px; top: 6px;
- width: 12px; height: 12px;
- border-radius: 50%;
- background: var(--page);
- border: 2px solid var(--g500);
- box-shadow: 0 0 0 4px var(--g050);
- }
- .timeline-item.current::before {
- background: var(--g500);
- box-shadow: 0 0 0 4px var(--g050), 0 0 0 8px rgba(45,122,79,0.18);
- }
- .timeline-meta {
- display: flex;
- flex-wrap: wrap;
- align-items: baseline;
- gap: 12px;
- margin-bottom: 8px;
- font-family: var(--mono);
- font-size: 12px;
- color: var(--ink-3);
- letter-spacing: 0.04em;
- }
- .timeline-meta .period {
- color: var(--g700);
- font-weight: 600;
- }
- .timeline-meta .badge {
- display: inline-block;
- background: var(--g100);
- color: var(--g700);
- padding: 2px 8px;
- border-radius: var(--r-pill);
- font-size: 10px;
- font-weight: 600;
- letter-spacing: 0.08em;
- text-transform: uppercase;
- }
- .timeline-item h3 {
- font-family: var(--serif);
- font-weight: 600;
- font-size: 22px;
- color: var(--ink-1);
- margin-bottom: 4px;
- letter-spacing: -0.01em;
- }
- .timeline-item h3 a {
- color: inherit;
- border-bottom: 1px solid transparent;
- transition: border-color .18s ease, color .18s ease;
- }
- .timeline-item h3 a:hover { color: var(--g700); border-color: var(--g500); }
- .timeline-role {
- font-family: var(--mono);
- font-size: 13px;
- color: var(--g700);
- margin-bottom: 12px;
- }
- .timeline-desc {
- color: var(--ink-2);
- line-height: 1.6;
- max-width: 64ch;
- }
- .timeline-contract {
- font-family: var(--mono);
- font-size: 12px;
- color: var(--ink-3);
- font-style: italic;
- margin-top: -6px;
- margin-bottom: 12px;
- }
- .timeline-intro {
- color: var(--ink-2);
- line-height: 1.55;
- max-width: 64ch;
- margin-bottom: 14px;
- }
- .timeline-bullets {
- list-style: none;
- display: flex;
- flex-direction: column;
- gap: 10px;
- margin-bottom: 18px;
- max-width: 70ch;
- }
- .timeline-bullets li {
- position: relative;
- padding-left: 22px;
- color: var(--ink-2);
- line-height: 1.55;
- font-size: 15px;
- }
- .timeline-bullets li::before {
- content: "▸";
- position: absolute;
- left: 0;
- top: 1px;
- color: var(--g500);
- font-size: 13px;
- line-height: 1.55;
- }
- .timeline-stack {
- margin-top: 4px;
- }
- .timeline-stack .pill {
- font-size: 11px;
- padding: 4px 10px;
- }
- /* ── PROJETS ── */
- .projets { background: var(--page); }
- .projects-grid {
- display: grid;
- grid-template-columns: 1fr;
- gap: 20px;
- margin-top: 40px;
- }
- @media (min-width: 768px) { .projects-grid { grid-template-columns: repeat(2, 1fr); } }
- .project-card {
- background: #fff;
- border: 1px solid var(--rule);
- border-radius: var(--r-md);
- padding: 24px;
- transition: border-color .25s ease, transform .25s ease, box-shadow .25s ease;
- display: flex;
- flex-direction: column;
- }
- .project-card:hover {
- border-color: var(--g300);
- transform: translateY(-2px);
- box-shadow: var(--shadow-md);
- }
- .project-card-head {
- display: flex;
- align-items: baseline;
- justify-content: space-between;
- gap: 12px;
- margin-bottom: 12px;
- padding-bottom: 10px;
- border-bottom: 1px dashed var(--rule);
- }
- .project-card h3 {
- font-family: var(--serif);
- font-weight: 600;
- font-size: 20px;
- color: var(--ink-1);
- letter-spacing: -0.01em;
- }
- .project-card-tag {
- font-family: var(--mono);
- font-size: 11px;
- color: var(--g500);
- letter-spacing: 0.1em;
- flex-shrink: 0;
- white-space: nowrap;
- }
- .project-tagline {
- font-family: var(--serif);
- font-style: italic;
- font-weight: 300;
- font-size: 15px;
- color: var(--g700);
- margin-bottom: 12px;
- line-height: 1.4;
- }
- .project-desc {
- color: var(--ink-2);
- line-height: 1.6;
- font-size: 15px;
- margin-bottom: 14px;
- }
- .project-link {
- margin-top: auto;
- font-family: var(--mono);
- font-size: 13px;
- color: var(--g500);
- border-bottom: 1px solid transparent;
- transition: color .18s ease, border-color .18s ease;
- align-self: flex-start;
- }
- .project-link:hover {
- color: var(--g700);
- border-bottom-color: var(--g500);
- }
- /* ── FORMATION ── */
- .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 {
- font-family: var(--serif);
- font-style: italic;
- font-weight: 300;
- color: var(--ink-2);
- line-height: 1.55;
- max-width: 64ch;
- margin-bottom: 20px;
- }
- .formation-themes {
- display: grid;
- grid-template-columns: 1fr;
- gap: 18px;
- margin-top: 24px;
- }
- @media (min-width: 768px) { .formation-themes { grid-template-columns: repeat(2, 1fr); } }
- @media (min-width: 1200px) { .formation-themes { grid-template-columns: repeat(3, 1fr); } }
- .theme-card {
- background: #fff;
- border: 1px solid var(--rule);
- border-radius: var(--r-md);
- padding: 22px;
- transition: border-color .25s ease, transform .25s ease, box-shadow .25s ease;
- display: flex;
- flex-direction: column;
- }
- .theme-card:hover {
- border-color: var(--g300);
- transform: translateY(-2px);
- box-shadow: var(--shadow-md);
- }
- .theme-card-head {
- display: flex;
- align-items: baseline;
- justify-content: space-between;
- gap: 12px;
- margin-bottom: 12px;
- padding-bottom: 10px;
- border-bottom: 1px dashed var(--rule);
- }
- .theme-card h4 {
- font-family: var(--serif);
- font-weight: 600;
- font-size: 18px;
- color: var(--ink-1);
- letter-spacing: -0.01em;
- line-height: 1.2;
- }
- .theme-card-tag {
- font-family: var(--mono);
- font-size: 11px;
- color: var(--g500);
- letter-spacing: 0.1em;
- flex-shrink: 0;
- }
- .theme-quote {
- font-family: var(--serif);
- font-style: italic;
- font-weight: 300;
- color: var(--ink-2);
- font-size: 14px;
- line-height: 1.5;
- padding-left: 12px;
- border-left: 2px solid var(--g500);
- margin-bottom: 16px;
- }
- .theme-list {
- list-style: none;
- display: flex;
- flex-direction: column;
- gap: 10px;
- }
- .theme-list li {
- font-size: 13.5px;
- line-height: 1.55;
- color: var(--ink-2);
- }
- .theme-list code {
- 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 {
- list-style: none;
- display: flex;
- flex-direction: column;
- gap: 10px;
- margin-top: 12px;
- max-width: 64ch;
- }
- .formation-tsrit-list li {
- color: var(--ink-2);
- line-height: 1.55;
- padding-left: 18px;
- position: relative;
- }
- .formation-tsrit-list li::before {
- content: "";
- position: absolute;
- left: 0; top: 0.65em;
- width: 8px; height: 1px;
- background: var(--g500);
- }
- .formation-tsrit-list li strong { color: var(--ink-1); font-weight: 600; }
- .honors {
- display: inline-flex;
- align-items: center;
- gap: 8px;
- font-family: var(--mono);
- font-size: 12px;
- font-weight: 600;
- color: var(--g700);
- background: var(--g100);
- border: 1px solid var(--g300);
- padding: 6px 14px;
- border-radius: var(--r-pill);
- letter-spacing: 0.04em;
- margin: 4px 0 14px;
- }
- .honors::before {
- content: "★";
- color: var(--g500);
- font-size: 13px;
- }
- /* ── MÉTHODE ── */
- .methode { background: var(--page); }
- .methode-list {
- list-style: none;
- display: grid;
- grid-template-columns: 1fr;
- gap: 16px;
- margin-top: 40px;
- max-width: 820px;
- }
- .methode-item {
- display: grid;
- grid-template-columns: 56px 1fr;
- gap: 20px;
- align-items: start;
- background: #fff;
- border: 1px solid var(--rule);
- border-radius: var(--r-md);
- padding: 22px 24px;
- transition: border-color .25s ease, transform .25s ease, box-shadow .25s ease;
- }
- .methode-item:hover {
- border-color: var(--g300);
- transform: translateY(-2px);
- box-shadow: var(--shadow-md);
- }
- .methode-num {
- font-family: var(--mono);
- font-size: 22px;
- font-weight: 700;
- color: var(--g500);
- letter-spacing: -0.02em;
- line-height: 1;
- padding-top: 4px;
- }
- .methode-body h3 {
- font-family: var(--serif);
- font-weight: 600;
- font-size: 19px;
- color: var(--ink-1);
- letter-spacing: -0.01em;
- margin-bottom: 6px;
- line-height: 1.25;
- }
- .methode-body p {
- color: var(--ink-2);
- line-height: 1.6;
- font-size: 15px;
- max-width: 64ch;
- }
- @media (max-width: 640px) {
- .methode-item { grid-template-columns: 1fr; gap: 8px; padding: 20px; }
- .methode-num { font-size: 18px; padding-top: 0; }
- }
- /* ── CONTACT ── */
- .contact {
- background: var(--dark);
- color: #fff;
- position: relative;
- overflow: hidden;
- }
- .contact::after {
- content: "";
- position: absolute;
- right: -120px; bottom: -120px;
- width: 360px; height: 360px;
- border-radius: 50%;
- background: radial-gradient(circle, rgba(45,122,79,0.18) 0%, transparent 70%);
- pointer-events: none;
- }
- .contact-grid {
- display: grid;
- grid-template-columns: 1fr;
- gap: 32px;
- position: relative;
- z-index: 1;
- }
- .contact-list {
- list-style: none;
- display: grid;
- grid-template-columns: 1fr;
- gap: 12px;
- margin-top: 32px;
- }
- .contact-row {
- display: grid;
- grid-template-columns: 28px 1fr;
- gap: 18px;
- align-items: center;
- padding: 18px 20px;
- background: rgba(255, 255, 255, 0.04);
- border: 1px solid rgba(106,185,138,0.18);
- border-radius: var(--r-md);
- transition: border-color .18s ease, background .18s ease, transform .18s ease;
- color: var(--g100);
- }
- .contact-row:hover {
- border-color: var(--g300);
- background: rgba(106,185,138,0.08);
- transform: translateY(-1px);
- color: #fff;
- }
- .contact-row svg { width: 20px; height: 20px; color: var(--g300); flex-shrink: 0; }
- .contact-row .label {
- display: block;
- font-family: var(--mono);
- font-size: 11px;
- color: var(--g300);
- letter-spacing: 0.12em;
- text-transform: uppercase;
- margin-bottom: 2px;
- }
- .contact-row .value {
- font-family: var(--mono);
- font-size: 15px;
- color: #fff;
- font-weight: 500;
- word-break: break-word;
- }
- @media (min-width: 768px) {
- .contact-list { grid-template-columns: repeat(2, 1fr); }
- }
- /* ── FOOTER ── */
- .footer {
- background: #061008;
- color: rgba(223, 240, 231, 0.55);
- padding: 32px 24px;
- border-top: 1px solid rgba(106,185,138,0.1);
- }
- .footer-inner {
- max-width: var(--max-w);
- margin: 0 auto;
- display: flex;
- flex-wrap: wrap;
- gap: 16px 32px;
- justify-content: space-between;
- align-items: center;
- font-family: var(--mono);
- font-size: 12px;
- letter-spacing: 0.04em;
- }
- .footer a { color: var(--g300); }
- .footer a:hover { color: var(--g100); }
- .footer-links { display: flex; gap: 20px; flex-wrap: wrap; }
- /* ── RESPONSIVE TWEAKS ── */
- @media (max-width: 768px) {
- section { padding: 72px 20px; }
- .hero { padding: 56px 20px 72px; }
- .hero-cta .btn { flex: 1 1 auto; justify-content: center; }
- .timeline { padding-left: 22px; }
- .timeline-item { padding-left: 18px; }
- .timeline-item::before { left: -29px; }
- }
- @media (min-width: 1200px) {
- section { padding: 120px 24px; }
- }
- </style>
- </head>
- <body>
- <!-- NAV -->
- <header class="nav" role="banner">
- <div class="nav-inner">
- <a href="#hero" class="brand" aria-label="Bastien Chanot — accueil">bchanot.fr</a>
- <button class="nav-toggle" type="button" aria-label="Ouvrir le menu" aria-expanded="false" aria-controls="primary-nav">
- <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><line x1="3" y1="6" x2="21" y2="6"/><line x1="3" y1="12" x2="21" y2="12"/><line x1="3" y1="18" x2="21" y2="18"/></svg>
- </button>
- <nav aria-label="Navigation principale">
- <ul id="primary-nav" class="nav-links">
- <li><a href="#about">À propos</a></li>
- <li><a href="#stack">Stack</a></li>
- <li><a href="#experience">Parcours</a></li>
- <li><a href="#projets">Projets</a></li>
- <li><a href="#formation">Formation</a></li>
- <li><a href="#methode">Méthode</a></li>
- <li><a href="#contact">Contact</a></li>
- </ul>
- </nav>
- </div>
- </header>
- <main>
- <!-- HERO -->
- <section id="hero" class="hero" aria-labelledby="hero-name">
- <div class="hero-inner">
- <p class="hero-eyebrow reveal">Disponible — CDI systèmes / embarqué · missions freelance</p>
- <h1 id="hero-name" class="hero-name reveal d1">Bastien <em>Chanot</em></h1>
- <p class="hero-title reveal d2">Développeur Systèmes<span class="sep">·</span>Embarqué<span class="sep">·</span>Backend</p>
- <p class="hero-tagline reveal d3">Du kernel Linux au backend Rust — 7 ans de développement systèmes en production.</p>
- <div class="hero-cta reveal d4">
- <a class="btn btn-primary" href="#contact">
- Me contacter
- <svg class="arrow" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"><line x1="5" y1="19" x2="19" y2="5"/><polyline points="8 5 19 5 19 16"/></svg>
- </a>
- <a class="btn btn-secondary" href="CV_Bastien_Chanot.html">
- Voir le CV
- <svg class="arrow" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"><line x1="5" y1="19" x2="19" y2="5"/><polyline points="8 5 19 5 19 16"/></svg>
- </a>
- <a class="btn btn-secondary" href="CV_Bastien_Chanot.pdf" download>
- Télécharger PDF
- <svg class="arrow" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="7 10 12 15 17 10"/><line x1="12" y1="15" x2="12" y2="3"/></svg>
- </a>
- </div>
- <div class="hero-meta reveal d5">
- <span><span class="dot"></span>C · Rust · Linux Kernel</span>
- <span><span class="dot"></span>AOSP · Embarqué</span>
- <span><span class="dot"></span>Backend · Cloud</span>
- </div>
- </div>
- </section>
- <!-- ABOUT -->
- <section id="about" class="about section-dark" aria-labelledby="about-title">
- <div class="container">
- <span class="section-label">À propos</span>
- <h2 id="about-title" class="section-title">Sept ans à écrire du code qui tourne là où ça compte.</h2>
- <div class="about-grid">
- <div class="about-text">
- <p>Je suis développeur systèmes senior, formé à l'<strong>École 42</strong> et passé par six ans chez <strong>CareGame</strong> où j'ai écrit des drivers Linux kernel, un backend Rust temps réel et fait tourner des serveurs GPU bare-metal en production.</p>
- <p>Mon terrain de jeu : <strong>C, Rust, Linux kernel, AOSP, embarqué, infrastructure</strong>. Quand un problème touche au bas niveau — port matériel, latence, sécurité, kernel — c'est là que j'apporte le plus de valeur.</p>
- <p>Ce qui m'intéresse, c'est descendre jusqu'à ce qu'il n'y ait plus de magie — <strong>kernel, hardware, drivers</strong>. Là, soit ça marche, soit ça ne marche pas.</p>
- <p>C'est ce confort-là que je cherche dans une équipe : <strong>systèmes, embarqué, backend bas niveau</strong>, sur une stack dont on peut lire le code source. Pas envie d'aller vers le buzzword-driven — microservices à tout prix, framework du mois, archi conçue pour le pitch deck.</p>
- <p>Aujourd'hui indépendant sous la marque <strong>ZenQuality</strong>, mais avant tout en recherche d'un <strong>CDI en systèmes embarqués ou logiciel</strong> — les missions freelance se font en parallèle.</p>
- <p>Côté présence : <strong>full remote</strong> idéalement, ou <strong>hybride 1 à 2 jours par mois</strong> si l'équipe est à Paris. Mobilité visée à moyen terme : <strong>Pays de la Loire</strong>.</p>
- </div>
- <dl class="about-callout">
- <dt>Recherche prioritaire</dt>
- <dd>CDI systèmes embarqués / logiciel</dd>
- <dt>En parallèle</dt>
- <dd>Missions freelance · ZenQuality</dd>
- <dt>Localisation actuelle</dt>
- <dd>Yerres (91) · mobilité Pays de la Loire</dd>
- <dt>Présence</dt>
- <dd>Full remote · ou 1–2 j/mois si Paris</dd>
- <dt>Site pro</dt>
- <dd><a href="https://zenquality.fr" target="_blank" rel="noopener">zenquality.fr ↗</a></dd>
- </dl>
- </div>
- </div>
- </section>
- <!-- STACK -->
- <section id="stack" class="stack" aria-labelledby="stack-title">
- <div class="container">
- <span class="section-label">Stack technique</span>
- <h2 id="stack-title" class="section-title">Ce avec quoi je travaille, sans le marketing.</h2>
- <p class="section-intro">Outils éprouvés, choisis pour leurs garanties — pas pour leur hype. Tout ce qui suit est en production ou l'a été.</p>
- <div class="stack-grid">
- <article class="stack-card">
- <header class="stack-card-head">
- <h3>Langages</h3>
- <span class="stack-card-tag">// 01</span>
- </header>
- <ul class="pills">
- <li class="pill">C</li>
- <li class="pill">Rust</li>
- <li class="pill">Bash</li>
- <li class="pill">Python</li>
- <li class="pill">Java<span class="pill-context">(AOSP/Android)</span></li>
- </ul>
- <p class="stack-note">Familier avec : <code>C++</code></p>
- </article>
- <article class="stack-card">
- <header class="stack-card-head">
- <h3>Embarqué</h3>
- <span class="stack-card-tag">// 02</span>
- </header>
- <ul class="pills">
- <li class="pill">Linux kernel drivers</li>
- <li class="pill">AOSP</li>
- <li class="pill">ARM / x86</li>
- <li class="pill">GPIO</li>
- <li class="pill">NFC</li>
- <li class="pill">ESC/POS</li>
- <li class="pill">cross-compilation GCC</li>
- </ul>
- </article>
- <article class="stack-card">
- <header class="stack-card-head">
- <h3>Conteneurs</h3>
- <span class="stack-card-tag">// 03</span>
- </header>
- <ul class="pills">
- <li class="pill">Docker</li>
- <li class="pill">LXC / LXD</li>
- <li class="pill">QEMU</li>
- <li class="pill">cgroups</li>
- <li class="pill">namespaces</li>
- </ul>
- </article>
- <article class="stack-card">
- <header class="stack-card-head">
- <h3>Backend</h3>
- <span class="stack-card-tag">// 04</span>
- </header>
- <ul class="pills">
- <li class="pill">Rust</li>
- <li class="pill">WebSocket</li>
- <li class="pill">GPU bare-metal</li>
- <li class="pill">ramdisk I/O</li>
- </ul>
- </article>
- <article class="stack-card">
- <header class="stack-card-head">
- <h3>Systèmes</h3>
- <span class="stack-card-tag">// 05</span>
- </header>
- <ul class="pills">
- <li class="pill">Linux bare-metal</li>
- <li class="pill">AOSP</li>
- <li class="pill">Android Backup</li>
- <li class="pill">systemd</li>
- <li class="pill">SELinux</li>
- </ul>
- </article>
- <article class="stack-card">
- <header class="stack-card-head">
- <h3>Cloud / Infra</h3>
- <span class="stack-card-tag">// 06</span>
- </header>
- <ul class="pills">
- <li class="pill">AWS EC2</li>
- <li class="pill">AWS g4dn bare-metal</li>
- <li class="pill">IAM</li>
- <li class="pill">S3</li>
- <li class="pill">CloudWatch</li>
- <li class="pill">Scaleway VPS</li>
- <li class="pill">OVH / Hetzner</li>
- <li class="pill">Nginx</li>
- <li class="pill">Apache</li>
- <li class="pill">Let's Encrypt</li>
- </ul>
- </article>
- <article class="stack-card">
- <header class="stack-card-head">
- <h3>DevOps</h3>
- <span class="stack-card-tag">// 07</span>
- </header>
- <ul class="pills">
- <li class="pill">Git</li>
- <li class="pill">GitHub Actions</li>
- <li class="pill">GitLab</li>
- <li class="pill">CI/CD</li>
- </ul>
- </article>
- <article class="stack-card">
- <header class="stack-card-head">
- <h3>IA / Outils</h3>
- <span class="stack-card-tag">// 08</span>
- </header>
- <ul class="pills">
- <li class="pill">Claude Code (agents/skills custom)</li>
- <li class="pill">N8N</li>
- <li class="pill">automatisation</li>
- </ul>
- </article>
- </div>
- </div>
- </section>
- <!-- EXPERIENCE -->
- <section id="experience" class="experience" aria-labelledby="experience-title">
- <div class="container">
- <span class="section-label">Parcours</span>
- <h2 id="experience-title" class="section-title">Trois expériences qui résument l'essentiel.</h2>
- <p class="section-intro">Sept ans de développement systèmes en production — du kernel au backend, de la puce au serveur.</p>
- <ol class="timeline">
- <li class="timeline-item current">
- <div class="timeline-meta">
- <span class="period">avr. 2026 — présent</span>
- <span class="badge">En cours</span>
- <span>Yerres · Full remote</span>
- </div>
- <h3><a href="https://zenquality.fr" target="_blank" rel="noopener">ZenQuality</a></h3>
- <p class="timeline-role">Développeur indépendant · Systèmes & Backend</p>
- <p class="timeline-intro">Indépendant systèmes / embarqué / backend. En recherche prioritaire d'un CDI en parallèle.</p>
- <ul class="timeline-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, médiateur CM2C. Plan d'action 12 sprints.</li>
- <li>Site vitrine WordPress (Gutenverse) pour PME esthétique — conception, intégration, déploiement et support continu (hébergement client).</li>
- <li>Setup et auto-hébergement de l'infra ZenQuality sur VPS Scaleway — stack Astro / React / PHP 8 / PostgreSQL conteneurisée Docker, déploiement automatisé, pipeline de production complet.</li>
- </ul>
- <ul class="pills timeline-stack">
- <li class="pill">Astro</li>
- <li class="pill">React</li>
- <li class="pill">PHP 8</li>
- <li class="pill">PostgreSQL</li>
- <li class="pill">Docker</li>
- <li class="pill">Scaleway VPS</li>
- <li class="pill">WordPress / Gutenverse</li>
- <li class="pill">SEO</li>
- <li class="pill">RGPD</li>
- </ul>
- </li>
- <li class="timeline-item">
- <div class="timeline-meta">
- <span class="period">mars 2019 — mars 2025</span>
- <span>Paris · Full remote dès 2020</span>
- </div>
- <h3>CareGame</h3>
- <p class="timeline-role">Développeur logiciel · Systèmes & Backend</p>
- <p class="timeline-intro">Plateforme de cloud gaming en production : fleet GPU bare-metal AWS g4dn, conteneurs AOSP, backend Rust temps réel. Plusieurs centaines de joueurs servis simultanément.</p>
- <ul class="timeline-bullets">
- <li>Conception et maintenance de modules kernel Linux en C (x86 / ARM) — drivers d'interface hôte / conteneur (Linux → AOSP), en interface avec les équipes infra et produit.</li>
- <li>Conception de l'isolation CPU/GPU par session — adaptation de modules GPU Nvidia, partitionnement 2 cœurs/session, sérialisation des accès concurrents sur zones GPU partagées. Résultat : 32 sessions AAA stables par serveur.</li>
- <li>Co-développement du backend Rust orchestrant le cycle de vie des conteneurs AOSP — WebSocket temps réel clients ↔ instances, intégration Docker + LXC, scheduling des sessions sur la fleet GPU.</li>
- <li>Développement de virtual input devices AOSP en Java (touchscreen, gamepad) — pipeline complet inputs frontend → backend Rust → drivers hôtes → injection AOSP, optimisé latence temps réel gameplay AAA.</li>
- <li>Architecture et exploitation de fleet GPU bare-metal AWS g4dn.metal (8× GPU T4, 64 vCPU, ~20 serveurs en pic) — isolation 2 cœurs CPU/session, ramdisk I/O, 32 sessions AAA simultanées/serveur. Plusieurs centaines de joueurs servis en parallèle (Asphalt 9 : 3 sessions/T4).</li>
- <li>Reprise et hardening d'un PoC LXD + Docker issu d'une R&D Nvidia (intégration côté Docker principalement) — adaptation production cloud gaming, débogage kernel/conteneur, performance validée par les équipes Nvidia comme dépassant le scope initial du PoC.</li>
- <li>Collaboration technique directe en anglais avec Canonical (Anbox + builds LXC/LXD non commerciaux, remontée bugs et feature requests) et Ampere Computing (intégration et benchmark de serveurs ARM pré-commerciaux pour évaluation de migration de fleet).</li>
- <li>Pipeline d'installation automatique de jeux AOSP et persistance des sauvegardes utilisateur — fusion Android Backup natif + scripts custom pour cas non gérés nativement (DRM, données externes).</li>
- <li>Développement d'un outil d'orchestration Bash modulaire (1000+ lignes) — parsing avancé arguments Docker, préparation et lancement automatisé conteneurs AOSP, brique appelée par la CI et le backend Rust.</li>
- </ul>
- <ul class="pills timeline-stack">
- <li class="pill">C</li>
- <li class="pill">Rust</li>
- <li class="pill">Java</li>
- <li class="pill">Bash</li>
- <li class="pill">Linux kernel</li>
- <li class="pill">AOSP</li>
- <li class="pill">Docker</li>
- <li class="pill">LXC / LXD</li>
- <li class="pill">AWS g4dn.metal</li>
- <li class="pill">WebSocket</li>
- <li class="pill">Nvidia GPU T4</li>
- </ul>
- </li>
- <li class="timeline-item">
- <div class="timeline-meta">
- <span class="period">fév. 2017 — nov. 2017</span>
- <span>Ivry-sur-Seine</span>
- </div>
- <h3>Deewee</h3>
- <p class="timeline-role">Développeur C · Système embarqué</p>
- <p class="timeline-contract">Stage 42 (6 mois) puis CDD (4 mois)</p>
- <p class="timeline-intro">Boîtier connecté pour interception du flux d'une imprimante thermique.</p>
- <ul class="timeline-bullets">
- <li>Développement du logiciel embarqué en C pour boîtier connecté basé Orange Pi (Debian ARM) — interception du flux ESC/POS d'une imprimante thermique, génération PNG du ticket, transfert WiFi direct vers application mobile à la connexion.</li>
- <li>Intégration matérielle : GPIO physique (bouton + timeout), hotspot WiFi embarqué avec diffusion des credentials via NFC pour appairage automatique.</li>
- </ul>
- <ul class="pills timeline-stack">
- <li class="pill">C</li>
- <li class="pill">Debian ARM</li>
- <li class="pill">Orange Pi</li>
- <li class="pill">ESC/POS</li>
- <li class="pill">GPIO</li>
- <li class="pill">NFC</li>
- <li class="pill">WiFi</li>
- </ul>
- </li>
- </ol>
- </div>
- </section>
- <!-- PROJETS -->
- <section id="projets" class="projets" aria-labelledby="projets-title">
- <div class="container">
- <span class="section-label">Projets</span>
- <h2 id="projets-title" class="section-title">Ce que je fais à côté.</h2>
- <p class="section-intro">Infra perso et code public — l'environnement où je teste, casse, documente, et reprends.</p>
- <div class="projects-grid">
- <article class="project-card">
- <header class="project-card-head">
- <h3>Code source & projets persos</h3>
- <span class="project-card-tag">en continu</span>
- </header>
- <p class="project-tagline">Serveur Git auto-hébergé en production.</p>
- <p class="project-desc">Configuration Claude Code, dotfiles, projets bas-niveau (42, expérimentations C/Rust) — accessibles publiquement. Mirror automatique vers GitHub via push hook.</p>
- <a class="project-link" href="https://git.bchanot.fr/bchanot" target="_blank" rel="noopener">git.bchanot.fr/bchanot ↗</a>
- </article>
- <article class="project-card">
- <header class="project-card-head">
- <h3>Homelab</h3>
- <span class="project-card-tag">en continu</span>
- </header>
- <p class="project-tagline">Infrastructure personnelle.</p>
- <p class="project-desc">Auto-hébergement Git (Gogs) / DNS / VPN / SMB — NAS Asustor, Freebox WireGuard VPN site-to-site, Pi-hole, segmentation réseau, hardening fail2ban, gocryptfs sur dossiers sensibles.</p>
- </article>
- </div>
- </div>
- </section>
- <!-- FORMATION -->
- <section id="formation" class="formation" aria-labelledby="formation-title">
- <div class="container">
- <span class="section-label">Formation</span>
- <h2 id="formation-title" class="section-title">Deux écoles, un fil rouge : le bas niveau.</h2>
- <p class="section-intro">Le socle technique derrière sept ans de production.</p>
- <ol class="timeline">
- <li class="timeline-item">
- <div class="timeline-meta">
- <span class="period">2015 — 2019</span>
- <span>Clichy</span>
- </div>
- <h3>École 42</h3>
- <p class="timeline-role">Cursus en informatique fondamentale</p>
- <p class="formation-school-desc">Kernel, mémoire, shell, sécurité — recoder pour comprendre.</p>
- <div class="formation-themes">
- <article class="theme-card">
- <header class="theme-card-head">
- <h4>Systèmes & Kernel</h4>
- <span class="theme-card-tag">// 01</span>
- </header>
- <p class="theme-quote">Bootstrap d'OS, drivers, gestion matérielle, allocation mémoire.</p>
- <ul class="theme-list">
- <li><code>ft_linux</code> & <code>kfs-1</code> — Linux From Scratch et noyau minimaliste : bootloader ASM, GDT, interruptions, driver char device clavier mappé.</li>
- <li><code>drivers & interrupt</code> — drivers kernel Linux et gestion d'interruptions niveau noyau.</li>
- <li><code>process & memory</code> — modèle de processus Unix, gestion mémoire kernel.</li>
- <li><code>little penguin</code> — contribution kernel Linux : style guide, patch submission, contrib upstream.</li>
- <li><code>malloc</code> — allocateur mémoire complet (libft_malloc.so) avec mmap, zones tiny / small / large.</li>
- </ul>
- </article>
- <article class="theme-card">
- <header class="theme-card-head">
- <h4>Bas niveau & Outils système</h4>
- <span class="theme-card-tag">// 02</span>
- </header>
- <p class="theme-quote">Recoder les outils qu'on utilise tous les jours pour comprendre vraiment ce qu'ils font.</p>
- <ul class="theme-list">
- <li><code>nm</code> — parsing d'exécutables ELF, tables de symboles.</li>
- <li><code>42sh</code> / <code>21</code> — shell POSIX complet : parser, redirections, jobs, history, autocomplétion.</li>
- <li><code>ft_ls</code> — réimplémentation <code>ls</code> avec options POSIX, permissions, tri, formats.</li>
- <li><code>ft_select</code> — TUI custom avec gestion termios, signaux, redessin partiel.</li>
- </ul>
- </article>
- <article class="theme-card">
- <header class="theme-card-head">
- <h4>Sécurité & Algorithmie</h4>
- <span class="theme-card-tag">// 03</span>
- </header>
- <p class="theme-quote">Comprendre comment un système peut être cassé pour savoir le sécuriser.</p>
- <ul class="theme-list">
- <li><code>snow crash</code> — wargame exploitation système : escalation de privilèges, stack overflow, format string, race conditions.</li>
- <li><code>doctor quine</code> — programme auto-réplicatif (métaprogrammation).</li>
- <li><code>ft_ssl_md5</code> — réimplémentation MD5, SHA-256, base64.</li>
- <li><code>lem-in</code>, <code>push-swap</code> — algorithmique : pathfinding (Edmonds-Karp), optimisation de tri sous contrainte.</li>
- </ul>
- </article>
- </div>
- </li>
- <li class="timeline-item">
- <div class="timeline-meta">
- <span class="period">2013 — 2015</span>
- <span>Vincennes</span>
- </div>
- <h3>TSRIT — Next Formation</h3>
- <p class="timeline-role">BTS Technicien Supérieur Réseaux Informatiques & Télécoms</p>
- <span class="honors">Félicitations du jury</span>
- <p class="timeline-desc">Le socle réseau et infrastructure derrière les compétences systèmes.</p>
- <ul class="formation-tsrit-list">
- <li>Architecture réseau (<strong>OSI</strong>, <strong>TCP/IP</strong>), routage, commutation.</li>
- <li>Administration <strong>Linux</strong> / <strong>Windows Server</strong>, sécurité réseau, virtualisation.</li>
- </ul>
- </li>
- </ol>
- </div>
- </section>
- <!-- MÉTHODE -->
- <section id="methode" class="methode" aria-labelledby="methode-title">
- <div class="container">
- <span class="section-label">Méthode</span>
- <h2 id="methode-title" class="section-title">Façon de travailler.</h2>
- <p class="section-intro">Cinq habitudes héritées de sept ans en prod — pas un manifeste, des réflexes.</p>
- <ol class="methode-list">
- <li class="methode-item">
- <span class="methode-num">01</span>
- <div class="methode-body">
- <h3>Comprendre avant d'écrire.</h3>
- <p>Si je n'arrive pas à expliquer comment un système se comporte, je ne touche pas au code.</p>
- </div>
- </li>
- <li class="methode-item">
- <span class="methode-num">02</span>
- <div class="methode-body">
- <h3>Solutions éprouvées > hype.</h3>
- <p>Choix techniques défendus sur leurs garanties (perf, lisibilité, maintenabilité), pas sur leur buzz.</p>
- </div>
- </li>
- <li class="methode-item">
- <span class="methode-num">03</span>
- <div class="methode-body">
- <h3>Autonome sur la décomposition technique.</h3>
- <p>En interface directe avec les équipes produit, infra et stakeholders externes quand ça compte.</p>
- </div>
- </li>
- <li class="methode-item">
- <span class="methode-num">04</span>
- <div class="methode-body">
- <h3>Trace écrite par défaut.</h3>
- <p>Décisions, post-mortems, docs internes. Le code qui n'est pas documenté est un code qui sera réécrit dans 6 mois.</p>
- </div>
- </li>
- <li class="methode-item">
- <span class="methode-num">05</span>
- <div class="methode-body">
- <h3>Anglais ou français.</h3>
- <p>Communication aussi bien en anglais (Nvidia, Canonical, Ampere) qu'en français — peu importe, je m'adapte à l'équipe.</p>
- </div>
- </li>
- </ol>
- </div>
- </section>
- <!-- CONTACT -->
- <section id="contact" class="contact section-dark" aria-labelledby="contact-title">
- <div class="container">
- <span class="section-label">Contact</span>
- <h2 id="contact-title" class="section-title">Une mission, une question technique, un projet ?</h2>
- <p class="section-intro">Le plus simple : l'email. Réponse sous 48 h ouvrées.</p>
- <div class="contact-grid">
- <ul class="contact-list">
- <li>
- <a class="contact-row" href="mailto:bastien@bchanot.fr">
- <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><rect x="3" y="5" width="18" height="14" rx="2"/><polyline points="3 7 12 13 21 7"/></svg>
- <span>
- <span class="label">Email</span>
- <span class="value">bastien@bchanot.fr</span>
- </span>
- </a>
- </li>
- <li>
- <a class="contact-row" href="tel:+33778822297">
- <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M22 16.92v3a2 2 0 0 1-2.18 2 19.86 19.86 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6A19.86 19.86 0 0 1 2.12 4.18 2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72c.13.96.37 1.9.72 2.8a2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45c.9.35 1.84.59 2.8.72A2 2 0 0 1 22 16.92z"/></svg>
- <span>
- <span class="label">Téléphone</span>
- <span class="value">+33 7 78 82 22 97</span>
- </span>
- </a>
- </li>
- <li>
- <a class="contact-row" href="https://zenquality.fr" target="_blank" rel="noopener">
- <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="12" cy="12" r="10"/><line x1="2" y1="12" x2="22" y2="12"/><path d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z"/></svg>
- <span>
- <span class="label">Site pro</span>
- <span class="value">zenquality.fr</span>
- </span>
- </a>
- </li>
- <li>
- <a class="contact-row" href="CV_Bastien_Chanot.pdf" download>
- <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="7 10 12 15 17 10"/><line x1="12" y1="15" x2="12" y2="3"/></svg>
- <span>
- <span class="label">CV</span>
- <span class="value">Télécharger le PDF</span>
- </span>
- </a>
- </li>
- </ul>
- </div>
- </div>
- </section>
- </main>
- <!-- FOOTER -->
- <footer class="footer" role="contentinfo">
- <div class="footer-inner">
- <span>© 2026 · Bastien Chanot · bchanot.fr</span>
- <div class="footer-links">
- <a href="CV_Bastien_Chanot.html">CV (HTML)</a>
- <a href="CV_Bastien_Chanot.pdf" download>CV (PDF)</a>
- <a href="https://zenquality.fr" target="_blank" rel="noopener">zenquality.fr ↗</a>
- </div>
- </div>
- </footer>
- <script>
- // Mobile nav toggle
- (function () {
- const toggle = document.querySelector('.nav-toggle');
- const links = document.getElementById('primary-nav');
- if (!toggle || !links) return;
- toggle.addEventListener('click', () => {
- const open = links.classList.toggle('open');
- toggle.setAttribute('aria-expanded', String(open));
- toggle.setAttribute('aria-label', open ? 'Fermer le menu' : 'Ouvrir le menu');
- });
- links.addEventListener('click', (e) => {
- if (e.target instanceof HTMLAnchorElement && links.classList.contains('open')) {
- links.classList.remove('open');
- toggle.setAttribute('aria-expanded', 'false');
- toggle.setAttribute('aria-label', 'Ouvrir le menu');
- }
- });
- })();
- // Active section highlight in nav (subtle — color shift only)
- (function () {
- const sections = document.querySelectorAll('main section[id]');
- const navLinks = document.querySelectorAll('.nav-links a[href^="#"]');
- if (!('IntersectionObserver' in window) || !sections.length) return;
- const map = new Map();
- navLinks.forEach(a => {
- const id = a.getAttribute('href').slice(1);
- map.set(id, a);
- });
- const io = new IntersectionObserver((entries) => {
- entries.forEach(entry => {
- const link = map.get(entry.target.id);
- if (!link) return;
- if (entry.isIntersecting) {
- navLinks.forEach(a => a.style.color = '');
- link.style.color = 'var(--g100)';
- }
- });
- }, { rootMargin: '-40% 0px -55% 0px', threshold: 0 });
- sections.forEach(s => io.observe(s));
- })();
- </script>
- </body>
- </html>
|