Add full trilingual EN/FR/NB support across all pages and data

- Convert all data files (site, profile, norway, jazz, projects, cv) to Record<LocaleCode, string> fields
- Update all page templates to use LocaleCopy component for locale-aware rendering
- Fix CSS specificity conflict: .locale-copy .locale-copy__text (spec 20) now beats container span rules (spec 11)
- Update LocaleSwitcher, BaseLayout, and SectionCard for locale prop types
- Design system overhaul: Special Elite font, burgundy #8f2218, DG seal favicon

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-05-17 23:23:14 +02:00
parent ffb368670c
commit 2a06888fd6
21 changed files with 1377 additions and 848 deletions
+61 -115
View File
@@ -1,6 +1,8 @@
import type { LocaleCode } from "./locales";
export type RouteStop = {
place: string;
note: string;
note: Record<LocaleCode, string>;
};
export type SourceCredit = {
@@ -16,16 +18,16 @@ export type Venture = {
name: string;
label: string;
location: string;
summary: string;
detail: string;
highlights: string[];
summary: Record<LocaleCode, string>;
detail: Record<LocaleCode, string>;
highlights: Record<LocaleCode, string[]>;
source: SourceCredit;
};
export type VentureSignal = {
name: string;
strap: string;
summary: string;
strap: Record<LocaleCode, string>;
summary: Record<LocaleCode, string>;
href: string;
imageSrc: string;
imageAlt: string;
@@ -36,12 +38,12 @@ export type VentureSignal = {
export type CollageImage = {
src: string;
alt: string;
caption: string;
caption: Record<LocaleCode, string>;
};
export type AILabCapability = {
title: string;
summary: string;
title: Record<LocaleCode, string>;
summary: Record<LocaleCode, string>;
};
export type AILabProgramme = {
@@ -51,20 +53,20 @@ export type AILabProgramme = {
};
export const routeStops: RouteStop[] = [
{ place: "Ringwood, New Jersey", note: "born" },
{ place: "Villanova, Pennsylvania", note: "undergraduate chapter" },
{ place: "Brussels, Belgium", note: "trade and multilingual weather" },
{ place: "New Jersey", note: "return passage" },
{ place: "Columbia, South Carolina", note: "business school orbit" },
{ place: "Paris, France", note: "international MBA" },
{ place: "Washington, DC", note: "capital interval" },
{ place: "Manhattan, New York", note: "city tempo" },
{ place: "Hamilton, Bermuda", note: "Atlantic detour" },
{ place: "Washington, DC", note: "federal coda" },
{ place: "Brooklyn, New York", note: "borough voltage" },
{ place: "Krakow, Poland", note: "EU studies" },
{ place: "Oslo, Norway", note: "Nordic transition" },
{ place: "Kongsberg, Norway", note: "current desk" },
{ place: "Ringwood, New Jersey", note: { en: "born", fr: "naissance", nb: "født" } },
{ place: "Villanova, Pennsylvania", note: { en: "undergraduate chapter", fr: "chapitre universitaire", nb: "grunnleggende kapittel" } },
{ place: "Brussels, Belgium", note: { en: "trade and multilingual weather", fr: "commerce et météo multilingue", nb: "handel og flerspråklig vær" } },
{ place: "New Jersey", note: { en: "return passage", fr: "retour", nb: "returpassasje" } },
{ place: "Columbia, South Carolina", note: { en: "business school orbit", fr: "orbite de l'école de commerce", nb: "handelshøyskolebane" } },
{ place: "Paris, France", note: { en: "international MBA", fr: "MBA international", nb: "internasjonal MBA" } },
{ place: "Washington, DC", note: { en: "capital interval", fr: "intervalle capital", nb: "hovedstadsintervall" } },
{ place: "Manhattan, New York", note: { en: "city tempo", fr: "tempo urbain", nb: "bytempo" } },
{ place: "Hamilton, Bermuda", note: { en: "Atlantic detour", fr: "détour atlantique", nb: "atlantisk omvei" } },
{ place: "Washington, DC", note: { en: "federal coda", fr: "coda fédérale", nb: "føderal koda" } },
{ place: "Brooklyn, New York", note: { en: "borough voltage", fr: "voltage de quartier", nb: "bydelsspenning" } },
{ place: "Krakow, Poland", note: { en: "EU studies", fr: "études européennes", nb: "EU-studier" } },
{ place: "Oslo, Norway", note: { en: "Nordic transition", fr: "transition nordique", nb: "nordisk overgang" } },
{ place: "Kongsberg, Norway", note: { en: "current desk", fr: "bureau actuel", nb: "nåværende skrivebord" } },
];
export const ventureDesk: Venture[] = [
@@ -75,20 +77,13 @@ export const ventureDesk: Venture[] = [
name: "Gilligan TECH ENK",
label: "Norwegian ENK",
location: "Kongsberg, Norway",
summary:
"Local AI systems consulting for Nordic businesses, with strategy first, delivery second, and infrastructure only when it materially improves the result.",
detail:
"The Gilligan Tech line is practical and operator-minded: architectural audits, system builds, and fractional CTO guidance for Nordic SMBs that want useful AI without rented buzzwords.",
highlights: [
"AI Dispatch: fixed-fee architectural audit and strike map",
"Systems Forge: custom RAG, AI portals, and transcription services",
"Systems Command: fractional CTO support and board-ready AI strategy",
],
summary: { en: "Local AI systems consulting for Nordic businesses, with strategy first, delivery second, and infrastructure only when it materially improves the result.", fr: "Consultation en systèmes d'IA locaux pour les entreprises nordiques, avec la stratégie d'abord, la mise en œuvre ensuite, et l'infrastructure uniquement si elle améliore réellement le résultat.", nb: "Konsulenttjenester for lokale AI-systemer for nordiske bedrifter, med strategi først, levering deretter, og infrastruktur kun når det gir en materiell forbedring." },
detail: { en: "The Gilligan Tech line is practical and operator-minded: architectural audits, system builds, and fractional CTO guidance for Nordic SMBs that want useful AI without rented buzzwords.", fr: "La ligne Gilligan TECH est pratique et orientée opérateurs : audits architecturaux, constructions de systèmes et conseils CTO fractionnés pour les PME nordiques qui souhaitent une IA utile sans dépendre des mots à la mode.", nb: "Gilligan TECH-linjen er praktisk og operatørfokusert: arkitektoniske revisjoner, systembygging og delt CTO-veiledning for nordiske SMB-er som ønsker nyttig AI uten leide buzzwords." },
highlights: { en: ["AI Dispatch: fixed-fee architectural audit and strike map","Systems Forge: custom RAG, AI portals, and transcription services","Systems Command: fractional CTO support and board-ready AI strategy"], fr: ["AI Dispatch : audit architectural à tarif fixe et carte d'intervention","Systems Forge : RAG personnalisé, portails IA et services de transcription","Systems Command : support CTO fractionné et stratégie IA prête pour le conseil d'administration"], nb: ["AI Dispatch: fastpris arkitektonisk revisjon og handlingskart","Systems Forge: tilpasset RAG, AI-portaler og transkripsjonstjenester","Systems Command: delt CTO-støtte og styreklar AI-strategi"] },
source: {
label: "Gilligan Tech",
url: "https://gilligan.tech/",
note:
"Paraphrased from the official Gilligan Tech site, including the AI Dispatch, Systems Forge, and Systems Command descriptions.",
note: "Paraphrased from the official Gilligan Tech site, including the AI Dispatch, Systems Forge, and Systems Command descriptions.",
},
},
{
@@ -98,20 +93,13 @@ export const ventureDesk: Venture[] = [
name: "Blue Note Logic Inc",
label: "AI / IT Lab",
location: "Philadelphia to Paris, with EU infrastructure",
summary:
"Private AI platforms, document intelligence, and production infrastructure designed to turn working knowledge into owned systems rather than vendor dependency.",
detail:
"Blue Note Logic is the lab, forge, and infrastructure house behind the AI side of the publication: consultancy, sovereign model work, corpus design, and productized document intelligence with cited answers and European hosting.",
highlights: [
"CorpusAI and CaveauAI for private, source-cited retrieval",
"Knowledge corpus design, document intelligence, and deployment strategy",
"Sovereign fine-tuning paths built around owned data and owned outcomes",
],
summary: { en: "Private AI platforms, document intelligence, and production infrastructure designed to turn working knowledge into owned systems rather than vendor dependency.", fr: "Plateformes d'IA privées, intelligence documentaire et infrastructure de production conçues pour transformer le savoir-faire en systèmes propriétaires plutôt qu'en dépendance aux fournisseurs.", nb: "Private AI-plattformer, dokumentintelligens og produksjonsinfrastruktur designet for å gjøre arbeidskunnskap til egne systemer i stedet for leverandøravhengighet." },
detail: { en: "Blue Note Logic is the lab, forge, and infrastructure house behind the AI side of the publication: consultancy, sovereign model work, corpus design, and productized document intelligence with cited answers and European hosting.", fr: "Blue Note Logic est le laboratoire, la forge et la maison d'infrastructure derrière le volet IA de la publication : conseil, travail sur des modèles souverains, conception de corpus et intelligence documentaire produit avec des réponses citées et un hébergement européen.", nb: "Blue Note Logic er laboratoriet, smia og infrastrukturhuset bak AI-delen av publikasjonen: konsulenttjenester, arbeid med suverene modeller, korpusdesign og produktifisert dokumentintelligens med siterte svar og europeisk hosting." },
highlights: { en: ["CorpusAI and CaveauAI for private, source-cited retrieval","Knowledge corpus design, document intelligence, and deployment strategy","Sovereign fine-tuning paths built around owned data and owned outcomes"], fr: ["CorpusAI et CaveauAI pour une récupération privée et sourcée","Conception de corpus de connaissances, intelligence documentaire et stratégie de déploiement","Chemins de fine-tuning souverains basés sur des données et des résultats propriétaires"], nb: ["CorpusAI og CaveauAI for privat, kildebasert gjenfinning","Korpusdesign, dokumentintelligens og distribusjonsstrategi","Suverene finjusteringsveier bygget rundt egne data og egne resultater"] },
source: {
label: "Blue Note Logic official sites",
url: "https://ai.bluenotelogic.com/",
note:
"Paraphrased from Blue Note Logic and CorpusAI official pages covering private AI, document intelligence, and owned infrastructure.",
note: "Paraphrased from Blue Note Logic and CorpusAI official pages covering private AI, document intelligence, and owned infrastructure.",
},
},
];
@@ -119,9 +107,8 @@ export const ventureDesk: Venture[] = [
export const ventureSignals: VentureSignal[] = [
{
name: "Blue Note Logic",
strap: "private AI, document intelligence, and source-cited memory",
summary:
"The machine room behind the paper: owned infrastructure, private corpora, multilingual controls, and AI that keeps its receipts.",
strap: { en: "private AI, document intelligence, and source-cited memory", fr: "IA privée, intelligence documentaire et mémoire sourcée", nb: "privat AI, dokumentintelligens og kildebasert hukommelse" },
summary: { en: "The machine room behind the paper: owned infrastructure, private corpora, multilingual controls, and AI that keeps its receipts.", fr: "La salle des machines derrière le papier : infrastructure propriétaire, corpus privés, contrôles multilingues et IA qui garde ses preuves.", nb: "Maskinrommet bak papiret: egen infrastruktur, private korpus, flerspråklige kontroller og AI som holder kvitteringene sine." },
href: "https://ai.bluenotelogic.com/",
imageSrc: "/images/ai-lab/hero-lab.svg",
imageAlt: "Illustrated AI lab diagram for Blue Note Logic.",
@@ -130,21 +117,18 @@ export const ventureSignals: VentureSignal[] = [
},
{
name: "Trivia & Tunes",
strap: "live-hosted games, music rounds, and true AI in the loop",
summary:
"A culture product with venue instincts: playlists, game craft, AI grading, and voice features edging toward the microphone.",
strap: { en: "live-hosted games, music rounds, and true AI in the loop", fr: "jeux animés en direct, tours musicaux et vraie IA en boucle", nb: "live-vertede spill, musikkrunder og ekte AI i loopen" },
summary: { en: "A culture product with venue instincts: playlists, game craft, AI grading, and voice features edging toward the microphone.", fr: "Un produit culturel avec des instincts de lieu : playlists, conception de jeux, évaluation par IA et fonctionnalités vocales qui s'approchent du micro.", nb: "Et kulturprodukt med stedssans: spillelister, spilldesign, AI-evaluering og stemmefunksjoner som nærmer seg mikrofonen." },
href: "https://triviaandtunes.no/",
imageSrc:
"https://commons.wikimedia.org/wiki/Special:Redirect/file/Level_42_Kongsberg_Jazzfestival_2017_%28214257%29.jpg",
imageSrc: "https://commons.wikimedia.org/wiki/Special:Redirect/file/Level_42_Kongsberg_Jazzfestival_2017_%28214257%29.jpg",
imageAlt: "Crowd-facing stage image from Kongsberg Jazzfestival.",
imageNote: "Live rooms / music energy / quiz-night voltage",
external: true,
},
{
name: "Do Better Norge",
strap: "children's rights, due process, and family life protections",
summary:
"A civic and advocacy desk grounded in primary sources, practical guidance, and a refusal to treat children as procedural debris.",
strap: { en: "children's rights, due process, and family life protections", fr: "droits des enfants, procédure équitable et protection de la vie familiale", nb: "barns rettigheter, rettferdig prosess og beskyttelse av familieliv" },
summary: { en: "A civic and advocacy desk grounded in primary sources, practical guidance, and a refusal to treat children as procedural debris.", fr: "Un bureau civique et de plaidoyer ancré dans les sources primaires, des conseils pratiques et un refus de traiter les enfants comme des débris procéduraux.", nb: "En samfunns- og advokatdesk forankret i primærkilder, praktisk veiledning og en avvisning av å behandle barn som prosedyremessig avfall." },
href: "https://dobetternorge.no/",
imageSrc: "https://commons.wikimedia.org/wiki/Special:Redirect/file/Kongsberg_IMG_0357.JPG",
imageAlt: "Riverfront view in Kongsberg, Norway.",
@@ -153,12 +137,10 @@ export const ventureSignals: VentureSignal[] = [
},
{
name: "School dossier",
strap: "Brussels, Krakow, Paris, Villanova, and the long route north",
summary:
"The education issue turns institutions into chapters, cities into footnotes, and degrees into a proper migration story.",
strap: { en: "Brussels, Krakow, Paris, Villanova, and the long route north", fr: "Bruxelles, Cracovie, Paris, Villanova et la longue route vers le nord", nb: "Brussel, Krakow, Paris, Villanova og den lange veien nordover" },
summary: { en: "The education issue turns institutions into chapters, cities into footnotes, and degrees into a proper migration story.", fr: "Le numéro éducation transforme les institutions en chapitres, les villes en notes de bas de page et les diplômes en une véritable histoire de migration.", nb: "Utdanningsutgaven gjør institusjoner til kapitler, byer til fotnoter og grader til en ordentlig migrasjonshistorie." },
href: "/education",
imageSrc:
"https://commons.wikimedia.org/wiki/Special:Redirect/file/Grand-Place,_Brussels_%2839528722772%29.jpg",
imageSrc: "https://commons.wikimedia.org/wiki/Special:Redirect/file/Grand-Place,_Brussels_%2839528722772%29.jpg",
imageAlt: "Grand-Place in Brussels.",
imageNote: "Brussels / multilingual weather / first European chapter",
external: false,
@@ -169,43 +151,39 @@ export const collageImages: CollageImage[] = [
{
src: "https://commons.wikimedia.org/wiki/Special:Redirect/file/Villanova_University_A_panoramic_shot.jpg",
alt: "Panoramic view of Villanova University.",
caption: "Villanova / the first brass section",
caption: { en: "Villanova / the first brass section", fr: "Villanova / la première section de cuivres", nb: "Villanova / den første messingseksjonen" },
},
{
src: "https://commons.wikimedia.org/wiki/Special:Redirect/file/Jagiellonian_University_Collegium_Novum%2C_1882_designed_by_Feliks_Ksi%C4%99%C5%BCarski%2C_24_Go%C5%82%C4%99bia_street%2C_Old_Town%2C_Krak%C3%B3w%2C_Poland_%284%29.jpg",
alt: "Collegium Novum at Jagiellonian University in Krakow.",
caption: "Krakow / bureaucracy and stone",
caption: { en: "Krakow / bureaucracy and stone", fr: "Cracovie / bureaucratie et pierre", nb: "Krakow / byråkrati og stein" },
},
{
src: "https://commons.wikimedia.org/wiki/Special:Redirect/file/Kongsberg_IMG_0357.JPG",
alt: "Kongsberg riverfront in Norway.",
caption: "Kongsberg / present tense",
caption: { en: "Kongsberg / present tense", fr: "Kongsberg / présent immédiat", nb: "Kongsberg / nåtid" },
},
];
export const aiLabCapabilities: AILabCapability[] = [
{
title: "Private AI on your own corpus",
summary:
"Document intelligence built around a private corpus, with source-cited answers and search modes that stay anchored to the evidence.",
title: { en: "Private AI on your own corpus", fr: "IA privée sur votre propre corpus", nb: "Privat AI på ditt eget korpus" },
summary: { en: "Document intelligence built around a private corpus, with source-cited answers and search modes that stay anchored to the evidence.", fr: "Intelligence documentaire construite autour d'un corpus privé, avec des réponses sourcées et des modes de recherche ancrés dans les preuves.", nb: "Dokumentintelligens bygget rundt et privat korpus, med kildebaserte svar og søkemoduser som forblir forankret i bevisene." },
},
{
title: "European infrastructure by design",
summary:
"Dedicated European hosting, isolated telemetry, and a security posture built to reduce cloud leakage and shared-tenancy risk.",
title: { en: "European infrastructure by design", fr: "Infrastructure européenne par conception", nb: "Europeisk infrastruktur som standard" },
summary: { en: "Dedicated European hosting, isolated telemetry, and a security posture built to reduce cloud leakage and shared-tenancy risk.", fr: "Hébergement européen dédié, télémétrie isolée et posture de sécurité conçue pour réduire les fuites cloud et les risques de cohabitation.", nb: "Dedikert europeisk hosting, isolert telemetri og en sikkerhetsholdning bygget for å redusere sky-lekkasje og risiko for delt leietak." },
},
{
title: "From retrieval to owned model",
summary:
"A path from daily retrieval work toward domain-tuned models shaped by verified expert interaction instead of disposable prompt theatre.",
title: { en: "From retrieval to owned model", fr: "De la récupération au modèle propriétaire", nb: "Fra gjenfinning til egen modell" },
summary: { en: "A path from daily retrieval work toward domain-tuned models shaped by verified expert interaction instead of disposable prompt theatre.", fr: "Un chemin allant du travail quotidien de récupération vers des modèles adaptés au domaine, façonnés par une interaction experte vérifiée plutôt que par un théâtre de prompts jetables.", nb: "En vei fra daglig gjenfinningsarbeid til domene-tilpassede modeller formet av verifisert ekspertinteraksjon i stedet for engangs prompt-teater." },
},
];
export const aiLabProgrammes: AILabProgramme[] = [
{
title: "CorpusAI / CaveauAI",
summary:
"The product layer for private retrieval, cited answers, and document-grounded search from day one.",
summary: "The product layer for private retrieval, cited answers, and document-grounded search from day one.",
bullets: [
"Vector, keyword, and hybrid search modes",
"Cited answers linked back to source paragraphs",
@@ -214,8 +192,7 @@ export const aiLabProgrammes: AILabProgramme[] = [
},
{
title: "Corporate Memory Extraction",
summary:
"A flagship service that turns daily document workflows into a proprietary training asset and an owned model trajectory.",
summary: "A flagship service that turns daily document workflows into a proprietary training asset and an owned model trajectory.",
bullets: [
"EU-hosted RAG as the operational starting point",
"Verified interaction telemetry captured in isolated MariaDB",
@@ -224,8 +201,7 @@ export const aiLabProgrammes: AILabProgramme[] = [
},
{
title: "Related services",
summary:
"The working bench around the core platform: deployment, corpus architecture, and privacy-aware data engineering.",
summary: "The working bench around the core platform: deployment, corpus architecture, and privacy-aware data engineering.",
bullets: [
"Document intelligence consulting",
"Knowledge corpus development",
@@ -235,40 +211,10 @@ export const aiLabProgrammes: AILabProgramme[] = [
];
export const aiLabSources: SourceCredit[] = [
{
label: "Gilligan Tech",
url: "https://gilligan.tech/",
note:
"Used for the Gilligan Tech positioning, engagement models, and the relationship to the sister platform.",
},
{
label: "Blue Note Logic / CorpusAI",
url: "https://ai.bluenotelogic.com/",
note:
"Used for the private AI, document intelligence, and source-cited corpus positioning.",
},
{
label: "Blue Note Logic service page",
url: "https://bluenotelogic.com/service.php?slug=corporate-memory-extraction",
note:
"Used for the sovereign model, EU-hosted RAG, isolated telemetry, and related-service descriptions.",
},
{
label: "Trivia & Tunes",
url: "https://triviaandtunes.no/",
note:
"Used for the live-hosted trivia and music angle on the homepage culture desk.",
},
{
label: "Do Better Norge",
url: "https://dobetternorge.no/",
note:
"Used for the advocacy and children's-rights positioning on the homepage civic desk.",
},
{
label: "Wikimedia Commons",
url: "https://commons.wikimedia.org/",
note:
"Used for the public-domain and openly licensed city, campus, and festival images woven through the homepage and section cards.",
},
{ label: "Gilligan Tech", url: "https://gilligan.tech/", note: "Used for the Gilligan Tech positioning, engagement models, and the relationship to the sister platform." },
{ label: "Blue Note Logic / CorpusAI", url: "https://ai.bluenotelogic.com/", note: "Used for the private AI, document intelligence, and source-cited corpus positioning." },
{ label: "Blue Note Logic service page", url: "https://bluenotelogic.com/service.php?slug=corporate-memory-extraction", note: "Used for the sovereign model, EU-hosted RAG, isolated telemetry, and related-service descriptions." },
{ label: "Trivia & Tunes", url: "https://triviaandtunes.no/", note: "Used for the live-hosted trivia and music angle on the homepage culture desk." },
{ label: "Do Better Norge", url: "https://dobetternorge.no/", note: "Used for the advocacy and children's-rights positioning on the homepage civic desk." },
{ label: "Wikimedia Commons", url: "https://commons.wikimedia.org/", note: "Used for the public-domain and openly licensed city, campus, and festival images woven through the homepage and section cards." },
];