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:
@@ -1703,31 +1703,31 @@
|
||||
}
|
||||
}
|
||||
.border-brand-b1 {
|
||||
border-color: #0062ff;
|
||||
border-color: #7c3aed;
|
||||
}
|
||||
.border-brand-b1\/15 {
|
||||
border-color: color-mix(in oklab, #0062ff 15%, transparent);
|
||||
border-color: color-mix(in oklab, #7c3aed 15%, transparent);
|
||||
}
|
||||
.border-brand-b1\/20 {
|
||||
border-color: color-mix(in oklab, #0062ff 20%, transparent);
|
||||
border-color: color-mix(in oklab, #7c3aed 20%, transparent);
|
||||
}
|
||||
.border-brand-b1\/25 {
|
||||
border-color: color-mix(in oklab, #0062ff 25%, transparent);
|
||||
border-color: color-mix(in oklab, #7c3aed 25%, transparent);
|
||||
}
|
||||
.border-brand-b1\/30 {
|
||||
border-color: color-mix(in oklab, #0062ff 30%, transparent);
|
||||
border-color: color-mix(in oklab, #7c3aed 30%, transparent);
|
||||
}
|
||||
.border-brand-b1\/35 {
|
||||
border-color: color-mix(in oklab, #0062ff 35%, transparent);
|
||||
border-color: color-mix(in oklab, #7c3aed 35%, transparent);
|
||||
}
|
||||
.border-brand-b2\/40 {
|
||||
border-color: color-mix(in oklab, #00bdd8 40%, transparent);
|
||||
border-color: color-mix(in oklab, #a855f7 40%, transparent);
|
||||
}
|
||||
.border-brand-b3\/15 {
|
||||
border-color: color-mix(in oklab, #00c896 15%, transparent);
|
||||
border-color: color-mix(in oklab, #06b6d4 15%, transparent);
|
||||
}
|
||||
.border-brand-b3\/60 {
|
||||
border-color: color-mix(in oklab, #00c896 60%, transparent);
|
||||
border-color: color-mix(in oklab, #06b6d4 60%, transparent);
|
||||
}
|
||||
.border-brand-border {
|
||||
border-color: #e6ebf2;
|
||||
@@ -2030,28 +2030,28 @@
|
||||
background-color: var(--color-blue-600);
|
||||
}
|
||||
.bg-brand-b1 {
|
||||
background-color: #0062ff;
|
||||
background-color: #7c3aed;
|
||||
}
|
||||
.bg-brand-b1\/5 {
|
||||
background-color: color-mix(in oklab, #0062ff 5%, transparent);
|
||||
background-color: color-mix(in oklab, #7c3aed 5%, transparent);
|
||||
}
|
||||
.bg-brand-b1\/10 {
|
||||
background-color: color-mix(in oklab, #0062ff 10%, transparent);
|
||||
background-color: color-mix(in oklab, #7c3aed 10%, transparent);
|
||||
}
|
||||
.bg-brand-b1\/15 {
|
||||
background-color: color-mix(in oklab, #0062ff 15%, transparent);
|
||||
background-color: color-mix(in oklab, #7c3aed 15%, transparent);
|
||||
}
|
||||
.bg-brand-b1\/\[0\.06\] {
|
||||
background-color: color-mix(in oklab, #0062ff 6%, transparent);
|
||||
background-color: color-mix(in oklab, #7c3aed 6%, transparent);
|
||||
}
|
||||
.bg-brand-b3 {
|
||||
background-color: #00c896;
|
||||
background-color: #06b6d4;
|
||||
}
|
||||
.bg-brand-b3\/10 {
|
||||
background-color: color-mix(in oklab, #00c896 10%, transparent);
|
||||
background-color: color-mix(in oklab, #06b6d4 10%, transparent);
|
||||
}
|
||||
.bg-brand-b3\/60 {
|
||||
background-color: color-mix(in oklab, #00c896 60%, transparent);
|
||||
background-color: color-mix(in oklab, #06b6d4 60%, transparent);
|
||||
}
|
||||
.bg-brand-bg {
|
||||
background-color: #f7f9fc;
|
||||
@@ -2370,15 +2370,15 @@
|
||||
--tw-gradient-stops: var(--tw-gradient-via-stops, var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position));
|
||||
}
|
||||
.from-brand-b1\/15 {
|
||||
--tw-gradient-from: color-mix(in oklab, #0062ff 15%, transparent);
|
||||
--tw-gradient-from: color-mix(in oklab, #7c3aed 15%, transparent);
|
||||
--tw-gradient-stops: var(--tw-gradient-via-stops, var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position));
|
||||
}
|
||||
.from-brand-b1\/\[0\.06\] {
|
||||
--tw-gradient-from: color-mix(in oklab, #0062ff 6%, transparent);
|
||||
--tw-gradient-from: color-mix(in oklab, #7c3aed 6%, transparent);
|
||||
--tw-gradient-stops: var(--tw-gradient-via-stops, var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position));
|
||||
}
|
||||
.from-brand-b3 {
|
||||
--tw-gradient-from: #00c896;
|
||||
--tw-gradient-from: #06b6d4;
|
||||
--tw-gradient-stops: var(--tw-gradient-via-stops, var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position));
|
||||
}
|
||||
.from-orange-500 {
|
||||
@@ -2421,15 +2421,15 @@
|
||||
--tw-gradient-stops: var(--tw-gradient-via-stops, var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position));
|
||||
}
|
||||
.to-brand-b1 {
|
||||
--tw-gradient-to: #0062ff;
|
||||
--tw-gradient-to: #7c3aed;
|
||||
--tw-gradient-stops: var(--tw-gradient-via-stops, var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position));
|
||||
}
|
||||
.to-brand-b3\/10 {
|
||||
--tw-gradient-to: color-mix(in oklab, #00c896 10%, transparent);
|
||||
--tw-gradient-to: color-mix(in oklab, #06b6d4 10%, transparent);
|
||||
--tw-gradient-stops: var(--tw-gradient-via-stops, var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position));
|
||||
}
|
||||
.to-brand-b3\/\[0\.04\] {
|
||||
--tw-gradient-to: color-mix(in oklab, #00c896 4%, transparent);
|
||||
--tw-gradient-to: color-mix(in oklab, #06b6d4 4%, transparent);
|
||||
--tw-gradient-stops: var(--tw-gradient-via-stops, var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position));
|
||||
}
|
||||
.to-purple-500 {
|
||||
@@ -2979,9 +2979,6 @@
|
||||
color: color-mix(in oklab, var(--color-amber-900) 90%, transparent);
|
||||
}
|
||||
}
|
||||
.text-blue-300 {
|
||||
color: var(--color-blue-300);
|
||||
}
|
||||
.text-blue-400 {
|
||||
color: var(--color-blue-400);
|
||||
}
|
||||
@@ -3001,31 +2998,31 @@
|
||||
color: var(--color-blue-900);
|
||||
}
|
||||
.text-brand-b1 {
|
||||
color: #0062ff;
|
||||
color: #7c3aed;
|
||||
}
|
||||
.text-brand-b1\/45 {
|
||||
color: color-mix(in oklab, #0062ff 45%, transparent);
|
||||
color: color-mix(in oklab, #7c3aed 45%, transparent);
|
||||
}
|
||||
.text-brand-b1\/55 {
|
||||
color: color-mix(in oklab, #0062ff 55%, transparent);
|
||||
color: color-mix(in oklab, #7c3aed 55%, transparent);
|
||||
}
|
||||
.text-brand-b1\/60 {
|
||||
color: color-mix(in oklab, #0062ff 60%, transparent);
|
||||
color: color-mix(in oklab, #7c3aed 60%, transparent);
|
||||
}
|
||||
.text-brand-b1\/65 {
|
||||
color: color-mix(in oklab, #0062ff 65%, transparent);
|
||||
color: color-mix(in oklab, #7c3aed 65%, transparent);
|
||||
}
|
||||
.text-brand-b1\/70 {
|
||||
color: color-mix(in oklab, #0062ff 70%, transparent);
|
||||
color: color-mix(in oklab, #7c3aed 70%, transparent);
|
||||
}
|
||||
.text-brand-b1\/80 {
|
||||
color: color-mix(in oklab, #0062ff 80%, transparent);
|
||||
color: color-mix(in oklab, #7c3aed 80%, transparent);
|
||||
}
|
||||
.text-brand-b2 {
|
||||
color: #00bdd8;
|
||||
color: #a855f7;
|
||||
}
|
||||
.text-brand-b3 {
|
||||
color: #00c896;
|
||||
color: #06b6d4;
|
||||
}
|
||||
.text-brand-navy {
|
||||
color: #060d1a;
|
||||
@@ -3198,6 +3195,9 @@
|
||||
.text-teal-600 {
|
||||
color: var(--color-teal-600);
|
||||
}
|
||||
.text-violet-300 {
|
||||
color: var(--color-violet-300);
|
||||
}
|
||||
.text-violet-600 {
|
||||
color: var(--color-violet-600);
|
||||
}
|
||||
@@ -3324,7 +3324,7 @@
|
||||
}
|
||||
}
|
||||
.accent-brand-b1 {
|
||||
accent-color: #0062ff;
|
||||
accent-color: #7c3aed;
|
||||
}
|
||||
.opacity-0 {
|
||||
opacity: 0%;
|
||||
@@ -3378,8 +3378,8 @@
|
||||
--tw-shadow: 0 0 6px var(--tw-shadow-color, rgba(239,68,68,0.6));
|
||||
box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
|
||||
}
|
||||
.shadow-\[0_0_28px_rgba\(0\,98\,255\,0\.35\)\] {
|
||||
--tw-shadow: 0 0 28px var(--tw-shadow-color, rgba(0,98,255,0.35));
|
||||
.shadow-\[0_0_28px_rgba\(124\,58\,237\,0\.35\)\] {
|
||||
--tw-shadow: 0 0 28px var(--tw-shadow-color, rgba(124,58,237,0.35));
|
||||
box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
|
||||
}
|
||||
.shadow-\[0_8px_30px_-6px_rgba\(239\,68\,68\,0\.55\)\] {
|
||||
@@ -3387,7 +3387,7 @@
|
||||
box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
|
||||
}
|
||||
.shadow-cta {
|
||||
--tw-shadow: 0 4px 20px var(--tw-shadow-color, rgba(0, 98, 255, 0.28));
|
||||
--tw-shadow: 0 4px 20px var(--tw-shadow-color, rgba(124, 58, 237, 0.28));
|
||||
box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
|
||||
}
|
||||
.shadow-lg {
|
||||
@@ -3579,7 +3579,7 @@
|
||||
.group-hover\:text-brand-b1 {
|
||||
&:is(:where(.group):hover *) {
|
||||
@media (hover: hover) {
|
||||
color: #0062ff;
|
||||
color: #7c3aed;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3789,14 +3789,14 @@
|
||||
.hover\:border-brand-b1 {
|
||||
&:hover {
|
||||
@media (hover: hover) {
|
||||
border-color: #0062ff;
|
||||
border-color: #7c3aed;
|
||||
}
|
||||
}
|
||||
}
|
||||
.hover\:border-brand-b1\/30 {
|
||||
&:hover {
|
||||
@media (hover: hover) {
|
||||
border-color: color-mix(in oklab, #0062ff 30%, transparent);
|
||||
border-color: color-mix(in oklab, #7c3aed 30%, transparent);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4150,7 +4150,7 @@
|
||||
.hover\:from-brand-b1 {
|
||||
&:hover {
|
||||
@media (hover: hover) {
|
||||
--tw-gradient-from: #0062ff;
|
||||
--tw-gradient-from: #7c3aed;
|
||||
--tw-gradient-stops: var(--tw-gradient-via-stops, var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position));
|
||||
}
|
||||
}
|
||||
@@ -4190,7 +4190,7 @@
|
||||
.hover\:to-brand-b3 {
|
||||
&:hover {
|
||||
@media (hover: hover) {
|
||||
--tw-gradient-to: #00c896;
|
||||
--tw-gradient-to: #06b6d4;
|
||||
--tw-gradient-stops: var(--tw-gradient-via-stops, var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position));
|
||||
}
|
||||
}
|
||||
@@ -4306,7 +4306,7 @@
|
||||
.hover\:text-brand-b1 {
|
||||
&:hover {
|
||||
@media (hover: hover) {
|
||||
color: #0062ff;
|
||||
color: #7c3aed;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4426,7 +4426,7 @@
|
||||
.hover\:shadow-cta {
|
||||
&:hover {
|
||||
@media (hover: hover) {
|
||||
--tw-shadow: 0 4px 20px var(--tw-shadow-color, rgba(0, 98, 255, 0.28));
|
||||
--tw-shadow: 0 4px 20px var(--tw-shadow-color, rgba(124, 58, 237, 0.28));
|
||||
box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
|
||||
}
|
||||
}
|
||||
@@ -4434,7 +4434,7 @@
|
||||
.hover\:shadow-cta-hover {
|
||||
&:hover {
|
||||
@media (hover: hover) {
|
||||
--tw-shadow: 0 8px 32px var(--tw-shadow-color, rgba(0, 98, 255, 0.42));
|
||||
--tw-shadow: 0 8px 32px var(--tw-shadow-color, rgba(124, 58, 237, 0.42));
|
||||
box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
|
||||
}
|
||||
}
|
||||
@@ -4613,7 +4613,7 @@
|
||||
}
|
||||
.focus-visible\:outline-brand-b1 {
|
||||
&:focus-visible {
|
||||
outline-color: #0062ff;
|
||||
outline-color: #7c3aed;
|
||||
}
|
||||
}
|
||||
.focus-visible\:outline-red-700 {
|
||||
@@ -5890,13 +5890,13 @@
|
||||
}
|
||||
@layer utilities {
|
||||
.grad-text {
|
||||
background-image: linear-gradient(118deg, #0062ff, #00bdd8 52%, #00c896);
|
||||
background-image: linear-gradient(118deg, #7c3aed, #a855f7 52%, #06b6d4);
|
||||
-webkit-background-clip: text;
|
||||
background-clip: text;
|
||||
color: transparent;
|
||||
}
|
||||
.grad-bg {
|
||||
background-image: linear-gradient(118deg, #0062ff, #00bdd8 52%, #00c896);
|
||||
background-image: linear-gradient(118deg, #7c3aed, #a855f7 52%, #06b6d4);
|
||||
color: var(--color-white);
|
||||
}
|
||||
.eyebrow {
|
||||
|
||||
@@ -6,9 +6,9 @@ module.exports = {
|
||||
extend: {
|
||||
colors: {
|
||||
brand: {
|
||||
b1: '#0062ff',
|
||||
b2: '#00bdd8',
|
||||
b3: '#00c896',
|
||||
b1: '#7c3aed',
|
||||
b2: '#a855f7',
|
||||
b3: '#06b6d4',
|
||||
navy: '#060d1a',
|
||||
navy2: '#0b1525',
|
||||
navy3: '#0f1e35',
|
||||
@@ -21,11 +21,11 @@ module.exports = {
|
||||
mono: ['JetBrains Mono Variable', 'JetBrains Mono', 'monospace'],
|
||||
},
|
||||
backgroundImage: {
|
||||
'brand-grad': 'linear-gradient(118deg, #0062ff, #00bdd8 52%, #00c896)',
|
||||
'brand-grad': 'linear-gradient(118deg, #7c3aed, #a855f7 52%, #06b6d4)',
|
||||
},
|
||||
boxShadow: {
|
||||
'cta': '0 4px 20px rgba(0, 98, 255, 0.28)',
|
||||
'cta-hover': '0 8px 32px rgba(0, 98, 255, 0.42)',
|
||||
'cta': '0 4px 20px rgba(124, 58, 237, 0.28)',
|
||||
'cta-hover': '0 8px 32px rgba(124, 58, 237, 0.42)',
|
||||
},
|
||||
borderRadius: {
|
||||
DEFAULT: '0.75rem',
|
||||
@@ -44,8 +44,8 @@ module.exports = {
|
||||
'50%': { transform: 'translateY(-8px)' },
|
||||
},
|
||||
'tc-pulse-glow': {
|
||||
'0%, 100%': { boxShadow: '0 4px 20px rgba(0, 98, 255, 0.28)' },
|
||||
'50%': { boxShadow: '0 8px 32px rgba(0, 98, 255, 0.42)' },
|
||||
'0%, 100%': { boxShadow: '0 4px 20px rgba(124, 58, 237, 0.28)' },
|
||||
'50%': { boxShadow: '0 8px 32px rgba(124, 58, 237, 0.42)' },
|
||||
},
|
||||
'plus-breathe': {
|
||||
'0%, 100%': { transform: 'scale(1)' },
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
height: 4px;
|
||||
margin-top: 0.5rem;
|
||||
border-radius: 4px;
|
||||
background: linear-gradient(118deg, #0062ff, #00bdd8 52%, #00c896);
|
||||
background: linear-gradient(118deg, #7c3aed, #a855f7 52%, #06b6d4);
|
||||
}
|
||||
.legal-content h3 {
|
||||
font-size: 1.25rem; /* 20px */
|
||||
@@ -60,16 +60,16 @@
|
||||
.legal-content ol { list-style-type: decimal; list-style-position: outside; }
|
||||
.legal-content li { margin-bottom: 0.35rem; }
|
||||
.legal-content a {
|
||||
background: linear-gradient(118deg, #0062ff, #00bdd8 52%, #00c896);
|
||||
background: linear-gradient(118deg, #7c3aed, #a855f7 52%, #06b6d4);
|
||||
-webkit-background-clip: text;
|
||||
background-clip: text;
|
||||
color: transparent;
|
||||
font-weight: 600;
|
||||
text-decoration: underline;
|
||||
text-decoration-color: #0062ff;
|
||||
text-decoration-color: #7c3aed;
|
||||
}
|
||||
.legal-content a:focus-visible {
|
||||
outline: 2px solid #0062ff;
|
||||
outline: 2px solid #7c3aed;
|
||||
outline-offset: 2px;
|
||||
border-radius: 2px;
|
||||
}
|
||||
@@ -95,7 +95,7 @@
|
||||
background-color: #fafbfd;
|
||||
}
|
||||
.legal-content blockquote {
|
||||
border-left: 4px solid #0062ff;
|
||||
border-left: 4px solid #7c3aed;
|
||||
background-color: rgba(247, 249, 252, 0.6);
|
||||
padding: 0.75rem 1rem;
|
||||
margin: 1.25rem 0;
|
||||
@@ -156,12 +156,12 @@
|
||||
transition: color 150ms ease, border-color 150ms ease, background-color 150ms ease;
|
||||
}
|
||||
.legal-toc a:hover {
|
||||
background-color: rgba(0, 98, 255, 0.05);
|
||||
background-color: rgba(124, 58, 237, 0.05);
|
||||
}
|
||||
.legal-toc a.is-active {
|
||||
border-left-color: #0062ff;
|
||||
color: #0062ff !important;
|
||||
background-color: rgba(0, 98, 255, 0.06);
|
||||
border-left-color: #7c3aed;
|
||||
color: #7c3aed !important;
|
||||
background-color: rgba(124, 58, 237, 0.06);
|
||||
}
|
||||
.legal-breadcrumb {
|
||||
position: sticky;
|
||||
|
||||
@@ -13,16 +13,16 @@
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
.legal-card:focus-visible {
|
||||
outline: 2px solid #0062ff;
|
||||
outline: 2px solid #7c3aed;
|
||||
outline-offset: 3px;
|
||||
}
|
||||
/* Icône circulaire avec dégradé de marque, contraste suffisant. */
|
||||
.legal-card-icon {
|
||||
background: linear-gradient(135deg, rgba(0,98,255,0.10), rgba(0,200,150,0.10));
|
||||
color: #0062ff;
|
||||
background: linear-gradient(135deg, rgba(124,58,237,0.10), rgba(6,182,212,0.10));
|
||||
color: #7c3aed;
|
||||
}
|
||||
.legal-card.is-external .legal-card-icon {
|
||||
background: linear-gradient(135deg, rgba(0,189,216,0.12), rgba(0,200,150,0.12));
|
||||
background: linear-gradient(135deg, rgba(168,85,247,0.12), rgba(6,182,212,0.12));
|
||||
}
|
||||
/* Print : pas de bouton CTA, pas d'animations. */
|
||||
@media print {
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
{# ===== HEADER ===== #}
|
||||
<section class="bg-brand-navy text-white py-20 overflow-hidden relative" aria-labelledby="page-title">
|
||||
<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-[820px] mx-auto px-6 text-center">
|
||||
<p class="eyebrow grad-text mb-4">CONFORMITÉ — FORTERESSE QUÉBÉCOISE</p>
|
||||
<h1 id="page-title" class="text-[clamp(2.25rem,4vw,3.5rem)] font-black mb-4">
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
bottom: -10px;
|
||||
width: 0;
|
||||
height: 3px;
|
||||
background: linear-gradient(118deg, #0062ff, #00bdd8 52%, #00c896);
|
||||
background: linear-gradient(118deg, #7c3aed, #a855f7 52%, #06b6d4);
|
||||
transform: translateX(-50%);
|
||||
transition: width 600ms ease-out;
|
||||
}
|
||||
@@ -27,16 +27,16 @@
|
||||
|
||||
/* Hover lift cards */
|
||||
.ani-lift { transition: transform 200ms ease-out, box-shadow 200ms ease-out; }
|
||||
.ani-lift:hover { transform: translateY(-2px); box-shadow: 0 8px 32px rgba(0, 98, 255, 0.18); }
|
||||
.ani-lift:hover { transform: translateY(-2px); box-shadow: 0 8px 32px rgba(124, 58, 237, 0.18); }
|
||||
|
||||
/* Sticky sub-nav active link */
|
||||
.subnav-link[aria-current="true"] { color: #0062ff; }
|
||||
.subnav-link[aria-current="true"] { color: #7c3aed; }
|
||||
.subnav-link[aria-current="true"]::after {
|
||||
content: '';
|
||||
display: block;
|
||||
height: 2px;
|
||||
margin-top: 4px;
|
||||
background: linear-gradient(118deg, #0062ff, #00bdd8 52%, #00c896);
|
||||
background: linear-gradient(118deg, #7c3aed, #a855f7 52%, #06b6d4);
|
||||
}
|
||||
|
||||
/* Cosmic float orbs (n'utilise pas tc-float-y pour éviter rebuild) */
|
||||
@@ -46,8 +46,8 @@
|
||||
|
||||
/* DictIA Cloud pulse glow */
|
||||
@keyframes card-pulse-glow {
|
||||
0%, 100% { box-shadow: 0 4px 20px rgba(0, 98, 255, 0.28); }
|
||||
50% { box-shadow: 0 12px 40px rgba(0, 98, 255, 0.5); }
|
||||
0%, 100% { box-shadow: 0 4px 20px rgba(124, 58, 237, 0.28); }
|
||||
50% { box-shadow: 0 12px 40px rgba(124, 58, 237, 0.5); }
|
||||
}
|
||||
.card-pulse-glow { animation: card-pulse-glow 3s ease-in-out infinite; }
|
||||
|
||||
@@ -76,13 +76,13 @@
|
||||
{# Cosmic orbs background — float animation subtile #}
|
||||
<div class="absolute inset-0 pointer-events-none" aria-hidden="true">
|
||||
<div class="orb-float-a absolute top-1/4 left-1/4 w-[600px] h-[600px] rounded-full"
|
||||
style="background: radial-gradient(circle, rgba(0,98,255,0.16) 0%, transparent 60%); filter: blur(40px);"></div>
|
||||
style="background: radial-gradient(circle, rgba(124,58,237,0.16) 0%, transparent 60%); filter: blur(40px);"></div>
|
||||
<div class="orb-float-b 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>
|
||||
style="background: radial-gradient(circle, rgba(6,182,212,0.07) 0%, transparent 60%); filter: blur(40px);"></div>
|
||||
<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>
|
||||
<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>
|
||||
|
||||
<div class="relative max-w-[1200px] mx-auto px-6 text-center">
|
||||
@@ -330,7 +330,7 @@
|
||||
{# ===== ARCHITECTURE & INFRASTRUCTURE ===== #}
|
||||
<section id="architecture" class="relative bg-brand-navy text-white py-20 scroll-mt-32 overflow-hidden" aria-labelledby="architecture-title">
|
||||
<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-3xl mx-auto mb-14">
|
||||
|
||||
@@ -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 % 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">
|
||||
|
||||
@@ -117,7 +117,7 @@
|
||||
<section class="relative bg-brand-navy text-white py-20 overflow-hidden" aria-labelledby="tarifs-cta-title">
|
||||
<div class="absolute inset-0 pointer-events-none" aria-hidden="true">
|
||||
<div class="absolute top-1/3 left-1/3 w-[500px] h-[500px] rounded-full"
|
||||
style="background: radial-gradient(circle, rgba(0,98,255,0.12) 0%, transparent 60%); filter: blur(50px);"></div>
|
||||
style="background: radial-gradient(circle, rgba(124,58,237,0.12) 0%, transparent 60%); filter: blur(50px);"></div>
|
||||
</div>
|
||||
<div class="relative max-w-[820px] mx-auto px-6 text-center">
|
||||
<h2 id="tarifs-cta-title" class="text-[clamp(2rem,3vw,2.75rem)] font-black mb-6">
|
||||
|
||||
@@ -110,13 +110,13 @@ def test_hero_has_dual_cta():
|
||||
|
||||
|
||||
def test_hero_has_cosmic_orbs_background():
|
||||
"""Hero has 3 radial gradient orbs (FlexiHub signature)."""
|
||||
"""Hero has 3 radial gradient orbs (FlexiHub signature, mauve/aqua palette)."""
|
||||
client = app.test_client()
|
||||
body = client.get('/').data.decode('utf-8')
|
||||
# Look for the 3 orb opacities (16% blue, 7% cyan, 11% green)
|
||||
assert 'rgba(0,98,255,0.16)' in body, "Missing primary blue orb"
|
||||
assert 'rgba(0,189,216,0.07)' in body, "Missing cyan orb"
|
||||
assert 'rgba(0,200,150,0.11)' in body, "Missing green accent orb"
|
||||
# Look for the 3 orb opacities (16% mauve, 7% aqua, 11% aqua accent)
|
||||
assert 'rgba(124,58,237,0.16)' in body, "Missing primary mauve orb"
|
||||
assert 'rgba(6,182,212,0.07)' in body, "Missing aqua orb"
|
||||
assert 'rgba(6,182,212,0.11)' in body, "Missing aqua accent orb"
|
||||
|
||||
|
||||
def test_hero_has_social_proof_microcopy():
|
||||
|
||||
Reference in New Issue
Block a user