+
+ Prochaine Génération
+
{formatNumber(resources)} / {formatNumber(PRESTIGE_THRESHOLD)}
-
+
-
+
{remaining > 0
- ? `${formatNumber(remaining)} têtards restants`
+ ? `${formatNumber(remaining)} restants`
: "Nouvelle Génération disponible !"}
-
+
);
}
diff --git a/Frontend/src/components/PrestigePanel.tsx b/Frontend/src/components/PrestigePanel.tsx
index f221b2f..a789200 100644
--- a/Frontend/src/components/PrestigePanel.tsx
+++ b/Frontend/src/components/PrestigePanel.tsx
@@ -1,12 +1,10 @@
// PrestigePanel.tsx — Nouvelle Génération (prestige)
-// Visible uniquement quand canPrestige = true (ressources >= 1 000 000)
import { useGameStore } from "../store/useGameStore";
import { computePrestigeDna } from "../core/economy";
export function PrestigePanel() {
- const { prestigeCount, prestigeMultiplier, ancestralDna, lifetimeTadpoles } =
- useGameStore((s) => s.state);
+ const { lifetimeTadpoles } = useGameStore((s) => s.state);
const canPrestige = useGameStore((s) => s.canPrestige);
const prestige = useGameStore((s) => s.prestige);
@@ -18,40 +16,26 @@ export function PrestigePanel() {
`Reset : têtards et générateurs à zéro.\n` +
`Récompense : +${dnaPreview} ADN Ancestral\n` +
` +0.1x multiplicateur permanent\n\n` +
- `ADN actuel : ${ancestralDna}\n` +
- `ADN après : ${ancestralDna + dnaPreview}\n` +
- `Multiplicateur : x${prestigeMultiplier.toFixed(1)} → x${(prestigeMultiplier + 0.1).toFixed(1)}\n\n` +
`L'Arbre d'Évolution persiste.\n\n` +
- `Confirmer la Nouvelle Génération ?`
+ `Confirmer ?`
);
if (confirmed) prestige();
};
return (
-
-
Prestige
-
- Gén. {prestigeCount}
- Mult x{prestigeMultiplier.toFixed(1)}
- ADN {ancestralDna}
-
-
+
+
Prestige
{canPrestige ? (
-
-
+
+
+{dnaPreview} ADN · +0.1x mult
-
-
+
) : (
-
- Atteins 1M têtards pour prestige
-
+
Atteins 1M têtards pour prestige
)}
);
diff --git a/Frontend/src/pages/Home.jsx b/Frontend/src/pages/Home.jsx
index f01d022..32c3068 100755
--- a/Frontend/src/pages/Home.jsx
+++ b/Frontend/src/pages/Home.jsx
@@ -8,17 +8,16 @@ import { GeneratorShop } from "../components/GeneratorShop";
import { PrestigePanel } from "../components/PrestigePanel";
import { EvolutionTree } from "../components/EvolutionTree";
import { MilestoneBar } from "../components/MilestoneBar";
+import { CockpitHeader } from "../components/CockpitHeader";
import { ACHIEVEMENTS } from "../data/achievements";
import "../scss/home.scss";
+import "../scss/components/game-panels.scss";
export default function Home() {
const [toggleRain] = useOutletContext();
const click = useGameStore((s) => s.click);
const resources = useGameStore((s) => s.state.resources);
const clickMultiplier = useGameStore((s) => s.state.clickMultiplier);
- const productionPerSecond = useGameStore((s) => s.productionPerSecond);
- const state = useGameStore((s) => s.state);
- const prestigeMultiplier = state.prestigeMultiplier;
const createParticle = useCallback((clientX, clientY) => {
const particle = document.createElement("span");
@@ -122,24 +121,20 @@ export default function Home() {
{formatNumber(resources)}
-
- {formatNumber(productionPerSecond)}/s
- ·
- x{clickMultiplier} ponte
- ·
- x{prestigeMultiplier.toFixed(1)} mult
-
- {/* Game panels — sidebar (right desktop, bottom mobile) */}
+ {/* Cockpit — sidebar structurée en zones */}
diff --git a/Frontend/src/scss/components/game-panels.scss b/Frontend/src/scss/components/game-panels.scss
new file mode 100644
index 0000000..6f2b30b
--- /dev/null
+++ b/Frontend/src/scss/components/game-panels.scss
@@ -0,0 +1,172 @@
+// game-panels.scss — Système de style partagé pour tous les panels du cockpit
+// Modifier les tokens dans root.scss, pas ici.
+
+// --- Panel de base ---
+.gp {
+ display: flex;
+ flex-direction: column;
+ gap: var(--gp-gap);
+ padding: var(--gp-padding);
+ background: var(--gp-bg);
+ backdrop-filter: blur(8px);
+ border: 1px solid var(--gp-border);
+ border-radius: var(--gp-radius);
+}
+
+.gp-title {
+ font-family: var(--font);
+ font-size: var(--gp-title);
+ font-weight: 700;
+ color: var(--gp-text-color);
+ letter-spacing: 0.02em;
+ text-transform: uppercase;
+}
+
+.gp-label {
+ font-family: var(--font);
+ font-size: var(--gp-text-sm);
+ font-weight: 500;
+ color: var(--gp-text-muted);
+}
+
+.gp-value {
+ font-family: var(--font);
+ font-size: var(--gp-text);
+ font-weight: 600;
+ color: var(--gp-text-color);
+}
+
+.gp-accent-green { color: var(--gp-accent-green); }
+.gp-accent-purple { color: var(--gp-accent-purple); }
+.gp-accent-amber { color: var(--gp-accent-amber); }
+
+// --- Row item (générateur, noeud évolution) ---
+.gp-row {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ gap: 0.4rem;
+ padding: 0.4rem 0.5rem;
+ border-radius: calc(var(--gp-radius) - 0.15rem);
+ border: 1px solid transparent;
+ transition: background 0.15s ease, border-color 0.15s ease;
+}
+
+.gp-row--active {
+ border-color: rgba(16, 185, 129, 0.3);
+ background: var(--gp-accent-green-bg);
+
+ &:hover {
+ background: rgba(16, 185, 129, 0.18);
+ }
+}
+
+.gp-row--locked {
+ border-color: var(--gp-border);
+ background: rgba(255, 255, 255, 0.02);
+ opacity: 0.5;
+}
+
+.gp-row--evolution {
+ border-color: rgba(251, 191, 36, 0.3);
+ background: var(--gp-accent-amber-bg);
+}
+
+.gp-row--unlocked {
+ border-color: rgba(16, 185, 129, 0.3);
+ background: var(--gp-accent-green-bg);
+}
+
+// --- Bouton achat ---
+.gp-btn {
+ font-family: var(--font);
+ font-size: var(--gp-text-sm);
+ font-weight: 600;
+ padding: 0.3rem 0.6rem;
+ border-radius: 0.4rem;
+ border: none;
+ cursor: pointer;
+ transition: background 0.15s ease;
+ white-space: nowrap;
+}
+
+.gp-btn--buy {
+ background: var(--gp-btn-bg);
+ color: white;
+
+ &:hover {
+ background: var(--gp-btn-bg-hover);
+ }
+}
+
+.gp-btn--disabled {
+ background: var(--gp-btn-disabled);
+ color: var(--gp-btn-text-disabled);
+ cursor: not-allowed;
+}
+
+.gp-btn--prestige {
+ background: #7c3aed;
+ color: white;
+ padding: 0.4rem 0.8rem;
+ font-size: var(--gp-text);
+ animation: gp-pulse 2s ease-in-out infinite;
+
+ &:hover {
+ background: #8b5cf6;
+ }
+}
+
+@keyframes gp-pulse {
+ 0%, 100% { box-shadow: 0 0 0 0 rgba(124, 58, 237, 0.4); }
+ 50% { box-shadow: 0 0 0 6px rgba(124, 58, 237, 0); }
+}
+
+// --- Header cockpit (stats résumé) ---
+.gp-cockpit-header {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ flex-wrap: wrap;
+ gap: 0.3rem;
+}
+
+.gp-stat {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ gap: 0.1rem;
+ min-width: 3.5rem;
+}
+
+// --- Progress bar ---
+.gp-progress {
+ height: 0.35rem;
+ background: rgba(255, 255, 255, 0.08);
+ border-radius: 1rem;
+ overflow: hidden;
+}
+
+.gp-progress-fill {
+ height: 100%;
+ border-radius: 1rem;
+ transition: width 0.5s ease;
+}
+
+// --- Section separator ---
+.gp-sep {
+ height: 1px;
+ background: var(--gp-border);
+ margin: 0.15rem 0;
+}
+
+// --- Zone titles in sidebar ---
+.gp-zone-label {
+ font-family: var(--font);
+ font-size: var(--gp-text-sm);
+ font-weight: 600;
+ color: var(--gp-text-muted);
+ text-transform: uppercase;
+ letter-spacing: 0.06em;
+ padding-left: 0.2rem;
+}
diff --git a/Frontend/src/scss/home.scss b/Frontend/src/scss/home.scss
index a97de3b..bf1e172 100755
--- a/Frontend/src/scss/home.scss
+++ b/Frontend/src/scss/home.scss
@@ -47,45 +47,29 @@
}
}
-// --- Stats bar sous le compteur ---
+// --- Stats sous le compteur ---
.click-zone-stats {
display: flex;
flex-direction: column;
align-items: center;
- gap: 0.3rem;
pointer-events: none;
user-select: none;
}
-.stats-bar {
- display: flex;
- align-items: center;
- gap: 0.4rem;
- font-family: var(--font);
- font-size: 0.85rem;
- font-weight: 500;
- color: rgba(255, 255, 255, 0.7);
- text-shadow: 0 1px 3px rgba(0, 0, 0, 0.5);
-}
-
-.stats-sep {
- opacity: 0.4;
-}
-
// --- Badge achievements sidebar ---
.achieve-badge {
display: block;
text-align: center;
- padding: 0.5rem;
- border-radius: 0.5rem;
- background: rgba(16, 185, 129, 0.1);
+ padding: 0.4rem;
+ border-radius: var(--gp-radius);
+ background: var(--gp-accent-green-bg);
border: 1px solid rgba(16, 185, 129, 0.2);
font-family: var(--font);
- font-size: 0.8rem;
- font-weight: 500;
- color: #6ee7b7;
+ font-size: var(--gp-text-sm);
+ font-weight: 600;
+ color: var(--gp-accent-green);
text-decoration: none;
transition: all 0.15s ease;
diff --git a/Frontend/src/scss/root.scss b/Frontend/src/scss/root.scss
index aed1737..051dea7 100755
--- a/Frontend/src/scss/root.scss
+++ b/Frontend/src/scss/root.scss
@@ -17,6 +17,35 @@
--bg-color: var(--color-blue-light);
--font: "Hanken Grotesk", sans-serif;
+
+ // --- Game panel tokens ---
+ --gp-bg: rgba(17, 17, 17, 0.75);
+ --gp-bg-hover: rgba(17, 17, 17, 0.85);
+ --gp-border: rgba(255, 255, 255, 0.08);
+ --gp-radius: 0.75rem;
+ --gp-padding: 0.75rem;
+ --gp-gap: 0.5rem;
+
+ // Text
+ --gp-title: 0.8rem;
+ --gp-text: 0.75rem;
+ --gp-text-sm: 0.65rem;
+ --gp-text-color: rgba(255, 255, 255, 0.9);
+ --gp-text-muted: rgba(255, 255, 255, 0.5);
+
+ // Accent colors
+ --gp-accent-green: #34d399;
+ --gp-accent-purple: #a78bfa;
+ --gp-accent-amber: #fbbf24;
+ --gp-accent-green-bg: rgba(16, 185, 129, 0.12);
+ --gp-accent-purple-bg: rgba(139, 92, 246, 0.12);
+ --gp-accent-amber-bg: rgba(251, 191, 36, 0.12);
+
+ // Buttons
+ --gp-btn-bg: #059669;
+ --gp-btn-bg-hover: #10b981;
+ --gp-btn-disabled: rgba(255, 255, 255, 0.08);
+ --gp-btn-text-disabled: rgba(255, 255, 255, 0.3);
}
a {