irpf/src/pages/index.astro
Marc Reverdin b687720cce refonte: UI/UX complet — landing page éditoriale + design system Tailwind
- BaseLayout: bandeau tricolore, nav sticky mobile (hamburger), footer 4col
- index.astro: landing éditoriale (hero + stats live + méthode + thèmes + scénarios)
  Données Eurostat live depuis indicators.json (dette, déficit, chômage, croissance)
  Thèmes à venir en cards dashed — séparation claire publiés / en préparation
- themes/index.astro: nettoyage inline styles → Tailwind classes
- themes/[slug].astro: header hero refait, nav interne, sidebar sticky, prose améliorée
- donnees/index.astro: grille indicateurs responsive, tableau comparatif
- global.css: design tokens unifiés (nuit/republic/accent/rouge), badges, cards, prose

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-07 10:04:06 +02:00

275 lines
14 KiB
Text
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
import BaseLayout from '../layouts/BaseLayout.astro';
import { getCollection } from 'astro:content';
import { existsSync, readFileSync } from 'node:fs';
import { join } from 'node:path';
const themes = (await getCollection('themes')).sort((a, b) => a.data.ordre - b.data.ordre);
// Indicateurs live
let byId: Record<string, any> = {};
let generatedAt = '';
const jsonPath = join(process.cwd(), 'src/data/live/indicators.json');
if (existsSync(jsonPath)) {
try {
const d = JSON.parse(readFileSync(jsonPath, 'utf-8'));
byId = Object.fromEntries((d.indicators ?? []).map((i: any) => [i.id, i]));
generatedAt = d.generated_at ?? '';
} catch {}
}
function fmt(id: string, digits = 1): string {
const v = byId[id]?.france?.value;
if (v == null) return 'N/D';
return Number(v).toLocaleString('fr-FR', { minimumFractionDigits: digits, maximumFractionDigits: digits });
}
const THEMES_A_VENIR = [
'Éducation', 'Emploi & Travail', 'Retraites', 'Logement',
'Justice & Sécurité', 'Énergie & Environnement', 'Agriculture',
'Numérique', 'Cohésion sociale', 'Démocratie', 'Europe', 'Immigration',
];
---
<BaseLayout
title="IRPF — Institut de Recherche Politique pour la France"
description="Analyse non-partisane des politiques publiques françaises fondée sur les données de l'INSEE, l'OCDE et Eurostat. Diagnostics, propositions, scénarios pour 2027."
>
<!-- ── HERO ──────────────────────────────────────────── -->
<section class="relative bg-white overflow-hidden">
<!-- Fond graphique subtil -->
<div class="absolute inset-0 bg-[radial-gradient(ellipse_at_top_right,_#eff6ff_0%,_transparent_60%)]"></div>
<div class="relative max-w-7xl mx-auto px-6 pt-20 pb-16 lg:pt-28 lg:pb-24 grid lg:grid-cols-2 gap-12 items-center">
<div>
<div class="section-label mb-4">Institut de Recherche Politique pour la France</div>
<h1 class="font-serif text-5xl lg:text-6xl font-black text-[#0f172a] leading-tight mb-6">
La France<br/>sous les données.
</h1>
<p class="text-lg text-gray-500 leading-relaxed mb-8 max-w-xl">
Des diagnostics rigoureux sur les 14 grandes problématiques françaises. Des données, pas des slogans. Des propositions chiffrées, pas des promesses.
</p>
<div class="flex flex-wrap gap-3">
<a href="/themes/" class="inline-flex items-center gap-2 bg-[#1e3a6e] text-white px-5 py-2.5 rounded-lg font-semibold text-sm hover:bg-[#162d56] transition-colors no-underline">
Explorer les analyses →
</a>
<a href="/donnees/" class="inline-flex items-center gap-2 border border-gray-300 text-gray-600 px-5 py-2.5 rounded-lg font-medium text-sm hover:border-[#1e3a6e] hover:text-[#1e3a6e] transition-colors no-underline">
Tableau de bord France
</a>
</div>
<p class="mt-5 text-xs text-gray-400">
Non-partisan · Données publiques · Accès libre
</p>
</div>
<!-- Carte stat mise en avant -->
<div class="hidden lg:block">
<div class="bg-[#0f172a] rounded-2xl p-8 text-white shadow-2xl">
<div class="text-xs text-blue-400 font-semibold uppercase tracking-wider mb-6">France — chiffres clés 2025</div>
<div class="space-y-5">
{[
{ id: 'dette_pib', label: 'Dette publique / PIB', unit: '%', alert: true },
{ id: 'deficit_pib', label: 'Déficit public / PIB', unit: '%', alert: true },
{ id: 'taux_chomage_jeunes',label: 'Chômage des jeunes', unit: '%', alert: false },
{ id: 'croissance_pib', label: 'Croissance du PIB', unit: '%', alert: false },
{ id: 'esperance_vie', label: 'Espérance de vie', unit: ' ans', alert: false },
].map(({ id, label, unit, alert }) => (
<div class="flex items-baseline justify-between border-b border-white/10 pb-4 last:border-0 last:pb-0">
<span class="text-sm text-gray-400">{label}</span>
<span class={`font-mono font-bold text-lg ${alert ? 'text-red-400' : 'text-green-400'}`}>
{fmt(id)}{unit}
</span>
</div>
))}
</div>
<div class="mt-5 text-xs text-gray-600 text-right">
Source : Eurostat · {generatedAt ? new Date(generatedAt).toLocaleDateString('fr-FR', { month: 'long', year: 'numeric' }) : ''}
</div>
</div>
</div>
</div>
</section>
<!-- ── CHIFFRES CLÉS (mobile / complément) ─────────── -->
<section class="bg-[#0f172a] border-t border-gray-800">
<div class="max-w-7xl mx-auto px-6 py-8 grid grid-cols-2 sm:grid-cols-4 gap-px bg-gray-800">
{[
{ id: 'dette_pib', label: 'Dette / PIB', unit: '%' },
{ id: 'deficit_pib', label: 'Déficit / PIB', unit: '%' },
{ id: 'taux_chomage', label: 'Chômage', unit: '%' },
{ id: 'prelevements_obligatoires', label: 'Prélèvements oblig.', unit: '%' },
].map(({ id, label, unit }) => (
<div class="bg-[#0f172a] px-6 py-5 text-center">
<div class="font-mono text-2xl font-bold text-white">{fmt(id)}<span class="text-sm">{unit}</span></div>
<div class="text-xs text-gray-500 mt-1">{label}</div>
<div class="text-xs text-gray-700 mt-0.5">{byId[id]?.france?.year ?? ''}</div>
</div>
))}
</div>
</section>
<!-- ── MÉTHODE ─────────────────────────────────────── -->
<section class="py-20 px-6 max-w-7xl mx-auto">
<div class="text-center mb-12">
<div class="section-label mb-3">Notre démarche</div>
<h2 class="font-serif text-3xl text-[#0f172a] mb-4">Le diagnostic avant le programme</h2>
<p class="text-gray-500 max-w-2xl mx-auto leading-relaxed">
Le débat politique français manque de données. L'IRPF fait le chemin inverse : partir des faits pour cartographier chaque problématique, recenser les propositions, et évaluer leur impact.
</p>
</div>
<div class="grid md:grid-cols-3 gap-8">
{[
{
num: '01',
titre: 'Données publiques',
desc: 'INSEE, OCDE, Eurostat, Banque de France, Cour des comptes, data.gouv.fr. Chaque chiffre est sourcé, daté, contextualisé.',
color: '#1e3a6e',
},
{
num: '02',
titre: 'Diagnostic rigoureux',
desc: 'Cartographie des dynamiques longues, comparaisons européennes, identification des nœuds structurels — sans idéologie.',
color: '#2563eb',
},
{
num: '03',
titre: 'Propositions chiffrées',
desc: 'Recensement de toutes les propositions des acteurs politiques, économiques et de la société civile. Évaluation de leur faisabilité.',
color: '#0891b2',
},
].map(({ num, titre, desc, color }) => (
<div class="relative p-8 rounded-xl border border-gray-200 bg-white hover:shadow-md transition-shadow">
<div class="text-5xl font-black mb-4 leading-none" style={`color: ${color}; opacity: 0.12;`}>{num}</div>
<h3 class="font-semibold text-[#0f172a] text-lg mb-3">{titre}</h3>
<p class="text-sm text-gray-500 leading-relaxed">{desc}</p>
</div>
))}
</div>
</section>
<!-- ── THÈMES ─────────────────────────────────────── -->
<section class="bg-[#f8fafc] border-y border-gray-200 py-20 px-6">
<div class="max-w-7xl mx-auto">
<div class="flex items-baseline justify-between mb-10">
<div>
<div class="section-label mb-2">14 grandes thématiques</div>
<h2 class="font-serif text-3xl text-[#0f172a]">Les chantiers de la France</h2>
</div>
<a href="/themes/" class="text-sm text-[#1e3a6e] font-medium hover:underline no-underline hidden sm:block">Voir tout →</a>
</div>
<!-- Fiches publiées -->
{themes.length > 0 && (
<div class="mb-6">
<div class="flex items-center gap-3 mb-5">
<span class="badge badge-dark">EN LIGNE</span>
<div class="flex-1 h-px bg-gray-300"></div>
</div>
<div class="grid sm:grid-cols-2 gap-5">
{themes.map(theme => (
<a href={`/themes/${theme.data.slug}/`} class="card p-6 no-underline block group">
<div class="flex items-start justify-between gap-3 mb-3">
<h3 class="font-semibold text-[#0f172a] text-base group-hover:text-[#1e3a6e] transition-colors leading-snug">
{theme.data.title}
</h3>
{theme.data.priorite === 'critique' && <span class="badge badge-critique shrink-0">CRITIQUE</span>}
{theme.data.priorite === 'haute' && <span class="badge badge-haute shrink-0">PRIORITÉ</span>}
</div>
<p class="text-sm text-gray-500 leading-relaxed mb-4">{theme.data.description}</p>
<div class="flex items-center justify-between">
<div class="flex gap-2 flex-wrap">
{theme.data.budget_etat_milliards && (
<span class="badge badge-blue">{theme.data.budget_etat_milliards} Md€/an</span>
)}
{theme.data.tags.slice(0, 2).map((tag: string) => (
<span class="badge badge-muted">#{tag}</span>
))}
</div>
<span class="text-xs text-[#1e3a6e] font-medium opacity-0 group-hover:opacity-100 transition-opacity">Lire →</span>
</div>
</a>
))}
</div>
</div>
)}
<!-- Thèmes à venir -->
<div>
<div class="flex items-center gap-3 mb-5">
<span class="badge badge-muted">À VENIR</span>
<div class="flex-1 h-px bg-gray-200"></div>
</div>
<div class="grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-4 gap-3">
{THEMES_A_VENIR.map(t => (
<div class="rounded-lg border border-dashed border-gray-300 px-4 py-3 text-sm text-gray-400 bg-white/60 select-none">
{t}
</div>
))}
</div>
</div>
<div class="mt-8 text-center sm:hidden">
<a href="/themes/" class="text-sm text-[#1e3a6e] font-medium hover:underline no-underline">Voir tous les thèmes →</a>
</div>
</div>
</section>
<!-- ── SCÉNARIOS ──────────────────────────────────── -->
<section class="py-20 px-6 max-w-7xl mx-auto">
<div class="bg-[#0f172a] rounded-2xl p-10 lg:p-14 grid lg:grid-cols-5 gap-10 items-center">
<div class="lg:col-span-3">
<div class="text-xs text-blue-400 font-semibold uppercase tracking-wider mb-4">Projection macro 20272032</div>
<h2 class="font-serif text-3xl text-white mb-4 leading-tight">
Trois trajectoires possibles pour la France
</h2>
<p class="text-gray-400 leading-relaxed mb-6 text-sm">
Déficit, dette, croissance, services publics — nous chiffrons les conséquences de chaque trajectoire politique sur un horizon de 5 ans.
</p>
<a href="/scenarios/" class="inline-flex items-center gap-2 bg-white text-[#1e3a6e] px-5 py-2.5 rounded-lg font-semibold text-sm hover:bg-blue-50 transition-colors no-underline">
Lire les scénarios →
</a>
</div>
<div class="lg:col-span-2 space-y-3">
{[
{ label: 'Dérive', kpi: '-5,5% PIB · +0,8%/an', color: '#ef4444' },
{ label: 'Réforme graduelle',kpi: '-3% PIB · +1,4%/an', color: '#f59e0b' },
{ label: 'Choc républicain', kpi: '-1,5% PIB · +2%/an', color: '#22c55e' },
].map(({ label, kpi, color }) => (
<div class="bg-white/5 border border-white/10 rounded-xl px-5 py-4 flex items-center justify-between">
<div class="flex items-center gap-3">
<div class="w-2.5 h-2.5 rounded-full shrink-0" style={`background: ${color};`}></div>
<span class="font-medium text-white text-sm">{label}</span>
</div>
<span class="font-mono text-xs font-semibold" style={`color: ${color};`}>{kpi}</span>
</div>
))}
</div>
</div>
</section>
<!-- ── À PROPOS ────────────────────────────────────── -->
<section class="bg-[#f8fafc] border-t border-gray-200 py-20 px-6">
<div class="max-w-3xl mx-auto text-center">
<div class="section-label mb-4">Pourquoi l'IRPF</div>
<h2 class="font-serif text-3xl text-[#0f172a] mb-6">Ni de gauche ni de droite. Exigeant sur les chiffres.</h2>
<div class="text-gray-500 leading-relaxed space-y-4 text-base">
<p>
Le débat politique français souffre d'un paradoxe : beaucoup de propositions, peu de données ; beaucoup de slogans, peu de diagnostic. Chaque camp dispose de ses instituts, de ses économistes, de ses chiffres. L'IRPF fait le chemin inverse.
</p>
<p>
Nous partons des faits — ceux de l'INSEE, de l'OCDE, de la Cour des comptes, des rapports parlementaires — pour cartographier chaque grande problématique française, recenser toutes les propositions des acteurs du débat, et proposer des analyses originales.
</p>
</div>
<div class="mt-8 flex flex-wrap gap-4 justify-center">
<a href="/donnees/" class="inline-flex items-center gap-2 bg-[#1e3a6e] text-white px-5 py-2.5 rounded-lg font-semibold text-sm hover:bg-[#162d56] transition-colors no-underline">
Tableau de bord France
</a>
<a href="/methode/" class="inline-flex items-center gap-2 border border-gray-300 text-gray-600 px-5 py-2.5 rounded-lg font-medium text-sm hover:border-[#1e3a6e] hover:text-[#1e3a6e] transition-colors no-underline">
Notre méthode
</a>
</div>
</div>
</section>
</BaseLayout>