feat: update portfolio.astro

This commit is contained in:
Clément SAILLANT
2026-03-20 14:53:47 +01:00
parent eb7de7f44d
commit 4420f18eb0
+122 -34
View File
@@ -11,55 +11,124 @@ import '@/styles/global.css';
permettent de zoomer, naviguer et inspecter chaque composant.
</p>
<!-- KXKM ESP32 Base Board -->
<section class="portfolio-section">
<h2 class="portfolio-h2">Viewer interactif KiCad</h2>
<h2 class="portfolio-h2">KXKM — ESP32 Battery Management Board</h2>
<p class="portfolio-desc">
Chargez un fichier <code>.kicad_sch</code> ou <code>.kicad_pcb</code> pour l'explorer directement dans le navigateur.
Carte de gestion batterie et ESP32 pour systèmes audio autonomes.
Monitoring batterie, alimentation régulée, connectique terrain.
<span class="portfolio-tag">ESP32</span>
<span class="portfolio-tag">BMS</span>
<span class="portfolio-tag">Audio</span>
<span class="portfolio-tag">KXKM</span>
</p>
<div class="viewer-tabs">
<button class="viewer-tab viewer-tab--active" data-target="kxkm-esp32-sch">Schéma</button>
<button class="viewer-tab" data-target="kxkm-esp32-pcb">PCB</button>
<button class="viewer-tab" data-target="kxkm-batt-sch">Monitoring batterie</button>
<button class="viewer-tab" data-target="kxkm-power-sch">Alimentation</button>
</div>
<div class="viewer-panels">
<div class="viewer-panel viewer-panel--active" id="kxkm-esp32-sch">
<kicanvas-embed src="/assets/kicad/kxkm-esp32-base.kicad_sch" controls="full" theme="kicad" style="width:100%;height:600px;"></kicanvas-embed>
</div>
<div class="viewer-panel" id="kxkm-esp32-pcb">
<kicanvas-embed src="/assets/kicad/kxkm-esp32-base.kicad_pcb" controls="full" theme="kicad" style="width:100%;height:600px;"></kicanvas-embed>
</div>
<div class="viewer-panel" id="kxkm-batt-sch">
<kicanvas-embed src="/assets/kicad/kxkm-battery-monitoring.kicad_sch" controls="full" theme="kicad" style="width:100%;height:600px;"></kicanvas-embed>
</div>
<div class="viewer-panel" id="kxkm-power-sch">
<kicanvas-embed src="/assets/kicad/kxkm-power.kicad_sch" controls="full" theme="kicad" style="width:100%;height:600px;"></kicanvas-embed>
</div>
</div>
</section>
<!-- KXKM Batterie Parallelator -->
<section class="portfolio-section">
<h2 class="portfolio-h2">KXKM — Batterie Parallelator (BMU v2)</h2>
<p class="portfolio-desc">
Système de parallélisation de batteries lithium avec monitoring individuel,
commutation MOSFET et bus I2C. Gestion intelligente multi-pack pour autonomie terrain.
<span class="portfolio-tag">BMS</span>
<span class="portfolio-tag">MOSFET</span>
<span class="portfolio-tag">I2C</span>
<span class="portfolio-tag">Lithium</span>
</p>
<div class="viewer-tabs">
<button class="viewer-tab viewer-tab--active" data-target="para-bmu-sch">Schéma BMU</button>
<button class="viewer-tab" data-target="para-bmu-pcb">PCB BMU</button>
<button class="viewer-tab" data-target="para-mosfet-sch">Switch MOSFET</button>
<button class="viewer-tab" data-target="para-mosfet-pcb">PCB MOSFET</button>
<button class="viewer-tab" data-target="para-batt-sch">Batteries</button>
<button class="viewer-tab" data-target="para-power-sch">Alimentation</button>
</div>
<div class="viewer-panels">
<div class="viewer-panel viewer-panel--active" id="para-bmu-sch">
<kicanvas-embed src="/assets/kicad/kxkm-parallelator-bmu-v2.kicad_sch" controls="full" theme="kicad" style="width:100%;height:600px;"></kicanvas-embed>
</div>
<div class="viewer-panel" id="para-bmu-pcb">
<kicanvas-embed src="/assets/kicad/kxkm-parallelator-bmu-v2.kicad_pcb" controls="full" theme="kicad" style="width:100%;height:600px;"></kicanvas-embed>
</div>
<div class="viewer-panel" id="para-mosfet-sch">
<kicanvas-embed src="/assets/kicad/kxkm-parallelator-mosfet.kicad_sch" controls="full" theme="kicad" style="width:100%;height:600px;"></kicanvas-embed>
</div>
<div class="viewer-panel" id="para-mosfet-pcb">
<kicanvas-embed src="/assets/kicad/kxkm-parallelator-mosfet.kicad_pcb" controls="full" theme="kicad" style="width:100%;height:600px;"></kicanvas-embed>
</div>
<div class="viewer-panel" id="para-batt-sch">
<kicanvas-embed src="/assets/kicad/kxkm-parallelator-batteries.kicad_sch" controls="full" theme="kicad" style="width:100%;height:600px;"></kicanvas-embed>
</div>
<div class="viewer-panel" id="para-power-sch">
<kicanvas-embed src="/assets/kicad/kxkm-parallelator-power.kicad_sch" controls="full" theme="kicad" style="width:100%;height:600px;"></kicanvas-embed>
</div>
</div>
</section>
<!-- Upload custom -->
<section class="portfolio-section">
<h2 class="portfolio-h2">Viewer libre</h2>
<p class="portfolio-desc">
Chargez votre propre fichier <code>.kicad_sch</code> ou <code>.kicad_pcb</code> pour l'explorer.
</p>
<div class="portfolio-upload">
<label for="kicad-file" class="portfolio-upload-label">
Glissez un fichier KiCad ou cliquez pour ouvrir
</label>
<input type="file" id="kicad-file" accept=".kicad_sch,.kicad_pcb,.kicad_prj" class="portfolio-upload-input" />
</div>
<div id="viewer-container" class="portfolio-viewer" style="display:none;">
<kicanvas-embed id="kicad-viewer" controls="full" theme="kicad" style="width:100%;height:600px;border-radius:8px;border:1px solid var(--line, #3a2f24);"></kicanvas-embed>
<div id="viewer-container" class="viewer-wrap" style="display:none;">
<kicanvas-embed id="kicad-viewer" controls="full" theme="kicad" style="width:100%;height:600px;"></kicanvas-embed>
</div>
<p class="portfolio-note">
Propulsé par <a href="https://kicanvas.org" target="_blank" rel="noopener" class="portfolio-link">KiCanvas</a> — viewer open source pour KiCad.
</p>
</section>
<!-- Projets -->
<section class="portfolio-section">
<h2 class="portfolio-h2">Projets récents</h2>
<h2 class="portfolio-h2">Autres projets</h2>
<div class="portfolio-grid">
<div class="portfolio-card">
<h3>Contrôleur LED DMX</h3>
<p>Carte custom ESP32 pour pilotage LED haute puissance via DMX512. Spectacle vivant, KXKM.</p>
<span class="portfolio-tag">ESP32</span>
<span class="portfolio-tag">DMX</span>
<span class="portfolio-tag">LED</span>
<span class="portfolio-tag">ESP32</span><span class="portfolio-tag">DMX</span><span class="portfolio-tag">LED</span>
</div>
<div class="portfolio-card">
<h3>Banc de test BMS</h3>
<p>Système de test automatisé pour batteries lithium. Mesure, charge/décharge, logging.</p>
<span class="portfolio-tag">BMS</span>
<span class="portfolio-tag">Mesure</span>
<span class="portfolio-tag">XT60</span>
<span class="portfolio-tag">BMS</span><span class="portfolio-tag">Mesure</span><span class="portfolio-tag">XT60</span>
</div>
<div class="portfolio-card">
<h3>Automate Siemens S7</h3>
<p>Diagnostic et reprogrammation d'automate industriel. Migration firmware, câblage armoire.</p>
<span class="portfolio-tag">Siemens</span>
<span class="portfolio-tag">PLC</span>
<span class="portfolio-tag">Industrie</span>
<span class="portfolio-tag">Siemens</span><span class="portfolio-tag">PLC</span><span class="portfolio-tag">Industrie</span>
</div>
</div>
</section>
<p class="portfolio-note">
Viewers propulsés par <a href="https://kicanvas.org" target="_blank" rel="noopener" class="portfolio-link">KiCanvas</a> — open source.
Fichiers source : <a href="https://github.com/KomplexKapharnaum/KXKM_ESP32_Audio_Battery_hardware" target="_blank" rel="noopener" class="portfolio-link">GitHub KXKM</a>.
</p>
<div class="portfolio-cta">
<a href="/preview#contact" class="portfolio-btn">Discuter de votre projet →</a>
</div>
@@ -68,41 +137,60 @@ import '@/styles/global.css';
<script type="module" src="/assets/js/kicanvas.js"></script>
<script>
// Tab switching for viewer panels
document.querySelectorAll('.viewer-tab').forEach(tab => {
tab.addEventListener('click', () => {
const section = tab.closest('.portfolio-section');
section.querySelectorAll('.viewer-tab').forEach(t => t.classList.remove('viewer-tab--active'));
section.querySelectorAll('.viewer-panel').forEach(p => p.classList.remove('viewer-panel--active'));
tab.classList.add('viewer-tab--active');
document.getElementById(tab.dataset.target)?.classList.add('viewer-panel--active');
});
});
// File upload
const fileInput = document.getElementById('kicad-file');
const viewerContainer = document.getElementById('viewer-container');
const viewer = document.getElementById('kicad-viewer');
fileInput?.addEventListener('change', async (e) => {
fileInput?.addEventListener('change', (e) => {
const file = e.target.files?.[0];
if (!file) return;
const url = URL.createObjectURL(file);
viewer?.setAttribute('src', url);
viewer?.setAttribute('src', URL.createObjectURL(file));
if (viewerContainer) viewerContainer.style.display = 'block';
});
</script>
<style>
.portfolio-page { max-width:900px; margin:0 auto; padding:48px 24px; min-height:100vh; }
.portfolio-page { max-width:960px; margin:0 auto; padding:48px 24px; min-height:100vh; }
.portfolio-title { font-family:'Fraunces',serif; font-size:clamp(28px,5vw,42px); color:var(--text,#f4eee3); margin:0 0 16px; }
.portfolio-intro { font-family:'IBM Plex Mono',monospace; font-size:14px; color:var(--text-muted,#d6cbb9); line-height:1.7; margin:0 0 40px; }
.portfolio-section { margin-bottom:48px; }
.portfolio-h2 { font-family:'Fraunces',serif; font-size:22px; color:var(--accent,#f1c27a); margin:0 0 12px; }
.portfolio-desc { font-size:14px; color:var(--text-dim,#b6a894); margin:0 0 20px; }
.portfolio-desc { font-size:14px; color:var(--text-dim,#b6a894); margin:0 0 16px; line-height:1.6; }
.portfolio-desc code { color:var(--electric,#5bd1d8); background:var(--surface,#1a1510); padding:2px 6px; border-radius:3px; font-size:13px; }
.viewer-tabs { display:flex; gap:4px; margin-bottom:12px; border-bottom:1px solid var(--line,#3a2f24); }
.viewer-tab { font-family:'IBM Plex Mono',monospace; font-size:12px; padding:8px 14px; background:none; border:none; color:var(--text-dim,#b6a894); cursor:pointer; border-bottom:2px solid transparent; transition:all .2s; }
.viewer-tab:hover { color:var(--text,#f4eee3); }
.viewer-tab--active { color:var(--electric,#5bd1d8); border-bottom-color:var(--electric,#5bd1d8); }
.viewer-panel { display:none; }
.viewer-panel--active { display:block; }
.viewer-wrap { border-radius:8px; overflow:hidden; border:1px solid var(--line,#3a2f24); }
.portfolio-upload { border:2px dashed var(--line,#3a2f24); border-radius:8px; padding:32px; text-align:center; margin-bottom:20px; transition:border-color .2s; }
.portfolio-upload:hover { border-color:var(--electric,#5bd1d8); }
.portfolio-upload-label { font-family:'IBM Plex Mono',monospace; font-size:14px; color:var(--text-muted,#d6cbb9); cursor:pointer; display:block; }
.portfolio-upload-input { position:absolute; opacity:0; width:0; height:0; }
.portfolio-viewer { margin:20px 0; border-radius:8px; overflow:hidden; }
.portfolio-note { font-size:12px; color:var(--text-dim,#b6a894); opacity:.6; }
.portfolio-link { color:var(--electric,#5bd1d8); }
.portfolio-grid { display:grid; grid-template-columns:repeat(auto-fit,minmax(260px,1fr)); gap:20px; }
.portfolio-grid { display:grid; grid-template-columns:repeat(auto-fit,minmax(260px,1fr)); gap:16px; }
.portfolio-card { background:var(--surface,#1a1510); border:1px solid var(--line,#3a2f24); border-radius:8px; padding:20px; }
.portfolio-card h3 { font-family:'Fraunces',serif; font-size:18px; color:var(--text,#f4eee3); margin:0 0 8px; }
.portfolio-card p { font-size:14px; color:var(--text-muted,#d6cbb9); line-height:1.6; margin:0 0 12px; }
.portfolio-tag { display:inline-block; font-family:'IBM Plex Mono',monospace; font-size:11px; color:var(--electric,#5bd1d8); background:rgba(91,209,216,.1); padding:2px 8px; border-radius:3px; margin-right:6px; margin-bottom:4px; }
.portfolio-cta { text-align:center; margin-top:48px; }
.portfolio-card p { font-size:13px; color:var(--text-muted,#d6cbb9); line-height:1.6; margin:0 0 12px; }
.portfolio-tag { display:inline-block; font-family:'IBM Plex Mono',monospace; font-size:11px; color:var(--electric,#5bd1d8); background:rgba(91,209,216,.1); padding:2px 8px; border-radius:3px; margin-right:4px; margin-bottom:4px; }
.portfolio-note { font-size:12px; color:var(--text-dim,#b6a894); opacity:.6; margin:0 0 24px; }
.portfolio-link { color:var(--electric,#5bd1d8); }
.portfolio-cta { text-align:center; margin-top:32px; }
.portfolio-btn { display:inline-block; padding:12px 28px; font-family:'IBM Plex Mono',monospace; font-size:14px; color:var(--bg,#0b0a09); background:var(--accent,#f1c27a); text-decoration:none; border-radius:4px; transition:all .2s; }
.portfolio-btn:hover { background:var(--electric,#5bd1d8); box-shadow:0 0 20px rgba(91,209,216,.3); }
.portfolio-btn:hover { background:var(--electric,#5bd1d8); }
</style>