From cf10410f2f3a1cab02092e42794bcf49b69b6291 Mon Sep 17 00:00:00 2001 From: LATCHIMY Nicolas Date: Sat, 21 Feb 2026 17:52:28 +0400 Subject: [PATCH] card cosmo ambient --- src/components/Card.astro | 152 ++++++++++++++++++++++---- src/pages/[...id].astro | 218 +++++++++++++++++++++++++++++++------ src/pages/collection.astro | 5 +- src/pages/index.astro | 30 ++++- 4 files changed, 347 insertions(+), 58 deletions(-) diff --git a/src/components/Card.astro b/src/components/Card.astro index d29f123..addd7d6 100644 --- a/src/components/Card.astro +++ b/src/components/Card.astro @@ -2,7 +2,7 @@ const { frontmatter, streakCount = 1 } = Astro.props; const { birthDate, health, manifestations, date, name } = frontmatter; -// 1. CALCUL DU NIVEAU ET VARIABLES DE BASE [cite: 25, 26, 27] +// 1. CALCUL DU NIVEAU ET VARIABLES DE BASE const referenceDate = new Date(date); const birth = new Date(birthDate); let age = referenceDate.getFullYear() - birth.getFullYear(); @@ -15,16 +15,19 @@ if ( const stress = health?.somatic?.stress_level ?? 2; const hallucinations = health?.mental?.hallucinations ?? 0; const sleepBase = health?.somatic?.sleep_avg ?? 7.5; +const energy = health?.somatic?.energy_level ?? 5; +const hygieneScore = health?.somatic?.hygiene_level ?? 5; -// 2. RÉINTÉGRATION DES COMPTAGES (Le fix pour l'erreur) [cite: 28, 29, 30, 31] +// 2. RÉINTÉGRATION DES COMPTAGES const counts = { PRO: manifestations?.filter((m) => m.cercle === "PRO").length || 0, SAN: manifestations?.filter((m) => m.cercle === "SAN").length || 0, SOC: manifestations?.filter((m) => m.cercle === "SOC").length || 0, FLX: manifestations?.filter((m) => m.cercle === "FLX").length || 0, + HYG: manifestations?.filter((m) => m.cercle === "HYG").length || 0, }; -// 3. SCORE D'HARMONIE RAFFINÉ [cite: 32, 33] +// 3. SCORE D'HARMONIE RAFFINÉ const rawHarmony = manifestations?.reduce((acc, m) => { if (m.type === "pos") return acc + 1; @@ -33,7 +36,7 @@ const rawHarmony = }, 0) || 0; const uniqueCercles = new Set(manifestations?.map((m) => m.cercle)).size; -const hasAllCercles = uniqueCercles === 4; +const hasAllCercles = uniqueCercles === 5; const harmonyScore = rawHarmony + (hasAllCercles ? 2 : 0); // 4. SYSTÈME DE RARETÉ ET SHINY @@ -56,16 +59,22 @@ const autoMotivation = health?.mental?.motivation ?? Math.min(10, uniqueCercles * 2.5); const streakBonus = Math.floor(streakCount / 7); const autoAtk = Math.min( - 12, + 15, counts.PRO * 2 + Math.floor(autoMotivation / 4) + + Math.floor(energy / 3) + // L'énergie booste l'attaque (harmonyScore > 0 ? 1 : 0) + streakBonus, ); const sleepPenalty = sleepBase - (counts.PRO > 5 ? 1 : 0) < 6 ? 2 : 0; const autoDef = Math.max( 0, - 10 - stress - hallucinations - sleepPenalty + streakBonus, + 10 + + Math.floor(hygieneScore / 2) - + stress - + hallucinations - + sleepPenalty + + streakBonus, ); const autoCost = Math.max(1, Math.ceil((manifestations?.length || 0) / 2)); @@ -129,6 +138,36 @@ const circleSummaries = Object.entries(counts) manifestations?.find((m) => m.cercle === type && m.type)?.type || "neu", })); + +// LAYER AUTO : Les constantes biologiques et calculées +const autoLayer = [ + { + label: "Sommeil", + value: `${sleepBase}h`, + status: sleepBase < 6 ? "critique" : "stable", + }, + { + label: "Énergie", + value: `${energy}/10`, + status: energy < 3 ? "bas" : "normal", + }, + { + label: "Hallucinations", + value: hallucinations, + status: hallucinations > 4 ? "alerte" : "calme", + }, + { label: "Stabilité", value: currentBiome.label, status: "info" }, +]; + +// LAYER MANUEL : Les leviers d'action et ressentis +const manualLayer = [ + { label: "Stress ressenti", value: `${stress}/10` }, + { label: "Hygiène foyer", value: `${hygieneScore}/10` }, + { + label: "Harmonie globale", + value: harmonyScore > 0 ? `+${harmonyScore}` : harmonyScore, + }, +]; ---
-
-
-
    -
  • Origine : {biomeReason}
  • -
  • - Série : Bonus +{streakBonus} ATK/DEF -
  • -
  • - Stress {stress} • Sommeil {sleepBase}h • Harmonie { - harmonyScore > 0 ? `+${harmonyScore}` : harmonyScore - } -
  • -
+
+
+
Indicateurs Somatiques
+
+ { + autoLayer.map((stat) => ( +
+ {stat.label} + {stat.value} +
+ )) + } +
+
+ +
+ +
+
Ressentis & Hygiène
+
+ { + manualLayer.map((stat) => ( +
+ {stat.label} + {stat.value} +
+ )) + } +
@@ -283,14 +338,71 @@ const circleSummaries = Object.entries(counts) .FLX { border-bottom: 3px solid #10b981; } + .HYG { + border-bottom: 3px solid #9400ff; + } .rules-box { margin-top: auto; padding: 6px; background: rgba(255, 255, 255, 0.25); border-radius: 6px; } + .medical-dashboard { + color: #0f172a; + padding: 8px; + } + + .layer-title { + font-size: 0.65rem; + text-transform: uppercase; + letter-spacing: 0.5px; + font-weight: 800; + margin-bottom: 5px; + color: #475569; + } + + .stats-grid { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 4px; + } + + .stat-item { + display: flex; + justify-content: space-between; + font-size: 0.8rem; + padding: 2px 4px; + border-radius: 3px; + background: rgba(0, 0, 0, 0.05); + } + + /* Alertes visuelles pour le médecin */ + .stat-item.critique { + background: #fee2e27d; + color: #991b1b; + border-left: 3px solid #ef4444; + } + .stat-item.alerte { + background: #fef3c77d; + color: #92400e; + border-left: 3px solid #f59e0b; + } + + .layer-divider { + border: 0; + border-top: 1px dashed #cbd5e1; + margin: 8px 0; + } + + .stat-label { + font-weight: 500; + } + .stat-value { + font-family: monospace; + font-weight: bold; + } .mechanics-summary li { - font-size: 0.58rem; + font-size: 1rem; list-style: none; line-height: 1.3; } diff --git a/src/pages/[...id].astro b/src/pages/[...id].astro index 98a88b7..07685d6 100644 --- a/src/pages/[...id].astro +++ b/src/pages/[...id].astro @@ -18,9 +18,24 @@ export async function getStaticPaths() { const { entry, sortedEntries } = Astro.props; const manifestations = entry.data.manifestations || []; + +// Groupement des manifestations par catégorie (cercle) +const groupedManifestations = manifestations.reduce((acc, m) => { + if (!acc[m.cercle]) { + acc[m.cercle] = []; + } + acc[m.cercle].push(m); + return acc; +}, {}); + +// Définition de l'ordre d'affichage des cercles +const circleOrder = ["PRO", "SAN", "HYG", "SOC", "FLX"]; --- - + +
+ ← Retour à la collection +