/* global React, ReactDOM, TweaksPanel, useTweaks, TweakSection, TweakRadio, TweakColor */ const { useState, useEffect, useMemo } = React; // ───────────────────────────────────────────────────────────────────────────── // i18n // ───────────────────────────────────────────────────────────────────────────── const T = { fr: { locale: 'fr-CA', edition: 'CANADIAN PORTAL · ÉDITION FR-CA · MAI 2026', updated: 'Mise à jour\u00a0: 06.05.2026', notice: 'Site indépendant, non affilié au gouvernement', nav: [ { label: 'Immigrer', href: '#immigrer' }, { label: 'Travailler', href: '#travailler' }, { label: 'Vivre', href: '#vivre' }, { label: 'Provinces', href: '#provinces' }, { label: 'Actualités', href: '#actu' }, { label: 'Guides', href: '#guides' }, { label: 'Citoyenneté', href: '#citoyennete' }, ], subscribe: 'S’abonner', searchPlaceholder: 'Chercher un guide, une province, un programme…', live: 'EN DIRECT', eyebrow: 'Vol. 07 · Édition de mai', heroTitleA: 'Comprendre le', heroTitleEm: 'Canada', heroTitleB: 'avant de le', heroTitleC: 'choisir.', heroDek: 'Un journal indépendant pour préparer un projet d’immigration avec calme. Programmes officiels, vie quotidienne, finances, citoyenneté. Relus, sourcés, jamais alarmistes.', ctaExplore: 'Explorer les rubriques', ctaRead: 'Lire les guides récents', metaGuides: 'Guides publiés', metaProvinces: 'Provinces et territoires', metaEdition: 'Édition à jour', cardKicker: 'À LA UNE · 06.05.2026', cardTitleA: 'Entrée express, 2026', cardTitleB: 'les seuils des dernières rondes', cardDek: 'Lecture mesurée des invitations récentes. Ce que les chiffres permettent réellement de prévoir, et ce qu’ils ne disent pas.', cardReadTime: '10 min de lecture', cardCta: 'Lire l’article →', sec1Mono: '§ I · RUBRIQUES', sec1Title: 'Sept entrées, un seul fil rouge.', sec1Lead: 'Chaque rubrique regroupe des guides relus à la main, mis à jour, et croisés avec les sources officielles d’IRCC et des provinces.', sec2Mono: '§ II · GUIDES RÉCENTS', sec2Title: 'La rédaction cette semaine.', sec2Lead: 'Filtrez par rubrique. Tous les articles sont datés et révisés à chaque changement officiel signalé par IRCC.', all: 'Tout', results: 'résultats', result: 'résultat', fullArticle: 'Lire l’article complet →', minRead: 'min', emptyTitle: 'Aucun guide ne correspond à ce filtre pour le moment.', emptyCta: 'Tout afficher', pull: 'Immigrer, c’est traduire sa vie dans un nouveau cadre administratif. Ce portail aide à le faire', pullAccent: 'sans perdre la sienne.', pullCredit: 'La rédaction', sec3Mono: '§ III · INFOLETTRE', sec3Title: 'Une lettre, deux fois par mois.', sec3Lead: 'Les changements officiels qui méritent vraiment votre attention. Sans alarmisme, sans clickbait, avec les liens vers les sources.', nlLabel: 'VOTRE COURRIEL', nlPlaceholder: 'vous@exemple.ca', nlFine1: 'Aucun spam. Désabonnement en un clic. Voir notre', nlFineLink: 'politique de confidentialité', footerBrand: 'Un journal indépendant pour préparer un projet canadien avec calme. Pédagogique, vérifié, jamais alarmiste.', footerNotice: 'Site indépendant non affilié au gouvernement du Canada.', fSections: 'Rubriques', fAbout: 'À propos', fFollow: 'Suivre', fAboutLinks: ['Notre méthode', 'Contact', 'Mentions légales', 'Politique de confidentialité', 'Conditions d’utilisation'], fFollowLinks: ['Infolettre', 'Instagram', 'YouTube', 'Pinterest', 'RSS'], fCopy: '© 2026 CANADIAN PORTAL · TOUS DROITS RÉSERVÉS', fMade: 'FAIT AVEC SOIN POUR FUTURS NOUVEAUX ARRIVANTS', ticker: [ { tag: 'NOUVEAU', text: 'Ontario PNP, nouveau tirage Tech Draw, seuil CRS 472' }, { tag: 'IRCC', text: 'Entrée express, ronde du 06 mai, 4 500 invitations envoyées' }, { tag: 'QUÉBEC', text: 'PEQ volet diplômés, ouverture des inscriptions le 15 mai 2026' }, { tag: 'C.-B.', text: 'BC PNP Tech, 168 invitations cette semaine, score min. 105' }, { tag: 'ALERTE', text: 'Permis postdiplôme, nouvelles règles dès juin 2026' }, { tag: 'ALBERTA', text: 'AAIP rouvre la catégorie Tourism & Hospitality après 18 mois' }, { tag: 'CITOYENNETÉ', text: 'Délais de traitement réduits à 10 mois en moyenne' }, { tag: 'MANITOBA', text: 'MPNP, 312 candidats invités, secteurs prioritaires en santé' }, { tag: 'NOUVEAU', text: 'Programme pilote pour les aides familiaux, ouverture confirmée' }, ], topics: [ { id: 'immigrer', label: 'Immigrer', kicker: '01', count: 14, hue: 25, title: 'Immigrer au Canada', desc: 'Programmes de résidence permanente, Entrée express, candidats des provinces, critères et étapes avant la demande.' }, { id: 'travailler', label: 'Travailler', kicker: '02', count: 11, hue: 165, title: 'Travailler au Canada', desc: 'Permis de travail, droits des travailleurs étrangers, transition vers la résidence permanente, employeurs et offres.' }, { id: 'vivre', label: 'Vivre', kicker: '03', count: 9, hue: 230, title: 'Vivre au Canada', desc: 'Préparer l’arrivée, services d’établissement, logement, santé, finances, impôts et intégration au quotidien.' }, { id: 'provinces', label: 'Provinces', kicker: '04', count: 10, hue: 290, title: 'Provinces et territoires', desc: 'Comparer les provinces selon immigration, emploi, coût de la vie et installation. Panoramas pratiques.' }, { id: 'actu', label: 'Actualités', kicker: '05', count: 8, hue: 50, title: 'Actualités IRCC', desc: 'Décryptages prudents des changements officiels, annonces, mises à jour de programmes et tendances à surveiller.' }, { id: 'guides', label: 'Guides', kicker: '06', count: 16, hue: 130, title: 'Guides et conseils', desc: 'Conseils concrets pour organiser un dossier, éviter les pièges, préparer son budget, communiquer avec les autorités.' }, { id: 'citoyennete', label: 'Citoyenneté', kicker: '07', count: 7, hue: 340, title: 'Citoyenneté canadienne', desc: 'Repères sur la présence physique, le test, les langues et les étapes après la résidence permanente.' }, ], articles: [], }, en: { locale: 'en-CA', edition: 'CANADIAN PORTAL · EN-CA EDITION · MAY 2026', updated: 'Updated\u00a0: 05.06.2026', notice: 'Independent site, not affiliated with the Government of Canada', nav: [ { label: 'Immigrate', href: '#immigrer' }, { label: 'Work', href: '#travailler' }, { label: 'Live', href: '#vivre' }, { label: 'Provinces', href: '#provinces' }, { label: 'News', href: '#actu' }, { label: 'Guides', href: '#guides' }, { label: 'Citizenship', href: '#citoyennete' }, ], subscribe: 'Subscribe', searchPlaceholder: 'Search a guide, a province, a program…', live: 'LIVE', eyebrow: 'Vol. 07 · May Edition', heroTitleA: 'Understand', heroTitleEm: 'Canada', heroTitleB: 'before you', heroTitleC: 'choose it.', heroDek: 'An independent journal for planning your immigration project calmly. Official programs, daily life, finances, citizenship. Edited, sourced, never alarmist.', ctaExplore: 'Explore sections', ctaRead: 'Read recent guides', metaGuides: 'Published guides', metaProvinces: 'Provinces and territories', metaEdition: 'Up-to-date edition', cardKicker: 'FEATURED · 05.06.2026', cardTitleA: 'Express Entry, 2026', cardTitleB: 'thresholds of recent rounds', cardDek: 'A measured reading of recent invitations. What the numbers really tell us, and what they don’t.', cardReadTime: '10 min read', cardCta: 'Read the article →', sec1Mono: '§ I · SECTIONS', sec1Title: 'Seven entries, one common thread.', sec1Lead: 'Each section gathers guides reviewed by hand, kept up to date, and cross-checked with official IRCC and provincial sources.', sec2Mono: '§ II · RECENT GUIDES', sec2Title: 'The newsroom this week.', sec2Lead: 'Filter by section. All articles are dated and revised whenever IRCC announces an official change.', all: 'All', results: 'results', result: 'result', fullArticle: 'Read the full article →', minRead: 'min', emptyTitle: 'No guide matches this filter at the moment.', emptyCta: 'Show all', pull: 'Immigrating means translating your life into a new administrative frame. This portal helps you do that', pullAccent: 'without losing your own.', pullCredit: 'The editors', sec3Mono: '§ III · NEWSLETTER', sec3Title: 'A letter, twice a month.', sec3Lead: 'The official changes that truly deserve your attention. No alarmism, no clickbait, with links to the sources.', nlLabel: 'YOUR EMAIL', nlPlaceholder: 'you@example.ca', nlFine1: 'No spam. Unsubscribe in one click. See our', nlFineLink: 'privacy policy', footerBrand: 'An independent journal to plan a Canadian project calmly. Educational, fact-checked, never alarmist.', footerNotice: 'Independent site not affiliated with the Government of Canada.', fSections: 'Sections', fAbout: 'About', fFollow: 'Follow', fAboutLinks: ['Our method', 'Contact', 'Legal notice', 'Privacy policy', 'Terms of use'], fFollowLinks: ['Newsletter', 'Instagram', 'YouTube', 'Pinterest', 'RSS'], fCopy: '© 2026 CANADIAN PORTAL · ALL RIGHTS RESERVED', fMade: 'MADE WITH CARE FOR FUTURE NEWCOMERS', ticker: [ { tag: 'NEW', text: 'Ontario PNP, new Tech Draw, CRS threshold 472' }, { tag: 'IRCC', text: 'Express Entry, May 6 round, 4,500 invitations issued' }, { tag: 'QUÉBEC', text: 'PEQ graduates stream, registrations open May 15, 2026' }, { tag: 'B.C.', text: 'BC PNP Tech, 168 invitations this week, min. score 105' }, { tag: 'ALERT', text: 'Postgraduate work permit, new rules from June 2026' }, { tag: 'ALBERTA', text: 'AAIP reopens Tourism & Hospitality category after 18 months' }, { tag: 'CITIZENSHIP', text: 'Processing times reduced to 10 months on average' }, { tag: 'MANITOBA', text: 'MPNP, 312 candidates invited, priority sectors in healthcare' }, { tag: 'NEW', text: 'Pilot program for caregivers, opening confirmed' }, ], topics: [ { id: 'immigrer', label: 'Immigrate', kicker: '01', count: 14, hue: 25, title: 'Immigrate to Canada', desc: 'Permanent residence programs, Express Entry, provincial nominees, criteria and steps before applying.' }, { id: 'travailler', label: 'Work', kicker: '02', count: 11, hue: 165, title: 'Work in Canada', desc: 'Work permits, rights of foreign workers, transitioning to permanent residence, employers and job offers.' }, { id: 'vivre', label: 'Live', kicker: '03', count: 9, hue: 230, title: 'Live in Canada', desc: 'Prepare your arrival, settlement services, housing, healthcare, finances, taxes and daily integration.' }, { id: 'provinces', label: 'Provinces', kicker: '04', count: 10, hue: 290, title: 'Provinces and territories', desc: 'Compare provinces by immigration, employment, cost of living and settlement. Practical overviews.' }, { id: 'actu', label: 'News', kicker: '05', count: 8, hue: 50, title: 'IRCC news', desc: 'Careful analysis of official changes, announcements, program updates and trends to watch.' }, { id: 'guides', label: 'Guides', kicker: '06', count: 16, hue: 130, title: 'Guides and tips', desc: 'Concrete advice to organize a file, avoid pitfalls, plan a budget, and communicate with authorities.' }, { id: 'citoyennete', label: 'Citizenship', kicker: '07', count: 7, hue: 340, title: 'Canadian citizenship', desc: 'Reference points on physical presence, the test, languages, and steps after permanent residence.' }, ], articles: [], }, }; if (window.ARTICLES_FR) T.fr.articles = window.ARTICLES_FR; if (window.ARTICLES_EN) T.en.articles = window.ARTICLES_EN; // Hash routing helpers function parseHash(h) { if (!h || h === '#') return { kind: 'home' }; const m = h.replace(/^#/, '').match(/^(article|rubrique|page)\/(.+)$/); if (!m) return { kind: 'home' }; if (m[1] === 'article') return { kind: 'article', id: parseInt(m[2], 10) }; if (m[1] === 'page') return { kind: 'page', id: m[2] }; return { kind: 'topic', id: m[2] }; } function slugArticle(idx) { return `#article/${idx}`; } function slugTopic(id) { return `#rubrique/${id}`; } // ───────────────────────────────────────────────────────────────────────────── // Logo // ───────────────────────────────────────────────────────────────────────────── function CPLogo({ size = 38 }) { return ( Canadian Portal ); } // ───────────────────────────────────────────────────────────────────────────── // Article art (richer placeholder illustrations) // ───────────────────────────────────────────────────────────────────────────── // Photo gallery is provided by cp-articles.js (window.ART_PHOTOS) function ArticleArt({ kind, large = false }) { const url = (window.ART_PHOTOS && (window.ART_PHOTOS[kind] || window.ART_PHOTOS.editorial)) || ''; const wrapStyle = { width: '100%', aspectRatio: large ? '4 / 3' : '3 / 2', background: '#1a1815', borderRadius: 6, overflow: 'hidden', position: 'relative', border: '1px solid var(--line)', }; const imgStyle = { position: 'absolute', inset: 0, width: '100%', height: '100%', objectFit: 'cover', display: 'block', filter: 'saturate(0.92) contrast(1.04)', }; const overlay = (