Files
dictia-public/templates/marketing/landing.html
Allison e49652d85d feat(marketing): intègre pipeline 4 étapes + réseau hub d'intégrations depuis dictia.ca/solutions/dictai
- Pipeline (entre Solution & Bento) : Upload → GPU WhisperX → IA Mistral → Export
  Auto-advance Alpine 2400ms, sweep ring SVG CSS, dot glow, prefers-reduced-motion
- Hub (entre Bento & Pricing) : DictIA → 3 hubs → 9 outils
  SVG natif <animateMotion> sur bezier paths, zéro lib JS, fallback liste 3-col WCAG
- Texte 100% canonique extrait de Website-Sanity dictai-pipeline.tsx + dictai-hub.tsx
- OQLF NBSP : "1 heure d'audio → 2 minutes", "5 000+ apps", "100 % en local"
- WCAG : aria-labelledby sections, role=tab/list, focus-visible, prefers-reduced-motion
- +397 lignes, npm run build:css exécuté pour utilities cyan/purple/opacity

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-28 12:03:33 -04:00

1242 lines
79 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{% extends 'marketing/base.html' %}
{% block title %}Transcription IA conforme Loi 25 — DictIA pour avocats, CPA, secteur public{% endblock %}
{% block description %}DictIA transcrit vos réunions confidentielles 100% au Québec. Conforme Loi 25, Barreau, CPA, ChAD. Conçu avec 9 ordres professionnels — lancement printemps 2026.{% endblock %}
{% block content %}
{# ===== HERO ===== #}
{# Local keyframes scoped to the hero — audio progress bar loops 50%→75%→50% over 15s #}
<style>
@keyframes audio-progress {
0%, 100% { width: 50%; }
50% { width: 75%; }
}
.hero-audio-progress { animation: audio-progress 15s ease-in-out infinite; }
.hero-audio-thumb { animation: audio-progress 15s ease-in-out infinite; }
/* Mockup tilt + interactive hover — straightens on hover */
@media (min-width: 1024px) {
.hero-mockup-tilt { transform: rotate(1deg); transition: transform 500ms ease-out; }
.hero-mockup-tilt:hover { transform: rotate(0deg) scale(1.01); }
}
/* Glow orbs decorative float — uses tc-float-y from tailwind.config */
.hero-mockup-glow-a { animation: tc-float-y 6s ease-in-out infinite; }
.hero-mockup-glow-b { animation: tc-float-y 8s ease-in-out infinite reverse; }
/* Reduced-motion: freeze all hero mockup animations on first frame */
@media (prefers-reduced-motion: reduce) {
.hero-audio-progress, .hero-audio-thumb,
.hero-mockup-glow-a, .hero-mockup-glow-b {
animation: none !important;
}
.hero-audio-progress { width: 60% !important; }
.hero-audio-thumb { left: 60% !important; }
.hero-mockup-tilt { transform: none !important; transition: none !important; }
}
</style>
<section class="relative overflow-hidden bg-brand-navy text-white py-24 md:py-32" aria-labelledby="hero-title">
{# Cosmic orbs background — 3 radial gradients (blue 16%, cyan 7%, green 11%) + subtle grid + horizontal accent line #}
<div class="absolute inset-0 pointer-events-none" aria-hidden="true">
{# Orb 1 — primary blue, top-left #}
<div class="absolute top-1/4 left-1/4 w-[600px] h-[600px] rounded-full opacity-100"
style="background: radial-gradient(circle, rgba(0,98,255,0.16) 0%, transparent 60%); filter: blur(40px);"></div>
{# Orb 2 — cyan, mid-right #}
<div class="absolute top-1/2 right-1/4 w-[500px] h-[500px] rounded-full"
style="background: radial-gradient(circle, rgba(0,189,216,0.07) 0%, transparent 60%); filter: blur(40px);"></div>
{# Orb 3 — accent green, bottom-left #}
<div class="absolute bottom-1/4 left-1/3 w-[400px] h-[400px] rounded-full"
style="background: radial-gradient(circle, rgba(0,200,150,0.11) 0%, transparent 60%); filter: blur(40px);"></div>
{# Subtle grid overlay (FlexiHub signature) #}
<div class="absolute inset-0"
style="background-image: linear-gradient(rgba(255,255,255,0.02) 1px, transparent 1px), linear-gradient(90deg, rgba(255,255,255,0.02) 1px, transparent 1px); background-size: 40px 40px;"></div>
{# Horizontal accent line — gradient blue to cyan to transparent #}
<div class="absolute top-1/3 left-0 right-0 h-px"
style="background: linear-gradient(90deg, transparent, rgba(0,98,255,0.3), rgba(0,189,216,0.2), transparent);"></div>
</div>
<div class="relative max-w-[1200px] mx-auto px-6">
{# 2-col grid on lg+: text left, app mockup right. On <lg, mockup hidden, text centered as before. #}
<div class="grid lg:grid-cols-[1fr_minmax(0,560px)] gap-12 lg:gap-16 items-center">
{# ---------- COLUMN LEFT: hero copy ---------- #}
<div class="text-center lg:text-left max-w-3xl mx-auto lg:mx-0">
{# Eyebrow with gradient text and 0.18em tracking #}
<p class="eyebrow grad-text mb-6 animate-tc-fade-in-up" style="animation-delay: 0ms; animation-fill-mode: backwards;">
TRANSCRIPTION IA · CONFORME LOI 25 · QUÉBEC
</p>
{# H1 — clamp typography + grad-text accent on key phrase #}
<h1 id="hero-title" class="text-[clamp(2.5rem,4vw,4rem)] font-black leading-[1.05] mb-6 animate-tc-fade-in-up" style="animation-delay: 75ms; animation-fill-mode: backwards;">
Transcrivez vos réunions
<span class="grad-text">sans risquer votre permis</span>.
</h1>
{# Sub-headline — ≤25 words, value prop #}
<p class="text-lg text-white/70 max-w-xl mx-auto lg:mx-0 mb-10 animate-tc-fade-in-up" style="animation-delay: 150ms; animation-fill-mode: backwards;">
DictIA convertit vos audio en texte, résumé et points d'action — 100% au Québec, conforme Barreau, CPA Québec, ChAD et 6 autres ordres professionnels.
</p>
{# Dual CTA — primary (demo) + secondary ghost (pricing) #}
<div class="flex flex-col sm:flex-row gap-3 justify-center lg:justify-start animate-tc-fade-in-up" style="animation-delay: 300ms; animation-fill-mode: backwards;">
{% from 'macros/button.html' import button %}
{{ button('Réserver une démo', href='/contact', variant='primary', size='lg') }}
{{ button('Voir les tarifs', href='/tarifs', variant='ghost', size='lg', icon='<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="w-4 h-4" aria-hidden="true"><path d="M14 5l7 7m0 0l-7 7m7-7H3"/></svg>') }}
</div>
{# Social proof microcopy — defensible: refers to pre-launch waitlist + factual ordres pros count #}
<p class="mt-8 text-sm text-white/70 flex flex-wrap items-center justify-center lg:justify-start gap-x-2 gap-y-1 animate-tc-fade-in-up" style="animation-delay: 400ms; animation-fill-mode: backwards;">
<span class="inline-flex items-center gap-1.5">
<svg width="14" height="14" viewBox="0 0 20 20" fill="currentColor" class="text-brand-b3" aria-hidden="true">
<path d="M10 2L3 5v5.5c0 4.04 2.84 7.85 7 8.5 4.16-.65 7-4.46 7-8.5V5l-7-3z"/>
</svg>
<span>Conçu avec 9 ordres professionnels québécois</span>
</span>
<span class="text-white/30">·</span>
<span>Pré-inscription ouverte</span>
<span class="text-white/30">·</span>
<span>Lancement printemps 2026</span>
</p>
</div>
{# ---------- COLUMN RIGHT: app mockup (lg+ only) ---------- #}
<div class="hidden lg:block relative animate-tc-fade-in-up" style="animation-delay: 250ms; animation-fill-mode: backwards;">
{# Decorative glow orbs floating behind the mockup #}
<div class="absolute -inset-8 pointer-events-none" aria-hidden="true">
<div class="hero-mockup-glow-a absolute -top-10 -left-10 w-72 h-72 rounded-full bg-brand-b1/15 blur-3xl"></div>
<div class="hero-mockup-glow-b absolute -bottom-10 -right-6 w-64 h-64 rounded-full bg-brand-b3/10 blur-3xl"></div>
</div>
{# The mockup itself — role=img with descriptive label for screen readers #}
<div role="img"
aria-label="Aperçu de l'interface DictIA — liste d'enregistrements à gauche, transcription au centre, résumé IA à droite"
class="hero-mockup-tilt relative bg-brand-navy2 border border-white/[0.08] shadow-2xl shadow-black/40 rounded overflow-hidden">
{# A) Browser chrome / window header (h-8) #}
<div class="flex items-center px-3 h-8 border-b border-white/[0.06] bg-white/[0.03]" aria-hidden="true">
{# Traffic light dots #}
<div class="flex items-center gap-1.5">
<span class="block w-3 h-3 rounded-full" style="background:#ff5f57"></span>
<span class="block w-3 h-3 rounded-full" style="background:#febc2e"></span>
<span class="block w-3 h-3 rounded-full" style="background:#28c840"></span>
</div>
{# Centered tab label #}
<div class="flex-1 text-center text-[11px] font-medium text-white/60 tracking-tight">DictIA — Enquêter</div>
{# Expand icon #}
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="w-3.5 h-3.5 text-white/40">
<path d="M15 3h6v6M9 21H3v-6M21 3l-7 7M3 21l7-7"/>
</svg>
</div>
{# B) Main app area — 3 sub-columns (sidebar / center / summary), h-[460px] #}
<div class="grid grid-cols-[180px_1fr_170px] h-[460px]"
x-data="{ idx: 0 }"
x-init="$el.__hero_int = setInterval(() => { idx = (idx + 1) % 5 }, 2800)">
{# B1 — SIDEBAR (left) #}
<aside class="border-r border-white/[0.06] flex flex-col overflow-hidden">
{# Sidebar header — DictIA monogram + JD avatar #}
<div class="flex items-center justify-between px-3 py-2.5 border-b border-white/[0.05]">
<span class="grad-text font-black text-[13px] tracking-tight">DictIA</span>
<span class="grad-bg rounded-full w-6 h-6 flex items-center justify-center text-[10px] font-bold text-white">JD</span>
</div>
{# New recording button — rounded-none brutalist #}
<div class="px-2 pt-2">
<button type="button" class="grad-bg w-full inline-flex items-center justify-center gap-1.5 py-2 text-[11px] font-semibold rounded-none" tabindex="-1" aria-hidden="true">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" class="w-3 h-3"><path d="M12 5v14M5 12h14"/></svg>
<span>Nouvel Enregistrement</span>
</button>
</div>
{# Search input #}
<div class="px-2 pt-2">
<div class="relative">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="absolute left-2 top-1/2 -translate-y-1/2 w-3 h-3 text-white/40"><circle cx="11" cy="11" r="7"/><path d="m21 21-4.3-4.3"/></svg>
<div class="bg-white/[0.05] border border-white/[0.06] py-1.5 pl-7 pr-2 text-[10px] text-white/40 rounded-none">Rechercher…</div>
</div>
</div>
{# Sidebar list — scrollable area #}
<div class="flex-1 overflow-hidden mt-3 px-1">
{# Group: Semaine dernière #}
<p class="px-2 text-[9px] uppercase tracking-[0.12em] text-white/40 font-bold mb-1.5">Semaine dernière</p>
{# Item 1 — ACTIVE #}
<div class="px-2 py-2 mb-1 bg-white/[0.08] border-l-2 border-brand-b1">
<p class="text-[11px] text-white font-semibold truncate">Dossier Beaumont — clauses 7 et 9</p>
<p class="text-[9px] text-white/50 truncate mt-0.5">Jeu · Me Roy, Jean T., Marie C.</p>
<span class="inline-block mt-1 rounded-full bg-blue-500/20 text-blue-300 text-[9px] px-2 py-0.5 font-medium">En cours</span>
</div>
{# Item 2 #}
<div class="px-2 py-2 mb-1 hover:bg-white/[0.04]">
<p class="text-[11px] text-white/90 truncate">Succession Gagnon — répartition…</p>
<p class="text-[9px] text-white/50 truncate mt-0.5">26 févr. · Me Gagnon, Client</p>
</div>
{# Group: Mois dernier #}
<p class="px-2 mt-3 text-[9px] uppercase tracking-[0.12em] text-white/40 font-bold mb-1.5">Mois dernier</p>
{# Item 3 #}
<div class="px-2 py-2 mb-1 hover:bg-white/[0.04]">
<p class="text-[11px] text-white/90 truncate">Consultation Tremblay — litige loc…</p>
<p class="text-[9px] text-white/50 truncate mt-0.5">19 févr. · Me Roy, Sophie T.</p>
</div>
{# Item 4 — Barreau Confidentiel #}
<div class="px-2 py-2 mb-1 hover:bg-white/[0.04]">
<p class="text-[11px] text-white/90 truncate">Réunion constitutive INC Bédard…</p>
<p class="text-[9px] text-white/50 truncate mt-0.5">10 févr. · Sophie B., Jean R.</p>
<span class="inline-block mt-1 rounded-full bg-purple-500/20 text-purple-300 text-[9px] px-2 py-0.5 font-medium">Barreau Confidentiel</span>
</div>
{# Item 5 — CPA Corporatif #}
<div class="px-2 py-2 mb-1 hover:bg-white/[0.04]">
<p class="text-[11px] text-white/90 truncate">Entretien RQAP et structure salariale</p>
<p class="text-[9px] text-white/50 truncate mt-0.5">10 févr. · Me Roy, Allison, Robert</p>
<span class="inline-block mt-1 rounded-full bg-emerald-500/20 text-emerald-300 text-[9px] px-2 py-0.5 font-medium">CPA Corporatif</span>
</div>
{# Item 6 — Urgent Client #}
<div class="px-2 py-2 mb-1 hover:bg-white/[0.04]">
<p class="text-[11px] text-white/90 truncate">Révision contrat Côté &amp; Associés</p>
<p class="text-[9px] text-white/50 truncate mt-0.5">5 févr. · Me Roy, Marie C.</p>
<span class="inline-block mt-1 rounded-full bg-red-500/20 text-red-300 text-[9px] px-2 py-0.5 font-medium">Urgent Client</span>
</div>
</div>
</aside>
{# B2 — CENTER (audio + transcript) #}
<section class="flex flex-col p-3 overflow-hidden">
{# Header card #}
<div class="mb-3">
<h3 class="text-[13px] font-bold text-white">Dossier Beaumont — clauses 7 et 9</h3>
<div class="flex flex-wrap items-center gap-x-3 gap-y-1 mt-1.5 text-[10px] text-white/50">
<span class="inline-flex items-center gap-1">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="w-3 h-3"><path d="M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2"/><circle cx="9" cy="7" r="4"/><path d="M22 21v-2a4 4 0 0 0-3-3.87"/><path d="M16 3.13a4 4 0 0 1 0 7.75"/></svg>
<span>Me Roy, Jean T., Marie C.</span>
</span>
<span class="inline-flex items-center gap-1">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="w-3 h-3"><rect x="3" y="4" width="18" height="18" rx="2"/><path d="M16 2v4M8 2v4M3 10h18"/></svg>
<span>27 févr. 2026</span>
</span>
<span class="inline-flex items-center gap-1">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="w-3 h-3"><circle cx="12" cy="12" r="10"/><path d="M12 6v6l4 2"/></svg>
<span>38:47</span>
</span>
<span class="inline-flex items-center gap-1">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="w-3 h-3"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/><path d="M14 2v6h6"/></svg>
<span>28.3 MB</span>
</span>
</div>
</div>
{# Audio player block #}
<div class="bg-white/[0.04] p-3 rounded-none">
{# Progress bar #}
<div class="relative h-1 bg-white/10">
<div class="hero-audio-progress h-full grad-bg" style="width:60%"></div>
<div class="hero-audio-thumb absolute -top-1 grad-bg w-3 h-3 rounded-full" style="left:60%; transform: translateX(-50%);"></div>
</div>
{# Time + speed + play row #}
<div class="flex items-center justify-between mt-2">
<div class="text-[10px] font-mono text-white/60">
<span class="text-white/80">28:17</span>
<span class="text-white/30 mx-1">/</span>
<span>46:23</span>
</div>
<div class="flex items-center gap-2">
<span class="text-[9px] text-white/60 px-1.5 py-0.5 bg-white/[0.06] rounded-full font-mono">1x</span>
<button type="button" class="grad-bg w-8 h-8 rounded-full flex items-center justify-center animate-plus-breathe" tabindex="-1" aria-hidden="true">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="white" class="w-3 h-3"><path d="M8 5v14l11-7z"/></svg>
</button>
</div>
</div>
</div>
{# Transcript area — 5 lines, active line cycles via Alpine idx #}
<div class="flex-1 mt-3 overflow-hidden space-y-1.5">
<div class="px-2 py-1.5 transition-colors duration-300" :class="idx === 0 ? 'bg-brand-b1/10 border-l-2 border-brand-b1' : 'border-l-2 border-transparent'">
<p class="text-[10px]">
<span class="text-brand-b1 font-bold">Allison</span>
<span class="text-white/80 ml-1.5">Tu l'as su? Comment ça va, vous deux?</span>
</p>
</div>
<div class="px-2 py-1.5 transition-colors duration-300" :class="idx === 1 ? 'bg-brand-b1/10 border-l-2 border-brand-b1' : 'border-l-2 border-transparent'">
<p class="text-[10px]">
<span class="text-brand-b3 font-bold">SPEAKER_02</span>
<span class="text-white/80 ml-1.5">Super bien, super vite, mais très bien.</span>
</p>
</div>
<div class="px-2 py-1.5 transition-colors duration-300" :class="idx === 2 ? 'bg-brand-b1/10 border-l-2 border-brand-b1' : 'border-l-2 border-transparent'">
<p class="text-[10px]">
<span class="text-brand-b1 font-bold">Allison</span>
<span class="text-white/80 ml-1.5">Oui, oui. Je suis contente d'entendre ça.</span>
</p>
</div>
<div class="px-2 py-1.5 transition-colors duration-300" :class="idx === 3 ? 'bg-brand-b1/10 border-l-2 border-brand-b1' : 'border-l-2 border-transparent'">
<p class="text-[10px]">
<span class="text-brand-b3 font-bold">SPEAKER_02</span>
<span class="text-white/80 ml-1.5">Moi, je l'ai vu quand vous l'avez payé.</span>
</p>
</div>
<div class="px-2 py-1.5 transition-colors duration-300" :class="idx === 4 ? 'bg-brand-b1/10 border-l-2 border-brand-b1' : 'border-l-2 border-transparent'">
<p class="text-[10px]">
<span class="text-brand-b1 font-bold">Allison</span>
<span class="text-white/80 ml-1.5">J'étais comme, « Hein? »</span>
</p>
</div>
</div>
{# Question input (disabled — visual only) #}
<div class="mt-3">
<input type="text" disabled tabindex="-1" aria-hidden="true"
placeholder="Posez une question sur cette transcription…"
class="w-full bg-white/[0.05] border border-white/10 px-3 py-2 text-[11px] text-white/40 placeholder-white/40 rounded-none">
</div>
</section>
{# B3 — RIGHT pane (summary) #}
<aside class="border-l border-white/[0.06] p-3 overflow-hidden">
{# Tabs #}
<div class="flex items-center gap-3 border-b border-white/[0.06] pb-2 mb-3">
<span class="text-[10px] uppercase tracking-[0.12em] text-brand-b1 font-bold border-b-2 border-brand-b1 pb-1 -mb-[0.5rem]">Résumé</span>
<span class="text-[10px] uppercase tracking-[0.12em] text-white/40 font-medium">Notes</span>
<span class="text-[10px] uppercase tracking-[0.12em] text-white/40 font-medium">Discuter</span>
</div>
{# Summary text #}
<p class="text-[10px] text-white/80 leading-relaxed">
Cette réunion aborde les complexités fiscales et juridiques liées à la création d'un nouveau produit nommé Dictéa…
</p>
{# Key points #}
<p class="mt-3 text-[9px] uppercase tracking-[0.12em] text-white/50 font-bold mb-1.5">Points clés</p>
<ul class="space-y-1 text-[10px] text-white/70 leading-snug">
<li class="flex gap-1.5"><span class="text-brand-b1"></span><span>Structure de propriété : SNC + INC</span></li>
<li class="flex gap-1.5"><span class="text-brand-b1"></span><span>RQAP et Salaire : Allison ne peut pas se verser</span></li>
<li class="flex gap-1.5"><span class="text-brand-b1"></span><span>Subventions : 4 ans à conserver</span></li>
<li class="flex gap-1.5"><span class="text-brand-b1"></span><span>Exonération des gains personnels</span></li>
</ul>
</aside>
</div>{# /Main app area #}
</div>{# /mockup container #}
</div>{# /column right #}
</div>{# /grid #}
</div>
</section>
{# ===== TRUST BAR — 9 ordres pros ===== #}
<section class="bg-white py-16 border-y border-brand-border" aria-labelledby="trust-bar-title">
<div class="max-w-[1200px] mx-auto px-6">
<div class="text-center max-w-xl mx-auto mb-10">
<p id="trust-bar-title" class="eyebrow text-brand-navy/70 mb-3">
Mappé aux 9&nbsp;ordres professionnels québécois
</p>
<p class="text-sm text-brand-navy/70">
L'architecture DictIA est conçue pour répondre aux exigences de confidentialité et d'audit des principaux ordres professionnels du Québec.
</p>
</div>
{# 9 ordres — uniform card grid, official names, profession labels (no repeated acronyms) #}
<ul class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-3 mb-14" role="list">
{% for ordre in [
{'acronym': 'Barreau', 'name': 'Barreau du Québec', 'profession': 'Avocats'},
{'acronym': 'CNQ', 'name': 'Chambre des notaires du Québec', 'profession': 'Notaires'},
{'acronym': 'CPA', 'name': 'Ordre des CPA du Québec', 'profession': 'Comptables'},
{'acronym': 'ChAD', 'name': "Chambre de l'assurance de dommages", 'profession': 'Assurance'},
{'acronym': 'OACIQ', 'name': "Organisme d'autoréglementation du courtage immobilier du Québec", 'profession': 'Courtage immobilier'},
{'acronym': 'CMQ', 'name': 'Collège des médecins du Québec', 'profession': 'Médecins'},
{'acronym': 'OIIQ', 'name': 'Ordre des infirmières et infirmiers du Québec', 'profession': 'Infirmières'},
{'acronym': 'OPQ', 'name': 'Ordre des pharmaciens du Québec', 'profession': 'Pharmaciens'},
{'acronym': 'OEQ', 'name': 'Ordre des ergothérapeutes du Québec', 'profession': 'Ergothérapeutes'}
] %}
<li class="flex items-center gap-4 p-4 bg-white border border-brand-border rounded hover:border-brand-b1 transition-colors">
<span class="flex-shrink-0 w-14 h-14 flex items-center justify-center bg-brand-bg border border-brand-border" aria-hidden="true">
<span class="grad-text font-black text-sm tracking-tight">{{ ordre.acronym }}</span>
</span>
<span class="min-w-0 flex-1">
<span class="block text-sm font-semibold text-brand-navy leading-snug">{{ ordre.name | safe }}</span>
<span class="block text-xs uppercase tracking-wider text-brand-navy/60 mt-1">{{ ordre.profession }}</span>
</span>
</li>
{% endfor %}
</ul>
{# 4 KPI metrics — defensible numbers with footnote attribution #}
<div class="grid grid-cols-2 md:grid-cols-4 gap-8">
{% for kpi in [
('~5 min', 'par heure d\'audio', 'Traitement local 30× temps réel sur GPU RTX'),
('95&nbsp;%+', 'précision FR-CA', 'WhisperX Large-v3 — test interne 2026-Q1'),
('0&nbsp;$', 'frais par utilisateur', 'Modèle par serveur, volume illimité'),
('100&nbsp;%', 'local au Québec', 'OVH Beauharnois ou vos serveurs')
] %}
<div class="text-center">
<div class="text-4xl font-black grad-text mb-2">{{ kpi[0] | safe }}</div>
<div class="text-sm font-semibold text-brand-navy mb-1">{{ kpi[1] }}</div>
<div class="text-xs text-brand-navy/60">{{ kpi[2] }}</div>
</div>
{% endfor %}
</div>
{# Footnote — discloses methodology for the 95% claim (LPC art. 219 hygiene) #}
<p class="text-xs text-brand-navy/70 text-center mt-8 max-w-2xl mx-auto">
Précision mesurée sur un échantillon interne d'audio professionnel québécois (juridique, médical, municipal) — méthodologie disponible sur demande à <a href="mailto:info@dictia.ca" class="hover:text-brand-navy">info@dictia.ca</a>.
</p>
</div>
</section>
{# ===== PROBLÈME (P de PAS) ===== #}
<section class="bg-brand-bg py-20" aria-labelledby="probleme-title">
<div class="max-w-[1200px] mx-auto px-6">
<div class="text-center max-w-2xl mx-auto mb-12">
<p class="eyebrow grad-text mb-4">LE PROBLÈME — TRANSCRIPTION CLOUD</p>
<h2 id="probleme-title" class="text-[clamp(2rem,3vw,2.75rem)] font-black mb-4">
Vos réunions confidentielles dans Teams Copilot ou Otter.ai
<span class="grad-text">violent la Loi&nbsp;25</span>.
</h2>
<p class="text-lg text-brand-navy/70">
Le transfert de données vocales hors-Québec sans consentement explicite expose les professionnels réglementés à des sanctions disciplinaires de leurs ordres et à des amendes CAI jusqu'à 25&nbsp;M$ ou 4&nbsp;% du chiffre d'affaires mondial.
</p>
</div>
{# 3 problem cards on white surface — Cloud Act, Loi 25, Sanctions #}
<div class="grid md:grid-cols-3 gap-6 mt-12">
{% for card in [
('Cloud Act', 'Loi américaine 2018', 'Microsoft, Google et OpenAI sont soumis au Cloud Act. Vos données peuvent être saisies par les autorités américaines sans votre consentement ni notification — y compris les enregistrements de vos réunions client.',
'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" class="w-6 h-6" aria-hidden="true"><path d="M12 3v18"/><path d="M5 7h14"/><path d="M5 7l-2 6a4 4 0 0 0 8 0L9 7"/><path d="M19 7l2 6a4 4 0 0 1-8 0l2-6"/><path d="M8 21h8"/></svg>'),
('Loi 25 — biométrie', 'Sanctions CAI jusqu\'à 25&nbsp;M$', 'La voix est une donnée biométrique au sens des articles 44-45 de la LCCJTI et un renseignement sensible au sens de la Loi 25 (art.&nbsp;12 LSP). Tout traitement nécessite un consentement explicite, une déclaration préalable à la CAI et un transfert vers un territoire offrant une protection équivalente — ce que les États-Unis n\'offrent pas.',
'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" class="w-6 h-6" aria-hidden="true"><path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"/></svg>'),
('Sanctions disciplinaires', '~250&nbsp;000 pros réglementés QC (CIQ)', 'Les ordres professionnels québécois — au premier rang desquels le Barreau, la Chambre des notaires et CPA Québec — exigent une obligation stricte de confidentialité. Le transfert de données client hors-juridiction sans consentement explicite peut être qualifié de manquement, jusqu\'à la radiation pour les fautes graves.',
'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" class="w-6 h-6" aria-hidden="true"><path d="M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z"/><line x1="12" y1="9" x2="12" y2="13"/><line x1="12" y1="17" x2="12.01" y2="17"/></svg>')
] %}
<article class="bg-white p-6 rounded border border-brand-border">
<div class="grad-text mb-4" aria-hidden="true">{{ card[3] | safe }}</div>
<h3 class="text-lg font-bold mb-1 text-brand-navy">{{ card[0] }}</h3>
<p class="text-xs uppercase tracking-wider text-brand-navy/70 mb-3 font-semibold">{{ card[1] | safe }}</p>
<p class="text-sm text-brand-navy/70 leading-relaxed">{{ card[2] | safe }}</p>
</article>
{% endfor %}
</div>
</div>
</section>
{# ===== SOLUTION (S de PAS) ===== #}
<section class="relative bg-brand-navy text-white py-20 overflow-hidden" aria-labelledby="solution-title">
{# Single subtle orb in solution bg — less busy than hero #}
<div class="absolute top-1/2 right-1/4 w-[500px] h-[500px] rounded-full pointer-events-none" aria-hidden="true"
style="background: radial-gradient(circle, rgba(0,200,150,0.08) 0%, transparent 60%); filter: blur(60px);"></div>
<div class="relative max-w-[1200px] mx-auto px-6">
<div class="text-center max-w-2xl mx-auto mb-12">
<p class="eyebrow grad-text mb-4">LA SOLUTION — DICTIA</p>
<h2 id="solution-title" class="text-[clamp(2rem,3vw,2.75rem)] font-black mb-4">
Conforme <span class="grad-text">par design</span>, pas par défaut.
</h2>
<p class="text-lg text-white/70">
DictIA reproduit la précision des outils cloud — WhisperX Large-v3 + Mistral 7B — mais avec une architecture où vos données ne quittent jamais vos murs ou nos serveurs OVH Beauharnois.
</p>
</div>
{# 3 solution pillars — dark cards with grad-bg icon corners #}
<div class="grid md:grid-cols-3 gap-6">
{% for pillar in [
('100&nbsp;% local', 'Vos données ne sortent jamais de vos murs. Inférence GPU sur place ou VPS Québec OVH Beauharnois — vous gardez le contrôle, l\'audit, et les clés.'),
('Conforme Loi&nbsp;25', 'Audit trail intégré (qui a écouté quoi, quand). Déclaration CAI prête. Consentement explicite tracé pour chaque enregistrement. Code source AGPL v3 — transparence vérifiable.'),
('Précision FR-CA', 'WhisperX Large-v3 fine-tuné français québécois. Diarisation pyannote 8 locuteurs. Résumés Mistral 7B local — aucune connexion OpenAI/Google/Microsoft.')
] %}
<article class="bg-white/[0.05] backdrop-blur-sm p-6 rounded border border-white/[0.08]">
<h3 class="text-lg font-bold mb-2 text-white">{{ pillar[0] | safe }}</h3>
<p class="text-sm text-white/70 leading-relaxed">{{ pillar[1] | safe }}</p>
</article>
{% endfor %}
</div>
</div>
</section>
{# ===== PIPELINE — Comment ça marche : 4 étapes ===== #}
{# Source canonique : InnovA-AI/Website-Sanity/components/sections/dictai-pipeline.tsx
Animation traduite : Framer Motion auto-advance + sweep ring → Alpine.js setInterval + CSS keyframes #}
<style>
/* Sweep ring on the active pipeline node — restarts via :key (DOM swap) */
@keyframes pipeline-sweep {
from { stroke-dashoffset: 257.6; }
to { stroke-dashoffset: 0; }
}
.pipeline-sweep-ring {
stroke-dasharray: 257.6; /* 2π × 41 */
animation: pipeline-sweep 2400ms linear forwards;
}
/* Underline sweep on the description card — restart on Alpine swap */
@keyframes pipeline-underline {
from { transform: scaleX(0); }
to { transform: scaleX(1); }
}
.pipeline-underline {
transform-origin: left;
animation: pipeline-underline 2400ms linear forwards;
}
/* Glowing dot trailing the active step on the track */
.pipeline-dot {
transition: left 450ms cubic-bezier(0.4, 0, 0.2, 1);
}
/* Filled track from start to active step */
.pipeline-track-fill {
transition: transform 450ms cubic-bezier(0.4, 0, 0.2, 1);
transform-origin: left;
}
/* Reduced motion : freeze auto-advance + remove all animations */
@media (prefers-reduced-motion: reduce) {
.pipeline-sweep-ring, .pipeline-underline, .pipeline-dot, .pipeline-track-fill {
animation: none !important;
transition: none !important;
}
}
/* Hide Alpine x-show elements until Alpine hydrates (avoids FOUC flash of all 4 cards) */
[x-cloak] { display: none !important; }
</style>
<section class="bg-white py-20 border-y border-brand-border" aria-labelledby="pipeline-title">
<div class="max-w-[1100px] mx-auto px-6">
<div class="text-center max-w-2xl mx-auto mb-14">
<p class="eyebrow grad-text mb-4">COMMENT&nbsp;ÇA MARCHE</p>
<h2 id="pipeline-title" class="text-[clamp(2rem,3vw,2.75rem)] font-black mb-4 text-brand-navy">
Du fichier au résumé <span class="grad-text">en 4 étapes</span>.
</h2>
<p class="text-lg text-brand-navy/70">
Aucune installation côté utilisateur, aucune conversion préalable. DictIA orchestre l'ensemble du pipeline — du téléversement à l'export — en moins de deux minutes pour une heure d'audio.
</p>
</div>
{# Pipeline track + 4 nodes — Alpine state drives all visuals.
active = 0..3 (current step), prefers-reduced-motion stops the autoplay (handled in x-init). #}
<div
class="relative max-w-4xl mx-auto"
x-data="{
active: 0,
timer: null,
steps: [
{ positionPct: 12.5, fillPct: 0 },
{ positionPct: 37.5, fillPct: 33.33 },
{ positionPct: 62.5, fillPct: 66.66 },
{ positionPct: 87.5, fillPct: 100 }
],
startTimer() {
if (this.timer) clearInterval(this.timer);
if (window.matchMedia('(prefers-reduced-motion: reduce)').matches) return;
this.timer = setInterval(() => { this.active = (this.active + 1) % 4; }, 2400);
},
select(i) { this.active = i; this.startTimer(); }
}"
x-init="startTimer()"
>
{# Background + filled track (top: 44px = node center 88px / 2) #}
<div class="absolute h-px bg-brand-border" style="top: 44px; left: 12.5%; right: 12.5%;" aria-hidden="true"></div>
<div
class="pipeline-track-fill absolute h-[2px]"
style="top: 43px; left: 12.5%; width: 75%; background: linear-gradient(90deg, #0062ff 0%, #00bdd8 100%);"
:style="`transform: scaleX(${steps[active].fillPct / 100})`"
aria-hidden="true"
></div>
{# Moving glowing dot — left transitions via CSS #}
<div
class="pipeline-dot absolute w-3.5 h-3.5 rounded-full bg-white pointer-events-none z-10"
style="top: 44px; transform: translate(-50%, -50%); box-shadow: 0 0 18px rgba(0,189,216,0.55), 0 0 36px rgba(0,98,255,0.35);"
:style="`left: ${steps[active].positionPct}%`"
aria-hidden="true"
></div>
{# Nodes grid — 4 cols #}
<div class="grid grid-cols-4 gap-2">
{# Each step rendered statically; active state computed via :class. #}
{% set steps = [
('Uploader', 'Audio ou vidéo', '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="w-7 h-7" aria-hidden="true"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="17 8 12 3 7 8"/><line x1="12" y1="3" x2="12" y2="15"/></svg>',
"Glissez n'importe quel format — MP3, WAV, MP4, MKV. Aucune conversion nécessaire. DictIA accepte tout sans préparation."),
('GPU transcrit', 'WhisperX Large-v3', '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="w-7 h-7" aria-hidden="true"><rect x="4" y="4" width="16" height="16" rx="2"/><rect x="9" y="9" width="6" height="6"/><path d="M9 1v3M15 1v3M9 20v3M15 20v3M20 9h3M20 14h3M1 9h3M1 14h3"/></svg>',
"Votre GPU traite le fichier 60× plus vite qu'un humain. 1&nbsp;heure d'audio → 2&nbsp;minutes. Précision 95&nbsp;%+ en français canadien. 100&nbsp;% en local — zéro cloud étranger."),
('IA structure', 'Mistral 7B / Nemo 12B', '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="w-7 h-7" aria-hidden="true"><path d="M9.5 2A2.5 2.5 0 0 1 12 4.5v15a2.5 2.5 0 0 1-4.96.44 2.5 2.5 0 0 1-2.96-3.08 3 3 0 0 1-.34-5.58 2.5 2.5 0 0 1 1.32-4.24 2.5 2.5 0 0 1 1.98-3A2.5 2.5 0 0 1 9.5 2z"/><path d="M14.5 2A2.5 2.5 0 0 0 12 4.5v15a2.5 2.5 0 0 0 4.96.44 2.5 2.5 0 0 0 2.96-3.08 3 3 0 0 0 .34-5.58 2.5 2.5 0 0 0-1.32-4.24 2.5 2.5 0 0 0-1.98-3A2.5 2.5 0 0 0 14.5 2z"/></svg>',
"L'IA identifie automatiquement chaque locuteur, génère un résumé structuré, extrait les points d'action et répond à vos questions sur le contenu transcrit."),
('Exporter', 'Dans votre écosystème', '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="w-7 h-7" aria-hidden="true"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="7 10 12 15 17 10"/><line x1="12" y1="15" x2="12" y2="3"/></svg>',
"DOCX, SRT, VTT, JSON, Obsidian, Logseq. Connectez avec n8n, Zapier ou Make pour automatiser vos workflows — zéro copier-coller.")
] %}
{% for label, sublabel, icon, desc in steps %}
<button
type="button"
@click="select({{ loop.index0 }})"
class="group flex flex-col items-center gap-4 cursor-pointer select-none focus-visible:outline-2 focus-visible:outline-brand-b1 focus-visible:outline-offset-4 rounded-none p-2"
:aria-current="active === {{ loop.index0 }} ? 'step' : 'false'"
aria-label="Étape {{ loop.index }} sur 4 : {{ label }} — {{ sublabel }}"
>
{# Circle node — visual state driven by :class (active / completed / pending) #}
<span
class="relative w-[88px] h-[88px] rounded-full border-2 flex items-center justify-center transition-all duration-300"
:class="{
'border-brand-b1 bg-brand-b1/10 scale-105 shadow-[0_0_28px_rgba(0,98,255,0.35)]': active === {{ loop.index0 }},
'border-brand-b3/60 bg-brand-b3/10': active > {{ loop.index0 }},
'border-brand-border bg-white': active < {{ loop.index0 }}
}"
aria-hidden="true"
>
<span
class="transition-opacity duration-300"
:class="active >= {{ loop.index0 }} ? 'opacity-100 text-brand-b1' : 'opacity-30 text-brand-navy/30'"
>{{ icon | safe }}</span>
{# Step badge — top-right corner with index #}
<span
class="absolute -top-1.5 -right-1.5 w-6 h-6 rounded-full flex items-center justify-center text-[11px] font-bold transition-colors duration-300"
:class="active >= {{ loop.index0 }} ? 'bg-brand-b1 text-white' : 'bg-brand-border text-brand-navy/40'"
>{{ loop.index }}</span>
{# Sweep progress ring — only visible on active step. Re-keyed via :key when active changes. #}
<template x-if="active === {{ loop.index0 }}">
<svg
:key="active"
class="absolute inset-0 w-full h-full -rotate-90 pointer-events-none"
viewBox="0 0 88 88"
aria-hidden="true"
>
<circle class="pipeline-sweep-ring" cx="44" cy="44" r="41" fill="none" stroke="#0062ff" stroke-width="2" stroke-linecap="round"></circle>
</svg>
</template>
</span>
{# Label + sublabel — opacity dimmed on pending steps #}
<span
class="text-center px-1 transition-opacity duration-300 block"
:class="active >= {{ loop.index0 }} ? 'opacity-100' : 'opacity-40'"
>
<span class="block font-bold text-sm leading-tight mb-0.5 text-brand-navy">{{ label }}</span>
<span class="block text-xs text-brand-navy/70 leading-tight">{{ sublabel }}</span>
</span>
</button>
{% endfor %}
</div>
{# Step description card — swaps with x-show + x-transition. Underline sweep restarts via :key on active. #}
<div class="mt-12 max-w-2xl mx-auto min-h-[110px] flex items-center justify-center">
{% for label, sublabel, icon, desc in steps %}
<div
x-show="active === {{ loop.index0 }}"
x-transition:enter="transition ease-out duration-300"
x-transition:enter-start="opacity-0 translate-y-2"
x-transition:enter-end="opacity-100 translate-y-0"
x-transition:leave="transition ease-in duration-150"
x-transition:leave-start="opacity-100"
x-transition:leave-end="opacity-0"
class="relative w-full bg-brand-bg border border-brand-border px-7 py-6 text-center rounded overflow-hidden"
x-cloak
>
<p class="text-sm text-brand-navy/80 leading-relaxed">{{ desc | safe }}</p>
<span
:key="active"
class="pipeline-underline absolute bottom-0 left-0 h-[2px] w-full"
style="background: linear-gradient(90deg, #0062ff, #00bdd8);"
aria-hidden="true"
></span>
</div>
{% endfor %}
</div>
{# Progress dots (mobile-friendly + click target redundancy) #}
<div class="flex justify-center gap-2 mt-8" role="tablist" aria-label="Sélectionner une étape">
{% for label, sublabel, icon, desc in steps %}
<button
type="button"
role="tab"
@click="select({{ loop.index0 }})"
class="h-1 rounded-full transition-all duration-300 focus-visible:outline-2 focus-visible:outline-brand-b1 focus-visible:outline-offset-2"
:class="{
'w-8 bg-brand-b1': active === {{ loop.index0 }},
'w-8 bg-brand-b3/60': active > {{ loop.index0 }},
'w-2 bg-brand-border': active < {{ loop.index0 }}
}"
:aria-selected="active === {{ loop.index0 }} ? 'true' : 'false'"
aria-label="Aller à l'étape {{ loop.index }} : {{ label }}"
></button>
{% endfor %}
</div>
</div>
</div>
</section>
{# ===== BENTO FEATURES ===== #}
<section class="bg-white py-20" aria-labelledby="bento-title">
<div class="max-w-[1060px] mx-auto px-6">
<div class="text-center max-w-2xl mx-auto mb-12">
<p class="eyebrow grad-text mb-4">FONCTIONNALITÉS</p>
<h2 id="bento-title" class="text-[clamp(2rem,3vw,2.75rem)] font-black text-brand-navy">
Tout ce dont vous avez besoin, <span class="grad-text">rien que vous n'ayez besoin</span>.
</h2>
</div>
{# NOTE: bento card content is duplicated between landing.html and fonctionnalites.html.
When editing, sync both files. Future refactor: extract to _partials/_bento_features.html.
Icon SVGs (heroicons-style outline) are inlined directly because the macro renders `icon | safe`. #}
{% from 'macros/bento.html' import bento_card %}
{%- set icon_microphone = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="w-7 h-7" aria-hidden="true"><rect x="9" y="2" width="6" height="12" rx="3"/><path d="M19 10v2a7 7 0 0 1-14 0v-2"/><line x1="12" y1="19" x2="12" y2="22"/></svg>' -%}
{%- set icon_users = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="w-7 h-7" aria-hidden="true"><path d="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"/><circle cx="9" cy="7" r="4"/><path d="M23 21v-2a4 4 0 0 0-3-3.87"/><path d="M16 3.13a4 4 0 0 1 0 7.75"/></svg>' -%}
{%- set icon_document = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="w-7 h-7" aria-hidden="true"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/><polyline points="14 2 14 8 20 8"/><line x1="9" y1="13" x2="15" y2="13"/><line x1="9" y1="17" x2="15" y2="17"/></svg>' -%}
{%- set icon_chat = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="w-7 h-7" aria-hidden="true"><path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"/></svg>' -%}
{%- set icon_export = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="w-7 h-7" aria-hidden="true"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="7 10 12 15 17 10"/><line x1="12" y1="15" x2="12" y2="3"/></svg>' -%}
{%- set icon_plug = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="w-7 h-7" aria-hidden="true"><path d="M9 2v6"/><path d="M15 2v6"/><path d="M5 8h14v4a5 5 0 0 1-5 5h-4a5 5 0 0 1-5-5z"/><path d="M12 17v5"/></svg>' -%}
<div class="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 gap-[1.5px] bg-brand-border rounded overflow-hidden">
{{ bento_card('01', 'Transcription WhisperX', 'Large-v3 fine-tuné FR-CA. Précision 95&nbsp;%+ sur réunions, dictées, audiences (méthodologie disponible sur demande).', icon_microphone) }}
{{ bento_card('02', 'Diarisation 8 locuteurs', 'pyannote sépare automatiquement les intervenants. Identification par embeddings vocaux.', icon_users) }}
{{ bento_card('03', 'Résumés Mistral 7B', 'IA locale génère résumés, points d\'action et procès-verbaux. Aucune connexion cloud.', icon_document) }}
{{ bento_card('04', 'Q&amp;R sur enregistrement', 'Posez des questions à vos réunions. RAG local sur embeddings sentence-transformers.', icon_chat) }}
{{ bento_card('05', 'Exports multiples', 'DOCX, PDF, SRT, VTT, TXT, JSON, MD. Formats avocat, notaire, CPA.', icon_export) }}
{{ bento_card('06', 'Intégrations', 'Word, Outlook, Teams, Notion, Obsidian, Zapier, Make, n8n.', icon_plug) }}
</div>
</div>
</section>
{# ===== HUB — Réseau d'intégrations ===== #}
{# Source canonique : InnovA-AI/Website-Sanity/components/sections/dictai-hub.tsx
Animation : SVG pur avec <animateMotion> sur bezier paths — aucune lib JS, aucune config.
Particules cyan circulent en continu de DictIA → Hubs → Outils. #}
<style>
/* DictIA central node — pulsing rings (decorative, native CSS) */
@keyframes hub-ring-pulse {
0% { transform: scale(1); opacity: 0.55; }
70% { transform: scale(2.6); opacity: 0; }
100% { transform: scale(2.6); opacity: 0; }
}
.hub-ring { animation: hub-ring-pulse 3s ease-out infinite; }
.hub-ring-2 { animation-delay: 1s; }
.hub-ring-3 { animation-delay: 2s; }
/* DictIA core breathing glow */
@keyframes hub-core-breathe {
0%, 100% { box-shadow: 0 0 26px rgba(0,189,216,0.55), 0 0 56px rgba(0,189,216,0.18); }
50% { box-shadow: 0 0 38px rgba(0,189,216,0.75), 0 0 72px rgba(0,189,216,0.28); }
}
.hub-core { animation: hub-core-breathe 3.5s ease-in-out infinite; }
/* Reduced motion : freeze everything */
@media (prefers-reduced-motion: reduce) {
.hub-ring, .hub-core { animation: none !important; }
/* Disable SVG animateMotion via display:none on the animateMotion elements (browser respects this). */
.hub-network-svg animateMotion { display: none !important; }
}
</style>
<section class="bg-brand-navy text-white py-20 overflow-hidden relative" aria-labelledby="hub-title">
{# Decorative cosmic orb — cyan, mid-section #}
<div class="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 w-[700px] h-[700px] rounded-full pointer-events-none" aria-hidden="true"
style="background: radial-gradient(circle, rgba(0,189,216,0.10) 0%, transparent 60%); filter: blur(60px);"></div>
<div class="relative max-w-[1200px] mx-auto px-6">
<div class="text-center max-w-2xl mx-auto mb-12">
<p class="eyebrow grad-text mb-4">INTÉGRATIONS — RÉSEAU OUVERT</p>
<h2 id="hub-title" class="text-[clamp(2rem,3vw,2.75rem)] font-black mb-4">
DictIA <span class="grad-text">se connecte à tout</span>.
</h2>
<p class="text-lg text-white/70">
Transcriptions et résumés acheminés automatiquement vers vos outils de travail. Trois familles d'intégrations couvrent l'essentiel des flux documentaires, communication et automatisation.
</p>
</div>
{# Network diagram — SVG with native <animateMotion> for particle flow.
Layout : DictIA center-top, 3 hubs (Documents | Communication | Automatisation), 9 tools below. #}
<div class="relative max-w-4xl mx-auto">
<svg
viewBox="0 0 900 460"
preserveAspectRatio="xMidYMid meet"
class="hub-network-svg w-full h-auto"
role="img"
aria-labelledby="hub-svg-title hub-svg-desc"
>
<title id="hub-svg-title">Diagramme du réseau d'intégrations DictIA</title>
<desc id="hub-svg-desc">DictIA au centre, connecté à trois familles : Documents (Word, Google Docs, Obsidian), Communication (Outlook, Teams, Notion) et Automatisation (Zapier, Make, n8n).</desc>
<defs>
{# Bezier path definitions — DictIA top → 3 hubs (mid) #}
<path id="hub-path-docs" d="M450,54 C450,127 168,127 168,200" />
<path id="hub-path-comm" d="M450,54 C450,127 450,127 450,200" />
<path id="hub-path-auto" d="M450,54 C450,127 732,127 732,200" />
{# Bezier paths — Hub → Tool #}
{# Documents hub (168, 200) → Word(62,390), Google(175,390), Obsidian(282,390) #}
<path id="hub-path-word" d="M168,216 C168,303 62,303 62,390" />
<path id="hub-path-google" d="M168,216 C168,303 175,303 175,390" />
<path id="hub-path-obsidian" d="M168,216 C168,303 282,303 282,390" />
{# Communication hub (450, 200) → Outlook(358,390), Teams(450,390), Notion(542,390) #}
<path id="hub-path-outlook" d="M450,216 C450,303 358,303 358,390" />
<path id="hub-path-teams" d="M450,216 C450,303 450,303 450,390" />
<path id="hub-path-notion" d="M450,216 C450,303 542,303 542,390" />
{# Automatisation hub (732, 200) → Zapier(618,390), Make(722,390), n8n(828,390) #}
<path id="hub-path-zapier" d="M732,216 C732,303 618,303 618,390" />
<path id="hub-path-make" d="M732,216 C732,303 722,303 722,390" />
<path id="hub-path-n8n" d="M732,216 C732,303 828,303 828,390" />
</defs>
{# Render bezier connections (visible strokes) — DictIA → Hubs (thick), Hub → Tools (thin) #}
{# DictIA → Hubs #}
<use href="#hub-path-docs" fill="none" stroke="#0062ff" stroke-width="1.5" opacity="0.55" />
<use href="#hub-path-comm" fill="none" stroke="#00bdd8" stroke-width="1.5" opacity="0.55" />
<use href="#hub-path-auto" fill="none" stroke="#8b5cf6" stroke-width="1.5" opacity="0.55" />
{# Hub → Tool (lighter) #}
<use href="#hub-path-word" fill="none" stroke="#0062ff" stroke-width="1" opacity="0.30" />
<use href="#hub-path-google" fill="none" stroke="#0062ff" stroke-width="1" opacity="0.30" />
<use href="#hub-path-obsidian" fill="none" stroke="#0062ff" stroke-width="1" opacity="0.30" />
<use href="#hub-path-outlook" fill="none" stroke="#00bdd8" stroke-width="1" opacity="0.30" />
<use href="#hub-path-teams" fill="none" stroke="#00bdd8" stroke-width="1" opacity="0.30" />
<use href="#hub-path-notion" fill="none" stroke="#00bdd8" stroke-width="1" opacity="0.30" />
<use href="#hub-path-zapier" fill="none" stroke="#8b5cf6" stroke-width="1" opacity="0.30" />
<use href="#hub-path-make" fill="none" stroke="#8b5cf6" stroke-width="1" opacity="0.30" />
<use href="#hub-path-n8n" fill="none" stroke="#8b5cf6" stroke-width="1" opacity="0.30" />
{# Animated particles — DictIA → Hubs (bigger, dual particles) #}
{% for hub in [
('docs', '#0062ff', '0s', '2.4s'),
('comm', '#00bdd8', '0.8s', '2.4s'),
('auto', '#8b5cf6', '1.6s', '2.4s')
] %}
<circle r="3.2" fill="{{ hub[1] }}" opacity="0.95">
<animateMotion dur="{{ hub[3] }}" repeatCount="indefinite" begin="{{ hub[2] }}">
<mpath href="#hub-path-{{ hub[0] }}" />
</animateMotion>
</circle>
<circle r="1.8" fill="{{ hub[1] }}" opacity="0.6">
<animateMotion dur="{{ hub[3] }}" repeatCount="indefinite" begin="{{ hub[2] }}s + 1.2s">
<mpath href="#hub-path-{{ hub[0] }}" />
</animateMotion>
</circle>
{% endfor %}
{# Animated particles — Hub → Tool (smaller, fast) #}
{% for tool in [
('word', '#0062ff', '0s'),
('google', '#0062ff', '0.4s'),
('obsidian', '#0062ff', '0.8s'),
('outlook', '#00bdd8', '0.2s'),
('teams', '#00bdd8', '0.6s'),
('notion', '#00bdd8', '1.0s'),
('zapier', '#8b5cf6', '0.1s'),
('make', '#8b5cf6', '0.5s'),
('n8n', '#8b5cf6', '0.9s')
] %}
<circle r="2.2" fill="{{ tool[1] }}" opacity="0.75">
<animateMotion dur="2s" repeatCount="indefinite" begin="{{ tool[2] }}">
<mpath href="#hub-path-{{ tool[0] }}" />
</animateMotion>
</circle>
{% endfor %}
</svg>
{# DictIA central node — absolute positioned over the SVG (z-10) #}
<div class="absolute pointer-events-none" style="left: 50%; top: 11.7%; transform: translate(-50%, -50%); z-index: 10;" aria-hidden="true">
<div class="relative w-[68px] h-[68px]">
{# Pulsing rings #}
<span class="hub-ring absolute inset-0 rounded-full border-2 border-brand-b2/40"></span>
<span class="hub-ring hub-ring-2 absolute inset-0 rounded-full border-2 border-brand-b2/40"></span>
<span class="hub-ring hub-ring-3 absolute inset-0 rounded-full border-2 border-brand-b2/40"></span>
{# Core orb #}
<span class="hub-core absolute inset-0 rounded-full grad-bg flex items-center justify-center">
<span class="font-black text-white text-[13px] tracking-tight">DictIA</span>
</span>
</div>
</div>
{# Hub labels overlay — positioned to match SVG hub coords (200/460 = 43.5% top, 168/900=18.7% / 450/900=50% / 732/900=81.3% left) #}
{% set hub_data = [
('Documents', 'Word · Google Docs · Obsidian', '18.7%', 'rgba(0,98,255,0.10)', 'rgba(0,98,255,0.30)', 'text-blue-300'),
('Communication', 'Outlook · Teams · Notion', '50%', 'rgba(0,189,216,0.10)', 'rgba(0,189,216,0.30)', 'text-cyan-300'),
('Automatisation', 'Zapier · Make · n8n', '81.3%', 'rgba(139,92,246,0.10)', 'rgba(139,92,246,0.30)', 'text-purple-300')
] %}
{% for name, sub, leftpos, bgcol, brdcol, txtcol in hub_data %}
<div
class="absolute pointer-events-none px-3 py-2 rounded-full backdrop-blur-sm whitespace-nowrap"
style="left: {{ leftpos }}; top: 43.5%; transform: translate(-50%, -50%); background: {{ bgcol }}; border: 1px solid {{ brdcol }};"
aria-hidden="true"
>
<p class="text-[11px] font-bold text-white leading-none">{{ name }}</p>
<p class="text-[9px] {{ txtcol }} leading-none mt-0.5 opacity-80">{{ sub }}</p>
</div>
{% endfor %}
</div>
{# Tool list — text fallback below the diagram (covers screen readers + reduces visual noise on mobile) #}
<div class="mt-12 grid sm:grid-cols-3 gap-6 max-w-3xl mx-auto" role="list" aria-label="Outils intégrés à DictIA">
{% for col_label, tools, accent in [
('Documents', [('Word', 'Export .docx instantané'), ('Google Docs', 'Sync Google Workspace'), ('Obsidian', 'Notes Markdown locales')], 'text-brand-b1'),
('Communication', [('Outlook', 'Envoi email automatique'), ('Teams', 'Canal Teams dédié'), ('Notion', 'Page Notion structurée')], 'text-brand-b2'),
('Automatisation', [('Zapier', '5&nbsp;000+ apps connectées'), ('Make', 'Scénarios visuels no-code'), ('n8n', 'Workflows open-source')], 'text-purple-400')
] %}
<div role="listitem" class="bg-white/[0.03] border border-white/[0.06] p-5 rounded">
<p class="eyebrow {{ accent }} mb-3">{{ col_label | upper }}</p>
<ul class="space-y-2">
{% for tool_name, tool_desc in tools %}
<li class="text-sm">
<span class="font-semibold text-white">{{ tool_name }}</span>
<span class="text-white/70"> — {{ tool_desc | safe }}</span>
</li>
{% endfor %}
</ul>
</div>
{% endfor %}
</div>
<p class="text-center text-sm text-white/70 mt-8 max-w-2xl mx-auto">
Architecture ouverte. Tout export est aussi disponible en DOCX, SRT, VTT, JSON, TXT et MD — formats standards consommables par n'importe quel logiciel métier (gestion de dossiers, paie, CRM).
</p>
</div>
</section>
{# ===== PRICING ===== #}
<section class="bg-brand-bg py-20" id="tarifs" aria-labelledby="pricing-title">
<div class="max-w-[1200px] mx-auto px-6">
<div class="text-center max-w-2xl mx-auto mb-12">
<p class="eyebrow grad-text mb-4">TARIFS</p>
<h2 id="pricing-title" class="text-[clamp(2rem,3vw,2.75rem)] font-black mb-4 text-brand-navy">
Choisissez votre formule.
</h2>
<p class="text-lg text-brand-navy/70">
Tous les forfaits incluent WhisperX Large-v3, volume illimité et zéro frais par utilisateur. Prix en CAD, taxes en sus (TPS&nbsp;5&nbsp;% + TVQ&nbsp;9,975&nbsp;%).
</p>
</div>
{% include 'marketing/_partials/_pricing_tiers.html' %}
{# ROI CALCULATOR — Alpine.js, hypotheses transparentes pour LPC art. 219 hygiene #}
<div x-data="roiCalculator()" class="mt-16 max-w-3xl mx-auto bg-white p-8 rounded border border-brand-border" aria-labelledby="roi-title">
<p class="eyebrow text-center grad-text mb-2">CALCULATEUR ROI</p>
<h3 id="roi-title" class="text-2xl font-black text-center mb-6 text-brand-navy">Combien DictIA peut vous faire économiser&nbsp;?</h3>
<div class="grid sm:grid-cols-3 gap-4 mb-6">
<label class="flex flex-col">
<span class="text-xs font-semibold mb-1 text-brand-navy">Utilisateurs</span>
<input type="range" x-model.number="users" min="1" max="25" step="1" class="accent-brand-b1" aria-label="Nombre d'utilisateurs">
<span class="text-sm text-brand-navy/70" x-text="users + ' utilisateur' + (users > 1 ? 's' : '')"></span>
</label>
<label class="flex flex-col">
<span class="text-xs font-semibold mb-1 text-brand-navy">Heures audio / jour</span>
<input type="range" x-model.number="hours" min="0.5" max="4" step="0.5" class="accent-brand-b1" aria-label="Heures d'audio par jour">
<span class="text-sm text-brand-navy/70" x-text="hours + ' h/jour'"></span>
</label>
<label class="flex flex-col">
<span class="text-xs font-semibold mb-1 text-brand-navy">Tarif horaire ($)</span>
<input type="range" x-model.number="rate" min="50" max="500" step="25" class="accent-brand-b1" aria-label="Tarif horaire en dollars">
<span class="text-sm text-brand-navy/70" x-text="rate + ' $/h'"></span>
</label>
</div>
<div class="text-center pt-6 border-t border-brand-border">
<p class="text-sm text-brand-navy/70 mb-2">Économies estimées par an</p>
<p class="text-5xl font-black grad-text" aria-live="polite" aria-atomic="true"
x-text="savings.toLocaleString('fr-CA') + ' $'"></p>
<p class="text-sm text-brand-navy/70 mt-2"
x-text="payback === null ? 'Payable dès la première année' : (payback < 1 ? 'Payback : moins d\'un mois' : 'Payback : ' + Math.round(payback) + ' mois')"></p>
</div>
<p class="text-xs text-brand-navy/70 mt-6 text-center">
Hypothèses&nbsp;: 80&nbsp;% du temps de transcription manuelle économisé, 220 jours ouvrables/an, comparé à DictIA 16 (5&nbsp;750&nbsp;$ + 201&nbsp;$/mois). Estimation à titre indicatif.
</p>
</div>
</div>
</section>
{# ===== COMPARATIF ===== #}
<section class="bg-white py-20" aria-labelledby="comparatif-title">
<div class="max-w-[1200px] mx-auto px-6">
<div class="text-center max-w-3xl mx-auto mb-12">
<p class="eyebrow grad-text mb-4">COMPARATIF</p>
<h2 id="comparatif-title" class="text-[clamp(2rem,3vw,2.75rem)] font-black mb-4 text-brand-navy">
DictIA face aux solutions cloud américaines.
</h2>
<p class="text-lg text-brand-navy/70">
Comparaison factuelle au 2026-04-27. Sources&nbsp;: politiques de confidentialité publiques + grilles tarifaires officielles. Détails sur demande&nbsp;: <a href="mailto:info@dictia.ca" class="grad-text font-semibold hover:underline">info@dictia.ca</a>.
</p>
</div>
<div class="overflow-x-auto rounded border border-brand-border">
<table class="w-full min-w-[720px] text-sm">
<caption class="sr-only">Comparaison DictIA, Microsoft Teams Premium, Otter.ai Business, Whisper local sur 6 critères</caption>
<thead class="bg-brand-bg">
<tr>
<th scope="col" class="text-left p-4 font-bold text-brand-navy">Critère</th>
<th scope="col" class="p-4 font-bold text-brand-navy">DictIA</th>
<th scope="col" class="p-4 font-bold text-brand-navy/70">MS Teams Premium</th>
<th scope="col" class="p-4 font-bold text-brand-navy/70">Otter.ai Business</th>
<th scope="col" class="p-4 font-bold text-brand-navy/70">Whisper local (DIY)</th>
</tr>
</thead>
{# Status SVGs — check (green), x (red), warning (amber). `aria-label` preserves the meaning for AT users. #}
{%- set svg_check = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" class="w-4 h-4 inline-block flex-shrink-0 text-brand-b3" aria-label="Conforme" role="img"><path d="M5 13l4 4L19 7"/></svg>' -%}
{%- set svg_x = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" class="w-4 h-4 inline-block flex-shrink-0 text-red-500" aria-label="Non conforme" role="img"><path d="M6 18L18 6M6 6l12 12"/></svg>' -%}
{%- set svg_warn = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="w-4 h-4 inline-block flex-shrink-0 text-amber-500" aria-label="Partiel" role="img"><path d="M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z"/><line x1="12" y1="9" x2="12" y2="13"/><line x1="12" y1="17" x2="12.01" y2="17"/></svg>' -%}
<tbody class="divide-y divide-brand-border">
{% for row in [
{
'critere': 'Conforme Loi&nbsp;25 sans transfert hors-Québec',
'dictia': {'status': 'check', 'text': 'Hébergement OVH Beauharnois'},
'teams': {'status': 'x', 'text': 'Soumis Cloud Act (US)'},
'otter': {'status': 'x', 'text': 'Hébergement US'},
'whisper':{'status': 'check', 'text': 'Aucun transfert (local)'}
},
{
'critere': 'Souveraineté hors Cloud Act US',
'dictia': {'status': 'check', 'text': 'Aucune exposition'},
'teams': {'status': 'x', 'text': 'Microsoft = entité US'},
'otter': {'status': 'x', 'text': 'Otter.ai Inc. = US'},
'whisper':{'status': 'check', 'text': 'Local'}
},
{
'critere': 'WhisperX Large-v3 fine-tuné FR-CA',
'dictia': {'status': 'check', 'text': 'FR-CA optimisé'},
'teams': {'status': 'warn', 'text': 'FR générique (FR-FR)'},
'otter': {'status': 'x', 'text': 'Anglais privilégié'},
'whisper':{'status': 'warn', 'text': 'FR générique de base'}
},
{
'critere': 'Diarisation jusqu\'à 8 locuteurs (pyannote)',
'dictia': {'status': 'check', 'text': 'Inclus par défaut'},
'teams': {'status': 'warn', 'text': 'Limité ~6 (Premium)'},
'otter': {'status': 'warn', 'text': 'Variable selon le forfait'},
'whisper':{'status': 'x', 'text': 'Non incluse'}
},
{
'critere': 'Coût mensuel par utilisateur',
'dictia': {'status': None, 'text': '0&nbsp;$ (forfait fixe)'},
'teams': {'status': None, 'text': '~14&nbsp;$ CAD (Premium)'},
'otter': {'status': None, 'text': '~20&nbsp;$ US (Business)'},
'whisper':{'status': None, 'text': '0&nbsp;$ (mais GPU&nbsp;+ DevOps requis)'}
},
{
'critere': 'Audit trail intégré (Loi&nbsp;25 art.&nbsp;3.5)',
'dictia': {'status': 'check', 'text': 'Inclus par défaut'},
'teams': {'status': 'warn', 'text': 'Via M365 Audit séparé'},
'otter': {'status': 'warn', 'text': 'Logs basiques seulement'},
'whisper':{'status': 'x', 'text': 'À développer soi-même'}
}
] %}
{%- set status_svg = {'check': svg_check, 'x': svg_x, 'warn': svg_warn} -%}
<tr class="hover:bg-brand-bg/50 transition-colors">
<th scope="row" class="text-left p-4 font-semibold text-brand-navy/80">{{ row.critere | safe }}</th>
<td class="p-4 text-center font-semibold text-brand-navy">
<span class="inline-flex items-center gap-1.5 px-2 py-1 rounded-none bg-brand-b3/10 text-brand-navy">
{%- if row.dictia.status -%}{{ status_svg[row.dictia.status] | safe }}{%- endif -%}
<span>{{ row.dictia.text | safe }}</span>
</span>
</td>
<td class="p-4 text-center text-brand-navy/70">
<span class="inline-flex items-center gap-1.5">
{%- if row.teams.status -%}{{ status_svg[row.teams.status] | safe }}{%- endif -%}
<span>{{ row.teams.text | safe }}</span>
</span>
</td>
<td class="p-4 text-center text-brand-navy/70">
<span class="inline-flex items-center gap-1.5">
{%- if row.otter.status -%}{{ status_svg[row.otter.status] | safe }}{%- endif -%}
<span>{{ row.otter.text | safe }}</span>
</span>
</td>
<td class="p-4 text-center text-brand-navy/70">
<span class="inline-flex items-center gap-1.5">
{%- if row.whisper.status -%}{{ status_svg[row.whisper.status] | safe }}{%- endif -%}
<span>{{ row.whisper.text | safe }}</span>
</span>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
<p class="text-xs text-brand-navy/70 mt-6 text-center max-w-3xl mx-auto">
Comparatif établi à partir de sources publiques (politiques de confidentialité, grilles tarifaires officielles, documentation produit) au 2026-04-27. Microsoft Teams Premium et Otter.ai sont des marques déposées de leurs propriétaires respectifs. DictIA n'est pas affilié à ces produits.
</p>
</div>
</section>
{# ===== CONFORMITÉ FORTERESSE ===== #}
<section class="bg-brand-navy text-white py-20 overflow-hidden relative" aria-labelledby="conformite-title">
{# Subtle decorative orb — green this time, like the Solution section #}
<div class="absolute top-1/3 left-1/4 w-[500px] h-[500px] rounded-full pointer-events-none" aria-hidden="true"
style="background: radial-gradient(circle, rgba(0,200,150,0.07) 0%, transparent 60%); filter: blur(60px);"></div>
<div class="relative max-w-[1200px] mx-auto px-6">
<div class="text-center max-w-2xl mx-auto mb-12">
<p class="eyebrow grad-text mb-4">CONFORMITÉ — FORTERESSE QUÉBÉCOISE</p>
<h2 id="conformite-title" class="text-[clamp(2rem,3vw,2.75rem)] font-black mb-4">
Architecture <span class="grad-text">conçue avec</span> les exigences professionnelles québécoises.
</h2>
<p class="text-lg text-white/70">
DictIA mappe son architecture aux cadres réglementaires applicables au secteur public et aux ordres professionnels du Québec. Détails techniques (EFVP, audit trail, déclaration CAI) disponibles sur demande&nbsp;: <a href="mailto:info@dictia.ca" class="grad-text font-semibold hover:underline">info@dictia.ca</a>.
</p>
</div>
{# 4 conformity pillars — dark cards with grad-bg icon corners (matches Solution pillars style).
Icons (heroicons-style outline): map-pin (Québec), scale (Loi 25), building-library (LGGRI), code-bracket (AGPL). #}
{%- set svg_pin = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="w-7 h-7" aria-hidden="true"><path d="M21 10c0 7-9 13-9 13s-9-6-9-13a9 9 0 0 1 18 0z"/><circle cx="12" cy="10" r="3"/></svg>' -%}
{%- set svg_scale = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="w-7 h-7" aria-hidden="true"><path d="M12 3v18"/><path d="M5 7h14"/><path d="M5 7l-2 6a4 4 0 0 0 8 0L9 7"/><path d="M19 7l2 6a4 4 0 0 1-8 0l2-6"/><path d="M8 21h8"/></svg>' -%}
{%- set svg_building = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="w-7 h-7" aria-hidden="true"><path d="M3 21h18"/><path d="M5 21V8l7-4 7 4v13"/><path d="M9 21v-6h6v6"/><path d="M9 11h.01"/><path d="M15 11h.01"/></svg>' -%}
{%- set svg_code = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="w-7 h-7" aria-hidden="true"><polyline points="16 18 22 12 16 6"/><polyline points="8 6 2 12 8 18"/><line x1="14" y1="4" x2="10" y2="20"/></svg>' -%}
<div class="grid md:grid-cols-2 lg:grid-cols-4 gap-6">
{% for card in [
{
'icon': svg_pin,
'title': 'Hébergement OVH Beauharnois',
'desc': 'Centre de données opéré par OVHcloud Canada en territoire québécois. Conformité documentée selon les services (ISO&nbsp;27001, SOC&nbsp;2 selon le périmètre). Détails sur demande.'
},
{
'icon': svg_scale,
'title': 'Mappé Loi&nbsp;25 (LPRPSP)',
'desc': 'Audit trail art.&nbsp;3.5, EFVP préparée art.&nbsp;3.3, registre des consentements art.&nbsp;14. Modèles de déclaration CAI fournis.'
},
{
'icon': svg_building,
'title': 'Compatible Cadre IA secteur public',
'desc': 'DictIA est conçu pour s\'inscrire dans le cadre de gestion des systèmes d\'IA du secteur public québécois (LGGRI). Documentation détaillée sur demande.'
},
{
'icon': svg_code,
'title': 'Code source AGPL&nbsp;v3 vérifiable',
'desc': 'Architecture entièrement auditable sur <a href="https://gitea.innova-ai.ca/Innova-AI/dictia-public" target="_blank" rel="noopener" class="underline hover:text-white">Gitea public</a>. Aucune boîte noire. Vos auditeurs peuvent examiner chaque ligne.'
}
] %}
<article class="bg-white/[0.05] backdrop-blur-sm p-6 rounded border border-white/[0.08]">
<div class="text-brand-b1 mb-4" aria-hidden="true">{{ card.icon | safe }}</div>
<h3 class="text-lg font-bold mb-2 text-white">{{ card.title | safe }}</h3>
<p class="text-sm text-white/80 leading-relaxed">{{ card.desc | safe }}</p>
</article>
{% endfor %}
</div>
<div class="text-center mt-10">
<p class="text-sm text-white/70">
Lancement prévu&nbsp;: <strong class="text-white">printemps 2026</strong>. Pré-inscription ouverte.
</p>
</div>
</div>
</section>
{# ===== TÉMOIGNAGES (placeholder pré-lancement) ===== #}
<section class="bg-brand-bg py-20" aria-labelledby="testimonials-title">
<div class="max-w-[1200px] mx-auto px-6">
<div class="text-center max-w-2xl mx-auto mb-12">
<p class="eyebrow grad-text mb-4">TÉMOIGNAGES</p>
<h2 id="testimonials-title" class="text-[clamp(2rem,3vw,2.75rem)] font-black mb-4 text-brand-navy">
Premiers cabinets pilotes interviewés au printemps&nbsp;2026.
</h2>
<p class="text-lg text-brand-navy/70">
Trois pilotes confidentiels en cours&nbsp;: un cabinet juridique, un cabinet CPA, une municipalité. Témoignages publiés ici dès l'aboutissement des entrevues, accompagnés d'une métrique vérifiable.
</p>
</div>
<div class="grid md:grid-cols-3 gap-6">
{% for t in testimonials %}
<article class="bg-white p-6 rounded border border-brand-border flex flex-col items-center text-center"
aria-label="Témoignage {{ t.placeholder_label }} à venir">
<div class="w-16 h-16 rounded-full grad-bg flex items-center justify-center mb-4 shadow-cta text-white" aria-hidden="true">
{%- if t.persona == 'avocat' -%}
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="w-7 h-7"><path d="M12 3v18"/><path d="M5 7h14"/><path d="M5 7l-2 6a4 4 0 0 0 8 0L9 7"/><path d="M19 7l2 6a4 4 0 0 1-8 0l2-6"/><path d="M8 21h8"/></svg>
{%- elif t.persona == 'cpa' -%}
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="w-7 h-7"><line x1="18" y1="20" x2="18" y2="10"/><line x1="12" y1="20" x2="12" y2="4"/><line x1="6" y1="20" x2="6" y2="14"/><line x1="3" y1="20" x2="21" y2="20"/></svg>
{%- elif t.persona == 'municipal' -%}
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="w-7 h-7"><path d="M3 21h18"/><path d="M5 21V8l7-4 7 4v13"/><path d="M9 21v-6h6v6"/><path d="M9 11h.01"/><path d="M15 11h.01"/></svg>
{%- endif -%}
</div>
<p class="text-sm font-bold text-brand-navy mb-1">{{ t.placeholder_label | safe }}</p>
<p class="text-xs text-brand-navy/70 mb-4">Témoignage à venir &middot; {{ t.expected | safe }}</p>
<p class="text-sm text-brand-navy/70 italic">
« Citation et métrique publiées après validation par le pilote. »
</p>
</article>
{% endfor %}
</div>
</div>
</section>
{# ===== FAQ ===== #}
<section class="bg-white py-20" aria-labelledby="faq-title">
<div class="max-w-[820px] mx-auto px-6">
<div class="text-center mb-12">
<p class="eyebrow grad-text mb-4">FAQ</p>
<h2 id="faq-title" class="text-[clamp(2rem,3vw,2.75rem)] font-black mb-4 text-brand-navy">
Vos questions les plus fréquentes.
</h2>
<p class="text-lg text-brand-navy/70">
Une question qui n'est pas couverte ici&nbsp;? Écrivez-nous&nbsp;:
<a href="mailto:info@dictia.ca" class="grad-text font-semibold hover:underline">info@dictia.ca</a>.
</p>
</div>
<div class="divide-y divide-brand-border border-y border-brand-border" role="list">
{% for item in faq %}
<div x-data="{ open: false }" class="py-2" role="listitem">
<h3>
<button type="button"
class="w-full flex items-center justify-between gap-4 py-4 text-left hover:bg-brand-bg/50 transition-colors rounded-none px-2 focus-visible:outline-2 focus-visible:outline-brand-b1 focus-visible:outline-offset-2"
@click="open = !open"
:aria-expanded="open.toString()"
aria-controls="faq-panel-{{ loop.index }}">
<span class="font-semibold text-brand-navy text-base">{{ item.q | safe }}</span>
<span class="grad-text text-2xl flex-shrink-0 transition-transform"
:class="open ? 'rotate-45' : ''" aria-hidden="true">+</span>
</button>
</h3>
<div id="faq-panel-{{ loop.index }}"
x-show="open"
x-transition.opacity.duration.200ms>
<p class="px-2 pb-4 text-sm text-brand-navy/80 leading-relaxed">{{ item.a | safe }}</p>
</div>
</div>
{% endfor %}
</div>
</div>
{# Schema.org FAQPage JSON-LD for SEO/GEO — inline so it travels with this page only #}
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "FAQPage",
"mainEntity": [
{%- for item in faq -%}
{
"@type": "Question",
"name": {{ (item.q | striptags | replace('&nbsp;', ' '))|tojson }},
"acceptedAnswer": {
"@type": "Answer",
"text": {{ (item.a | striptags | replace('&nbsp;', ' '))|tojson }}
}
}{{ "," if not loop.last }}
{%- endfor -%}
]
}
</script>
</section>
{# ===== CTA FINAL ===== #}
<section class="relative bg-brand-navy text-white py-24 overflow-hidden" aria-labelledby="cta-title">
{# Two warm cosmic orbs to mirror the Hero — visual closure of the page #}
<div class="absolute inset-0 pointer-events-none" aria-hidden="true">
<div class="absolute top-1/4 left-1/3 w-[500px] h-[500px] rounded-full"
style="background: radial-gradient(circle, rgba(0,98,255,0.14) 0%, transparent 60%); filter: blur(50px);"></div>
<div class="absolute bottom-1/4 right-1/3 w-[450px] h-[450px] rounded-full"
style="background: radial-gradient(circle, rgba(0,200,150,0.10) 0%, transparent 60%); filter: blur(50px);"></div>
</div>
<div class="relative max-w-[820px] mx-auto px-6 text-center">
<p class="eyebrow grad-text mb-4">PRÊT&nbsp;?</p>
<h2 id="cta-title" class="text-[clamp(2.25rem,4vw,3.5rem)] font-black mb-6">
Réservez votre <span class="grad-text">pré-inscription</span>.
</h2>
<p class="text-lg text-white/80 mb-8">
Lancement printemps&nbsp;2026. Les premiers utilisateurs bénéficient d'une remise de bienvenue et d'un accompagnement direct par notre équipe technique. Aucun engagement.
</p>
<div class="flex flex-col sm:flex-row gap-4 justify-center">
{% from 'macros/button.html' import button %}
{{ button('Pré-inscription par courriel', href='mailto:info@dictia.ca?subject=Pré-inscription%20DictIA', variant='primary', size='lg', icon='<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="w-4 h-4" aria-hidden="true"><path d="M4 4h16c1.1 0 2 .9 2 2v12c0 1.1-.9 2-2 2H4c-1.1 0-2-.9-2-2V6c0-1.1.9-2 2-2z"/><polyline points="22,6 12,13 2,6"/></svg>') }}
{{ button('Voir les forfaits', href='#tarifs', variant='ghost', size='lg') }}
</div>
<p class="text-xs text-white/70 mt-8">
Pré-inscription par courriel jusqu'à l'ouverture de la plateforme. Inscription en ligne disponible dès le lancement.
</p>
</div>
</section>
{% endblock %}
{% block scripts %}
<script src="/static/js/roi_calculator.js" defer></script>
{% endblock %}