feat(irpf): architecture enrichie — 9 sections, composants visuels, workflow v2
- 6 composants Astro : Structurel, Politique, Conjoncturel, Kpi, Sondage, Timeline - content.config.ts : schéma enrichi (kpi_*, opinion_*, sections, rang_eu) - [slug].astro : nav dynamique, header métriques, sidebar TOC, typographie complète - _TEMPLATE.mdx : template canonique 9 sections pour chaque fiche - workflows/build-theme.js : prompt deep-research complet — historique, opinion, acteurs, 3 couches d'enjeux, benchmarks pays, propositions IRPF fondées sur littérature internationale, lecture politique, MDX complet avec composants Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
e32a3a32fe
commit
e8285bd1ff
12 changed files with 1390 additions and 345 deletions
12
src/components/Conjoncturel.astro
Normal file
12
src/components/Conjoncturel.astro
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
---
|
||||
// Couche 3 — Conjoncturel : actualité des 6 derniers mois, décisions récentes, polémiques
|
||||
---
|
||||
<div style="border-left: 4px solid #d97706; background: #fffbeb; padding: 1.5rem 1.75rem; margin: 2rem 0; border-radius: 0 0.5rem 0.5rem 0;">
|
||||
<div style="display: flex; align-items: center; gap: 0.75rem; margin-bottom: 1rem;">
|
||||
<span style="background: #d97706; color: white; font-size: 0.65rem; font-weight: 700; padding: 0.25rem 0.625rem; border-radius: 0.25rem; letter-spacing: 0.08em; text-transform: uppercase;">Conjoncturel</span>
|
||||
<span style="font-size: 0.8rem; color: #475569; font-style: italic;">Actualité des 6 derniers mois — décisions, polémiques, sondages récents</span>
|
||||
</div>
|
||||
<div class="layer-content">
|
||||
<slot />
|
||||
</div>
|
||||
</div>
|
||||
35
src/components/Kpi.astro
Normal file
35
src/components/Kpi.astro
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
---
|
||||
interface Props {
|
||||
valeur: string;
|
||||
label: string;
|
||||
source?: string;
|
||||
annee?: string | number;
|
||||
tendance?: 'hausse' | 'baisse' | 'stable' | 'critique' | 'alerte';
|
||||
contexte?: string;
|
||||
}
|
||||
|
||||
const { valeur, label, source, annee, tendance = 'stable', contexte } = Astro.props;
|
||||
|
||||
const tendanceConfig: Record<string, { icon: string; couleur: string }> = {
|
||||
hausse: { icon: '↑', couleur: '#16a34a' },
|
||||
baisse: { icon: '↓', couleur: '#dc2626' },
|
||||
stable: { icon: '→', couleur: '#6b7280' },
|
||||
critique: { icon: '⚠', couleur: '#dc2626' },
|
||||
alerte: { icon: '!', couleur: '#d97706' },
|
||||
};
|
||||
|
||||
const cfg = tendanceConfig[tendance] ?? tendanceConfig.stable;
|
||||
---
|
||||
<div style="display: inline-flex; flex-direction: column; background: white; border: 1px solid #e5e7eb; border-radius: 0.5rem; padding: 1rem 1.25rem; margin: 0.4rem; min-width: 140px; text-align: center; vertical-align: top;">
|
||||
<div style="display: flex; align-items: baseline; justify-content: center; gap: 0.3rem; line-height: 1;">
|
||||
<span style="font-size: 1.75rem; font-weight: 700; color: #0f172a;">{valeur}</span>
|
||||
<span style={`font-size: 1rem; font-weight: 600; color: ${cfg.couleur};`}>{cfg.icon}</span>
|
||||
</div>
|
||||
<div style="font-size: 0.78rem; font-weight: 500; color: #374151; margin-top: 0.35rem; line-height: 1.3;">{label}</div>
|
||||
{contexte && <div style="font-size: 0.72rem; color: #6b7280; margin-top: 0.2rem; line-height: 1.3;">{contexte}</div>}
|
||||
{source && (
|
||||
<div style="font-size: 0.65rem; color: #9ca3af; margin-top: 0.4rem; border-top: 1px solid #f3f4f6; padding-top: 0.35rem;">
|
||||
{source}{annee ? ` · ${annee}` : ''}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
12
src/components/Politique.astro
Normal file
12
src/components/Politique.astro
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
---
|
||||
// Couche 2 — Dimension politique : ce qui fait débat selon les valeurs et les intérêts
|
||||
---
|
||||
<div style="border-left: 4px solid #7c3aed; background: #faf5ff; padding: 1.5rem 1.75rem; margin: 2rem 0; border-radius: 0 0.5rem 0.5rem 0;">
|
||||
<div style="display: flex; align-items: center; gap: 0.75rem; margin-bottom: 1rem;">
|
||||
<span style="background: #7c3aed; color: white; font-size: 0.65rem; font-weight: 700; padding: 0.25rem 0.625rem; border-radius: 0.25rem; letter-spacing: 0.08em; text-transform: uppercase;">Politique</span>
|
||||
<span style="font-size: 0.8rem; color: #475569; font-style: italic;">Ce qui fait débat selon les valeurs et les intérêts</span>
|
||||
</div>
|
||||
<div class="layer-content">
|
||||
<slot />
|
||||
</div>
|
||||
</div>
|
||||
45
src/components/Sondage.astro
Normal file
45
src/components/Sondage.astro
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
---
|
||||
interface Props {
|
||||
question: string;
|
||||
pct: number;
|
||||
reponse?: string;
|
||||
source: string;
|
||||
annee: number | string;
|
||||
note?: string;
|
||||
couleur?: string;
|
||||
}
|
||||
|
||||
const {
|
||||
question,
|
||||
pct,
|
||||
reponse = "Oui / D'accord",
|
||||
source,
|
||||
annee,
|
||||
note,
|
||||
couleur = '#1e3a6e',
|
||||
} = Astro.props;
|
||||
|
||||
const largeur = Math.min(Math.max(pct, 3), 100);
|
||||
---
|
||||
<div style="background: #f8fafc; border: 1px solid #e5e7eb; border-radius: 0.5rem; padding: 1.25rem 1.5rem; margin: 1rem 0;">
|
||||
<div style="font-size: 0.875rem; color: #374151; margin-bottom: 1rem; line-height: 1.6; font-style: italic;">
|
||||
« {question} »
|
||||
</div>
|
||||
<div style="display: flex; align-items: center; gap: 1rem;">
|
||||
<div style="flex: 1; background: #e5e7eb; border-radius: 999px; height: 10px; overflow: hidden;">
|
||||
<div style={`width: ${largeur}%; background: ${couleur}; border-radius: 999px; height: 10px;`}></div>
|
||||
</div>
|
||||
<div style="font-size: 1.75rem; font-weight: 700; color: #0f172a; white-space: nowrap; min-width: 60px; text-align: right;">
|
||||
{pct}<span style="font-size: 1rem;">%</span>
|
||||
</div>
|
||||
</div>
|
||||
<div style="display: flex; justify-content: space-between; align-items: center; margin-top: 0.5rem;">
|
||||
<div style="font-size: 0.75rem; color: #6b7280;">{reponse}</div>
|
||||
<div style="font-size: 0.7rem; color: #9ca3af; font-weight: 500;">{source} · {annee}</div>
|
||||
</div>
|
||||
{note && (
|
||||
<div style="font-size: 0.72rem; color: #6b7280; margin-top: 0.6rem; padding-top: 0.6rem; border-top: 1px dashed #e5e7eb; font-style: italic;">
|
||||
{note}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
12
src/components/Structurel.astro
Normal file
12
src/components/Structurel.astro
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
---
|
||||
// Couche 1 — Facteurs structurels : contraintes de long terme, invariants institutionnels
|
||||
---
|
||||
<div style="border-left: 4px solid #1e3a6e; background: #f0f4ff; padding: 1.5rem 1.75rem; margin: 2rem 0; border-radius: 0 0.5rem 0.5rem 0;">
|
||||
<div style="display: flex; align-items: center; gap: 0.75rem; margin-bottom: 1rem;">
|
||||
<span style="background: #1e3a6e; color: white; font-size: 0.65rem; font-weight: 700; padding: 0.25rem 0.625rem; border-radius: 0.25rem; letter-spacing: 0.08em; text-transform: uppercase;">Structurel</span>
|
||||
<span style="font-size: 0.8rem; color: #475569; font-style: italic;">Ce qui ne change pas facilement — contraintes de fond</span>
|
||||
</div>
|
||||
<div class="layer-content">
|
||||
<slot />
|
||||
</div>
|
||||
</div>
|
||||
43
src/components/Timeline.astro
Normal file
43
src/components/Timeline.astro
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
---
|
||||
export interface TimelineItem {
|
||||
annee: string | number;
|
||||
titre: string;
|
||||
description: string;
|
||||
impact?: 'positif' | 'negatif' | 'neutre' | 'majeur';
|
||||
}
|
||||
|
||||
interface Props {
|
||||
items: TimelineItem[];
|
||||
}
|
||||
|
||||
const { items } = Astro.props;
|
||||
|
||||
const impactConfig: Record<string, { couleur: string; fond: string }> = {
|
||||
positif: { couleur: '#16a34a', fond: '#f0fdf4' },
|
||||
negatif: { couleur: '#dc2626', fond: '#fef2f2' },
|
||||
majeur: { couleur: '#d97706', fond: '#fffbeb' },
|
||||
neutre: { couleur: '#6b7280', fond: '#f9fafb' },
|
||||
};
|
||||
---
|
||||
<div style="position: relative; padding-left: 2.5rem; margin: 1.5rem 0;">
|
||||
<!-- Ligne verticale -->
|
||||
<div style="position: absolute; left: 0.75rem; top: 0.5rem; bottom: 0.5rem; width: 2px; background: linear-gradient(to bottom, #e5e7eb, #e5e7eb);"></div>
|
||||
|
||||
{items.map((item) => {
|
||||
const cfg = impactConfig[item.impact ?? 'neutre'];
|
||||
return (
|
||||
<div style="position: relative; margin-bottom: 1.5rem; padding-bottom: 0.5rem;">
|
||||
<!-- Point sur la ligne -->
|
||||
<div style={`position: absolute; left: -1.75rem; top: 0.2rem; width: 0.875rem; height: 0.875rem; border-radius: 50%; background: ${cfg.couleur}; border: 2px solid white; box-shadow: 0 0 0 2px ${cfg.couleur};`}></div>
|
||||
|
||||
<div style={`background: ${cfg.fond}; border: 1px solid #e5e7eb; border-radius: 0.375rem; padding: 0.875rem 1rem;`}>
|
||||
<div style="display: flex; align-items: baseline; gap: 0.75rem; margin-bottom: 0.3rem; flex-wrap: wrap;">
|
||||
<span style={`font-size: 0.75rem; font-weight: 700; color: ${cfg.couleur}; white-space: nowrap; font-variant-numeric: tabular-nums;`}>{item.annee}</span>
|
||||
<span style="font-size: 0.875rem; font-weight: 600; color: #0f172a; line-height: 1.4;">{item.titre}</span>
|
||||
</div>
|
||||
<p style="font-size: 0.8rem; color: #4b5563; margin: 0; line-height: 1.55;">{item.description}</p>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
|
|
@ -9,8 +9,38 @@ const themesCollection = defineCollection({
|
|||
description: z.string(),
|
||||
ordre: z.number(),
|
||||
priorite: z.enum(['critique', 'haute', 'normale']).default('normale'),
|
||||
|
||||
// Budget & effectifs
|
||||
budget_etat_milliards: z.number().optional(),
|
||||
effectifs_publics: z.number().optional(),
|
||||
|
||||
// KPI principal affiché dans le header
|
||||
kpi_valeur: z.string().optional(),
|
||||
kpi_label: z.string().optional(),
|
||||
kpi_tendance: z.enum(['hausse', 'baisse', 'stable', 'critique', 'alerte']).optional(),
|
||||
kpi_contexte: z.string().optional(),
|
||||
|
||||
// Opinion publique (1 chiffre clé pour la sidebar)
|
||||
opinion_pct: z.number().optional(),
|
||||
opinion_question: z.string().optional(),
|
||||
opinion_source: z.string().optional(),
|
||||
opinion_annee: z.number().optional(),
|
||||
|
||||
// Comparaison internationale
|
||||
rang_eu: z.number().optional(),
|
||||
nb_pays_compares: z.number().optional(),
|
||||
|
||||
// Sections présentes — pilote la nav
|
||||
sections: z.array(z.enum([
|
||||
'diagnostic', 'historique', 'enjeux', 'international',
|
||||
'opinion', 'acteurs', 'propositions', 'scenarios', 'sources',
|
||||
])).default(['diagnostic', 'enjeux', 'propositions', 'scenarios', 'sources']),
|
||||
|
||||
// Qualité
|
||||
score_sources: z.number().optional(),
|
||||
nb_propositions: z.number().optional(),
|
||||
|
||||
// Tags & sources
|
||||
tags: z.array(z.string()).default([]),
|
||||
sources_data: z.array(z.string()).default([]),
|
||||
derniere_maj: z.string(),
|
||||
|
|
@ -24,7 +54,7 @@ const propositionsCollection = defineCollection({
|
|||
titre: z.string(),
|
||||
theme: z.string(),
|
||||
source: z.string(),
|
||||
type_source: z.enum(['parti', 'think-tank', 'rapport-officiel', 'programme-presidentiel', 'rapport-parlementaire']),
|
||||
type_source: z.enum(['parti', 'think-tank', 'rapport-officiel', 'programme-presidentiel', 'rapport-parlementaire', 'irpf']),
|
||||
orientation: z.enum(['gauche', 'centre-gauche', 'centre', 'centre-droit', 'droite', 'autre']).optional(),
|
||||
annee: z.number(),
|
||||
horizon: z.enum(['court-terme', 'moyen-terme', 'long-terme']).default('moyen-terme'),
|
||||
|
|
@ -52,7 +82,7 @@ const acteursCollection = defineCollection({
|
|||
loader: glob({ pattern: '**/*.{md,mdx}', base: './src/content/acteurs' }),
|
||||
schema: z.object({
|
||||
nom: z.string(),
|
||||
type: z.enum(['think-tank', 'institution-publique', 'parti-politique', 'organisation-internationale', 'media']),
|
||||
type: z.enum(['think-tank', 'institution-publique', 'parti-politique', 'organisation-internationale', 'media', 'syndicat', 'federation']),
|
||||
orientation: z.enum(['gauche', 'centre-gauche', 'centre', 'centre-droit', 'droite', 'neutre']).optional(),
|
||||
specialites: z.array(z.string()).default([]),
|
||||
site: z.string().url().optional(),
|
||||
|
|
|
|||
316
src/content/themes/_TEMPLATE.mdx
Normal file
316
src/content/themes/_TEMPLATE.mdx
Normal file
|
|
@ -0,0 +1,316 @@
|
|||
---
|
||||
title: "Titre du thème"
|
||||
slug: "slug-du-theme"
|
||||
description: "Résumé en 1-2 phrases — situation, enjeux principaux."
|
||||
ordre: 99
|
||||
priorite: haute
|
||||
|
||||
# Budget & effectifs
|
||||
budget_etat_milliards: 0
|
||||
effectifs_publics: 0
|
||||
|
||||
# KPI affiché dans le header
|
||||
kpi_valeur: "XX%"
|
||||
kpi_label: "Indicateur principal"
|
||||
kpi_tendance: stable # hausse | baisse | stable | critique | alerte
|
||||
kpi_contexte: "vs. UE : XX%"
|
||||
|
||||
# Opinion (1 chiffre clé)
|
||||
opinion_pct: 0
|
||||
opinion_question: "Question posée aux Français"
|
||||
opinion_source: "Eurobaromètre"
|
||||
opinion_annee: 2024
|
||||
|
||||
# Comparaison internationale
|
||||
rang_eu: 0
|
||||
nb_pays_compares: 27
|
||||
|
||||
# Sections disponibles → pilote la nav
|
||||
sections:
|
||||
- diagnostic
|
||||
- historique
|
||||
- enjeux
|
||||
- international
|
||||
- opinion
|
||||
- acteurs
|
||||
- propositions
|
||||
- scenarios
|
||||
- sources
|
||||
|
||||
# Qualité
|
||||
score_sources: 0
|
||||
nb_propositions: 0
|
||||
|
||||
# Tags & sources
|
||||
tags: []
|
||||
sources_data: []
|
||||
derniere_maj: "2026-06"
|
||||
---
|
||||
|
||||
import Structurel from '../../components/Structurel.astro';
|
||||
import Politique from '../../components/Politique.astro';
|
||||
import Conjoncturel from '../../components/Conjoncturel.astro';
|
||||
import Kpi from '../../components/Kpi.astro';
|
||||
import Sondage from '../../components/Sondage.astro';
|
||||
import Timeline from '../../components/Timeline.astro';
|
||||
|
||||
## Diagnostic {#diagnostic}
|
||||
|
||||
[Intro : 2-3 phrases de synthèse — le paradoxe ou la tension centrale du sujet en France]
|
||||
|
||||
### Indicateurs clés
|
||||
|
||||
<Kpi valeur="XX%" label="Indicateur A" source="INSEE" annee="2024" tendance="baisse" />
|
||||
<Kpi valeur="XX Md€" label="Indicateur B" source="OCDE" annee="2024" tendance="stable" />
|
||||
<Kpi valeur="XXe" label="Rang UE" source="Eurostat" annee="2023" tendance="critique" />
|
||||
|
||||
### La situation actuelle
|
||||
|
||||
[Analyse détaillée, chiffrée, sourcée. 4-6 paragraphes. Chaque chiffre cite sa source entre parenthèses italiques.]
|
||||
|
||||
### Chiffres clés
|
||||
|
||||
| Indicateur | France | Référence | Tendance | Source |
|
||||
|-----------|--------|-----------|---------|--------|
|
||||
| ... | ... | ... | → | ... |
|
||||
|
||||
---
|
||||
|
||||
## Historique {#historique}
|
||||
|
||||
[Phrase d'intro : pourquoi l'histoire explique la situation actuelle]
|
||||
|
||||
### Chronologie des réformes majeures (30 ans)
|
||||
|
||||
export const timelineItems = [
|
||||
{
|
||||
annee: "1995",
|
||||
titre: "Exemple réforme",
|
||||
description: "Description concise de l'impact.",
|
||||
impact: "neutre"
|
||||
},
|
||||
{
|
||||
annee: "2004",
|
||||
titre: "Tournant majeur",
|
||||
description: "Ce qui a changé structurellement.",
|
||||
impact: "majeur"
|
||||
},
|
||||
{
|
||||
annee: "2017",
|
||||
titre: "Réforme récente",
|
||||
description: "Résultats observés.",
|
||||
impact: "positif"
|
||||
},
|
||||
];
|
||||
|
||||
<Timeline items={timelineItems} />
|
||||
|
||||
### Les tournants décisifs
|
||||
|
||||
[Analyse des 2-3 moments qui ont le plus façonné la situation actuelle. Pourquoi ces réformes ont réussi ou échoué.]
|
||||
|
||||
---
|
||||
|
||||
## Enjeux {#enjeux}
|
||||
|
||||
[Intro : les trois couches de lecture du problème]
|
||||
|
||||
<Structurel>
|
||||
|
||||
### Contraintes de fond
|
||||
|
||||
[Ce qui est difficile à changer : démographie, géographie, culture administrative, contraintes constitutionnelles ou européennes, économie politique. Chiffres structurels.]
|
||||
|
||||
- **Contrainte 1** : ...
|
||||
- **Contrainte 2** : ...
|
||||
- **Invariant** : ...
|
||||
|
||||
</Structurel>
|
||||
|
||||
<Politique>
|
||||
|
||||
### Ce qui fait débat
|
||||
|
||||
[Les fractures politiques réelles sur ce sujet. Positions des 6 familles : gauche (LFI/PS), écologistes (EELV), centre (Renaissance/MoDem), droite (LR), extrême droite (RN), souverainistes. Votes parlementaires récents.]
|
||||
|
||||
| Famille | Position | Argument central | Textes récents |
|
||||
|---------|---------|-----------------|---------------|
|
||||
| Gauche (LFI/PS) | ... | ... | ... |
|
||||
| Écologistes | ... | ... | ... |
|
||||
| Centre (Renaissance) | ... | ... | ... |
|
||||
| Droite (LR) | ... | ... | ... |
|
||||
| RN | ... | ... | ... |
|
||||
|
||||
</Politique>
|
||||
|
||||
<Conjoncturel>
|
||||
|
||||
### Actualité (6 derniers mois)
|
||||
|
||||
[Décisions gouvernementales, textes en cours, polémiques, derniers sondages. Référence aux événements de fin 2025 / début 2026.]
|
||||
|
||||
- **[Mois AAAA]** : ...
|
||||
- **[Mois AAAA]** : ...
|
||||
- **Texte en cours** : ...
|
||||
|
||||
</Conjoncturel>
|
||||
|
||||
---
|
||||
|
||||
## International {#international}
|
||||
|
||||
### Comparaison UE & OCDE
|
||||
|
||||
| Pays | Indicateur principal | [Indicateur 2] | [Indicateur 3] | Note |
|
||||
|------|---------------------|---------------|---------------|------|
|
||||
| **France** | **XX** | **XX** | **XX** | Situation spécifique |
|
||||
| Allemagne | XX | XX | XX | — |
|
||||
| Suède | XX | XX | XX | Modèle de référence |
|
||||
| Espagne | XX | XX | XX | — |
|
||||
| Moyenne UE | XX | XX | XX | — |
|
||||
|
||||
### Ce que recommandent les institutions
|
||||
|
||||
**OCDE :** [Recommandation principale, numéro de rapport, année]
|
||||
|
||||
**Commission européenne :** [Position / Country Report France 2024]
|
||||
|
||||
**FMI :** [Recommandation Article IV 2024]
|
||||
|
||||
**Cour des comptes :** [Recommandation rapport récent]
|
||||
|
||||
**France Stratégie :** [Recommandation publication récente]
|
||||
|
||||
### Bonnes pratiques — ce qui fonctionne ailleurs
|
||||
|
||||
**[Pays modèle 1] — [Mesure]** : [Description et résultats mesurés]
|
||||
|
||||
**[Pays modèle 2] — [Mesure]** : [Description et résultats mesurés]
|
||||
|
||||
---
|
||||
|
||||
## Opinion {#opinion}
|
||||
|
||||
### Ce qu'en pensent les Français
|
||||
|
||||
<Sondage
|
||||
question="[Question posée dans le sondage]"
|
||||
pct={73}
|
||||
reponse="Oui / D'accord / Satisfait"
|
||||
source="Eurobaromètre"
|
||||
annee={2024}
|
||||
note="UE27 : XX% · Écart France/UE : +X points"
|
||||
/>
|
||||
|
||||
<Sondage
|
||||
question="[Deuxième question — confiance dans les institutions]"
|
||||
pct={45}
|
||||
reponse="Fait confiance"
|
||||
source="CEVIPOF Baromètre de la confiance"
|
||||
annee={2025}
|
||||
/>
|
||||
|
||||
### Évolution dans le temps
|
||||
|
||||
[Analyse de la tendance : est-ce que l'opinion s'améliore ou se dégrade ? Depuis quand ? Quels événements ont influencé l'opinion ?]
|
||||
|
||||
| Année | % satisfaction | Source |
|
||||
|-------|---------------|--------|
|
||||
| 2018 | XX% | ... |
|
||||
| 2020 | XX% | ... |
|
||||
| 2022 | XX% | ... |
|
||||
| 2024 | XX% | ... |
|
||||
|
||||
### Clivages dans l'opinion
|
||||
|
||||
[Différences significatives par âge, revenu, territoire, orientation politique]
|
||||
|
||||
---
|
||||
|
||||
## Acteurs {#acteurs}
|
||||
|
||||
### Institutions décisionnaires
|
||||
|
||||
| Institution | Rôle | Tutelle | Budget | Responsable |
|
||||
|------------|------|---------|--------|------------|
|
||||
| Ministère ... | ... | Premier ministre | XX Md€ | [Ministre] |
|
||||
| [Agence/établissement] | ... | [Ministère] | XX M€ | ... |
|
||||
|
||||
### Think tanks — par orientation
|
||||
|
||||
| Think tank | Orientation | Spécialité | Publications récentes |
|
||||
|-----------|------------|-----------|----------------------|
|
||||
| Institut Montaigne | Centre-droit | ... | [Titre rapport, 2024] |
|
||||
| Terra Nova | Centre-gauche | ... | [Titre rapport, 2024] |
|
||||
| iFRAP | Libéral | ... | [Titre rapport, 2024] |
|
||||
| Fondapol | Centre-droit | ... | ... |
|
||||
| OFCE | Centre-gauche | ... | ... |
|
||||
| CAE | Neutre/expert | ... | ... |
|
||||
|
||||
### Syndicats, fédérations, organisations professionnelles
|
||||
|
||||
[Les acteurs intermédiaires qui pèsent sur les décisions dans ce secteur]
|
||||
|
||||
---
|
||||
|
||||
## Propositions {#propositions}
|
||||
|
||||
### Comparatif des positions partisanes
|
||||
|
||||
| Parti | Proposition principale | Coût estimé | Horizon | Cohérence |
|
||||
|-------|----------------------|------------|---------|-----------|
|
||||
| LFI | ... | XX Md€ | CT | ... |
|
||||
| PS | ... | XX Md€ | MT | ... |
|
||||
| EELV | ... | XX Md€ | LT | ... |
|
||||
| Renaissance | ... | XX Md€ | MT | ... |
|
||||
| LR | ... | XX Md€ | MT | ... |
|
||||
| RN | ... | XX Md€ | CT | ... |
|
||||
|
||||
### Recommandations institutionnelles
|
||||
|
||||
[Synthèse des recommandations OCDE + CE + Cour des comptes + France Stratégie, classées par faisabilité politique]
|
||||
|
||||
### Propositions IRPF
|
||||
|
||||
> **Notre analyse** : [1 paragraphe de cadrage — pourquoi ces propositions, quelle philosophie]
|
||||
|
||||
**Proposition 1 — [Titre court]**
|
||||
[Description, impact attendu, coût, horizon, conditions de réussite]
|
||||
|
||||
**Proposition 2 — [Titre court]**
|
||||
[Description, impact attendu, coût, horizon, conditions de réussite]
|
||||
|
||||
**Proposition 3 — [Titre court]**
|
||||
[Description, impact attendu, coût, horizon, conditions de réussite]
|
||||
|
||||
---
|
||||
|
||||
## Scénarios 2027–2032 {#scenarios}
|
||||
|
||||
### Scénario A — Continuité (probabilité : XX%)
|
||||
**Hypothèse** : [statu quo politique]
|
||||
**Impact** : [dégradation / stabilisation]
|
||||
**Risques** : ...
|
||||
|
||||
### Scénario B — Réforme graduelle (probabilité : XX%)
|
||||
**Hypothèse** : [coalition + X réformes adoptées]
|
||||
**Impact** : [amélioration mesurable]
|
||||
**Conditions** : ...
|
||||
|
||||
### Scénario C — Rupture (probabilité : XX%)
|
||||
**Hypothèse** : [changement de majorité / crise déclenchante]
|
||||
**Impact** : [transformation structurelle]
|
||||
**Conditions** : ...
|
||||
|
||||
---
|
||||
|
||||
## Sources {#sources}
|
||||
|
||||
### Sources primaires
|
||||
- [Auteur, *Titre*, Institution, Année. URL]
|
||||
|
||||
### Sources secondaires
|
||||
- [...]
|
||||
|
||||
### Données
|
||||
- [Base de données, institution, accès]
|
||||
|
|
@ -88,7 +88,7 @@ const rapports = (await getCollection('rapports')).slice(0, 3);
|
|||
</div>
|
||||
<div style="display: grid; grid-template-columns: repeat(3, 1fr); gap: 1rem;">
|
||||
{themes.slice(0, 6).map((theme) => (
|
||||
<a href={`/themes/${theme.slug}/`} style="background: white; border: 1px solid #e5e7eb; border-radius: 0.5rem; padding: 1.5rem; text-decoration: none; display: block;" class="theme-card">
|
||||
<a href={`/themes/${theme.data.slug}/`} style="background: white; border: 1px solid #e5e7eb; border-radius: 0.5rem; padding: 1.5rem; text-decoration: none; display: block;" class="theme-card">
|
||||
<div style="font-weight: 600; color: #0f172a; margin-bottom: 0.5rem;">{theme.data.title}</div>
|
||||
<p style="font-size: 0.85rem; color: #6b7280; line-height: 1.5; margin-bottom: 1rem;">{theme.data.description}</p>
|
||||
<div style="display: flex; gap: 0.5rem; flex-wrap: wrap;">
|
||||
|
|
|
|||
|
|
@ -16,17 +16,44 @@ const { Content } = await render(theme);
|
|||
const allPropositions = await getCollection('propositions');
|
||||
const propositions = allPropositions.filter(p => p.data.theme === theme.data.slug);
|
||||
|
||||
// Sections configurées dans le frontmatter → nav dynamique
|
||||
const SECTION_LABELS: Record<string, string> = {
|
||||
diagnostic: 'Diagnostic',
|
||||
historique: 'Historique',
|
||||
enjeux: 'Enjeux',
|
||||
international: 'International',
|
||||
opinion: 'Opinion',
|
||||
acteurs: 'Acteurs',
|
||||
propositions: 'Propositions',
|
||||
scenarios: 'Scénarios',
|
||||
sources: 'Sources',
|
||||
};
|
||||
|
||||
const navSections = theme.data.sections.map(s => ({
|
||||
id: s,
|
||||
label: SECTION_LABELS[s] ?? s,
|
||||
}));
|
||||
|
||||
function orientationBadge(o?: string) {
|
||||
const map: Record<string, string> = {
|
||||
'gauche': 'background:#fee2e2;color:#991b1b',
|
||||
'gauche': 'background:#fee2e2;color:#991b1b',
|
||||
'centre-gauche': 'background:#fce7f3;color:#9d174d',
|
||||
'centre': 'background:#dbeafe;color:#1e40af',
|
||||
'centre-droit': 'background:#ede9fe;color:#5b21b6',
|
||||
'droite': 'background:#f3e8ff;color:#6b21a8',
|
||||
'neutre': 'background:#f3f4f6;color:#374151',
|
||||
'centre': 'background:#dbeafe;color:#1e40af',
|
||||
'centre-droit': 'background:#ede9fe;color:#5b21b6',
|
||||
'droite': 'background:#f3e8ff;color:#6b21a8',
|
||||
'neutre': 'background:#f3f4f6;color:#374151',
|
||||
'irpf': 'background:#0f172a;color:white',
|
||||
};
|
||||
return map[o ?? 'neutre'] ?? map['neutre'];
|
||||
}
|
||||
|
||||
function tendanceCouleur(t?: string) {
|
||||
return { hausse: '#16a34a', baisse: '#dc2626', stable: '#6b7280', critique: '#dc2626', alerte: '#d97706' }[t ?? 'stable'] ?? '#6b7280';
|
||||
}
|
||||
|
||||
function tendanceIcon(t?: string) {
|
||||
return { hausse: '↑', baisse: '↓', stable: '→', critique: '⚠', alerte: '!' }[t ?? 'stable'] ?? '→';
|
||||
}
|
||||
---
|
||||
|
||||
<BaseLayout
|
||||
|
|
@ -45,54 +72,96 @@ function orientationBadge(o?: string) {
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Header -->
|
||||
<section style="background: linear-gradient(135deg, #0f172a, #1e3a6e); color: white; padding: 3rem 1.5rem;">
|
||||
<div style="max-width: 1200px; margin: 0 auto; display: grid; grid-template-columns: 1fr auto; gap: 2rem; align-items: start;">
|
||||
<div>
|
||||
{theme.data.priorite === 'critique' && (
|
||||
<span style="background: #ef4444; color: white; font-size: 0.7rem; font-weight: 700; padding: 0.2rem 0.625rem; border-radius: 0.25rem; letter-spacing: 0.05em; margin-bottom: 1rem; display: inline-block;">PRIORITÉ CRITIQUE</span>
|
||||
)}
|
||||
<h1 style="font-family: 'Playfair Display', serif; font-size: 2.5rem; margin-bottom: 1rem;">{theme.data.title}</h1>
|
||||
<p style="color: #cbd5e1; font-size: 1.05rem; line-height: 1.7; max-width: 700px;">{theme.data.description}</p>
|
||||
<div style="display: flex; gap: 1rem; margin-top: 1.5rem; flex-wrap: wrap;">
|
||||
{theme.data.budget_etat_milliards && (
|
||||
<div style="background: rgba(255,255,255,0.1); padding: 0.5rem 1rem; border-radius: 0.375rem;">
|
||||
<div style="font-size: 1.25rem; font-weight: 700;">{theme.data.budget_etat_milliards} Md€</div>
|
||||
<div style="font-size: 0.75rem; color: #93c5fd;">Budget État 2025</div>
|
||||
</div>
|
||||
<!-- Header enrichi -->
|
||||
<section style="background: linear-gradient(135deg, #0f172a 0%, #1e3a6e 100%); color: white; padding: 3rem 1.5rem 2.5rem;">
|
||||
<div style="max-width: 1200px; margin: 0 auto;">
|
||||
<div style="display: grid; grid-template-columns: 1fr auto; gap: 2rem; align-items: start;">
|
||||
<div>
|
||||
{theme.data.priorite === 'critique' && (
|
||||
<span style="background: #ef4444; color: white; font-size: 0.65rem; font-weight: 700; padding: 0.2rem 0.625rem; border-radius: 0.25rem; letter-spacing: 0.06em; margin-bottom: 0.875rem; display: inline-block;">PRIORITÉ CRITIQUE</span>
|
||||
)}
|
||||
<div style="background: rgba(255,255,255,0.1); padding: 0.5rem 1rem; border-radius: 0.375rem;">
|
||||
<div style="font-size: 1.25rem; font-weight: 700;">{propositions.length}</div>
|
||||
<div style="font-size: 0.75rem; color: #93c5fd;">Propositions recensées</div>
|
||||
{theme.data.priorite === 'haute' && (
|
||||
<span style="background: #d97706; color: white; font-size: 0.65rem; font-weight: 700; padding: 0.2rem 0.625rem; border-radius: 0.25rem; letter-spacing: 0.06em; margin-bottom: 0.875rem; display: inline-block;">PRIORITÉ HAUTE</span>
|
||||
)}
|
||||
<h1 style="font-family: 'Playfair Display', serif; font-size: 2.5rem; font-weight: 700; margin: 0 0 0.875rem; line-height: 1.15;">{theme.data.title}</h1>
|
||||
<p style="color: #cbd5e1; font-size: 1.05rem; line-height: 1.7; max-width: 680px; margin: 0 0 1.75rem;">{theme.data.description}</p>
|
||||
|
||||
<!-- Métriques header -->
|
||||
<div style="display: flex; gap: 0.875rem; flex-wrap: wrap;">
|
||||
{theme.data.kpi_valeur && (
|
||||
<div style="background: rgba(255,255,255,0.12); border: 1px solid rgba(255,255,255,0.15); padding: 0.75rem 1.25rem; border-radius: 0.5rem; min-width: 130px;">
|
||||
<div style={`font-size: 1.5rem; font-weight: 700; display: flex; align-items: baseline; gap: 0.3rem; color: white;`}>
|
||||
{theme.data.kpi_valeur}
|
||||
<span style={`font-size: 0.9rem; color: ${tendanceCouleur(theme.data.kpi_tendance)};`}>{tendanceIcon(theme.data.kpi_tendance)}</span>
|
||||
</div>
|
||||
<div style="font-size: 0.72rem; color: #93c5fd; margin-top: 0.2rem;">{theme.data.kpi_label}</div>
|
||||
{theme.data.kpi_contexte && <div style="font-size: 0.65rem; color: #64748b; margin-top: 0.15rem;">{theme.data.kpi_contexte}</div>}
|
||||
</div>
|
||||
)}
|
||||
{theme.data.budget_etat_milliards && (
|
||||
<div style="background: rgba(255,255,255,0.12); border: 1px solid rgba(255,255,255,0.15); padding: 0.75rem 1.25rem; border-radius: 0.5rem;">
|
||||
<div style="font-size: 1.5rem; font-weight: 700; color: white;">{theme.data.budget_etat_milliards} Md€</div>
|
||||
<div style="font-size: 0.72rem; color: #93c5fd; margin-top: 0.2rem;">Budget État 2025</div>
|
||||
</div>
|
||||
)}
|
||||
{theme.data.opinion_pct && (
|
||||
<div style="background: rgba(255,255,255,0.12); border: 1px solid rgba(255,255,255,0.15); padding: 0.75rem 1.25rem; border-radius: 0.5rem;">
|
||||
<div style="font-size: 1.5rem; font-weight: 700; color: white;">{theme.data.opinion_pct}%</div>
|
||||
<div style="font-size: 0.72rem; color: #93c5fd; margin-top: 0.2rem; max-width: 140px; line-height: 1.3;">{theme.data.opinion_question ?? 'Satisfaction'}</div>
|
||||
{theme.data.opinion_source && <div style="font-size: 0.65rem; color: #64748b; margin-top: 0.15rem;">{theme.data.opinion_source} · {theme.data.opinion_annee}</div>}
|
||||
</div>
|
||||
)}
|
||||
<div style="background: rgba(255,255,255,0.12); border: 1px solid rgba(255,255,255,0.15); padding: 0.75rem 1.25rem; border-radius: 0.5rem;">
|
||||
<div style="font-size: 1.5rem; font-weight: 700; color: white;">{propositions.length}</div>
|
||||
<div style="font-size: 0.72rem; color: #93c5fd; margin-top: 0.2rem;">Propositions</div>
|
||||
</div>
|
||||
{theme.data.score_sources && (
|
||||
<div style="background: rgba(255,255,255,0.12); border: 1px solid rgba(255,255,255,0.15); padding: 0.75rem 1.25rem; border-radius: 0.5rem;">
|
||||
<div style="font-size: 1.5rem; font-weight: 700; color: white;">{theme.data.score_sources}</div>
|
||||
<div style="font-size: 0.72rem; color: #93c5fd; margin-top: 0.2rem;">Sources vérifiées</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div style="text-align: right;">
|
||||
<div style="font-size: 0.75rem; color: #6b7280;">Mis à jour</div>
|
||||
<div style="font-size: 0.875rem; color: #93c5fd;">{theme.data.derniere_maj}</div>
|
||||
<div style="margin-top: 1rem;">
|
||||
<div style="font-size: 0.75rem; color: #6b7280; margin-bottom: 0.5rem;">Sources data</div>
|
||||
{theme.data.sources_data.map(s => (
|
||||
<div style="font-size: 0.75rem; color: #93c5fd;">{s}</div>
|
||||
))}
|
||||
|
||||
<!-- Meta droite -->
|
||||
<div style="text-align: right; flex-shrink: 0;">
|
||||
<div style="font-size: 0.7rem; color: #64748b;">Mis à jour</div>
|
||||
<div style="font-size: 0.875rem; color: #93c5fd; margin-bottom: 1rem;">{theme.data.derniere_maj}</div>
|
||||
{theme.data.rang_eu && (
|
||||
<div style="margin-bottom: 1rem;">
|
||||
<div style="font-size: 0.7rem; color: #64748b;">Rang UE</div>
|
||||
<div style="font-size: 1.25rem; font-weight: 700; color: white;">{theme.data.rang_eu}<span style="font-size: 0.75rem; color: #64748b;">/{theme.data.nb_pays_compares ?? 27}</span></div>
|
||||
</div>
|
||||
)}
|
||||
<div>
|
||||
<div style="font-size: 0.7rem; color: #64748b; margin-bottom: 0.4rem;">Sources data</div>
|
||||
{theme.data.sources_data.slice(0, 6).map(s => (
|
||||
<div style="font-size: 0.72rem; color: #93c5fd; line-height: 1.6;">{s}</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Nav interne -->
|
||||
<nav style="background: white; border-bottom: 1px solid #e5e7eb; padding: 0 1.5rem; position: sticky; top: 64px; z-index: 40;">
|
||||
<div style="max-width: 1200px; margin: 0 auto; display: flex; gap: 2rem; overflow-x: auto;">
|
||||
{['Diagnostic', 'Enjeux', 'Propositions', 'Scénarios', 'Sources'].map(anchor => (
|
||||
<a href={`#${anchor.toLowerCase().replace('é','e').replace('s','s')}`} style="padding: 1rem 0; font-size: 0.875rem; font-weight: 500; color: #374151; text-decoration: none; white-space: nowrap; border-bottom: 2px solid transparent;" class="nav-anchor">
|
||||
{anchor}
|
||||
<!-- Nav interne dynamique -->
|
||||
<nav style="background: white; border-bottom: 2px solid #e5e7eb; padding: 0 1.5rem; position: sticky; top: 0; z-index: 40; box-shadow: 0 1px 3px rgba(0,0,0,0.06);">
|
||||
<div style="max-width: 1200px; margin: 0 auto; display: flex; gap: 0; overflow-x: auto; scrollbar-width: none;">
|
||||
{navSections.map(({ id, label }) => (
|
||||
<a
|
||||
href={`#${id}`}
|
||||
style="padding: 0.875rem 1rem; font-size: 0.82rem; font-weight: 500; color: #4b5563; text-decoration: none; white-space: nowrap; border-bottom: 2px solid transparent; margin-bottom: -2px; transition: all 0.15s;"
|
||||
class="nav-anchor"
|
||||
>
|
||||
{label}
|
||||
</a>
|
||||
))}
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<!-- Contenu -->
|
||||
<div style="max-width: 1200px; margin: 0 auto; padding: 3rem 1.5rem; display: grid; grid-template-columns: 1fr 280px; gap: 3rem; align-items: start;">
|
||||
<!-- Corps : article + sidebar -->
|
||||
<div style="max-width: 1200px; margin: 0 auto; padding: 2.5rem 1.5rem 4rem; display: grid; grid-template-columns: 1fr 300px; gap: 3rem; align-items: start;">
|
||||
|
||||
<article>
|
||||
<div class="prose-irpf">
|
||||
|
|
@ -100,44 +169,173 @@ function orientationBadge(o?: string) {
|
|||
</div>
|
||||
</article>
|
||||
|
||||
<aside style="position: sticky; top: 120px;">
|
||||
<!-- Sidebar enrichie -->
|
||||
<aside style="position: sticky; top: 60px; display: flex; flex-direction: column; gap: 1.25rem;">
|
||||
|
||||
<!-- Propositions -->
|
||||
{propositions.length > 0 && (
|
||||
<div style="background: #f8fafc; border: 1px solid #e5e7eb; border-radius: 0.5rem; padding: 1.25rem; margin-bottom: 1.5rem;">
|
||||
<div style="font-weight: 600; font-size: 0.875rem; color: #0f172a; margin-bottom: 1rem;">Propositions recensées ({propositions.length})</div>
|
||||
<div style="display: flex; flex-direction: column; gap: 0.75rem;">
|
||||
{propositions.slice(0, 5).map(p => (
|
||||
<div style="background: #f8fafc; border: 1px solid #e5e7eb; border-radius: 0.5rem; padding: 1.25rem;">
|
||||
<div style="font-weight: 600; font-size: 0.82rem; color: #0f172a; margin-bottom: 0.875rem; text-transform: uppercase; letter-spacing: 0.04em;">
|
||||
Propositions · {propositions.length}
|
||||
</div>
|
||||
<div style="display: flex; flex-direction: column; gap: 0.625rem;">
|
||||
{propositions.slice(0, 6).map(p => (
|
||||
<div style="background: white; border: 1px solid #e5e7eb; border-radius: 0.375rem; padding: 0.75rem;">
|
||||
<div style="font-size: 0.8rem; font-weight: 500; color: #0f172a; margin-bottom: 0.35rem; line-height: 1.4;">{p.data.titre}</div>
|
||||
<div style="font-size: 0.78rem; font-weight: 500; color: #0f172a; margin-bottom: 0.4rem; line-height: 1.45;">{p.data.titre}</div>
|
||||
<div style="display: flex; gap: 0.35rem; flex-wrap: wrap; align-items: center;">
|
||||
<span style={`font-size: 0.65rem; padding: 0.15rem 0.4rem; border-radius: 0.2rem; font-weight: 500; ${orientationBadge(p.data.orientation)}`}>
|
||||
<span style={`font-size: 0.62rem; padding: 0.15rem 0.4rem; border-radius: 0.2rem; font-weight: 600; ${orientationBadge(p.data.orientation)}`}>
|
||||
{p.data.source}
|
||||
</span>
|
||||
<span style="font-size: 0.65rem; color: #9ca3af;">{p.data.annee}</span>
|
||||
<span style="font-size: 0.62rem; color: #9ca3af;">{p.data.horizon} · {p.data.annee}</span>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
{propositions.length > 5 && (
|
||||
<a href="/propositions/" style="display: block; text-align: center; margin-top: 0.75rem; font-size: 0.8rem; color: #1e3a6e; text-decoration: none;">
|
||||
Voir les {propositions.length - 5} autres →
|
||||
{propositions.length > 6 && (
|
||||
<a href="/propositions/" style="display: block; text-align: center; margin-top: 0.75rem; font-size: 0.78rem; color: #1e3a6e; text-decoration: none; font-weight: 500;">
|
||||
+ {propositions.length - 6} autres propositions →
|
||||
</a>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
|
||||
<!-- Sections -->
|
||||
<div style="background: #f8fafc; border: 1px solid #e5e7eb; border-radius: 0.5rem; padding: 1.25rem;">
|
||||
<div style="font-weight: 600; font-size: 0.875rem; color: #0f172a; margin-bottom: 0.75rem;">Mots-clés</div>
|
||||
<div style="display: flex; flex-wrap: wrap; gap: 0.4rem;">
|
||||
{theme.data.tags.map(tag => (
|
||||
<span style="background: white; border: 1px solid #e5e7eb; color: #374151; font-size: 0.75rem; padding: 0.25rem 0.625rem; border-radius: 0.25rem;">#{tag}</span>
|
||||
<div style="font-weight: 600; font-size: 0.82rem; color: #0f172a; margin-bottom: 0.875rem; text-transform: uppercase; letter-spacing: 0.04em;">Contenu</div>
|
||||
<div style="display: flex; flex-direction: column; gap: 0.25rem;">
|
||||
{navSections.map(({ id, label }) => (
|
||||
<a href={`#${id}`} style="font-size: 0.8rem; color: #374151; text-decoration: none; padding: 0.3rem 0.5rem; border-radius: 0.25rem; display: block;" class="toc-link">
|
||||
{label}
|
||||
</a>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Tags -->
|
||||
<div style="background: #f8fafc; border: 1px solid #e5e7eb; border-radius: 0.5rem; padding: 1.25rem;">
|
||||
<div style="font-weight: 600; font-size: 0.82rem; color: #0f172a; margin-bottom: 0.75rem; text-transform: uppercase; letter-spacing: 0.04em;">Mots-clés</div>
|
||||
<div style="display: flex; flex-wrap: wrap; gap: 0.4rem;">
|
||||
{theme.data.tags.map(tag => (
|
||||
<span style="background: white; border: 1px solid #e5e7eb; color: #374151; font-size: 0.72rem; padding: 0.2rem 0.5rem; border-radius: 0.2rem;">#{tag}</span>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</aside>
|
||||
</div>
|
||||
|
||||
</BaseLayout>
|
||||
|
||||
<style>
|
||||
.nav-anchor:hover { color: #1e3a6e; border-bottom-color: #1e3a6e !important; }
|
||||
.nav-anchor:hover,
|
||||
.nav-anchor:focus { color: #1e3a6e !important; border-bottom-color: #1e3a6e !important; }
|
||||
|
||||
.toc-link:hover { background: #e5e7eb; color: #0f172a !important; }
|
||||
|
||||
/* Typographie du corps de fiche */
|
||||
.prose-irpf h2 {
|
||||
font-family: 'Playfair Display', serif;
|
||||
font-size: 1.6rem;
|
||||
font-weight: 700;
|
||||
color: #0f172a;
|
||||
margin: 3rem 0 1rem;
|
||||
padding-bottom: 0.5rem;
|
||||
border-bottom: 2px solid #e5e7eb;
|
||||
scroll-margin-top: 80px;
|
||||
}
|
||||
.prose-irpf h3 {
|
||||
font-size: 1.1rem;
|
||||
font-weight: 600;
|
||||
color: #1e3a6e;
|
||||
margin: 1.75rem 0 0.75rem;
|
||||
scroll-margin-top: 80px;
|
||||
}
|
||||
.prose-irpf h4 {
|
||||
font-size: 0.95rem;
|
||||
font-weight: 600;
|
||||
color: #374151;
|
||||
margin: 1.25rem 0 0.5rem;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.04em;
|
||||
}
|
||||
.prose-irpf p {
|
||||
font-size: 0.9rem;
|
||||
line-height: 1.8;
|
||||
color: #374151;
|
||||
margin: 0.75rem 0;
|
||||
}
|
||||
.prose-irpf strong { color: #0f172a; }
|
||||
.prose-irpf em { color: #4b5563; }
|
||||
|
||||
.prose-irpf table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
margin: 1.25rem 0;
|
||||
font-size: 0.82rem;
|
||||
}
|
||||
.prose-irpf th {
|
||||
background: #0f172a;
|
||||
color: white;
|
||||
padding: 0.6rem 0.875rem;
|
||||
text-align: left;
|
||||
font-size: 0.72rem;
|
||||
font-weight: 600;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.04em;
|
||||
}
|
||||
.prose-irpf td {
|
||||
padding: 0.6rem 0.875rem;
|
||||
border-bottom: 1px solid #e5e7eb;
|
||||
color: #374151;
|
||||
vertical-align: top;
|
||||
line-height: 1.5;
|
||||
}
|
||||
.prose-irpf tr:nth-child(even) td { background: #f8fafc; }
|
||||
.prose-irpf tr:hover td { background: #f0f4ff; }
|
||||
|
||||
.prose-irpf ul, .prose-irpf ol {
|
||||
padding-left: 1.5rem;
|
||||
margin: 0.75rem 0;
|
||||
}
|
||||
.prose-irpf li {
|
||||
font-size: 0.88rem;
|
||||
line-height: 1.75;
|
||||
color: #374151;
|
||||
margin-bottom: 0.25rem;
|
||||
}
|
||||
|
||||
.prose-irpf blockquote {
|
||||
border-left: 4px solid #1e3a6e;
|
||||
background: #f0f4ff;
|
||||
padding: 1rem 1.25rem;
|
||||
margin: 1.5rem 0;
|
||||
border-radius: 0 0.375rem 0.375rem 0;
|
||||
font-style: italic;
|
||||
color: #374151;
|
||||
}
|
||||
.prose-irpf blockquote p { margin: 0; }
|
||||
|
||||
.prose-irpf a {
|
||||
color: #1e3a6e;
|
||||
text-decoration: underline;
|
||||
text-decoration-color: #bfdbfe;
|
||||
}
|
||||
.prose-irpf a:hover { text-decoration-color: #1e3a6e; }
|
||||
|
||||
.prose-irpf code {
|
||||
background: #f1f5f9;
|
||||
padding: 0.1rem 0.35rem;
|
||||
border-radius: 0.2rem;
|
||||
font-size: 0.82rem;
|
||||
color: #0f172a;
|
||||
}
|
||||
|
||||
/* Couches visuelles : héritage du slot */
|
||||
.layer-content p { font-size: 0.88rem; }
|
||||
.layer-content ul { padding-left: 1.25rem; }
|
||||
.layer-content li { font-size: 0.85rem; }
|
||||
.layer-content table { font-size: 0.8rem; }
|
||||
|
||||
/* Scroll offset pour nav sticky */
|
||||
[id] { scroll-margin-top: 80px; }
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ const autres = themes.filter(t => t.data.priorite !== 'critique');
|
|||
</div>
|
||||
<div style="display: grid; grid-template-columns: repeat(3, 1fr); gap: 1rem;">
|
||||
{critiques.map(theme => (
|
||||
<a href={`/themes/${theme.slug}/`} style="background: white; border: 2px solid #fca5a5; border-radius: 0.5rem; padding: 1.5rem; text-decoration: none; display: block;" class="theme-card">
|
||||
<a href={`/themes/${theme.data.slug}/`} style="background: white; border: 2px solid #fca5a5; border-radius: 0.5rem; padding: 1.5rem; text-decoration: none; display: block;" class="theme-card">
|
||||
<div style="font-weight: 700; color: #0f172a; font-size: 1.05rem; margin-bottom: 0.5rem;">{theme.data.title}</div>
|
||||
<p style="font-size: 0.85rem; color: #6b7280; line-height: 1.5; margin-bottom: 1rem;">{theme.data.description}</p>
|
||||
<div style="display: flex; gap: 0.5rem; flex-wrap: wrap; align-items: center;">
|
||||
|
|
@ -52,7 +52,7 @@ const autres = themes.filter(t => t.data.priorite !== 'critique');
|
|||
</div>
|
||||
<div style="display: grid; grid-template-columns: repeat(3, 1fr); gap: 1rem;">
|
||||
{autres.map(theme => (
|
||||
<a href={`/themes/${theme.slug}/`} style="background: white; border: 1px solid #e5e7eb; border-radius: 0.5rem; padding: 1.5rem; text-decoration: none; display: block;" class="theme-card">
|
||||
<a href={`/themes/${theme.data.slug}/`} style="background: white; border: 1px solid #e5e7eb; border-radius: 0.5rem; padding: 1.5rem; text-decoration: none; display: block;" class="theme-card">
|
||||
<div style="font-weight: 600; color: #0f172a; margin-bottom: 0.5rem;">{theme.data.title}</div>
|
||||
<p style="font-size: 0.85rem; color: #6b7280; line-height: 1.5; margin-bottom: 1rem;">{theme.data.description}</p>
|
||||
<div style="display: flex; gap: 0.5rem; flex-wrap: wrap;">
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
Loading…
Add table
Reference in a new issue