refactor(brand): décale palette bleu→mauve dégradé (b1=#7c3aed, b2=#a855f7, b3=#06b6d4 aqua) pour différencier DictIA

Décale la palette canonique DictIA du bleu/cyan/vert vers mauve/violet/aqua
afin de distinguer visuellement le produit DictIA des autres outils InnovA AI
(qui restent sur palette bleue) tout en gardant la même structure de gradient,
mêmes tokens Tailwind, et même intensité visuelle.

Mapping appliqué:
- Hex semantic: #0062ff → #7c3aed (mauve), #00bdd8 → #a855f7 (lighter mauve)
- Hex aqua décoratif: #00c896 → #06b6d4 (cyan-500, aqua préservé)
- Hex secondaire: #6B9FFF / rgba(107,159,255,*) → #a78bfa (violet-400)
- Hex blue-700 #1d4ed8 (cadre reg label) → #7c3aed (mauve)
- Box shadows / rgba opacités: rgba(0,98,255,*) → rgba(124,58,237,*)
- Décoratif (orbes cosmiques, glows): mauve+aqua mix pour préserver l'effet
  "cosmic dégradé" — orbe primaire en mauve, orbes secondaires en aqua
- Hub network DictIA: Documents=mauve, Communication=aqua, Automatisation
  reste #8b5cf6 (déjà violet, marqueur visuel distinct via positionnement)
- Couleurs sémantiques fonctionnelles (red/green pour erreurs/succès, amber
  pour alertes) inchangées

Fichiers modifiés:
- static/css/tailwind.config.js (brand.b1/b2/b3 + brand-grad + boxShadow.cta
  + boxShadow.cta-hover + keyframes.tc-pulse-glow)
- static/css/marketing.css (rebuild Tailwind: 169356 → 163036 bytes)
- templates/legal/{_layout,index}.html
- templates/marketing/{landing,fonctionnalites,conformite,tarifs}.html
- tests/test_marketing_landing_template.py (test_hero_has_cosmic_orbs_background
  mis à jour avec assertions mauve/aqua au lieu de blue/cyan/green)

Hors scope (non touchés):
- Couleurs Tailwind utility (red/green/amber/emerald) sémantiques
- --brand-navy* (backgrounds dark restent neutres)
- Templates legacy (account.html, admin.html, components/, modals/)
- #8b5cf6 (Automatisation hub), #f59e0b (alertes), #ef4444 (erreurs)

Tests: 111 passed, 5 failed (toutes 5 pré-existantes, non liées aux couleurs:
/blog link manquant, MAPP eyebrow, SOC 2 phrasing, Gitea URL).
HTTP 200 vérifié sur /, /fonctionnalites, /tarifs, /conformite, /legal/,
/legal/conditions.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Allison
2026-04-28 15:39:09 -04:00
parent 680df39089
commit 34d40162b3
9 changed files with 151 additions and 151 deletions

View File

@@ -19,7 +19,7 @@
}
.hero-flow-card.is-active {
transform: scale(1.05);
box-shadow: 0 0 22px rgba(0, 189, 216, 0.45), 0 0 44px rgba(0, 98, 255, 0.18);
box-shadow: 0 0 22px rgba(6, 182, 212, 0.45), 0 0 44px rgba(124, 58, 237, 0.18);
}
.hero-flow-card.is-inactive { opacity: 0.45; }
/* Animated arrow draw between cards */
@@ -63,7 +63,7 @@
border-radius: 9999px;
pointer-events: none;
z-index: 9999;
background: radial-gradient(circle, rgba(0,189,216,0.18) 0%, rgba(0,98,255,0.10) 50%, transparent 70%);
background: radial-gradient(circle, rgba(6,182,212,0.18) 0%, rgba(124,58,237,0.10) 50%, transparent 70%);
animation: hero-shockwave 700ms cubic-bezier(0.2, 0.8, 0.2, 1) forwards;
}
/* ── Word-staggered title reveal ── */
@@ -144,23 +144,23 @@
<span class="hero-shockwave" :style="`left:${sw.x}px; top:${sw.y}px;`" aria-hidden="true"></span>
</template>
{# Cosmic orbs background — 3 radial gradients (blue 16%, cyan 7%, green 11%) + subtle grid + horizontal accent line #}
{# Cosmic orbs background — 3 radial gradients (mauve 16%, aqua 7%, aqua 11%) + subtle grid + horizontal accent line #}
<div class="absolute inset-0 pointer-events-none" aria-hidden="true">
{# Orb 1 — primary blue, top-left #}
{# Orb 1 — primary mauve, 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 #}
style="background: radial-gradient(circle, rgba(124,58,237,0.16) 0%, transparent 60%); filter: blur(40px);"></div>
{# Orb 2 — aqua, 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 #}
style="background: radial-gradient(circle, rgba(6,182,212,0.07) 0%, transparent 60%); filter: blur(40px);"></div>
{# Orb 3 — aqua accent, 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>
style="background: radial-gradient(circle, rgba(6,182,212,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 #}
{# Horizontal accent line — gradient mauve to aqua 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>
style="background: linear-gradient(90deg, transparent, rgba(124,58,237,0.3), rgba(6,182,212,0.2), transparent);"></div>
</div>
{# 3D abstract orb — reacts to mouse via Alpine ox/oy → CSS variables #}
@@ -174,14 +174,14 @@
<div class="absolute inset-0 rounded-full border border-brand-b3/15" style="transform: scale(1.35);"></div>
{# Ambient blob #}
<div class="absolute inset-0 rounded-full"
style="background: radial-gradient(ellipse at 40% 40%, rgba(107,159,255,0.14) 0%, rgba(0,189,216,0.07) 50%, transparent 75%); filter: blur(20px);"></div>
style="background: radial-gradient(ellipse at 40% 40%, rgba(167,139,250,0.14) 0%, rgba(6,182,212,0.07) 50%, transparent 75%); filter: blur(20px);"></div>
{# Rotating mesh ring A #}
<div class="hero-orb-ring-a absolute inset-0 rounded-full border border-dashed border-white/[0.07]" style="transform: scale(1.15);"></div>
{# Rotating mesh ring B #}
<div class="hero-orb-ring-b absolute inset-0 rounded-full border border-white/[0.05]" style="transform: scale(0.9);"></div>
{# Inner glow core #}
<div class="absolute inset-[30%] rounded-full"
style="background: radial-gradient(circle, rgba(107,159,255,0.25) 0%, rgba(0,189,216,0.08) 60%, transparent 100%);"></div>
style="background: radial-gradient(circle, rgba(167,139,250,0.25) 0%, rgba(6,182,212,0.08) 60%, transparent 100%);"></div>
</div>
</div>
@@ -273,7 +273,7 @@
<span class="relative inline-flex">
{# Pulse halo behind the primary CTA #}
<span class="hero-cta-halo absolute -inset-1 rounded pointer-events-none"
style="background: radial-gradient(ellipse, rgba(107,159,255,0.50) 0%, transparent 70%);"
style="background: radial-gradient(ellipse, rgba(167,139,250,0.50) 0%, transparent 70%);"
aria-hidden="true"></span>
<a
href="/contact"
@@ -432,8 +432,8 @@
/* Cycle col 3 (DictIA) — bordure lumineuse pulsante VERT (round 4 : conformité) */
@keyframes cycle-conforme-glow {
0%, 100% { box-shadow: 0 0 0 0 rgba(34,197,94,0.18), 0 0 0 0 rgba(0,189,216,0.10); }
50% { box-shadow: 0 0 32px 2px rgba(34,197,94,0.32), 0 0 60px 0 rgba(0,189,216,0.14); }
0%, 100% { box-shadow: 0 0 0 0 rgba(34,197,94,0.18), 0 0 0 0 rgba(6,182,212,0.10); }
50% { box-shadow: 0 0 32px 2px rgba(34,197,94,0.32), 0 0 60px 0 rgba(6,182,212,0.14); }
}
.cycle-card-dictia.is-visible { animation: cycle-conforme-glow 3.4s ease-in-out infinite; }
@@ -746,7 +746,7 @@
style="transition-delay: 240ms;">
{# Halo ambiant #}
<div class="absolute inset-0 pointer-events-none" aria-hidden="true"
style="background: radial-gradient(ellipse 80% 35% at 50% 0%, rgba(0,189,216,0.12) 0%, transparent 65%);"></div>
style="background: radial-gradient(ellipse 80% 35% at 50% 0%, rgba(6,182,212,0.12) 0%, transparent 65%);"></div>
<div class="relative px-5 py-3 border-b border-brand-b1/15 flex items-center gap-2.5">
{# Numéro 03 → checkmark vert (round 4) #}
@@ -870,7 +870,7 @@
<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>
style="background: radial-gradient(circle, rgba(6,182,212,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">
@@ -1024,13 +1024,13 @@
</g>
{# Order bar — visible quand p ≈ 1 #}
<g class="wave-bar" :style="`opacity: ${p}`">
<rect x="{{ cx - bw / 2 }}" y="{{ 25 - order_heights[i] / 2 }}" width="{{ bw }}" height="{{ order_heights[i] }}" rx="{{ bw / 2 }}" fill="rgba(107,159,255,0.6)"/>
<rect x="{{ cx - bw / 2 }}" y="{{ 25 - order_heights[i] / 2 }}" width="{{ bw }}" height="{{ order_heights[i] }}" rx="{{ bw / 2 }}" fill="rgba(167,139,250,0.6)"/>
</g>
{% endfor %}
{# Bouclier holographique (état ordre) #}
<path d="M 50 8 L 68 14 L 68 27 Q 68 38 50 43 Q 32 38 32 27 L 32 14 Z"
fill="none" stroke="rgba(107,159,255,0.55)" stroke-width="0.55" stroke-dasharray="2.5 2"
fill="none" stroke="rgba(167,139,250,0.55)" stroke-width="0.55" stroke-dasharray="2.5 2"
:style="`opacity: ${orderOp * 0.4}`"/>
</svg>
@@ -1038,18 +1038,18 @@
<div class="absolute z-20 left-[3%] top-1/2 -translate-y-1/2 flex flex-col items-center gap-1.5"
:style="`opacity: ${Math.max(0.25, 1 - p * 0.55)}`" aria-hidden="true">
<div class="w-10 h-10 md:w-12 md:h-12 rounded flex items-center justify-center backdrop-blur-md border"
:style="`background: rgba(${Math.round(255 + (107-255)*p)},${Math.round(60 + (130-60)*p)},${Math.round(60 + (159-60)*p)},0.12); border-color: rgba(${Math.round(255 + (107-255)*p)},${Math.round(80 + (159-80)*p)},${Math.round(80 + (255-80)*p)},0.28);`">
:style="`background: rgba(${Math.round(255 + (167-255)*p)},${Math.round(60 + (139-60)*p)},${Math.round(60 + (250-60)*p)},0.12); border-color: rgba(${Math.round(255 + (167-255)*p)},${Math.round(80 + (139-80)*p)},${Math.round(80 + (250-80)*p)},0.28);`">
<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 md:w-5 md:h-5"
:style="`color: ${p < 0.5 ? '#FF6B6B' : '#6B9FFF'}`"><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>
:style="`color: ${p < 0.5 ? '#FF6B6B' : '#a78bfa'}`"><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>
</div>
<span class="text-[8px] font-medium" :style="`color: ${p < 0.5 ? 'rgba(255,107,107,0.65)' : 'rgba(107,159,255,0.65)'}`">Audio</span>
<span class="text-[8px] font-medium" :style="`color: ${p < 0.5 ? 'rgba(255,107,107,0.65)' : 'rgba(167,139,250,0.65)'}`">Audio</span>
</div>
{# Icône Texte transcrit (droite) #}
<div class="absolute z-20 right-[3%] top-1/2 -translate-y-1/2 flex flex-col items-center gap-1.5"
:style="`opacity: ${orderOp}`" aria-hidden="true">
<div class="w-10 h-10 md:w-12 md:h-12 rounded flex items-center justify-center backdrop-blur-md border border-brand-b1/30"
style="background: linear-gradient(135deg, rgba(107,159,255,0.15), rgba(45,127,249,0.07)); box-shadow: 0 0 18px rgba(107,159,255,0.18);">
style="background: linear-gradient(135deg, rgba(167,139,250,0.15), rgba(124,58,237,0.07)); box-shadow: 0 0 18px rgba(167,139,250,0.18);">
<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 md:w-5 md:h-5 text-brand-b1"><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"/></svg>
</div>
<span class="text-[8px] font-medium text-brand-b1/70">Texte</span>
@@ -1076,7 +1076,7 @@
<div class="absolute inset-0 z-10 pointer-events-none" :style="`opacity: ${orderOp}`" aria-hidden="true">
{% for fy in [18, 21, 24, 27, 30] %}
<span class="wave-flow absolute w-1 h-1 rounded-full bg-brand-b1"
style="top: {{ fy }}%; left: 12%; box-shadow: 0 0 5px rgba(107,159,255,0.7); animation-delay: {{ loop.index0 * 0.32 }}s;"></span>
style="top: {{ fy }}%; left: 12%; box-shadow: 0 0 5px rgba(167,139,250,0.7); animation-delay: {{ loop.index0 * 0.32 }}s;"></span>
{% endfor %}
</div>
@@ -1104,7 +1104,7 @@
{'text': '100&nbsp;% Confidentiel — Hébergé au Qc', 'x': 18, 'y': 40}
] %}
<div class="absolute flex items-center gap-1.5 px-2 py-1 rounded backdrop-blur-sm"
style="left: {{ sol.x }}%; top: {{ sol.y }}%; transform: translate(-50%, -50%); background: rgba(107,159,255,0.10); border: 1px solid rgba(107,159,255,0.20);">
style="left: {{ sol.x }}%; top: {{ sol.y }}%; transform: translate(-50%, -50%); background: rgba(167,139,250,0.10); border: 1px solid rgba(167,139,250,0.20);">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-linejoin="round" class="w-2.5 h-2.5 text-brand-b1 shrink-0" aria-hidden="true"><path d="M5 13l4 4L19 7"/></svg>
<span class="text-[8px] md:text-[10px] text-white/80 whitespace-nowrap">{{ sol.text | safe }}</span>
</div>
@@ -1129,7 +1129,7 @@
@click.stop="toggle()"
class="absolute bottom-3 left-1/2 -translate-x-1/2 z-30 inline-flex items-center gap-2 px-5 py-2.5 rounded text-xs font-bold transition-all border focus-visible:outline-2 focus-visible:outline-brand-b1 focus-visible:outline-offset-2"
:class="activated ? 'border-brand-b1/30 text-brand-b1' : 'border-white/15 text-white/70'"
:style="activated ? 'background: linear-gradient(135deg, rgba(107,159,255,0.2), rgba(45,127,249,0.1));' : 'background: linear-gradient(135deg, rgba(255,255,255,0.08), rgba(255,255,255,0.03));'"
:style="activated ? 'background: linear-gradient(135deg, rgba(167,139,250,0.2), rgba(124,58,237,0.1));' : 'background: linear-gradient(135deg, rgba(255,255,255,0.08), rgba(255,255,255,0.03));'"
x-cloak>
<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"><rect x="9" y="2" width="6" height="12" rx="3"/><path d="M19 10v2a7 7 0 0 1-14 0v-2"/></svg>
<span x-text="activated ? 'Voir sans DictIA' : 'Activer DictIA'"></span>
@@ -1220,7 +1220,7 @@
<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="top: 43px; left: 12.5%; width: 75%; background: linear-gradient(90deg, #7c3aed 0%, #a855f7 100%);"
:style="`transform: scaleX(${steps[active].fillPct / 100})`"
aria-hidden="true"
></div>
@@ -1228,7 +1228,7 @@
{# 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="top: 44px; transform: translate(-50%, -50%); box-shadow: 0 0 18px rgba(168,85,247,0.55), 0 0 36px rgba(124,58,237,0.35);"
:style="`left: ${steps[active].positionPct}%`"
aria-hidden="true"
></div>
@@ -1258,7 +1258,7 @@
<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-b1 bg-brand-b1/10 scale-105 shadow-[0_0_28px_rgba(124,58,237,0.35)]': active === {{ loop.index0 }},
'border-brand-b3/60 bg-brand-b3/10': active > {{ loop.index0 }},
'border-brand-border bg-white': active < {{ loop.index0 }}
}"
@@ -1283,7 +1283,7 @@
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>
<circle class="pipeline-sweep-ring" cx="44" cy="44" r="41" fill="none" stroke="#7c3aed" stroke-width="2" stroke-linecap="round"></circle>
</svg>
</template>
</span>
@@ -1318,7 +1318,7 @@
<span
:key="active"
class="pipeline-underline absolute bottom-0 left-0 h-[2px] w-full"
style="background: linear-gradient(90deg, #0062ff, #00bdd8);"
style="background: linear-gradient(90deg, #7c3aed, #a855f7);"
aria-hidden="true"
></span>
</div>
@@ -1386,7 +1386,7 @@
<div class="bg-brand-navy text-white rounded p-6 relative overflow-hidden">
{# Subtle orb décoratif #}
<div class="absolute -top-12 -right-12 w-48 h-48 rounded-full pointer-events-none" aria-hidden="true"
style="background: radial-gradient(circle, rgba(0,189,216,0.15) 0%, transparent 60%); filter: blur(30px);"></div>
style="background: radial-gradient(circle, rgba(6,182,212,0.15) 0%, transparent 60%); filter: blur(30px);"></div>
<div class="relative">
<div class="flex items-center gap-3 mb-4">
@@ -1470,8 +1470,8 @@
.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); }
0%, 100% { box-shadow: 0 0 26px rgba(168,85,247,0.55), 0 0 56px rgba(168,85,247,0.18); }
50% { box-shadow: 0 0 38px rgba(168,85,247,0.75), 0 0 72px rgba(168,85,247,0.28); }
}
.hub-core { animation: hub-core-breathe 3.5s ease-in-out infinite; }
/* Reduced motion : freeze everything */
@@ -1482,9 +1482,9 @@
}
</style>
<section class="bg-brand-navy text-white py-20 overflow-hidden relative" aria-labelledby="hub-title">
{# Decorative cosmic orb — cyan, mid-section #}
{# Decorative cosmic orb — aqua, 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>
style="background: radial-gradient(circle, rgba(6,182,212,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">
@@ -1533,25 +1533,25 @@
{# 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-docs" fill="none" stroke="#7c3aed" stroke-width="1.5" opacity="0.55" />
<use href="#hub-path-comm" fill="none" stroke="#06b6d4" 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-word" fill="none" stroke="#7c3aed" stroke-width="1" opacity="0.30" />
<use href="#hub-path-google" fill="none" stroke="#7c3aed" stroke-width="1" opacity="0.30" />
<use href="#hub-path-obsidian" fill="none" stroke="#7c3aed" stroke-width="1" opacity="0.30" />
<use href="#hub-path-outlook" fill="none" stroke="#06b6d4" stroke-width="1" opacity="0.30" />
<use href="#hub-path-teams" fill="none" stroke="#06b6d4" stroke-width="1" opacity="0.30" />
<use href="#hub-path-notion" fill="none" stroke="#06b6d4" 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'),
('docs', '#7c3aed', '0s', '2.4s'),
('comm', '#06b6d4', '0.8s', '2.4s'),
('auto', '#8b5cf6', '1.6s', '2.4s')
] %}
<circle r="3.2" fill="{{ hub[1] }}" opacity="0.95">
@@ -1568,12 +1568,12 @@
{# 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'),
('word', '#7c3aed', '0s'),
('google', '#7c3aed', '0.4s'),
('obsidian', '#7c3aed', '0.8s'),
('outlook', '#06b6d4', '0.2s'),
('teams', '#06b6d4', '0.6s'),
('notion', '#06b6d4', '1.0s'),
('zapier', '#8b5cf6', '0.1s'),
('make', '#8b5cf6', '0.5s'),
('n8n', '#8b5cf6', '0.9s')
@@ -1602,8 +1602,8 @@
{# 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'),
('Documents', 'Word · Google Docs · Obsidian', '18.7%', 'rgba(124,58,237,0.10)', 'rgba(124,58,237,0.30)', 'text-violet-300'),
('Communication', 'Outlook · Teams · Notion', '50%', 'rgba(6,182,212,0.10)', 'rgba(6,182,212,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 %}
@@ -1814,9 +1814,9 @@
{# ===== 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 #}
{# Subtle decorative orb — aqua, 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>
style="background: radial-gradient(circle, rgba(6,182,212,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">
@@ -2148,7 +2148,7 @@
<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="relative w-5 h-5 transition-colors duration-300"
:class="step >= 2 ? 'text-amber-500' : 'text-brand-b1'"
:style="`filter: drop-shadow(0 0 ${step >= 2 ? '6px rgba(245,158,11,0.7)' : '4px rgba(0,98,255,0.5)'})`"
:style="`filter: drop-shadow(0 0 ${step >= 2 ? '6px rgba(245,158,11,0.7)' : '4px rgba(124,58,237,0.5)'})`"
aria-hidden="true">
<path d="M3 7a2 2 0 0 1 2-2h4l2 2h8a2 2 0 0 1 2 2v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"/>
</svg>
@@ -2225,15 +2225,15 @@
<a href="{{ reg.href }}" target="_blank" rel="noopener noreferrer"
class="cadre-reg group flex items-start gap-2 rounded px-2.5 py-1.5 no-underline border focus-visible:outline-2 focus-visible:outline-amber-500 focus-visible:outline-offset-2"
:class="flashIdx === {{ loop.index0 }} ? 'is-flash' : ''"
style="border-color: {{ 'rgba(239,68,68,0.20)' if reg.risk else 'rgba(0,98,255,0.15)' }};">
style="border-color: {{ 'rgba(239,68,68,0.20)' if reg.risk else 'rgba(124,58,237,0.15)' }};">
<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 mt-0.5 shrink-0"
style="color: {{ 'rgba(239,68,68,0.65)' if reg.risk else 'rgba(0,98,255,0.55)' }};"
style="color: {{ 'rgba(239,68,68,0.65)' if reg.risk else 'rgba(124,58,237,0.55)' }};"
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>
<div class="min-w-0 flex-1">
<div class="flex items-start gap-1.5 flex-wrap">
<span class="cadre-reg-label font-semibold text-[11px] leading-tight shrink-0 transition-colors"
style="color: {{ '#dc2626' if reg.risk else '#1d4ed8' }};">{{ reg.label }}</span>
style="color: {{ '#dc2626' if reg.risk else '#7c3aed' }};">{{ reg.label }}</span>
<span class="text-[10px] leading-tight text-brand-navy/55">{{ reg.detail | safe }}</span>
</div>
</div>
@@ -2513,9 +2513,9 @@
{# 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>
style="background: radial-gradient(circle, rgba(124,58,237,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>
style="background: radial-gradient(circle, rgba(6,182,212,0.10) 0%, transparent 60%); filter: blur(50px);"></div>
</div>
<div class="relative max-w-[820px] mx-auto px-6 text-center">