// Main app — composes the Christoph Napierala homepage.
// Order of script tags in index.html: react, react-dom, babel, tweaks-panel.jsx, art.jsx, app.jsx

const { useState, useEffect } = React;

// Asset resolver — in a bundled standalone file, image paths are lifted into
// window.__resources (blob URLs) via <meta name="ext-resource-dependency">.
// Falls back to the raw path in the normal multi-file dev version.
const ASSET_IDS = {
  "assets/portrait.jpg": "portrait",
  "assets/talk-enso.webp": "enso",
  "assets/talk-snow-pano.webp": "snowPano",
  "assets/talk-lake-reflection.webp": "lakeReflection",
  "assets/talk-fruit.webp": "fruit",
  "assets/talk-peak-golden.webp": "peakGolden",
  "assets/talk-lake-sunrise.webp": "lakeSunrise"
};
function asset(p) {
  const id = ASSET_IDS[p];
  if (id && window.__resources && window.__resources[id]) return window.__resources[id];
  return p;
}

const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "accent": "#b4321f",
  "bg": "#f4efe6",
  "displayFont": "Source Serif 4",
  "language": "de",
  "darkHero": false
} /*EDITMODE-END*/;

const ACCENT_OPTIONS = [
{ label: "Swiss Red", value: "#b4321f" },
{ label: "Ink Blue", value: "#1f3b6e" },
{ label: "Forest", value: "#2d4a3e" },
{ label: "Ochre", value: "#b07a1f" },
{ label: "Graphite", value: "#2a2a2a" }];


const BG_OPTIONS = [
{ label: "Paper", value: "#f4efe6" },
{ label: "Bone", value: "#ece6d6" },
{ label: "Cool White", value: "#f3f3f1" },
{ label: "Slate Mist", value: "#e8eaec" }];


const FONT_OPTIONS = [
{ label: "Source Serif", value: "Source Serif 4" },
{ label: "Fraunces", value: "Fraunces" },
{ label: "Crimson Pro", value: "Crimson Pro" },
{ label: "EB Garamond", value: "EB Garamond" }];


/* ------------------------------------------------------------------ */
/* Content                                                              */
/* ------------------------------------------------------------------ */

const COPY = {
  de: {
    nav: ["Profil", "Philosophie", "Themen", "Beiträge", "Vorträge", "Publikationen", "Kontakt"],
    heroMetaL: "Bern · Biel/Bienne",
    heroMetaC: "Vol. 12 — Ausgabe Frühling 2026",
    heroMetaR: "Dr. phil. · Healthcare Management",
    heroTitle1: "Gesundheit",
    heroTitle2: "ist",
    heroTitleEm: "Strategie",
    heroTitle3: "—",
    heroTitle4: "und kein",
    heroTitle5: "Zufall.",
    heroLede: "Christoph Napierala denkt das Schweizer Gesundheitswesen vom Ergebnis her: integriert, bezahlbar, nahe an den Menschen, die Versorgung brauchen.",
    heroRoles: ["Geschäftsführer Spitex Biel-Bienne Regio", "Sciana Health Leaders Network", "Dozent · Universität Luzern (CHPE)"],
    statsLabel: ["Jahre Versorgungs­forschung", "Geleitete Organisationen", "Publikationen & Working Papers", "Vorträge & Keynotes"],
    statsNum: ["18", "07", "24", "60"],
    aboutNum: "01 / Profil",
    aboutTitle: ["Versorgung neu", "denken."],
    aboutKicker: "Über",
    aboutSidebar: "Gesundheits­ökonom, Praktiker und Brücken­bauer zwischen Spitalfinanzierung, ambulanter Versorgung und Forschung.",
    aboutP1: "Christoph Napierala ist Gesundheitsmanager mit über fünfzehn Jahren Erfahrung an der Schnittstelle von Spital­finanzierung, integrierter Versorgung und Public Health. Er hat als Forscher die Einführung von SwissDRG begleitet und führt heute die Spitex Biel-Bienne Regio.",
    aboutP2: "Seine Arbeit verbindet ökonomische Klarheit mit dem Glauben, dass gute Versorgung ein lokales Handwerk ist — getragen von Pflegenden, Hausärzt:innen und Familien, nicht von Tabellen.",
    cv: [
    ["2024 –", "Geschäftsführer", "Leitung der Geschäftsstelle, ca. 280 Mitarbeitende.", "SPITEX BIEL-BIENNE REGIO"],
    ["2022 – 24", "Strategy & Operations", "Konzernweite Programme zur Versorgungs­integration.", "SWISS MEDICAL NETWORK"],
    ["2019 – 22", "Leitung Projekte / Region", "Aufbau ambulanter Versorgungs­modelle in der Deutsch­schweiz.", "MEDBASE"],
    ["2014 – 19", "Wissenschaftlicher Mitarbeiter", "Promotion zu DRG-Effekten, Compliance LOS, Versorgungs­forschung.", "UNI LUZERN · CHPE"],
    ["2012 – 14", "Projektleiter Healthcare", "Strategische Portfolio-Visualisierung für Universitätsspitäler.", "SIEMENS HEALTHCARE"]],

    philoNum: "02 / Philosophie",
    philoTitle: ["Was mich ", "trägt."],
    philoSidebar: "Vor jedem Modell, jeder Tabelle, jedem Tarif: ein paar Bilder, an denen sich meine Arbeit ausrichtet. Sie kommen aus Bergen, vom Wasser, aus dem Zen — und aus dem Spitex-Alltag.",
    philoLede: "Führen heisst Spuren legen. Im Schnee sieht man, ob sie tragen.",
    philo: [
    { img: "assets/talk-enso.webp", caption: "Enso — der unvollständige Kreis. In einem Strich, ohne Korrektur. Was bleibt, ist Haltung.", tag: "Klarheit" },
    { img: "assets/talk-snow-pano.webp", caption: "Erste Spur im Schnee. Eine Entscheidung, die alle anderen formt — und der Weg zurück bleibt sichtbar.", tag: "Verantwortung" },
    { img: "assets/talk-lake-reflection.webp", caption: "Stilles Wasser zeigt, was über ihm steht. Reflexion ist kein Luxus, sondern Steuerungs­instrument.", tag: "Reflexion" },
    { img: "assets/talk-fruit.webp", caption: "Eigene Ernte. Was wirklich gesund ist, hat selten ein Etikett — und reift in seiner eigenen Zeit.", tag: "Mass" },
    { img: "assets/talk-peak-golden.webp", caption: "Zwei Seilschaften am Grat. Tempo verhandelt sich nicht über Worte, sondern über das Seil dazwischen.", tag: "Vertrauen" },
    { img: "assets/talk-lake-sunrise.webp", caption: "Bielersee, kurz vor sechs. Tage, die so beginnen, vertragen schwierige Sitzungen.", tag: "Rhythmus" }],


    expertiseNum: "03 / Themen",
    expertiseTitle: ["Worüber ich", "schreibe und spreche."],
    expertiseSidebar: "Sechs Themen­felder, in denen ich seit Jahren publiziere, beraten habe oder operativ Verantwortung trage.",
    expertise: [
    ["Spital­finanzierung & SwissDRG", "Wirkung, Limiten und nächste Generation des fallpauschalen Systems."],
    ["Integrierte Versorgung", "Ambulant vor stationär — und was dazwischen liegt: Spitex, HA-Netze, Reha."],
    ["Strategische Portfolio-Steuerung", "Datengetriebene Entscheidungen über Leistungs­angebote im Spital."],
    ["Healthcare Leadership", "Organisationen führen, in denen Pflege, Medizin und Verwaltung Augenhöhe haben."],
    ["Public Health Policy", "Gesundheits­politik zwischen Effizienz, Solidarität und föderaler Realität."],
    ["Versorgungs­forschung", "Outcome-Messung, Compliance LOS, Wochenend-Effekte, Qualitäts­indikatoren."]],

    blogNum: "04 / Beiträge",
    blogTitle: ["Notizen zum", "System."],
    blogSidebar: "Längere Texte, Kommentare und Working Papers — auf Deutsch, gelegentlich Englisch.",
    blogAll: "Alle Beiträge ansehen",
    posts: [
    { tag: "Essay", read: "12 min", date: "14.04.2026", title: "Was nach der Fallpauschale kommt — Versorgungs­finanzierung jenseits von SwissDRG.", excerpt: "Vierzehn Jahre nach Einführung des fallpauschalen Systems hat sich die Realität verändert: ambulant vor stationär, chronische Leiden, Personal­knappheit. Eine Skizze für die nächste Generation.", art: "PostArt1" },
    { tag: "Analyse", read: "8 min", date: "02.03.2026", title: "Spitex als zentrales Stück integrierter Versorgung.", excerpt: "Was die Hausarzt­netze von der Spitex lernen — und umgekehrt.", art: "PostArt2" },
    { tag: "Kommentar", read: "6 min", date: "21.01.2026", title: "Tarife 2026 — eine ehrliche Lektüre.", excerpt: "Was die Tariflandschaft wirklich steuert, und was nur Symptom ist.", art: "PostArt3" }],

    talksNum: "05 / Vorträge",
    talksTitle: ["Vorträge &", "Präsentationen."],
    talksSidebar: "Eine Auswahl aktueller, kommender und früherer Auftritte — von Keynotes bis zu archivierten Prezi-Präsentationen. Für Anfragen zu Keynotes, Panels und Inhouse-Workshops bitte direkt kontaktieren.",
    talksAll: "Vollständiges Programm",
    talks: [
    { d: "29", my: "Apr 2026", upcoming: false, title: "Healthcare Leadership & Governance — Bilder einer Führungs­praxis.", ctx: "Universität Luzern · Executive MBA", venue: "Frohburgstrasse", city: "Luzern, CH", format: "Vortrag · 75 min", href: "leadership-talk.html", linkLabel: "Vortrag lesen ↗" },
    { d: "07", my: "Sep 2025", upcoming: false, title: "Strukturen des Schweizer Gesundheitswesens — Akteure, Tarife, Reformen.", ctx: "ZHAW · CAS Gesundheitswesen", venue: "Lehrveranstaltung", city: "Männedorf, CH", format: "Seminar · 2 Tage", href: "gesundheitswesen-talk.html", linkLabel: "Vortrag lesen ↗" },
    { d: "27", my: "Mär 2025", upcoming: false, title: "Spitalplanung im Vergleich — internationale «Lessons Learnt» für den Kanton Bern.", ctx: "GSOK · Kanton Bern", venue: "Spitalplanungs­vergleich", city: "Bern, CH", format: "Fachvortrag · 60 min", href: "spitalplanung-talk.html", linkLabel: "Vortrag lesen ↗" },
    { d: "18", my: "Sep 2014", upcoming: false, title: "Timing in der radiologischen Intervention — ökonomische Effekte im DRG-System.", ctx: "MTRA-Kongress · Pontresina", venue: "Rondo Kongresszentrum", city: "Pontresina, CH", format: "Vortrag · 30 min", href: "https://prezi.com/qebd_95dayus/mtra-kongress-pontresina-2014/?present=1", external: true, linkLabel: "Prezi ansehen ↗" },
    { d: "06", my: "Mai 2014", upcoming: false, title: "Health Innovation — wenn Daten das Leistungs­portfolio formen.", ctx: "Siemens Healthcare · Innovation Forum", venue: "Siemens", city: "Erlangen, DE", format: "Präsentation · 20 min", href: "https://prezi.com/5sqwltqsrmqv/siemens-health-innovation/?present=1", external: true, linkLabel: "Prezi ansehen ↗" },
    { d: "21", my: "Mär 2013", upcoming: false, title: "eHealth zwischen Versprechen und Versorgungs­alltag.", ctx: "Swiss eHealth Summit · Bern", venue: "BERNEXPO", city: "Bern, CH", format: "Vortrag · 25 min", href: "https://prezi.com/misafrjm8zhc/swiss-ehealth-summit-bern/?present=1", external: true, linkLabel: "Prezi ansehen ↗" }],

    pubsNum: "06 / Schriften",
    pubsTitle: ["Auswahl", "Publikationen."],
    pubsSidebar: "Peer-reviewed Artikel, Working Papers und Beiträge in der Volkswirtschaft.",
    pubs: [
    ["Is the timing of radiological intervention and treatment day associated with economic outcomes in DRG-financed health care systems", "BMC Health Services Research", "2017", "PEER-REVIEWED"],
    ["Why Compliance Length of Stay (LOS) is the Stronger Outcome Measure than Crude LOS in DRG Systems", "CHPE Working Paper Nr. 14", "2017", "WORKING PAPER"],
    ["Visualisierung von Leistungs­portfolios als Grundlage strategischer Spital­planung", "HEALTHINF Conference", "2015", "PROCEEDINGS"],
    ["Weekends influencing Process and Economic Results in a Swiss University Hospital in the Era of SwissDRG", "CHPE Technical Report", "2014", "REPORT"],
    ["Effizienz im Gesundheits­wesen — was die DRG-Einführung uns gelehrt hat", "Die Volkswirtschaft", "2017", "ESSAY"]],

    contactNum: "07 / Kontakt",
    contactTitle: ["Reden wir", "darüber."],
    contactSidebar: "Für Vorträge, Beratungs­mandate, redaktionelle Anfragen oder einen Kaffee in Bern.",
    footerTag: ["Versorgung", "ist eine ", "Frage der", "Haltung."],
    marqueeItems: ["Versorgung vor System", "Daten dienen Menschen", "Ambulant vor stationär", "Pflege ist Arbeit, nicht Berufung", "Ökonomie als Werkzeug, nicht als Ziel"],
    draft: { tag: "In Vorbereitung", text: "Die Beiträge sind in Arbeit — die folgenden Vorschauen sind Platzhalter. Echte Texte folgen in Kürze." },
    footer: { contactH: "Kontakt", intro: "Anfragen für Vorträge, Mandate oder Gespräche an ", topicsH: "Themen", topics: ["Spitalfinanzierung", "Integrierte Versorgung", "Healthcare Leadership", "Public Health"], formatH: "Format", formats: ["Essays", "Keynotes", "Panels & Workshops", "Publikationen"], elsewhereH: "Anderswo", elsewhere: ["LinkedIn ↗", "ResearchGate ↗", "Academia ↗", "Newsletter abonnieren"], legal: "Site v.2026.04 — Impressum · Datenschutz" }
  },

  fr: {
    nav: ["Profil", "Philosophie", "Thèmes", "Articles", "Conférences", "Publications", "Contact"],
    heroMetaL: "Berne · Bienne",
    heroMetaC: "Vol. 12 — Édition printemps 2026",
    heroMetaR: "Dr phil. · Healthcare Management",
    heroTitle1: "La santé",
    heroTitle2: "est",
    heroTitleEm: "Stratégie",
    heroTitle3: "—",
    heroTitle4: "pas le",
    heroTitle5: "hasard.",
    heroLede: "Christoph Napierala pense le système de santé suisse à partir du résultat : intégré, abordable, proche des personnes qui ont besoin de soins.",
    heroRoles: ["Directeur Spitex Biel-Bienne Regio", "Sciana Health Leaders Network", "Chargé de cours · Université de Lucerne (CHPE)"],
    statsLabel: ["Ans de recherche sur les soins", "Organisations dirigées", "Publications & working papers", "Conférences & keynotes"],
    statsNum: ["18", "07", "24", "60"],
    aboutNum: "01 / Profil",
    aboutTitle: ["Repenser", "les soins."],
    aboutKicker: "À propos",
    aboutSidebar: "Économiste de la santé, praticien et bâtisseur de ponts entre financement hospitalier, soins ambulatoires et recherche.",
    aboutP1: "Christoph Napierala est gestionnaire de santé avec plus de quinze ans d'expérience à l'intersection du financement hospitalier, des soins intégrés et de la santé publique. Chercheur, il a accompagné l'introduction de SwissDRG et dirige aujourd'hui la Spitex Biel-Bienne Regio.",
    aboutP2: "Son travail allie la clarté économique à la conviction que de bons soins sont un artisanat local — portés par le personnel soignant, les médecins de famille et les familles, non par des tableaux.",
    cv: [
    ["2024 –", "Directeur", "Direction du siège, env. 280 collaborateurs.", "SPITEX BIEL-BIENNE REGIO"],
    ["2022 – 24", "Strategy & Operations", "Programmes de groupe pour l'intégration des soins.", "SWISS MEDICAL NETWORK"],
    ["2019 – 22", "Direction projets / région", "Mise en place de modèles de soins ambulatoires en Suisse alémanique.", "MEDBASE"],
    ["2014 – 19", "Collaborateur scientifique", "Doctorat sur les effets DRG, compliance LOS, recherche sur les soins.", "UNI LUCERNE · CHPE"],
    ["2012 – 14", "Chef de projet Healthcare", "Visualisation stratégique de portefeuille pour hôpitaux universitaires.", "SIEMENS HEALTHCARE"]],

    philoNum: "02 / Philosophie",
    philoTitle: ["Ce qui me ", "porte."],
    philoSidebar: "Avant chaque modèle, chaque tableau, chaque tarif : quelques images qui orientent mon travail. Elles viennent des montagnes, de l'eau, du zen — et du quotidien de la Spitex.",
    philoLede: "Diriger, c'est tracer une trace. Dans la neige, on voit si elle tient.",
    philo: [
    { img: "assets/talk-enso.webp", caption: "Enso — le cercle inachevé. En un seul trait, sans correction. Ce qui reste, c'est l'attitude.", tag: "Clarté" },
    { img: "assets/talk-snow-pano.webp", caption: "Première trace dans la neige. Une décision qui façonne toutes les autres — et le chemin du retour reste visible.", tag: "Responsabilité" },
    { img: "assets/talk-lake-reflection.webp", caption: "L'eau calme révèle ce qui se tient au-dessus d'elle. La réflexion n'est pas un luxe, mais un instrument de pilotage.", tag: "Réflexion" },
    { img: "assets/talk-fruit.webp", caption: "Sa propre récolte. Ce qui est vraiment sain porte rarement une étiquette — et mûrit à son rythme.", tag: "Mesure" },
    { img: "assets/talk-peak-golden.webp", caption: "Deux cordées sur l'arête. Le rythme ne se négocie pas par des mots, mais par la corde entre les deux.", tag: "Confiance" },
    { img: "assets/talk-lake-sunrise.webp", caption: "Lac de Bienne, juste avant six heures. Les journées qui débutent ainsi supportent les réunions difficiles.", tag: "Rythme" }],

    expertiseNum: "03 / Thèmes",
    expertiseTitle: ["Ce dont j'écris", "et je parle."],
    expertiseSidebar: "Six champs thématiques dans lesquels je publie, conseille ou assume une responsabilité opérationnelle depuis des années.",
    expertise: [
    ["Financement hospitalier & SwissDRG", "Effets, limites et prochaine génération du système de forfaits par cas."],
    ["Soins intégrés", "L'ambulatoire avant le stationnaire — et ce qui se trouve entre : Spitex, réseaux de médecins, réadaptation."],
    ["Pilotage stratégique de portefeuille", "Décisions fondées sur les données concernant l'offre de prestations hospitalières."],
    ["Healthcare Leadership", "Diriger des organisations où soins, médecine et administration sont à égalité."],
    ["Politique de santé publique", "La politique de santé entre efficience, solidarité et réalité fédérale."],
    ["Recherche sur les soins", "Mesure des résultats, compliance LOS, effets de week-end, indicateurs de qualité."]],

    blogNum: "04 / Articles",
    blogTitle: ["Notes sur le", "système."],
    blogSidebar: "Textes plus longs, commentaires et working papers — en allemand, parfois en anglais.",
    blogAll: "Voir tous les articles",
    posts: [
    { tag: "Essai", read: "12 min", date: "14.04.2026", title: "Ce qui vient après le forfait par cas — financer les soins au-delà de SwissDRG.", excerpt: "Quatorze ans après l'introduction du système de forfaits par cas, la réalité a changé : ambulatoire avant stationnaire, maladies chroniques, pénurie de personnel. Une esquisse pour la prochaine génération.", art: "PostArt1" },
    { tag: "Analyse", read: "8 min", date: "02.03.2026", title: "La Spitex, pièce centrale des soins intégrés.", excerpt: "Ce que les réseaux de médecins apprennent de la Spitex — et inversement.", art: "PostArt2" },
    { tag: "Commentaire", read: "6 min", date: "21.01.2026", title: "Tarifs 2026 — une lecture honnête.", excerpt: "Ce qui pilote vraiment le paysage tarifaire, et ce qui n'est que symptôme.", art: "PostArt3" }],

    talksNum: "05 / Conférences",
    talksTitle: ["Conférences &", "présentations."],
    talksSidebar: "Une sélection d'interventions actuelles, à venir et passées — des keynotes aux présentations Prezi archivées. Pour des demandes de keynotes, panels et ateliers internes, merci de contacter directement.",
    talksAll: "Programme complet",
    talks: [
    { d: "29", my: "avr. 2026", upcoming: false, title: "Healthcare Leadership & Governance — images d'une pratique de direction.", ctx: "Université de Lucerne · Executive MBA", venue: "Frohburgstrasse", city: "Lucerne, CH", format: "Conférence · 75 min", href: "leadership-talk.html", linkLabel: "Lire la conférence ↗" },
    { d: "07", my: "sept. 2025", upcoming: false, title: "Structures du système de santé suisse — acteurs, tarifs, réformes.", ctx: "ZHAW · CAS Système de santé", venue: "Cours", city: "Männedorf, CH", format: "Séminaire · 2 jours", href: "gesundheitswesen-talk.html", linkLabel: "Lire la conférence ↗" },
    { d: "27", my: "mars 2025", upcoming: false, title: "Planification hospitalière comparée — «Lessons Learnt» internationales pour le canton de Berne.", ctx: "GSOK · Canton de Berne", venue: "Comparaison hospitalière", city: "Berne, CH", format: "Exposé · 60 min", href: "spitalplanung-talk.html", linkLabel: "Lire la conférence ↗" },
    { d: "18", my: "sept. 2014", upcoming: false, title: "Timing de l'intervention radiologique — effets économiques dans le système DRG.", ctx: "Congrès TRM · Pontresina", venue: "Centre de congrès Rondo", city: "Pontresina, CH", format: "Exposé · 30 min", href: "https://prezi.com/qebd_95dayus/mtra-kongress-pontresina-2014/?present=1", external: true, linkLabel: "Voir la Prezi ↗" },
    { d: "06", my: "mai 2014", upcoming: false, title: "Health Innovation — quand les données façonnent le portefeuille de prestations.", ctx: "Siemens Healthcare · Innovation Forum", venue: "Siemens", city: "Erlangen, DE", format: "Présentation · 20 min", href: "https://prezi.com/5sqwltqsrmqv/siemens-health-innovation/?present=1", external: true, linkLabel: "Voir la Prezi ↗" },
    { d: "21", my: "mars 2013", upcoming: false, title: "eHealth, entre promesse et quotidien des soins.", ctx: "Swiss eHealth Summit · Berne", venue: "BERNEXPO", city: "Berne, CH", format: "Exposé · 25 min", href: "https://prezi.com/misafrjm8zhc/swiss-ehealth-summit-bern/?present=1", external: true, linkLabel: "Voir la Prezi ↗" }],

    pubsNum: "06 / Écrits",
    pubsTitle: ["Sélection de", "publications."],
    pubsSidebar: "Articles évalués par les pairs, working papers et contributions économiques.",
    pubs: [
    ["Is the timing of radiological intervention and treatment day associated with economic outcomes in DRG-financed health care systems", "BMC Health Services Research", "2017", "PEER-REVIEWED"],
    ["Why Compliance Length of Stay (LOS) is the Stronger Outcome Measure than Crude LOS in DRG Systems", "CHPE Working Paper Nr. 14", "2017", "WORKING PAPER"],
    ["Visualisation des portefeuilles de prestations comme base de la planification hospitalière stratégique", "HEALTHINF Conference", "2015", "PROCEEDINGS"],
    ["Weekends influencing Process and Economic Results in a Swiss University Hospital in the Era of SwissDRG", "CHPE Technical Report", "2014", "REPORT"],
    ["Efficience dans le système de santé — ce que l'introduction des DRG nous a appris", "Die Volkswirtschaft", "2017", "ESSAI"]],

    contactNum: "07 / Contact",
    contactTitle: ["Parlons-en", "ensemble."],
    contactSidebar: "Pour des conférences, des mandats de conseil, des demandes éditoriales ou un café à Berne.",
    footerTag: ["Les soins", "sont une ", "question", "d'attitude."],
    marqueeItems: ["Les soins avant le système", "Les données servent les personnes", "L'ambulatoire avant le stationnaire", "Soigner est un travail, pas une vocation", "L'économie comme outil, non comme but"],
    draft: { tag: "En préparation", text: "Les articles sont en cours de rédaction — les aperçus ci-dessous sont des espaces réservés. Les textes réels suivront prochainement." },
    footer: { contactH: "Contact", intro: "Demandes de conférences, mandats ou entretiens à ", topicsH: "Thèmes", topics: ["Financement hospitalier", "Soins intégrés", "Healthcare Leadership", "Santé publique"], formatH: "Format", formats: ["Essais", "Keynotes", "Panels & ateliers", "Publications"], elsewhereH: "Ailleurs", elsewhere: ["LinkedIn ↗", "ResearchGate ↗", "Academia ↗", "S'abonner à la newsletter"], legal: "Site v.2026.04 — Mentions légales · Confidentialité" }
  },

  en: {
    nav: ["Profile", "Philosophy", "Topics", "Articles", "Talks", "Publications", "Contact"],
    heroMetaL: "Bern · Biel/Bienne",
    heroMetaC: "Vol. 12 — Spring 2026 Edition",
    heroMetaR: "Dr phil. · Healthcare Management",
    heroTitle1: "Health is",
    heroTitle2: "a",
    heroTitleEm: "Strategy",
    heroTitle3: "—",
    heroTitle4: "not a",
    heroTitle5: "coincidence.",
    heroLede: "Christoph Napierala thinks about the Swiss healthcare system from the outcome: integrated, affordable, close to the people who need care.",
    heroRoles: ["Managing Director, Spitex Biel-Bienne Regio", "Sciana Health Leaders Network", "Lecturer · University of Lucerne (CHPE)"],
    statsLabel: ["Years of health services research", "Organisations led", "Publications & working papers", "Talks & keynotes"],
    statsNum: ["18", "07", "24", "60"],
    aboutNum: "01 / Profile",
    aboutTitle: ["Rethinking", "care."],
    aboutKicker: "About",
    aboutSidebar: "Health economist, practitioner and bridge-builder between hospital financing, outpatient care and research.",
    aboutP1: "Christoph Napierala is a healthcare manager with more than fifteen years of experience at the intersection of hospital financing, integrated care and public health. As a researcher he accompanied the introduction of SwissDRG and today leads Spitex Biel-Bienne Regio.",
    aboutP2: "His work combines economic clarity with the belief that good care is a local craft — carried by nurses, family doctors and families, not by spreadsheets.",
    cv: [
    ["2024 –", "Managing Director", "Leading the head office, approx. 280 staff.", "SPITEX BIEL-BIENNE REGIO"],
    ["2022 – 24", "Strategy & Operations", "Group-wide programmes for care integration.", "SWISS MEDICAL NETWORK"],
    ["2019 – 22", "Head of Projects / Region", "Building outpatient care models in German-speaking Switzerland.", "MEDBASE"],
    ["2014 – 19", "Research Associate", "PhD on DRG effects, compliance LOS, health services research.", "UNI LUCERNE · CHPE"],
    ["2012 – 14", "Healthcare Project Lead", "Strategic portfolio visualisation for university hospitals.", "SIEMENS HEALTHCARE"]],

    philoNum: "02 / Philosophy",
    philoTitle: ["What carries ", "me."],
    philoSidebar: "Before every model, every spreadsheet, every tariff: a few images that orient my work. They come from mountains, from water, from Zen — and from everyday life at Spitex.",
    philoLede: "To lead is to lay a track. In the snow you see whether it holds.",
    philo: [
    { img: "assets/talk-enso.webp", caption: "Enso — the unfinished circle. One stroke, no correction. What remains is attitude.", tag: "Clarity" },
    { img: "assets/talk-snow-pano.webp", caption: "First track in the snow. A decision that shapes all the others — and the way back stays visible.", tag: "Responsibility" },
    { img: "assets/talk-lake-reflection.webp", caption: "Still water shows what stands above it. Reflection is no luxury, but an instrument of steering.", tag: "Reflection" },
    { img: "assets/talk-fruit.webp", caption: "Your own harvest. What is truly healthy rarely carries a label — and ripens in its own time.", tag: "Measure" },
    { img: "assets/talk-peak-golden.webp", caption: "Two rope teams on the ridge. Pace is negotiated not in words, but through the rope between them.", tag: "Trust" },
    { img: "assets/talk-lake-sunrise.webp", caption: "Lake Biel, just before six. Days that begin like this can bear difficult meetings.", tag: "Rhythm" }],

    expertiseNum: "03 / Topics",
    expertiseTitle: ["What I write", "and speak about."],
    expertiseSidebar: "Six thematic fields in which I have published, advised or held operational responsibility for years.",
    expertise: [
    ["Hospital financing & SwissDRG", "Effects, limits and the next generation of the case-based payment system."],
    ["Integrated care", "Outpatient before inpatient — and what lies between: Spitex, GP networks, rehab."],
    ["Strategic portfolio steering", "Data-driven decisions about hospital service offerings."],
    ["Healthcare Leadership", "Leading organisations where nursing, medicine and administration meet as equals."],
    ["Public Health Policy", "Health policy between efficiency, solidarity and federal reality."],
    ["Health services research", "Outcome measurement, compliance LOS, weekend effects, quality indicators."]],

    blogNum: "04 / Articles",
    blogTitle: ["Notes on the", "system."],
    blogSidebar: "Longer texts, commentary and working papers — in German, occasionally in English.",
    blogAll: "View all articles",
    posts: [
    { tag: "Essay", read: "12 min", date: "14.04.2026", title: "What comes after the case-based flat rate — financing care beyond SwissDRG.", excerpt: "Fourteen years after the introduction of the case-based system, reality has changed: outpatient before inpatient, chronic conditions, staff shortages. A sketch for the next generation.", art: "PostArt1" },
    { tag: "Analysis", read: "8 min", date: "02.03.2026", title: "Spitex as a central piece of integrated care.", excerpt: "What GP networks learn from Spitex — and vice versa.", art: "PostArt2" },
    { tag: "Commentary", read: "6 min", date: "21.01.2026", title: "Tariffs 2026 — an honest reading.", excerpt: "What really steers the tariff landscape, and what is merely a symptom.", art: "PostArt3" }],

    talksNum: "05 / Talks",
    talksTitle: ["Talks &", "presentations."],
    talksSidebar: "A selection of current, upcoming and past appearances — from keynotes to archived Prezi presentations. For keynote, panel and in-house workshop enquiries, please get in touch directly.",
    talksAll: "Full programme",
    talks: [
    { d: "29", my: "Apr 2026", upcoming: false, title: "Healthcare Leadership & Governance — images of a leadership practice.", ctx: "University of Lucerne · Executive MBA", venue: "Frohburgstrasse", city: "Lucerne, CH", format: "Talk · 75 min", href: "leadership-talk.html", linkLabel: "Read the talk ↗" },
    { d: "07", my: "Sep 2025", upcoming: false, title: "Structures of the Swiss healthcare system — actors, tariffs, reforms.", ctx: "ZHAW · CAS Healthcare", venue: "Lecture", city: "Männedorf, CH", format: "Seminar · 2 days", href: "gesundheitswesen-talk.html", linkLabel: "Read the talk ↗" },
    { d: "27", my: "Mar 2025", upcoming: false, title: "Hospital planning compared — international «Lessons Learnt» for the Canton of Bern.", ctx: "GSOK · Canton of Bern", venue: "Hospital planning review", city: "Bern, CH", format: "Lecture · 60 min", href: "spitalplanung-talk.html", linkLabel: "Read the talk ↗" },
    { d: "18", my: "Sep 2014", upcoming: false, title: "Timing of radiological intervention — economic effects in the DRG system.", ctx: "MTRA Congress · Pontresina", venue: "Rondo Congress Centre", city: "Pontresina, CH", format: "Talk · 30 min", href: "https://prezi.com/qebd_95dayus/mtra-kongress-pontresina-2014/?present=1", external: true, linkLabel: "View the Prezi ↗" },
    { d: "06", my: "May 2014", upcoming: false, title: "Health Innovation — when data shapes the service portfolio.", ctx: "Siemens Healthcare · Innovation Forum", venue: "Siemens", city: "Erlangen, DE", format: "Presentation · 20 min", href: "https://prezi.com/5sqwltqsrmqv/siemens-health-innovation/?present=1", external: true, linkLabel: "View the Prezi ↗" },
    { d: "21", my: "Mar 2013", upcoming: false, title: "eHealth between promise and everyday care.", ctx: "Swiss eHealth Summit · Bern", venue: "BERNEXPO", city: "Bern, CH", format: "Talk · 25 min", href: "https://prezi.com/misafrjm8zhc/swiss-ehealth-summit-bern/?present=1", external: true, linkLabel: "View the Prezi ↗" }],

    pubsNum: "06 / Writings",
    pubsTitle: ["Selected", "publications."],
    pubsSidebar: "Peer-reviewed articles, working papers and contributions in economics.",
    pubs: [
    ["Is the timing of radiological intervention and treatment day associated with economic outcomes in DRG-financed health care systems", "BMC Health Services Research", "2017", "PEER-REVIEWED"],
    ["Why Compliance Length of Stay (LOS) is the Stronger Outcome Measure than Crude LOS in DRG Systems", "CHPE Working Paper No. 14", "2017", "WORKING PAPER"],
    ["Visualising service portfolios as a basis for strategic hospital planning", "HEALTHINF Conference", "2015", "PROCEEDINGS"],
    ["Weekends influencing Process and Economic Results in a Swiss University Hospital in the Era of SwissDRG", "CHPE Technical Report", "2014", "REPORT"],
    ["Efficiency in healthcare — what the introduction of DRGs taught us", "Die Volkswirtschaft", "2017", "ESSAY"]],

    contactNum: "07 / Contact",
    contactTitle: ["Let's talk", "about it."],
    contactSidebar: "For talks, advisory mandates, editorial enquiries or a coffee in Bern.",
    footerTag: ["Care", "is a ", "question of", "attitude."],
    marqueeItems: ["Care before system", "Data serves people", "Outpatient before inpatient", "Nursing is work, not a calling", "Economics as a tool, not a goal"],
    draft: { tag: "In preparation", text: "The articles are still being written — the previews below are placeholders. Real texts will follow soon." },
    footer: { contactH: "Contact", intro: "Enquiries for talks, mandates or conversations to ", topicsH: "Topics", topics: ["Hospital financing", "Integrated care", "Healthcare Leadership", "Public Health"], formatH: "Format", formats: ["Essays", "Keynotes", "Panels & workshops", "Publications"], elsewhereH: "Elsewhere", elsewhere: ["LinkedIn ↗", "ResearchGate ↗", "Academia ↗", "Subscribe to newsletter"], legal: "Site v.2026.04 — Imprint · Privacy" }
  },

  it: {
    nav: ["Profilo", "Filosofia", "Temi", "Articoli", "Conferenze", "Pubblicazioni", "Contatto"],
    heroMetaL: "Berna · Bienne",
    heroMetaC: "Vol. 12 — Edizione primavera 2026",
    heroMetaR: "Dr phil. · Healthcare Management",
    heroTitle1: "La salute",
    heroTitle2: "è",
    heroTitleEm: "Strategia",
    heroTitle3: "—",
    heroTitle4: "non un",
    heroTitle5: "caso.",
    heroLede: "Christoph Napierala pensa il sistema sanitario svizzero a partire dal risultato: integrato, sostenibile, vicino alle persone che hanno bisogno di cure.",
    heroRoles: ["Direttore Spitex Biel-Bienne Regio", "Sciana Health Leaders Network", "Docente · Università di Lucerna (CHPE)"],
    statsLabel: ["Anni di ricerca sui servizi sanitari", "Organizzazioni dirette", "Pubblicazioni & working paper", "Conferenze & keynote"],
    statsNum: ["18", "07", "24", "60"],
    aboutNum: "01 / Profilo",
    aboutTitle: ["Ripensare", "le cure."],
    aboutKicker: "Chi sono",
    aboutSidebar: "Economista sanitario, pratico e costruttore di ponti tra finanziamento ospedaliero, cure ambulatoriali e ricerca.",
    aboutP1: "Christoph Napierala è manager sanitario con oltre quindici anni di esperienza all'incrocio tra finanziamento ospedaliero, cure integrate e sanità pubblica. Come ricercatore ha accompagnato l'introduzione di SwissDRG e oggi dirige la Spitex Biel-Bienne Regio.",
    aboutP2: "Il suo lavoro unisce la chiarezza economica alla convinzione che le buone cure siano un artigianato locale — sostenuto da personale infermieristico, medici di famiglia e famiglie, non da tabelle.",
    cv: [
    ["2024 –", "Direttore", "Direzione della sede, ca. 280 collaboratori.", "SPITEX BIEL-BIENNE REGIO"],
    ["2022 – 24", "Strategy & Operations", "Programmi di gruppo per l'integrazione delle cure.", "SWISS MEDICAL NETWORK"],
    ["2019 – 22", "Direzione progetti / regione", "Sviluppo di modelli di cure ambulatoriali nella Svizzera tedesca.", "MEDBASE"],
    ["2014 – 19", "Collaboratore scientifico", "Dottorato su effetti DRG, compliance LOS, ricerca sui servizi.", "UNI LUCERNA · CHPE"],
    ["2012 – 14", "Project manager Healthcare", "Visualizzazione strategica di portafoglio per ospedali universitari.", "SIEMENS HEALTHCARE"]],

    philoNum: "02 / Filosofia",
    philoTitle: ["Ciò che mi ", "sostiene."],
    philoSidebar: "Prima di ogni modello, ogni tabella, ogni tariffa: alcune immagini a cui si orienta il mio lavoro. Vengono dalle montagne, dall'acqua, dallo Zen — e dalla quotidianità della Spitex.",
    philoLede: "Guidare significa lasciare una traccia. Nella neve si vede se regge.",
    philo: [
    { img: "assets/talk-enso.webp", caption: "Enso — il cerchio incompiuto. In un solo tratto, senza correzione. Ciò che resta è l'atteggiamento.", tag: "Chiarezza" },
    { img: "assets/talk-snow-pano.webp", caption: "Prima traccia nella neve. Una decisione che forma tutte le altre — e la via del ritorno resta visibile.", tag: "Responsabilità" },
    { img: "assets/talk-lake-reflection.webp", caption: "L'acqua calma mostra ciò che le sta sopra. La riflessione non è un lusso, ma uno strumento di governo.", tag: "Riflessione" },
    { img: "assets/talk-fruit.webp", caption: "Il proprio raccolto. Ciò che è davvero sano raramente porta un'etichetta — e matura nei suoi tempi.", tag: "Misura" },
    { img: "assets/talk-peak-golden.webp", caption: "Due cordate sulla cresta. Il ritmo non si negozia con le parole, ma con la corda nel mezzo.", tag: "Fiducia" },
    { img: "assets/talk-lake-sunrise.webp", caption: "Lago di Bienne, poco prima delle sei. Le giornate che iniziano così reggono le riunioni difficili.", tag: "Ritmo" }],

    expertiseNum: "03 / Temi",
    expertiseTitle: ["Di cosa scrivo", "e parlo."],
    expertiseSidebar: "Sei campi tematici in cui pubblico, ho consigliato o ho responsabilità operativa da anni.",
    expertise: [
    ["Finanziamento ospedaliero & SwissDRG", "Effetti, limiti e prossima generazione del sistema a forfait per caso."],
    ["Cure integrate", "L'ambulatoriale prima dello stazionario — e ciò che sta nel mezzo: Spitex, reti di medici, riabilitazione."],
    ["Governo strategico di portafoglio", "Decisioni basate sui dati sull'offerta di prestazioni ospedaliere."],
    ["Healthcare Leadership", "Guidare organizzazioni dove cure, medicina e amministrazione sono alla pari."],
    ["Politica di sanità pubblica", "La politica sanitaria tra efficienza, solidarietà e realtà federale."],
    ["Ricerca sui servizi sanitari", "Misurazione degli esiti, compliance LOS, effetti del fine settimana, indicatori di qualità."]],

    blogNum: "04 / Articoli",
    blogTitle: ["Note sul", "sistema."],
    blogSidebar: "Testi più lunghi, commenti e working paper — in tedesco, talvolta in inglese.",
    blogAll: "Vedi tutti gli articoli",
    posts: [
    { tag: "Saggio", read: "12 min", date: "14.04.2026", title: "Cosa viene dopo il forfait per caso — finanziare le cure oltre SwissDRG.", excerpt: "Quattordici anni dopo l'introduzione del sistema a forfait per caso, la realtà è cambiata: ambulatoriale prima dello stazionario, malattie croniche, carenza di personale. Uno schizzo per la prossima generazione.", art: "PostArt1" },
    { tag: "Analisi", read: "8 min", date: "02.03.2026", title: "La Spitex come elemento centrale delle cure integrate.", excerpt: "Cosa imparano le reti di medici dalla Spitex — e viceversa.", art: "PostArt2" },
    { tag: "Commento", read: "6 min", date: "21.01.2026", title: "Tariffe 2026 — una lettura onesta.", excerpt: "Cosa governa davvero il panorama tariffario, e cosa è solo sintomo.", art: "PostArt3" }],

    talksNum: "05 / Conferenze",
    talksTitle: ["Conferenze &", "presentazioni."],
    talksSidebar: "Una selezione di interventi attuali, futuri e passati — dai keynote alle presentazioni Prezi archiviate. Per richieste di keynote, panel e workshop interni, si prega di contattare direttamente.",
    talksAll: "Programma completo",
    talks: [
    { d: "29", my: "apr 2026", upcoming: false, title: "Healthcare Leadership & Governance — immagini di una pratica di direzione.", ctx: "Università di Lucerna · Executive MBA", venue: "Frohburgstrasse", city: "Lucerna, CH", format: "Conferenza · 75 min", href: "leadership-talk.html", linkLabel: "Leggi la conferenza ↗" },
    { d: "07", my: "set 2025", upcoming: false, title: "Strutture del sistema sanitario svizzero — attori, tariffe, riforme.", ctx: "ZHAW · CAS Sanità", venue: "Lezione", city: "Männedorf, CH", format: "Seminario · 2 giorni", href: "gesundheitswesen-talk.html", linkLabel: "Leggi la conferenza ↗" },
    { d: "27", my: "mar 2025", upcoming: false, title: "Pianificazione ospedaliera a confronto — «Lessons Learnt» internazionali per il Canton Berna.", ctx: "GSOK · Canton Berna", venue: "Confronto ospedaliero", city: "Berna, CH", format: "Relazione · 60 min", href: "spitalplanung-talk.html", linkLabel: "Leggi la conferenza ↗" },
    { d: "18", my: "set 2014", upcoming: false, title: "Timing dell'intervento radiologico — effetti economici nel sistema DRG.", ctx: "Congresso TSRM · Pontresina", venue: "Centro congressi Rondo", city: "Pontresina, CH", format: "Relazione · 30 min", href: "https://prezi.com/qebd_95dayus/mtra-kongress-pontresina-2014/?present=1", external: true, linkLabel: "Vedi la Prezi ↗" },
    { d: "06", my: "mag 2014", upcoming: false, title: "Health Innovation — quando i dati formano il portafoglio di prestazioni.", ctx: "Siemens Healthcare · Innovation Forum", venue: "Siemens", city: "Erlangen, DE", format: "Presentazione · 20 min", href: "https://prezi.com/5sqwltqsrmqv/siemens-health-innovation/?present=1", external: true, linkLabel: "Vedi la Prezi ↗" },
    { d: "21", my: "mar 2013", upcoming: false, title: "eHealth tra promessa e quotidianità delle cure.", ctx: "Swiss eHealth Summit · Berna", venue: "BERNEXPO", city: "Berna, CH", format: "Relazione · 25 min", href: "https://prezi.com/misafrjm8zhc/swiss-ehealth-summit-bern/?present=1", external: true, linkLabel: "Vedi la Prezi ↗" }],

    pubsNum: "06 / Scritti",
    pubsTitle: ["Pubblicazioni", "selezionate."],
    pubsSidebar: "Articoli sottoposti a revisione paritaria, working paper e contributi economici.",
    pubs: [
    ["Is the timing of radiological intervention and treatment day associated with economic outcomes in DRG-financed health care systems", "BMC Health Services Research", "2017", "PEER-REVIEWED"],
    ["Why Compliance Length of Stay (LOS) is the Stronger Outcome Measure than Crude LOS in DRG Systems", "CHPE Working Paper Nr. 14", "2017", "WORKING PAPER"],
    ["Visualizzazione dei portafogli di prestazioni come base per la pianificazione ospedaliera strategica", "HEALTHINF Conference", "2015", "PROCEEDINGS"],
    ["Weekends influencing Process and Economic Results in a Swiss University Hospital in the Era of SwissDRG", "CHPE Technical Report", "2014", "REPORT"],
    ["Efficienza nel sistema sanitario — cosa ci ha insegnato l'introduzione dei DRG", "Die Volkswirtschaft", "2017", "SAGGIO"]],

    contactNum: "07 / Contatto",
    contactTitle: ["Parliamone", "insieme."],
    contactSidebar: "Per conferenze, mandati di consulenza, richieste editoriali o un caffè a Berna.",
    footerTag: ["Le cure", "sono una ", "questione di", "atteggiamento."],
    marqueeItems: ["Le cure prima del sistema", "I dati servono le persone", "L'ambulatoriale prima dello stazionario", "Curare è lavoro, non vocazione", "L'economia come strumento, non come fine"],
    draft: { tag: "In preparazione", text: "Gli articoli sono in lavorazione — le anteprime qui sotto sono segnaposto. I testi reali seguiranno a breve." },
    footer: { contactH: "Contatto", intro: "Richieste di conferenze, mandati o colloqui a ", topicsH: "Temi", topics: ["Finanziamento ospedaliero", "Cure integrate", "Healthcare Leadership", "Sanità pubblica"], formatH: "Formato", formats: ["Saggi", "Keynote", "Panel & workshop", "Pubblicazioni"], elsewhereH: "Altrove", elsewhere: ["LinkedIn ↗", "ResearchGate ↗", "Academia ↗", "Iscriviti alla newsletter"], legal: "Site v.2026.04 — Note legali · Privacy" }
  }
};

/* ------------------------------------------------------------------ */
/* Page                                                                 */
/* ------------------------------------------------------------------ */

function App() {
  const [tweaks, setTweak] = useTweaks(TWEAK_DEFAULTS);
  const t = COPY[tweaks.language] || COPY.de;

  // keep <html lang> in sync
  useEffect(() => {
    document.documentElement.setAttribute("lang", tweaks.language || "de");
  }, [tweaks.language]);

  // apply CSS variables
  useEffect(() => {
    const r = document.documentElement.style;
    r.setProperty("--accent", tweaks.accent);
    r.setProperty("--bg", tweaks.bg);
    r.setProperty("--serif", `"${tweaks.displayFont}", Georgia, serif`);
  }, [tweaks.accent, tweaks.bg, tweaks.displayFont]);

  return (
    <>
      <TopBar nav={t.nav} lang={tweaks.language} setLang={(v) => setTweak("language", v)} />

      <Hero t={t} accent={tweaks.accent} />

      <Marquee items={t.marqueeItems} />

      <section className="section" id="profil">
        <div className="wrap">
          <SectionHead num={t.aboutNum} title={t.aboutTitle} sidebar={t.aboutSidebar} />
          <div className="about">
            <div className="about-prose body-prose">
              <p>{t.aboutP1}</p>
              <p>{t.aboutP2}</p>
            </div>
            <div className="cv-list" data-screen-label="cv">
              {t.cv.map((row, i) =>
              <div className="cv-row" key={i}>
                  <span className="cv-year">{row[0]}</span>
                  <span className="cv-role">{row[1]}<span>{row[2]}</span></span>
                  <span className="cv-place">{row[3]}</span>
                </div>
              )}
            </div>
          </div>
        </div>
      </section>

      <section className="section" id="philosophie" data-screen-label="02 Philosophie" style={{ paddingTop: 0 }}>
        <div className="wrap">
          <SectionHead num={t.philoNum} title={t.philoTitle} sidebar={t.philoSidebar} />
          <p className="philo-lede">{t.philoLede}</p>
          <div className="philo-grid">
            {t.philo.map((p, i) =>
            <figure className={"philo-cell philo-" + i} key={i}>
                <div className="philo-img"><img src={asset(p.img)} alt="" /></div>
                <figcaption>
                  <span className="philo-tag">— {p.tag}</span>
                  <span className="philo-caption">{p.caption}</span>
                </figcaption>
              </figure>
            )}
          </div>
        </div>
      </section>

      <section className="section" id="themen" style={{ paddingTop: 0 }}>
        <div className="wrap">
          <SectionHead num={t.expertiseNum} title={t.expertiseTitle} sidebar={t.expertiseSidebar} />
          <div className="expertise-grid">
            {t.expertise.map((e, i) =>
            <div className="exp-cell" key={i}>
                <div className="exp-num">№ {String(i + 1).padStart(2, "0")}</div>
                <h3 className="exp-title">{e[0]}</h3>
                <p className="exp-body">{e[1]}</p>
              </div>
            )}
          </div>
        </div>
      </section>

      <section className="section" id="beitraege" data-screen-label="03 Blog">
        <div className="wrap">
          <SectionHead num={t.blogNum} title={t.blogTitle} sidebar={t.blogSidebar} link={t.blogAll} />
          <div className="draft-banner">
            <span className="draft-tag">{t.draft.tag}</span>
            <p className="draft-text">{t.draft.text}</p>
          </div>
          <div className="blog-grid is-draft">
            <Post post={t.posts[0]} featured accent={tweaks.accent} />
            <Post post={t.posts[1]} accent={tweaks.accent} />
            <Post post={t.posts[2]} accent={tweaks.accent} />
          </div>
        </div>
      </section>

      <section className="section" id="vortraege" data-screen-label="04 Speeches" style={{ background: "var(--bg-2)" }}>
        <div className="wrap">
          <SectionHead num={t.talksNum} title={t.talksTitle} sidebar={t.talksSidebar} link={t.talksAll} />
          <div className="speeches">
            {t.talks.map((talk, i) => <Talk key={i} talk={talk} />)}
          </div>
        </div>
      </section>

      <section className="section" id="publikationen">
        <div className="wrap">
          <SectionHead num={t.pubsNum} title={t.pubsTitle} sidebar={t.pubsSidebar} />
          <div className="pub-list">
            {t.pubs.map((p, i) =>
            <div className="pub" key={i}>
                <span className="pub-num">{String(i + 1).padStart(2, "0")} —</span>
                <div className="pub-title">{p[0]}<span className="journal">{p[1]}</span></div>
                <span className="pub-meta">{p[3]} · {p[2]}</span>
                <span className="pub-arrow">↗</span>
              </div>
            )}
          </div>
        </div>
      </section>

      <Footer t={t} />
    </>);

}

/* ------------------------------------------------------------------ */
/* Sub-components                                                       */
/* ------------------------------------------------------------------ */

function TopBar({ nav, lang, setLang }) {
  return (
    <header className="topbar">
      <div className="wrap topbar-inner">
        <div className="brand">
          <span className="mark"></span>
          <span><em style={{ fontStyle: "italic" }}>Christoph</em> Napierala</span>
        </div>
        <nav className="nav">
          {nav.map((n, i) => <a href={"#" + ["profil", "philosophie", "themen", "beitraege", "vortraege", "publikationen", "kontakt"][i]} key={i}>{n}</a>)}
        </nav>
        <div className="lang-switch">
          {["de", "fr", "en", "it"].map((lc, i) => (
            <React.Fragment key={lc}>
              {i > 0 && <span className="sep">/</span>}
              <button className={lang === lc ? "is-active" : ""} onClick={() => setLang(lc)}>{lc.toUpperCase()}</button>
            </React.Fragment>
          ))}
        </div>
      </div>
    </header>);

}

function Hero({ t, accent }) {
  return (
    <section className="hero" data-screen-label="01 Hero">
      <div className="wrap">
        <div className="hero-meta">
          <span>{t.heroMetaL}</span>
          <span className="center">{t.heroMetaC}</span>
          <span className="right">{t.heroMetaR}</span>
        </div>

        <div className="hero-grid">
          <div className="hero-main">
            <h1 className="h-display hero-title">
              {t.heroTitle1}<br />
              {t.heroTitle2} <em>{t.heroTitleEm}</em>{t.heroTitle3}<br />
              {t.heroTitle4} {t.heroTitle5}
            </h1>
          </div>
          <div className="hero-side">
            <div className="hero-portrait">
              <img src={asset("assets/portrait.jpg")} alt="Christoph Napierala" className="portrait-photo" />
              <div className="portrait-accent" style={{ background: accent }}></div>
              <span className="frame-meta">CN · BERN · 2026</span>
            </div>
            <p className="lede">{t.heroLede}</p>
            <ul style={{ listStyle: "none", padding: 0, margin: 0, display: "flex", flexDirection: "column", gap: 8 }}>
              {t.heroRoles.map((r, i) =>
              <li key={i} style={{ display: "flex", gap: 12, fontSize: 14, color: "var(--ink-2)" }}>
                  <span style={{ fontFamily: "var(--mono)", fontSize: 11, letterSpacing: "0.12em", color: "var(--accent)" }}>—</span>
                  {r}
                </li>
              )}
            </ul>
          </div>
        </div>

        <div className="hero-stats">
          {t.statsNum.map((n, i) =>
          <div className="stat" key={i}>
              <div className="stat-num">{n}<sup>+</sup></div>
              <div className="stat-label">{t.statsLabel[i]}</div>
            </div>
          )}
        </div>
      </div>
    </section>);

}

function Marquee({ items }) {
  const doubled = [...items, ...items];
  return (
    <div className="marquee">
      <div className="marquee-inner">
        {doubled.map((it, i) =>
        <span key={i}><span className="sep">—</span> {it}</span>
        )}
      </div>
    </div>);

}

function SectionHead({ num, title, sidebar, link }) {
  return (
    <div className="section-head">
      <div>
        <div className="section-num">№ <strong>{num}</strong></div>
        <h2 className="section-title" style={{ marginTop: 16 }}>
          {title[0]} <em>{title[1]}</em>
        </h2>
      </div>
      <div className="section-side">
        <p>{sidebar}</p>
        {link &&
        <a href="#" style={{ alignSelf: "flex-start", marginTop: 6, fontFamily: "var(--mono)", fontSize: 11, letterSpacing: "0.16em", textTransform: "uppercase", color: "var(--ink)", borderBottom: "1px solid var(--accent)", paddingBottom: 3 }}>
            {link} →
          </a>
        }
      </div>
    </div>);

}

function Post({ post, featured, accent }) {
  const Art = window[post.art] || (() => null);
  return (
    <article className={"post" + (featured ? " featured" : "")}>
      <div className="post-image">
        <Art accent={accent} />
      </div>
      <div className="post-meta">
        <span className="tag">{post.tag}</span>
        <span>·</span>
        <span>{post.date}</span>
        <span>·</span>
        <span>{post.read} Lesezeit</span>
      </div>
      <h3 className="post-title">{post.title}</h3>
      {featured && <p className="post-excerpt">{post.excerpt}</p>}
      <span className="post-readmore">Lesen <span className="arrow">→</span></span>
    </article>);

}

function Talk({ talk }) {
  const Wrapper = talk.href ? "a" : "article";
  const wrapperProps = talk.href ?
  {
    href: talk.href,
    className: "talk talk-link",
    ...(talk.external ? { target: "_blank", rel: "noopener noreferrer" } : {})
  } :
  { className: "talk" };
  return (
    <Wrapper {...wrapperProps}>
      <div className="talk-date">
        <span className="day">{talk.d}</span>
        <span className="my">{talk.my}</span>
      </div>
      <div className="talk-main">
        <h3 className="talk-title">{talk.title}</h3>
        <span className="talk-context"><span className="accent">▸</span> {talk.ctx}</span>
        {talk.href &&
        <span className="talk-sublink">{talk.linkLabel || "Vortrag lesen ↗"}</span>
        }
      </div>
      <div className="talk-venue">
        <strong>{talk.venue}</strong>
        <span className="city">{talk.city}</span>
      </div>
      <span className={"talk-format" + (talk.upcoming ? " upcoming" : "")}>
        {talk.upcoming && <span className="pulse"></span>}
        {talk.format}
      </span>
    </Wrapper>);

}

function Footer({ t }) {
  return (
    <footer className="footer" id="kontakt" data-screen-label="06 Footer">
      <div className="wrap">
        <div className="footer-grid">
          <div>
            <h4>{t.footer.contactH}</h4>
            <div className="footer-tag">
              {t.footerTag[0]}<br />{t.footerTag[1]}<em>{t.footerTag[2]}</em><br />{t.footerTag[3]}
            </div>
            <p style={{ color: "rgba(255,255,255,0.7)", maxWidth: "32ch", fontSize: 14 }}>
              {t.footer.intro}<a style={{ color: "#fff", borderBottom: "1px solid var(--accent)" }} href="mailto:cn@christophnapierala.ch">cn@christophnapierala.ch</a>
            </p>
          </div>
          <div>
            <h4>{t.footer.topicsH}</h4>
            <ul>
              {t.footer.topics.map((x, i) => <li key={i}><a href="#themen">{x}</a></li>)}
            </ul>
          </div>
          <div>
            <h4>{t.footer.formatH}</h4>
            <ul>
              {t.footer.formats.map((x, i) => <li key={i}><a href={["#beitraege", "#vortraege", "#vortraege", "#publikationen"][i]}>{x}</a></li>)}
            </ul>
          </div>
          <div>
            <h4>{t.footer.elsewhereH}</h4>
            <ul>
              {t.footer.elsewhere.map((x, i) => <li key={i}><a href="#">{x}</a></li>)}
            </ul>
          </div>
        </div>
        <div className="footer-bottom">
          <span>© 2026 Christoph Napierala — <span className="accent">Bern · Biel/Bienne</span></span>
          <span>{t.footer.legal}</span>
        </div>
      </div>
    </footer>);

}

/* ------------------------------------------------------------------ */
/* Tweaks panel                                                          */
/* ------------------------------------------------------------------ */

function Tweaks() {
  const [tweaks, setTweak] = useTweaks(TWEAK_DEFAULTS);

  return (
    <TweaksPanel title="Tweaks">
      <TweakSection label="Aesthetic">
        <div style={{ display: "flex", flexDirection: "column", gap: 8 }}>
          <label style={{ fontSize: 11, letterSpacing: "0.1em", textTransform: "uppercase", color: "#7a756a" }}>Accent</label>
          <div style={{ display: "flex", flexWrap: "wrap", gap: 8 }}>
            {ACCENT_OPTIONS.map((o) =>
            <button key={o.value}
            onClick={() => setTweak("accent", o.value)}
            title={o.label}
            style={{
              width: 28, height: 28, borderRadius: "50%",
              border: tweaks.accent === o.value ? "2px solid #16181a" : "2px solid transparent",
              background: o.value, cursor: "pointer",
              outline: "1px solid rgba(0,0,0,0.15)",
              outlineOffset: "-3px"
            }} />
            )}
          </div>
        </div>
        <div style={{ display: "flex", flexDirection: "column", gap: 8, marginTop: 14 }}>
          <label style={{ fontSize: 11, letterSpacing: "0.1em", textTransform: "uppercase", color: "#7a756a" }}>Background</label>
          <div style={{ display: "flex", flexWrap: "wrap", gap: 8 }}>
            {BG_OPTIONS.map((o) =>
            <button key={o.value}
            onClick={() => setTweak("bg", o.value)}
            title={o.label}
            style={{
              width: 28, height: 28, borderRadius: "50%",
              border: tweaks.bg === o.value ? "2px solid #16181a" : "2px solid transparent",
              background: o.value, cursor: "pointer",
              outline: "1px solid rgba(0,0,0,0.15)",
              outlineOffset: "-3px"
            }} />
            )}
          </div>
        </div>
      </TweakSection>

      <TweakSection label="Typography">
        <TweakSelect
          label="Display serif"
          value={tweaks.displayFont}
          onChange={(v) => setTweak("displayFont", v)}
          options={FONT_OPTIONS.map((o) => ({ value: o.value, label: o.label }))} />
        
      </TweakSection>
    </TweaksPanel>);

}

/* ------------------------------------------------------------------ */
/* Mount                                                                 */
/* ------------------------------------------------------------------ */

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