const { useRef, useState, useEffect, useCallback } = React;
const FM = window.Motion || window.FramerMotion;
const { motion, useTransform, useMotionValue } = FM;
const EASE = FM.cubicBezier ? FM.cubicBezier(0.22, 1, 0.30, 1) : undefined;

/* ── Le mur : décrit du BAS (fondation) vers le HAUT ──
   units = largeur en modules (mur = 6 modules). side = direction d'arrivée. */
const ROWS = [
  // r0 — fondation : le coeur de métier
  [{ l: "C", u: 2, side: "left" }, { l: "Linux", u: 2, side: "mid" }, { l: "Bash", u: 2, side: "right" }],
  // r1 — décalage running-bond (½ briques muettes aux bords)
  [{ l: "", u: 1, side: "left" }, { l: "Python", u: 2, side: "left" }, { l: "Git", u: 2, side: "right" }, { l: "", u: 1, side: "right" }],
  // r2
  [{ l: "React", u: 2, side: "left" }, { l: "Docker", u: 2, side: "mid" }, { l: "TypeScript", u: 2, side: "right" }],
  // r3
  [{ l: "", u: 1, side: "left" }, { l: "Claude", u: 2, side: "left", accent: 1 }, { l: "Gemini", u: 2, side: "right" }, { l: "", u: 1, side: "right" }],
  // r4 — sommet : concepts signature (projets Epitech)
  [{ l: "CSFML", u: 2, side: "left" }, { l: "Unix Systems", u: 2, side: "mid" }, { l: "C++", u: 2, side: "right" }],
];

const NB_ROWS = ROWS.length;
const GAP = 1.3;          // mortier (% du mur)
const ROW_H = 100 / NB_ROWS;

/* Pré-calcule géométrie + fenêtre de scroll de chaque brique */
function buildBricks() {
  const out = [];
  let labeled = 0;
  
  // Mapping ciblé utilisant les CDN stables testés
  const iconMapping = {
    "C": "https://cdn.jsdelivr.net/npm/simple-icons@v9/icons/c.svg",
    "Linux": "https://cdn.jsdelivr.net/npm/simple-icons@v9/icons/linux.svg",
    "Bash": "https://cdn.jsdelivr.net/npm/simple-icons@v9/icons/gnubash.svg",
    "Python": "https://cdn.jsdelivr.net/npm/simple-icons@v9/icons/python.svg",
    "Git": "https://cdn.jsdelivr.net/npm/simple-icons@v9/icons/git.svg",
    "React": "https://cdn.jsdelivr.net/npm/simple-icons@v9/icons/react.svg",
    "Docker": "https://cdn.jsdelivr.net/npm/simple-icons@v9/icons/docker.svg",
    "TypeScript": "https://cdn.jsdelivr.net/npm/simple-icons@v9/icons/typescript.svg",
    "CSFML": "https://cdn.jsdelivr.net/npm/simple-icons@v9/icons/sfml.svg",
    "Unix Systems": "https://cdn.jsdelivr.net/npm/simple-icons@v9/icons/gnubash.svg",
    "C++": "https://cdn.jsdelivr.net/npm/simple-icons@v9/icons/cplusplus.svg",
    // Sources spécifiques validées pour éviter les icônes brisées :
    "Claude": "https://cdn.jsdelivr.net/gh/glincker/thesvg@main/public/icons/claude/default.svg",
    "Gemini": "https://upload.wikimedia.org/wikipedia/commons/8/8a/Google_Gemini_logo.svg"
  };

  ROWS.forEach((row, r) => {
    let cursor = 0;
    row.forEach((b, ci) => {
      const w = b.u;
      const left = (cursor / 6) * 100;
      const width = (w / 6) * 100;
      cursor += w;

      const rowStart = r * 0.165;
      const enter = Math.min(rowStart + ci * 0.028, 0.92);
      const settle = Math.min(enter + 0.16, 0.99);

      if (b.l) labeled++;
      out.push({
        key: `${r}-${ci}`,
        label: b.l,
        accent: b.accent ? 1 : 0,
        blank: !b.l,
        side: b.side,
        iconUrl: iconMapping[b.l] || null, // URL absolue directe
        x: left + GAP / 2,
        y: (NB_ROWS - 1 - r) * ROW_H + GAP / 2,
        w: width - GAP,
        h: ROW_H - GAP,
        enter, settle,
      });
    });
  });
  return { bricks: out, labeled };
}

const { bricks: BRICKS, labeled: LABELED } = buildBricks();

/* ── Dictionnaire de Traductions ── */
const T = {
  en: {
    hero_subtitle: "SOFTWARE ENGINEERING STUDENT",
    hero_internship: "Looking for a 4 to 6-month Software Engineering internship in Madrid.",
    hero_bio_1: "Based in Madrid for over ten years, I thrive in multicultural environments, which has made me highly adaptable and independent. Trained through Epitech’s intensive project-based curriculum, my technical foundation is focused on clean code, performance, and efficient delivery.",

    pillar_unix_title: "UNIX & C Systems",
    pillar_unix_desc: "Solid systems programming background. Experienced in low-level memory allocation, asynchronous processes, IPC, and developing custom UNIX shells.",

    pillar_ai_title: "AI Orchestration & Claude Code",
    pillar_ai_desc: "Power-user of Claude Code and agentic workflows. Automating multi-file refactoring, deep code reviews, and speeding up architecture prototyping.",

    pillar_discipline_title: "Discipline & Consistency",
    pillar_discipline_desc: "Daily high-intensity Street Workout and structured nutrition. This personal discipline translates directly into my work: focus, consistency, and clean execution.",

    pillar_defi_title: "DeFi & Web3",
    pillar_defi_desc: "Keen interest in Web3 protocols and decentralized finance. Combining product vision with a solid understanding of distributed ledgers and smart contract mechanics.",

    section_wall_title: "Tech Stack",

    onbars_status: "IN PROGRESS",
    onbars_text: "Building Onbars — a mobile app where street workout athletes track reps, discover parks on a community map, validate skills through peer review, and compete on a global leaderboard.",
    onbars_link: "onbars.app",

    narrative_0_sub: "BUILD IN PROGRESS",
    narrative_0_title: "Every scroll builds a brick...",
    narrative_0_text: "Scroll down to see my technical skills come together, from low-level Unix foundations to advanced AI orchestration and modern stacks.",

    narrative_1_sub: "01 — UNIX FOUNDATIONS",
    narrative_1_title: "Systems Rigor & C",
    narrative_1_text: "My engineering background started with C and Unix systems. This is where I learned memory management, process management (fork/exec), pipes, and code precision.",

    narrative_2_sub: "02 — MODERN STACK & PIPELINES",
    narrative_2_title: "Automation & Tools",
    narrative_2_text: "Docker and Git structure my daily workflow. I use GitHub Actions and Bash to automate environments, and TypeScript/React to build reliable, responsive interfaces.",

    narrative_3_sub: "03 — ADVANCED AI & LOGIC",
    narrative_3_title: "AI-Assisted Development",
    narrative_3_text: "Leveraging tools like Claude as an autonomous coding partner to refactor complex codebases, optimize performance, and prototype features faster.",

    projects_title: "Systems & Algorithmic Projects",
    projects_btn: "View on GitHub",
    projects_pipeline: "Execution Pipeline",

    footer_sub: "GET IN TOUCH",
    footer_title: "Ready to build something together?",
    footer_desc: "Available immediately for an internship in Madrid.",
    footer_cv: "DOWNLOAD MY CV",
    footer_rights: "All rights reserved.",
  },
  fr: {
    hero_subtitle: "ÉTUDIANT EN INGENIERIE LOGICIELLE",
    hero_internship: "À la recherche d'un stage de 4 à 6 mois en Software Engineering à Madrid.",
    hero_bio_1: "Basé à Madrid depuis plus de dix ans, j'évolue dans un environnement multiculturel qui m'a rendu très autonome et adaptable. Formé au rythme intensif des projets d'Epitech, je me concentre sur l'écriture d'un code propre, la performance et l'efficacité d'exécution.",

    pillar_unix_title: "Systèmes UNIX & C",
    pillar_unix_desc: "Solide formation en programmation système. Maîtrise de l'allocation mémoire bas niveau, de la gestion des processus, des IPC et du développement d'interpréteurs de commandes (shell).",

    pillar_ai_title: "Orchestration IA & Claude Code",
    pillar_ai_desc: "Utilisation avancée de Claude Code et des architectures agentiques. Automatisation de refactoring complexes, revues de code et prototypage rapide d'architectures.",

    pillar_discipline_title: "Discipline & Régularité",
    pillar_discipline_desc: "Pratique quotidienne du Street Workout et suivi nutritionnel. Une discipline personnelle que je transpose directement dans mon code : concentration, rigueur et structure.",

    pillar_defi_title: "DeFi & Web3",
    pillar_defi_desc: "Veille active sur les protocoles Web3 et la finance décentralisée. J'associe une vision produit à une bonne compréhension technique des systèmes distribués.",

    section_wall_title: "Mon Stack",

    onbars_status: "EN COURS",
    onbars_text: "Je construis Onbars — une app mobile où les pratiquants de street workout suivent leurs séries, découvrent des parcs sur une carte communautaire, font valider leurs skills par leurs pairs, et s'affrontent sur un classement mondial.",
    onbars_link: "onbars.app",

    narrative_0_sub: "CONSTRUCTION EN COURS",
    narrative_0_title: "Chaque scroll pose une brique...",
    narrative_0_text: "Faites défiler la page pour voir mes compétences se structurer, de mes fondations système à l'intégration de l'IA et des technos modernes.",

    narrative_1_sub: "01 — FONDATIONS UNIX",
    narrative_1_title: "Rigueur Système & C",
    narrative_1_text: "Mon parcours a commencé par le C et le système UNIX. C'est là que j'ai acquis mes réflexes : gestion fine de la mémoire, manipulation des processus (fork/exec) et précision du code.",

    narrative_2_sub: "02 — STACK MODERNE & PIPELINES",
    narrative_2_title: "Automatisation & Outils",
    narrative_2_text: "Docker et Git cadrent mes projets au quotidien. J'utilise Bash et GitHub Actions pour automatiser les tâches, et TypeScript/React pour concevoir des interfaces robustes.",

    narrative_3_sub: "03 — IA & ALGORITHMES",
    narrative_3_title: "Développement Augmenté par l'IA",
    narrative_3_text: "Intégration de Claude comme un partenaire de développement pour accélérer le refactoring de bases de code complexes et optimiser le prototypage.",

    projects_title: "Projets Système & Algorithmiques",
    projects_btn: "Voir sur GitHub",
    projects_pipeline: "Pipeline d'Exécution",

    footer_sub: "CONTACT",
    footer_title: "Prêt à concevoir de beaux projets ?",
    footer_desc: "Disponible immédiatement pour un stage à Madrid.",
    footer_cv: "TÉLÉCHARGER MON CV",
    footer_rights: "Tous droits réservés.",
  },
  es: {
    hero_subtitle: "ESTUDIANTE DE INGENIERÍA DE SOFTWARE",
    hero_internship: "Buscando prácticas de 4 a 6 meses en Ingeniería de Software en Madrid.",
    hero_bio_1: "Afincado en Madrid desde hace más de una década, me muevo con facilidad en entornos multiculturales, lo que me ha aportado una gran autonomía y adaptabilidad. Formado en el exigente modelo de proyectos de Epitech, me enfoco en el código limpio, el rendimiento y la eficiencia.",

    pillar_unix_title: "Sistemas UNIX y C",
    pillar_unix_desc: "Sólida base en programación de sistemas. Experiencia en gestión de memoria a bajo nivel, procesos asíncronos, IPC y desarrollo de intérpretes de comandos UNIX.",

    pillar_ai_title: "Orquestación de IA y Claude Code",
    pillar_ai_desc: "Usuario avanzado de Claude Code y flujos de trabajo con agentes. Automatización de refactorizaciones complejas, revisiones de código y prototipado rápido de arquitecturas.",

    pillar_discipline_title: "Disciplina y Constancia",
    pillar_discipline_desc: "Práctica diaria de Street Workout de alta intensidad y nutrición estructurada. Una disciplina personal que aplico directamente a mi código: enfoque, constancia y rigor.",

    pillar_defi_title: "DeFi y Web3",
    pillar_defi_desc: "Interés y análisis de protocolos Web3 y finanzas descentralizadas. Combino visión de producto con una comprensión técnica de los sistemas distribuidos.",

    section_wall_title: "Mi Stack",

    onbars_status: "EN PROGRESO",
    onbars_text: "Construyendo Onbars — una app móvil donde los atletas de street workout registran sus series, descubren parques en un mapa comunitario, validan sus skills mediante votación entre pares, y compiten en un ranking global.",
    onbars_link: "onbars.app",

    narrative_0_sub: "CONSTRUCCIÓN EN CURSO",
    narrative_0_title: "Cada scroll construye un ladrillo...",
    narrative_0_text: "Desplázate para ver cómo se estructuran mis competencias técnicas, desde los cimientos de sistemas hasta la integración de IA.",

    narrative_1_sub: "01 — CIMIENTOS DE UNIX",
    narrative_1_title: "Rigor de Sistemas y C",
    narrative_1_text: "Mi base técnica empezó con C y sistemas Unix. Ahí aprendí la gestión de memoria, control de procesos (fork/exec), pipes y la precisión en el código.",

    narrative_2_sub: "02 — STACK MODERNO Y PIPELINES",
    narrative_2_title: "Automatización y Herramientas",
    narrative_2_text: "Docker y Git estructuran mi día a día. Utilizo GitHub Actions y Bash para automatizar entornos, y TypeScript/React para crear interfaces robustas.",

    narrative_3_sub: "03 — IA Y ALGORITMOS",
    narrative_3_title: "Desarrollo Asistido por IA",
    narrative_3_text: "Integración de Claude como un compañero de desarrollo autónomo para refactorizar bases de código complejas y acelerar la creación de prototipos.",

    projects_title: "Proyectos de Sistemas y Algoritmia",
    projects_btn: "Ver en GitHub",
    projects_pipeline: "Pipeline de Ejecución",

    footer_sub: "CONTACTO",
    footer_title: "¿Listo para construir grandes proyectos?",
    footer_desc: "Disponible inmediatamente para prácticas en Madrid.",
    footer_cv: "DESCARGAR MI CV",
    footer_rights: "Todos los derechos reservados.",
  }
};

/* ── Estructura de Proyectos Detallada ── */
function getProjects(lang) {
  const isEn = lang === "en";
  const isFr = lang === "fr";

  return [
    {
      title: "A-maze-d",
      subtitle: isEn
        ? "Multi-Robot Pathfinding Engine"
        : (isFr ? "Moteur de Pathfinding Multi-Robot" : "Motor de Pathfinding Multi-Robot"),
      desc: isEn
        ? "A high-performance multi-robot pathfinding solver in C. Solves complex mazes by computing optimal distances using a reverse BFS from the exit in O(R+T), extracts non-overlapping shortest paths, distributes robots based on traversal costs, and prevents collisions turn-by-turn."
        : (isFr
          ? "Moteur de pathfinding multi-robot haute performance en C. Résout des labyrinthes complexes en calculant les distances optimales via un BFS inverse depuis la sortie en O(R+T), extrait les chemins disjoints optimaux, distribue les robots pour minimiser le temps de traversée, et évite les collisions tour par tour."
          : "Motor de pathfinding multi-robot de alto rendimiento en C. Resuelve laberintos complejos calculando distancias óptimas mediante un BFS inverso desde la salida en O(R+T), extrae caminos más cortos no superpuestos, distribuye los robots según el costo de tiempo y evita colisiones paso a paso."),
      tags: ["C", "Graph Theory", "BFS", "Algorithms"],
      steps: [
        {
          n: isEn ? "Reverse BFS" : (isFr ? "BFS Inverse" : "BFS Inverso"),
          desc: isEn ? "O(R+T) exit distance compute" : (isFr ? "Calcul des distances depuis la sortie en O(R+T)" : "Cálculo de distancias en O(R+T)")
        },
        {
          n: isEn ? "Optimal Paths" : (isFr ? "Routes Optimales" : "Rutas Óptimas"),
          desc: isEn ? "Extract non-overlapping paths" : (isFr ? "Extraction de chemins non-chevauchants" : "Extracción de caminos disjuntos")
        },
        {
          n: "Distribution",
          desc: isEn ? "Intelligent balancing on cost" : (isFr ? "Répartition intelligente selon la charge" : "Distribución inteligente según costos")
        },
        {
          n: isEn ? "Anti-Collision" : (isFr ? "Anti-Collision" : "Anti-Colisión"),
          desc: isEn ? "Lock-free turn-by-turn planning" : (isFr ? "Planification des pas sans blocage" : "Planificación de pasos sin bloqueos")
        }
      ],
      github: "https://github.com/quentin-hoa/A-maze-d"
    },
    {
      title: "BSQ (Biggest Square)",
      subtitle: isEn
        ? "Dynamic Tabulation Solver"
        : (isFr ? "Optimisation Tabulaire Dynamique" : "Optimización Tabular Dinámica"),
      desc: isEn
        ? "A high-performance C algorithm designed to locate the largest empty square in obstacle-filled grids. Using a single-pass Dynamic Programming tabulation in O(N), it processes massive 10,000x10,000 grids in milliseconds with highly optimized memory management."
        : (isFr
          ? "Algorithme d'optimisation en C résolvant le problème du plus grand carré vide. Grâce à une tabulation par programmation dynamique en une seule passe en O(N), il est capable de traiter des grilles gigantesques de 10 000 x 10 000 parsemées d'obstacles en seulement quelques millisecondes."
          : "Algoritmo de optimización en C que resuelve el problema del mayor cuadrado vacío. Mediante una tabulación por programación dinámica en una única pasada en O(N), es capaz de procesar cuadrículas de 10 000 x 10 000 con obstáculos en pocos milisegundos."),
      tags: ["C", "Performance", "Dynamic Programming", "O(N)"],
      steps: [
        {
          n: isEn ? "Fast Reading" : (isFr ? "Chargement rapide" : "Carga Rápida"),
          desc: isEn ? "Raw memory grid parsing" : (isFr ? "Lecture brute mémoire de la grille" : "Lectura en memoria directa de la cuadrícula")
        },
        {
          n: "DP Tabulation",
          desc: isEn ? "min(top, left, diag) + 1 formula" : (isFr ? "min(top, left, diag) + 1 direct" : "Fórmula min(arriba, izq, diag) + 1")
        },
        {
          n: isEn ? "Track Max" : (isFr ? "Suivi coordonnée" : "Seguir Máximo"),
          desc: isEn ? "Real-time updates of best square" : (isFr ? "Actualisation du meilleur carré" : "Actualización en tiempo real del cuadrado")
        },
        {
          n: isEn ? "Final Render" : (isFr ? "Rendu Final" : "Salida Final"),
          desc: isEn ? "Optimized high-speed stdout print" : (isFr ? "Remplacement et affichage optimisé" : "Reemplazo y visualización optimizados")
        }
      ],
      github: "https://github.com/quentin-hoa/BSQ"
    },
    {
      title: "Minishell",
      subtitle: isEn
        ? "Unix Command Interpreter"
        : (isFr ? "Interpréteur de Commandes UNIX" : "Intérprete de Comandos UNIX"),
      desc: isEn
        ? "A full-featured Unix shell developed in C. It includes a sophisticated syntax parser that builds execution binary trees based on right-associative operator precedence, handling process fork/exec, IPC pipe streams, redirections (>, >>, <, <<), and built-in environment variables."
        : (isFr
          ? "Interpréteur de commandes UNIX complet en C. Intègre un parser syntaxique robuste avec gestion de la précédence des opérateurs via un arbre binaire (associativité à droite). Supporte l'exécution de processus, les liaisons par tubes (pipes), les redirections et les variables d'environnement."
          : "Intérprete de comandos UNIX completo escrito en C. Integra un parser con precedencia de operadores mediante un árbol binario (asociatividad a derecha). Soporta la ejecución de procesos (fork/exec), redirecciones y tuberías (pipes), y variables de entorno."),
      tags: ["C", "UNIX System", "Processes", "IPC", "Parser"],
      steps: [
        {
          n: isEn ? "Parsing" : (isFr ? "Lexing & Parsing" : "Lexer y Parser"),
          desc: isEn ? "Syntax cutting of operators" : (isFr ? "Découpage syntaxique des opérateurs" : "Análisis sintáctico de operadores")
        },
        {
          n: isEn ? "Binary Tree" : (isFr ? "Arbre Binaire" : "Árbol Binario"),
          desc: isEn ? "Build tree on precedence logic" : (isFr ? "Construction selon les priorités" : "Construcción por orden de prioridad")
        },
        {
          n: isEn ? "Pipes Setup" : (isFr ? "Pipes & Redirections" : "Pipes y Redirecciones"),
          desc: isEn ? "Connect descriptors for stream IPC" : (isFr ? "Création des tubes et liaisons IPC" : "Creación de descriptores y flujos IPC")
        },
        {
          n: "Fork & Execve",
          desc: isEn ? "Process execution & environment" : (isFr ? "Instanciation de processus et variables" : "Ejecución de procesos y entorno")
        }
      ],
      github: "https://github.com/quentin-hoa/minishell"
    },
    {
      title: "My Radar",
      subtitle: isEn
        ? "Spatial Indexing ATC Simulator"
        : (isFr ? "Simulateur Aérien avec Indexation Spatiale" : "Simulador Aéreo con Indexación Espacial"),
      desc: isEn
        ? "An air traffic control simulator running at 60 FPS in CSFML. Handles over 1,000 aircraft simultaneously by implementing an adaptive Quadtree spatial partitioning system, achieving a 50x-100x speedup in collision checks. Includes circular tower protection areas and a custom storm system."
        : (isFr
          ? "Simulateur aérien fluide à 60 FPS développé en CSFML. Gère plus de 1000 avions simultanément via une partition spatiale par arbre quaternaire (Quadtree) adaptatif, offrant un gain de performance de 50x à 100x sur les collisions. Intègre des zones de protection et une tempête dynamique."
          : "Simulador aéreo fluido a 60 FPS desarrollado con CSFML. Gestiona más de 1000 aviones en tiempo real gracias a una partición espacial por árbol cuaternario (Quadtree) adaptativo, acelerando las colisiones 50x-100x. Cuenta con áreas de inmunidad y tormenta dinámica."),
      tags: ["C", "CSFML", "Quadtree", "2D Physics", "Optimization"],
      steps: [
        {
          n: isEn ? "Quadtree Index" : (isFr ? "Quadtree Indexing" : "Indexación Quadtree"),
          desc: isEn ? "Recursive map partition" : (isFr ? "Partition spatiale récursive de la carte" : "Partición espacial recursiva del mapa")
        },
        {
          n: isEn ? "Fast Filter" : (isFr ? "Filtrage O(N log N)" : "Filtrado O(N log N)"),
          desc: isEn ? "Prune distant entities checks" : (isFr ? "Élimination des checks de collision lointains" : "Eliminación de comprobaciones de distancia")
        },
        {
          n: isEn ? "Radio Towers" : (isFr ? "Zones de Contrôle" : "Zonas de Control"),
          desc: isEn ? "Immunity circles calculations" : (isFr ? "Cercles d'immunité des tours radio" : "Cálculo de círculos de inmunidad")
        },
        {
          n: isEn ? "Storm Mechanics" : (isFr ? "Tempête" : "Tormentas"),
          desc: isEn ? "Dynamic storm & Fortnite-themed graphics" : (isFr ? "Tempête dynamique et sprites thématiques" : "Tormenta dinámica y sprites personalizados")
        }
      ],
      github: "https://github.com/quentin-hoa/My_Radar"
    }
  ];
}

/* ── Brick piloted by scroll ── */
function Brick({ b, progress }) {
  const fromX = b.side === "left" ? -340 : b.side === "right" ? 340 : 0;
  const opt = EASE ? { ease: EASE } : undefined;

  const x = useTransform(progress, [b.enter, b.settle], [fromX, 0], opt);
  const y = useTransform(progress, [b.enter, b.settle], [-150, 0], opt);
  const rx = useTransform(progress, [b.enter, b.settle], [26, 0], opt);
  const rz = useTransform(progress, [b.enter, b.settle],
    [b.side === "left" ? -7 : b.side === "right" ? 7 : 0, 0], opt);
  const sc = useTransform(progress, [b.enter, b.settle], [0.94, 1], opt);
  const op = useTransform(progress, [b.enter, b.enter + (b.settle - b.enter) * 0.45], [0, 1]);

  const isClaude = b.label === "Claude";
  const isGemini = b.label === "Gemini";
  const isC = b.label === "C";
  const isCpp = b.label === "C++";

  // Toutes les écritures (Claude, React, Docker, etc.) restent en blanc pur
  const customColor = "white"; 

  // On donne une taille plus grande (w-8 h-8) à C++ et Gemini
  const iconSizeClass = isGemini 
  ? "w-10 h-10 md:w-20 md:h-20" // Taille XXL pour Gemini
  : isCpp 
    ? "w-8 h-8 md:w-9 md:h-9"   // Taille XL pour C++
    : "w-5 h-5 md:w-6 md:h-6";  // Taille normale pour le reste

  return (
    <motion.div
      className={"brick" + (b.blank ? " brick--blank" : "")}
      style={{
        left: b.x + "%", top: b.y + "%", width: b.w + "%", height: b.h + "%",
        x, y, rotateX: rx, rotateZ: rz, scale: sc, opacity: op,
        "--bx": "var(--light-x)", "--by": "var(--light-y)",
      }}
    >
      {b.label ? (
        <span 
          className="absolute inset-0 flex items-center justify-center gap-2.5 px-2 text-center select-none"
          style={{ 
            position: 'absolute', 
            inset: 0, 
            display: 'flex', 
            alignItems: 'center', 
            justifyContent: 'center',
            zIndex: 30 
          }}
        >
          {b.iconUrl && (
            <img 
              src={b.iconUrl}
              alt=""
              className={`${iconSizeClass} object-contain pointer-events-none shrink-0`}
              style={{ 
                // On garde la couleur originale pour Claude et Gemini, on passe les autres en blanc
                filter: (isClaude || isGemini) ? 'none' : 'brightness(0) invert(1)',
                margin: 0
              }} 
            />
          )}
          
          {/* On n'affiche l'écriture QUE si ce n'est NI C, NI C++, NI Gemini */}
          {!isC && !isCpp && !isGemini && (
            <span 
              className="truncate text-xs md:text-sm font-bold tracking-wide" 
              style={{ color: customColor, fontFamily: 'sans-serif' }}
            >
              {b.label}
            </span>
          )}
        </span>
      ) : null}
    </motion.div>
  );
}

function Wall({ progress, light, isStatic }) {
  return (
    <div className="wall-scene relative flex items-center justify-center w-full">
      <div
        className="wall"
        style={{ "--bx": light.x + "%", "--by": light.y + "%" }}
      >
        <div className="wall-floor"></div>
        {isStatic
          ? BRICKS.map((b) => {
              const isClaude = b.label === "Claude";
              const isGemini = b.label === "Gemini";
              const isC = b.label === "C";
              const isCpp = b.label === "C++";
              
              const customColor = "white"; 
              const iconSizeClass = (isCpp || isGemini) ? "w-8 h-8 md:w-9 md:h-9" : "w-5 h-5 md:w-6 md:h-6";
              
              return (
                <div
                  key={b.key}
                  className={"brick" + (b.blank ? " brick--blank" : "")}
                  style={{ left: b.x + "%", top: b.y + "%", width: b.w + "%", height: b.h + "%" }}
                >
                  {b.label ? (
                    <span 
                      className="absolute inset-0 flex items-center justify-center gap-2.5 px-2 text-center select-none"
                      style={{ position: 'absolute', inset: 0, display: 'flex', alignItems: 'center', justify: 'center', zIndex: 30 }}
                    >
                      {b.iconUrl && (
                        <img 
                          src={b.iconUrl}
                          alt="" 
                          className={`${iconSizeClass} object-contain shrink-0`}
                          style={{ filter: (isClaude || isGemini) ? 'none' : 'brightness(0) invert(1)', margin: 0 }}
                        />
                      )}
                      
                      {/* Masquage de l'écriture pour Gemini ici aussi */}
                      {!isC && !isCpp && !isGemini && (
                        <span 
                          className="truncate text-xs md:text-sm font-bold tracking-wide" 
                          style={{ color: customColor, fontFamily: 'sans-serif' }}
                        >
                          {b.label}
                        </span>
                      )}
                    </span>
                  ) : null}
                </div>
              );
            })
          : BRICKS.map((b) => <Brick key={b.key} b={b} progress={progress} />)}
        <div className="wall-light"></div>
      </div>
    </div>
  );
}

/* Ticker de progression */
function Ticker({ progress }) {
  const [n, setN] = useState(0);
  useEffect(() => {
    return progress.on("change", (v) => {
      const count = Math.round(Math.min(1, Math.max(0, (v - 0.0) / 0.86)) * LABELED);
      setN(Math.min(LABELED, count));
    });
  }, [progress]);
  return (
    <div className="mono text-right select-none" style={{ color: "var(--ink-dim)" }}>
      <div style={{ fontSize: 11, letterSpacing: ".18em", whiteSpace: "nowrap" }}>BRICKS LAID</div>
      <div style={{ fontSize: 32, color: "var(--ink)", lineHeight: 1, marginTop: 4 }}>
        {String(n).padStart(2, "0")}<span style={{ color: "var(--ink-dim)", fontSize: 18 }}>/{LABELED}</span>
      </div>
    </div>
  );
}

/* Segmented Language Selector */
function LanguageToggle({ lang, onChange }) {
  const options = ["EN", "FR", "ES"];
  return (
    <div className="flex items-center gap-1 bg-[#16191f] border border-white/5 p-1 rounded-full relative overflow-hidden backdrop-blur-md">
      {options.map((opt) => {
        const isActive = lang === opt.toLowerCase();
        return (
          <button
            key={opt}
            onClick={() => onChange(opt.toLowerCase())}
            className={`mono text-[10px] md:text-xs font-bold px-3 py-1.5 rounded-full transition-all duration-300 relative z-10 ${isActive ? "text-black" : "text-slate-400 hover:text-white"
              }`}
          >
            {opt}
            {isActive && (
              <motion.div
                layoutId="activeLang"
                className="absolute inset-0 bg-[#06d6a0] rounded-full z-[-1]"
                transition={{ type: "spring", stiffness: 380, damping: 32 }}
              />
            )}
          </button>
        );
      })}
    </div>
  );
}

/* ── 1. Hero & Pillar Sections merged at the top ── */
function Hero({ lang }) {
  const t = T[lang] || T.en;

  return (
    <section className="min-h-screen flex flex-col justify-center px-[6vw] relative overflow-hidden pt-28 pb-16">
      {/* Background Glows */}
      <div className="radial-glow w-[600px] h-[600px] top-[-10%] left-[-15%] opacity-40"></div>
      <div className="radial-glow w-[700px] h-[700px] bottom-[-20%] right-[-10%] opacity-25"></div>

      <div className="max-w-6xl mx-auto z-10 w-full">
        {/* Main Grid: Info on left, Picture on right */}
        <div className="grid grid-cols-1 lg:grid-cols-12 gap-12 items-center mb-16">
          <div className="lg:col-span-8 flex flex-col justify-center">
            <motion.div
              initial={{ opacity: 0, y: 15 }}
              animate={{ opacity: 1, y: 0 }}
              transition={{ duration: 0.7 }}
              className="mono text-sm uppercase tracking-[0.25em] mb-4 text-[#06d6a0] font-bold"
            >
              {t.hero_subtitle}
            </motion.div>

            <motion.h1
              initial={{ opacity: 0, y: 25 }}
              animate={{ opacity: 1, y: 0 }}
              transition={{ duration: 0.7, delay: 0.1 }}
              className="text-5xl md:text-7xl font-extrabold tracking-tight mb-6 leading-none text-white"
            >
              Quentin <span className="text-[#06d6a0] text-glow font-black">Hoarau</span>
            </motion.h1>

            {/* Madrid Internship status callout */}
            <motion.div
              initial={{ opacity: 0, y: 20 }}
              animate={{ opacity: 1, y: 0 }}
              transition={{ duration: 0.7, delay: 0.15 }}
              className="bg-[#06d6a0]/5 border border-[#06d6a0]/20 rounded-xl px-5 py-4 max-w-2xl mb-8 flex items-center gap-3"
            >
              <div className="w-2.5 h-2.5 rounded-full bg-[#06d6a0] animate-ping shrink-0"></div>
              <p className="mono text-xs md:text-sm text-slate-200 font-bold tracking-wide">
                {t.hero_internship}
              </p>
            </motion.div>

            <motion.p
              initial={{ opacity: 0, y: 25 }}
              animate={{ opacity: 1, y: 0 }}
              transition={{ duration: 0.7, delay: 0.2 }}
              className="text-base md:text-lg text-slate-300 font-normal max-w-3xl mb-6 leading-relaxed"
            >
              {t.hero_bio_1}
            </motion.p>

            <motion.p
              initial={{ opacity: 0, y: 25 }}
              animate={{ opacity: 1, y: 0 }}
              transition={{ duration: 0.7, delay: 0.25 }}
              className="text-base md:text-lg text-slate-300 font-normal max-w-3xl mb-8 leading-relaxed border-l-2 border-[#06d6a0]/30 pl-4"
            >
              {t.hero_bio_2}
            </motion.p>
          </div>

          {/* Profile photo aligned to the right */}
          <div className="lg:col-span-4 flex justify-center lg:justify-end">
            <motion.div
              initial={{ opacity: 0, scale: 0.9 }}
              animate={{ opacity: 1, scale: 1 }}
              transition={{ duration: 0.8, delay: 0.2 }}
              className="relative group shrink-0"
            >
              <div className="absolute inset-0 rounded-full bg-gradient-to-tr from-[#06d6a0] to-transparent opacity-30 blur-2xl group-hover:opacity-40 transition-opacity duration-500"></div>
              <div className="w-56 h-56 md:w-72 md:h-72 rounded-full overflow-hidden border-2 border-[#06d6a0]/30 p-1 bg-[#101216]/50 shadow-2xl relative z-10 flex items-center justify-center">
                <img
                  src="uploads/photo_profil.jpg"
                  alt="Quentin Hoarau"
                  className="w-full h-full object-cover rounded-full transition-all duration-700 ease-out"
                />
              </div>
            </motion.div>
          </div>
        </div>

        {/* Pillars Cards (4 Columns) containing Systems, Claude Code, Workout & DeFi */}
        <motion.div
          initial={{ opacity: 0, y: 35 }}
          animate={{ opacity: 1, y: 0 }}
          transition={{ duration: 0.8, delay: 0.3 }}
          className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6"
        >
          <div className="glass-card p-6 md:p-8 rounded-xl relative overflow-hidden group flex flex-col justify-between">
            <div>
              <div className="absolute top-0 left-0 w-1 h-full bg-[#06d6a0]/40 group-hover:bg-[#06d6a0] transition-all"></div>
              <h3 className="mono text-sm md:text-base font-bold uppercase mb-3 text-white tracking-wide">{t.pillar_unix_title}</h3>
              <p className="text-xs md:text-sm text-slate-400 leading-relaxed font-light">{t.pillar_unix_desc}</p>
            </div>
          </div>

          <div className="glass-card p-6 md:p-8 rounded-xl relative overflow-hidden group flex flex-col justify-between">
            <div>
              <div className="absolute top-0 left-0 w-1 h-full bg-[#06d6a0]/40 group-hover:bg-[#06d6a0] transition-all"></div>
              <h3 className="mono text-sm md:text-base font-bold uppercase mb-3 text-white tracking-wide">{t.pillar_ai_title}</h3>
              <p className="text-xs md:text-sm text-slate-400 leading-relaxed font-light">{t.pillar_ai_desc}</p>
            </div>
          </div>

          <div className="glass-card p-6 md:p-8 rounded-xl relative overflow-hidden group flex flex-col justify-between">
            <div>
              <div className="absolute top-0 left-0 w-1 h-full bg-[#06d6a0]/40 group-hover:bg-[#06d6a0] transition-all"></div>
              <h3 className="mono text-sm md:text-base font-bold uppercase mb-3 text-white tracking-wide">{t.pillar_discipline_title}</h3>
              <p className="text-xs md:text-sm text-slate-400 leading-relaxed font-light">{t.pillar_discipline_desc}</p>
            </div>
          </div>

          <div className="glass-card p-6 md:p-8 rounded-xl relative overflow-hidden group flex flex-col justify-between">
            <div>
              <div className="absolute top-0 left-0 w-1 h-full bg-[#06d6a0]/40 group-hover:bg-[#06d6a0] transition-all"></div>
              <h3 className="mono text-sm md:text-base font-bold uppercase mb-3 text-white tracking-wide">{t.pillar_defi_title}</h3>
              <p className="text-xs md:text-sm text-slate-400 leading-relaxed font-light">{t.pillar_defi_desc}</p>
            </div>
          </div>
        </motion.div>
      </div>

      {/* Scroll Down Hint */}
      <motion.div
        initial={{ opacity: 0 }}
        animate={{ opacity: [0, 1, 0], y: [0, 8, 0] }}
        transition={{ repeat: Infinity, duration: 2.5, delay: 1 }}
        className="absolute bottom-6 left-1/2 transform -translate-x-1/2 flex flex-col items-center pointer-events-none"
      >
        <svg className="w-5 h-5 text-slate-500" fill="none" viewBox="0 0 24 24" stroke="currentColor">
          <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={1.5} d="M19 13l-7 7-7-7" />
        </svg>
      </motion.div>
    </section>
  );
}

/* ── 2. Narrative Cards (driven by scroll progress) ── */
function NarrativeCards({ progress, lang }) {
  const [activeCard, setActiveCard] = useState(0);
  const t = T[lang] || T.en;

  useEffect(() => {
    return progress.on("change", (v) => {
      if (v < 0.05) setActiveCard(0);
      else if (v >= 0.05 && v < 0.38) setActiveCard(1); // UNIX
      else if (v >= 0.38 && v < 0.70) setActiveCard(2); // DevOps
      else if (v >= 0.70) setActiveCard(3); // AI / Algo
    });
  }, [progress]);

  const cards = [
    {
      id: 0,
      subtitle: t.narrative_0_sub,
      title: t.narrative_0_title,
      text: t.narrative_0_text
    },
    {
      id: 1,
      subtitle: t.narrative_1_sub,
      title: t.narrative_1_title,
      text: t.narrative_1_text
    },
    {
      id: 2,
      subtitle: t.narrative_2_sub,
      title: t.narrative_2_title,
      text: t.narrative_2_text
    },
    {
      id: 3,
      subtitle: t.narrative_3_sub,
      title: t.narrative_3_title,
      text: t.narrative_3_text
    }
  ];

  return (
    <div className="w-full md:max-w-md h-full flex flex-col justify-center px-4 relative z-20">
      <div className="h-[250px] md:h-[280px] relative flex items-center justify-center">
        {cards.map((c) => {
          const isActive = activeCard === c.id;
          return (
            <motion.div
              key={c.id}
              initial={{ opacity: 0, y: 30, scale: 0.95 }}
              animate={{
                opacity: isActive ? 1 : 0,
                y: isActive ? 0 : (activeCard > c.id ? -40 : 40),
                scale: isActive ? 1 : 0.95,
                pointerEvents: isActive ? "auto" : "none"
              }}
              transition={{ duration: 0.5, ease: "easeInOut" }}
              className="absolute inset-0 glass-card p-6 md:p-8 rounded-2xl flex flex-col justify-between border border-white/5"
            >
              <div>
                <span className="mono text-[10px] text-[#06d6a0] tracking-widest block mb-2">{c.subtitle}</span>
                <h3 className="text-xl md:text-2xl font-bold text-white mb-3 leading-tight">{c.title}</h3>
                <p className="text-sm md:text-base text-slate-300 leading-relaxed font-light">{c.text}</p>
              </div>
              {c.id > 0 && (
                <div className="flex items-center gap-2 mt-3 pt-3 border-t border-white/5">
                </div>
              )}
            </motion.div>
          );
        })}
      </div>
    </div>
  );
}

/* ── 3. Projects Showcase ── */
function ProjectFlow({ steps, lang }) {
  return (
    <div className="mt-8 pt-8 border-t border-white/5">
      <h4 className="mono text-[10px] text-slate-500 uppercase tracking-widest mb-4">
        {lang === "en" ? "Execution Pipeline" : (lang === "fr" ? "Pipeline d'Exécution" : "Pipeline de Ejecución")}
      </h4>
      <div className="grid grid-cols-1 sm:grid-cols-4 gap-4 items-stretch relative">
        {steps.map((s, idx) => (
          <div key={idx} className="relative flex flex-col items-center sm:items-start text-center sm:text-left bg-white/[0.01] p-4 rounded-lg border border-white/[0.02]">
            <div className="flex items-center gap-2 mb-2">
              <span className="mono text-[15px] bg-white/5 text-[#06d6a0] w-5 h-5 rounded-full flex items-center justify-center border border-white/10 font-bold">
                {idx + 1}
              </span>
              <span className="mono text-[15px] text-white font-bold tracking-wide">{s.n}</span>
            </div>
            <p className="text-[12px] text-slate-400 leading-relaxed">{s.desc}</p>

            {/* Horizontal Arrow for Desktop */}
            {idx < 3 && (
              <div className="hidden sm:block absolute top-[18px] right-[-14%] w-[18%] h-[8px] z-20 pointer-events-none">
                <svg className="w-full h-full overflow-visible" fill="none">
                  <path d="M0,4 L24,4" stroke="rgba(216, 180, 143, 0.2)" strokeWidth="1" className="animate-dash" strokeDasharray="3" />
                  <polygon points="20,1 24,4 20,7" fill="rgba(216, 180, 143, 0.4)" />
                </svg>
              </div>
            )}

            {/* Vertical Arrow for Mobile */}
            {idx < 3 && (
              <div className="sm:hidden flex justify-center py-2 text-[#06d6a0]/20">
                <svg className="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
                  <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={1.5} d="M19 13l-7 7-7-7" />
                </svg>
              </div>
            )}
          </div>
        ))}
      </div>
    </div>
  );
}

function Projects({ lang }) {
  const t = T[lang] || T.en;
  const projects = getProjects(lang);

  return (
    <section className="py-24 px-[6vw] relative overflow-hidden bg-[#0a0b0d]">
      <div className="radial-glow w-[500px] h-[500px] top-[20%] right-[-10%] opacity-20"></div>
      <div className="radial-glow w-[600px] h-[600px] bottom-[10%] left-[-20%] opacity-20"></div>

      <div className="max-w-6xl mx-auto z-10 relative">
        <div className="mono text-xs text-[#06d6a0] tracking-[0.28em] uppercase mb-2">{t.projects_sub}</div>
        <h2 className="text-4xl md:text-5xl font-bold text-white mb-16 tracking-tight">{t.projects_title}</h2>

        <div className="flex flex-col gap-10">
          {projects.map((p, idx) => (
            <motion.div
              key={idx}
              initial={{ opacity: 0, y: 40 }}
              whileInView={{ opacity: 1, y: 0 }}
              viewport={{ once: true, margin: "-100px" }}
              transition={{ duration: 0.6, delay: idx * 0.08 }}
              whileHover={{ 
                scale: 1.03, // Un poil plus léger (3%) pour rester élégant
                transition: { type: "spring", stiffness: 400, damping: 25, delay: 0 } 
              }}
              className="glass-card p-6 md:p-8 rounded-2xl relative overflow-hidden group flex flex-col justify-between"
            >
              <div className="flex flex-col md:flex-row md:items-center justify-between gap-4 mb-4">
                <div>
                  <h3 className="text-2xl md:text-3xl font-extrabold text-white group-hover:text-[#06d6a0] transition-colors">{p.title}</h3>
                  <span className="text-sm text-slate-400 font-light mt-1 block">{p.subtitle}</span>
                </div>
                <div className="flex flex-wrap gap-2">
                  {p.tags.map((t, tIdx) => (
                    <span key={tIdx} className="mono text-[15px] bg-white/5 border border-white/10 px-2.5 py-1 rounded text-slate-300 font-bold">
                      {t}
                    </span>
                  ))}
                </div>
              </div>

              <p className="text-sm md:text-lg text-slate-300 leading-relaxed max-w-5xl mb-6">
                {p.desc}
              </p>

              {/* Pipeline graphique */}
              <ProjectFlow steps={p.steps} lang={lang} />

              {/* GitHub Button */}
              <div className="flex justify-end mt-6">
                <a
                  href={p.github}
                  target="_blank"
                  rel="noopener noreferrer"
                  className="mono text-xs flex items-center gap-2 text-slate-400 hover:text-white border border-white/10 hover:border-[#06d6a0]/40 px-4 py-2.5 rounded-lg bg-white/5 hover:bg-[#06d6a0]/5 transition-all duration-300"
                >
                  <svg className="w-4 h-4 fill-current" viewBox="0 0 24 24">
                    <path fillRule="evenodd" clipRule="evenodd" d="M12 2C6.477 2 2 6.477 2 12c0 4.42 2.865 8.166 6.839 9.489.5.092.682-.217.682-.482 0-.237-.008-.866-.013-1.7-2.782.603-3.369-1.34-3.369-1.34-.454-1.156-1.11-1.462-1.11-1.462-.908-.62.069-.608.069-.608 1.003.07 1.531 1.03 1.531 1.03.892 1.529 2.341 1.087 2.91.831.092-.646.35-1.086.636-1.336-2.22-.253-4.555-1.11-4.555-4.943 0-1.091.39-1.984 1.029-2.683-.103-.253-.446-1.27.098-2.647 0 0 .84-.269 2.75 1.025A9.564 9.564 0 0112 6.844c.85.004 1.705.115 2.504.337 1.909-1.294 2.747-1.025 2.747-1.025.546 1.377.203 2.394.1 2.647.64.699 1.028 1.592 1.028 2.683 0 3.842-2.339 4.687-4.566 4.935.359.309.678.919.678 1.852 0 1.336-.012 2.415-.012 2.743 0 .267.18.579.688.481C19.138 20.161 22 16.416 22 12c0-5.523-4.477-10-10-10z" />
                  </svg>
                  {t.projects_btn}
                </a>
              </div>
            </motion.div>
          ))}
        </div>
      </div>
    </section>
  );
}

/* ── 4. Onbars Side Project Teaser ── */
function OnbarsTeaser({ lang }) {
  const t = T[lang] || T.en;
  const sectionRef = useRef(null);
  const posRef = useRef({ x: 10, y: 20 });
  const velRef = useRef({ x: 0.5, y: 0.45 });
  const pausedRef = useRef(false);
  const rafRef = useRef(null);
  const [pos, setPos] = useState({ x: 10, y: 20 });

  useEffect(() => {
    const tick = () => {
      if (!pausedRef.current && sectionRef.current) {
        const section = sectionRef.current;
        const cardW = section.querySelector(".dvd-card")?.offsetWidth || 400;
        const cardH = section.querySelector(".dvd-card")?.offsetHeight || 120;
        const maxX = section.offsetWidth - cardW;
        const maxY = section.offsetHeight - cardH;

        posRef.current.x += velRef.current.x;
        posRef.current.y += velRef.current.y;

        if (posRef.current.x <= 0 || posRef.current.x >= maxX) velRef.current.x *= -1;
        if (posRef.current.y <= 0 || posRef.current.y >= maxY) velRef.current.y *= -1;

        posRef.current.x = Math.max(0, Math.min(maxX, posRef.current.x));
        posRef.current.y = Math.max(0, Math.min(maxY, posRef.current.y));

        setPos({ x: posRef.current.x, y: posRef.current.y });
      }
      rafRef.current = requestAnimationFrame(tick);
    };
    rafRef.current = requestAnimationFrame(tick);
    return () => cancelAnimationFrame(rafRef.current);
  }, []);

  return (
    <section ref={sectionRef} className="relative px-0" style={{ height: "260px" }}>
      <div
        className="dvd-card absolute bg-[#06d6a0]/5 border border-[#06d6a0]/20 rounded-xl px-6 py-5 flex items-start gap-4 cursor-pointer"
        style={{
          left: pos.x,
          top: pos.y,
          width: "min(560px, 90vw)",
          transition: "box-shadow 0.3s",
        }}
        onMouseEnter={() => { pausedRef.current = true; }}
        onMouseLeave={() => { pausedRef.current = false; }}
      >
        <img
          src="uploads/logo_onbars.png"
          alt="Onbars"
          className="w-10 h-10 rounded-lg shrink-0 object-contain mt-0.5"
        />
        <div className="flex-1 min-w-0">
          <div className="flex items-center gap-2 mb-2">
            <div className="w-2 h-2 rounded-full bg-[#06d6a0] animate-ping shrink-0"></div>
            <span className="mono text-[10px] text-[#06d6a0] tracking-[0.28em] font-bold">{t.onbars_status}</span>
          </div>
          <p className="mono text-xs md:text-sm text-slate-200 font-bold tracking-wide mb-3 leading-relaxed">
            {t.onbars_text}
          </p>
          <a
            href="https://onbars.app"
            target="_blank"
            rel="noopener noreferrer"
            className="mono text-xs font-bold text-[#06d6a0] hover:text-white transition-colors duration-200 inline-flex items-center gap-1.5 group"
            onClick={(e) => e.stopPropagation()}
          >
            {t.onbars_link}
            <svg className="w-3 h-3 transition-transform duration-200 group-hover:translate-x-0.5 group-hover:-translate-y-0.5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
              <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14" />
            </svg>
          </a>
        </div>
      </div>
    </section>
  );
}

/* ── 5. Footer & CV Download ── */
function Footer({ lang }) {
  const t = T[lang] || T.en;

  return (
    <footer className="py-20 px-[6vw] relative border-t border-white/5 bg-[#0a0b0d] overflow-hidden">
      <div className="max-w-6xl mx-auto flex flex-col md:flex-row justify-between items-center gap-8 relative z-10">
        <div>
          <span className="mono text-xs text-[#06d6a0] tracking-widest block mb-1">{t.footer_sub}</span>
          <h3 className="text-2xl md:text-3xl font-extrabold text-white tracking-tight">{t.footer_title}</h3>
          <p className="text-sm md:text-base text-slate-400 mt-2">{t.footer_desc}</p>
        </div>

        <div className="flex flex-wrap gap-4 items-center justify-center">
          {/* Download CV */}
          <a
            href="https://docs.google.com/viewer?url=https://quentinhoarau.com/uploads/CV_linkedin_EN_v2.pdf"
            target="_blank"
            className="mono text-xs bg-[#06d6a0] text-black font-extrabold px-6 py-3 rounded-lg flex items-center gap-2 transition-all duration-300 shadow-lg shadow-[#06d6a0]/10"
          >
            <svg className="w-4 h-4 fill-current" viewBox="0 0 24 24">
              <path d="M19.35 10.04C18.67 6.59 15.64 4 12 4 9.11 4 6.6 5.64 5.35 8.04 2.34 8.36 0 10.91 0 14c0 3.31 2.69 6 6 6h13c2.76 0 5-2.24 5-5 0-2.64-2.05-4.78-4.65-4.96zM17 13l-5 5-5-5h3V9h4v4h3z" />
            </svg>
            {t.footer_cv}
          </a>

          {/* LinkedIn */}
          <a
            href="https://www.linkedin.com/in/quentinhoa"
            target="_blank"
            rel="noopener noreferrer"
            className="mono text-xs font-bold border border-white/10 hover:border-white/20 hover:bg-white/5 text-white px-5 py-3 rounded-lg transition-all"
          >
            LINKEDIN
          </a>

          {/* GitHub */}
          <a
            href="https://github.com/quentin-hoa"
            target="_blank"
            rel="noopener noreferrer"
            className="mono text-xs font-bold border border-white/10 hover:border-white/20 hover:bg-white/5 text-white px-5 py-3 rounded-lg transition-all"
          >
            GITHUB
          </a>

          {/* Email */}
          <a
            href="mailto:quentin.hoarau193@gmail.com"
            className="mono text-xs font-bold border border-white/10 hover:border-[#06d6a0]/20 hover:bg-[#06d6a0]/5 text-[#06d6a0] px-5 py-3 rounded-lg transition-all"
          >
            quentin.hoarau193@gmail.com
          </a>
        </div>
      </div>

      <div className="max-w-6xl mx-auto mt-20 pt-8 border-t border-white/5 flex flex-col md:flex-row justify-between items-center gap-4 text-xs text-slate-500 mono">
        <p>© 2026 Quentin Hoarau. {t.footer_rights}</p>
        <p>{t.footer_tech}</p>
      </div>
    </footer>
  );
}

const { useTweaks, TweaksPanel, TweakSection, TweakSlider, TweakRadio, TweakToggle } = window;

/* Finitions de brique */
const FINISHES = {
  Graphite: { hi: "#31343b", mid: "#25282e", lo: "#1b1d22", label: "#b7bcc6" },
  Acier: { hi: "#3b414a", mid: "#2d333b", lo: "#21262d", label: "#c7ced7" },
  Anthracite: { hi: "#2d2a29", mid: "#211e1d", lo: "#161414", label: "#b3aca7" },
};
const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "finish": "Graphite",
  "lightStrength": 0.85,
  "accent": true,
  "buildLength": 240
}/*EDITMODE-END*/;

function App() {
  const ref = useRef(null);
  const progress = useMotionValue(0);
  const [lang, setLang] = useState("en"); // English by default
  const [t, setTweak] = useTweaks ? useTweaks(TWEAK_DEFAULTS) : [TWEAK_DEFAULTS, () => { }];
  const isFull = typeof window !== "undefined" &&
    new URLSearchParams(window.location.search).has("full");

  // Applique les tweaks
  useEffect(() => {
    const f = FINISHES[t.finish] || FINISHES.Graphite;
    const r = document.documentElement.style;
    r.setProperty("--brick-hi", f.hi);
    r.setProperty("--brick-mid", f.mid);
    r.setProperty("--brick-lo", f.lo);
    r.setProperty("--brick-label", f.label);
    r.setProperty("--light-strength", String(t.lightStrength));
    document.documentElement.classList.toggle("accent-off", !t.accent);
  }, [t.finish, t.lightStrength, t.accent]);

  // Progression rAF - Sticky progress calculator
  useEffect(() => {
    if (isFull) { progress.set(1); return; }
    let raf;
    const tick = () => {
      const el = ref.current;
      if (el) {
        const start = el.offsetTop;
        const end = start + el.offsetHeight - window.innerHeight;
        const p = (window.scrollY - start) / Math.max(1, end - start);
        progress.set(Math.min(1, Math.max(0, p)));
      }
      raf = requestAnimationFrame(tick);
    };
    raf = requestAnimationFrame(tick);
    return () => cancelAnimationFrame(raf);
  }, []);

  const [light, setLight] = useState({ x: 50, y: 16 });
  const onMove = useCallback((e) => {
    const r = e.currentTarget.getBoundingClientRect();
    setLight({
      x: Math.round(((e.clientX - r.left) / r.width) * 100),
      y: Math.round(((e.clientY - r.top) / r.height) * 100),
    });
  }, []);

  useEffect(() => {
    document.documentElement.style.setProperty("--light-x", light.x + "%");
    document.documentElement.style.setProperty("--light-y", light.y + "%");
  }, [light]);

  const trans = T[lang] || T.en;

  // Aperçu statique ?full
  if (isFull) {
    return (
      <main className="h-screen w-screen overflow-hidden scene-bg vignette stage flex items-center justify-center relative" onMouseMove={onMove}>
        <header className="absolute top-0 left-0 right-0 px-[6vw] pt-[5vh] flex items-start justify-between z-10 pointer-events-none">
          <div>
            <div className="mono text-[10px] tracking-[0.28em] text-slate-500">
              {trans.section_wall_sub}
            </div>
            <h1 className="text-3xl md:text-5xl font-extrabold leading-tight mt-2 text-white">
              {trans.section_wall_title}
            </h1>
          </div>
          <div className="hidden sm:block"><Ticker progress={progress} /></div>
        </header>
        <Wall progress={progress} light={light} isStatic={true} />
      </main>
    );
  }

  return (
    <main className="relative min-h-screen text-slate-100 bg-[#0a0b0d]">
      {/* Fixed Sticky Header for navigation and language switcher */}
      <nav className="fixed top-0 left-0 right-0 h-20 px-[6vw] flex items-center justify-between z-50 bg-[#0a0b0d]/80 backdrop-blur-lg border-b border-white/5">
        <span className="mono text-xs md:text-sm font-black tracking-[0.25em] text-white">
          QUENTIN HOARAU
        </span>
        <LanguageToggle lang={lang} onChange={setLang} />
      </nav>

      {/* 1. Hero & Core Pillars merged at the top */}
      <Hero lang={lang} />

      {/* 2. Zone Scroll : Le mur & les cartes narratives */}
      <section ref={ref} style={{ height: t.buildLength + "vh" }} className="relative border-t border-b border-white/5">
        <div
          className="sticky top-0 h-screen w-full overflow-hidden scene-bg vignette flex items-center"
          onMouseMove={onMove}
        >
          {/* Éléments en-tête flottant */}
          <header className="absolute top-24 left-0 right-0 px-[6vw] flex items-start justify-between z-10 pointer-events-none">
            <div>
              <div className="mono text-[10px] tracking-[0.28em]" style={{ color: 'var(--ink-dim)' }}>
                {trans.section_wall_sub}
              </div>
              <h2 className="text-2xl md:text-3xl font-extrabold leading-tight mt-2 text-white">
                {trans.section_wall_title}
              </h2>
            </div>
            <div className="hidden sm:block"><Ticker progress={progress} /></div>
          </header>

          {/* Grille Double Colonne responsive */}
          <div className="w-full flex flex-col md:flex-row items-center justify-center gap-12 px-[6vw] h-full pt-16 md:pt-0">
            {/* Colonne gauche : Cartes de récit */}
            <div className="w-full md:w-[45%] flex items-center justify-center md:justify-start">
              <NarrativeCards progress={progress} lang={lang} />
            </div>

            {/* Colonne droite : Le mur 3D interactif */}
            <div className="w-full md:w-[55%] flex items-center justify-center">
              <Wall progress={progress} light={light} />
            </div>
          </div>

          {/* Footer discret flottant */}
          <footer className="absolute bottom-6 left-0 right-0 px-[6vw] flex items-end justify-between z-10 pointer-events-none">
            <p className="mono max-w-[34ch] text-[10px] leading-relaxed" style={{ color: 'var(--ink-dim)' }}>
              {trans.section_wall_footer}
            </p>
          </footer>
        </div>
      </section>

      {/* 3. Onbars Side Project */}
      <OnbarsTeaser lang={lang} />

      {/* 4. Showcase Projets */}
      <Projects lang={lang} />

      {/* 4. Footer de Contact & CV */}
      <Footer lang={lang} />

      {/* Tweaks Panel */}
      {TweaksPanel ? (
        <TweaksPanel title="Tweaks">
          <TweakSection label="Matière" />
          <TweakRadio label="Finition" value={t.finish}
            options={["Graphite", "Acier", "Anthracite"]}
            onChange={(v) => setTweak("finish", v)} />
          <TweakToggle label="Accent Claude" value={t.accent}
            onChange={(v) => setTweak("accent", v)} />
          <TweakSection label="Lumière" />
          <TweakSlider label="Intensité" value={t.lightStrength} min={0.2} max={1.6} step={0.05}
            onChange={(v) => setTweak("lightStrength", v)} />
          <TweakSection label="Construction" />
          <TweakSlider label="Longueur du scroll" value={t.buildLength} min={180} max={380} step={20} unit="vh"
            onChange={(v) => setTweak("buildLength", v)} />
        </TweaksPanel>
      ) : null}
    </main>
  );
}

ReactDOM.createRoot(document.getElementById("root")).render(<App />);
