diff --git a/src/services/email.py b/src/services/email.py index b3b6a3b..67aa8df 100644 --- a/src/services/email.py +++ b/src/services/email.py @@ -173,9 +173,10 @@ def _get_email_template(content_html: str, content_text: str, subject: str) -> t """ Wrap content in the DictIA branded email template. - Header uses the DictIA brand gradient (118deg, #0062ff → #00bdd8 → #00c896) - with a #0062ff fallback for clients that don't render gradients in inline - styles. Footer mentions ``info@dictia.ca`` (canonical contact) and the + Header uses the DictIA brand gradient (118deg, #2563eb → #06b6d4 → #c026d3) + with a #2563eb fallback for clients that don't render gradients in inline + styles. The gradient matches the official DictIA logo (blue → cyan → fuchsia). + Footer mentions ``info@dictia.ca`` (canonical contact) and the Loi 25 tagline. Returns (html_body, text_body) @@ -188,12 +189,12 @@ def _get_email_template(content_html: str, content_text: str, subject: str) -> t # Outside of request context, use a placeholder logo_url = "" - # Header: solid #0062ff fallback + linear-gradient overlay (best-effort + # Header: solid #2563eb fallback + linear-gradient overlay (best-effort # for the email clients that support inline-style gradients — Apple Mail, - # iOS Mail, Gmail web). + # iOS Mail, Gmail web). Matches official DictIA logo (blue → cyan → fuchsia). header_bg = ( - "background-color: #0062ff; " - "background-image: linear-gradient(118deg, #0062ff 0%, #00bdd8 52%, #00c896 100%);" + "background-color: #2563eb; " + "background-image: linear-gradient(118deg, #2563eb 0%, #06b6d4 52%, #c026d3 100%);" ) html_body = f""" @@ -250,7 +251,7 @@ def _get_email_template(content_html: str, content_text: str, subject: str) -> t

- Ce courriel vous est envoyé par DictIA. Pour toute question, contactez info@dictia.ca. + Ce courriel vous est envoyé par DictIA. Pour toute question, contactez info@dictia.ca.

© {datetime.utcnow().year} DictIA — Transcription IA conforme Loi 25 @@ -330,11 +331,11 @@ def send_verification_email(user) -> bool:

- Vérifier mon courriel + Vérifier mon courriel

Ou copiez-collez ce lien dans votre navigateur :

-

{verify_url}

+

{verify_url}

@@ -402,11 +403,11 @@ def send_password_reset_email(user) -> bool:

- Réinitialiser mon mot de passe + Réinitialiser mon mot de passe

Ou copiez-collez ce lien dans votre navigateur :

-

{reset_url}

+

{reset_url}

@@ -471,11 +472,11 @@ def send_magic_link_email(user, magic_url: str) -> bool:

- Se connecter à DictIA + Se connecter à DictIA

Ou copiez-collez ce lien dans votre navigateur :

-

{magic_url}

+

{magic_url}

diff --git a/static/css/marketing.css b/static/css/marketing.css index 3128dc9..a062f65 100644 --- a/static/css/marketing.css +++ b/static/css/marketing.css @@ -1703,31 +1703,31 @@ } } .border-brand-b1 { - border-color: #7c3aed; + border-color: #2563eb; } .border-brand-b1\/15 { - border-color: color-mix(in oklab, #7c3aed 15%, transparent); + border-color: color-mix(in oklab, #2563eb 15%, transparent); } .border-brand-b1\/20 { - border-color: color-mix(in oklab, #7c3aed 20%, transparent); + border-color: color-mix(in oklab, #2563eb 20%, transparent); } .border-brand-b1\/25 { - border-color: color-mix(in oklab, #7c3aed 25%, transparent); + border-color: color-mix(in oklab, #2563eb 25%, transparent); } .border-brand-b1\/30 { - border-color: color-mix(in oklab, #7c3aed 30%, transparent); + border-color: color-mix(in oklab, #2563eb 30%, transparent); } .border-brand-b1\/35 { - border-color: color-mix(in oklab, #7c3aed 35%, transparent); + border-color: color-mix(in oklab, #2563eb 35%, transparent); } .border-brand-b2\/40 { - border-color: color-mix(in oklab, #a855f7 40%, transparent); + border-color: color-mix(in oklab, #06b6d4 40%, transparent); } .border-brand-b3\/15 { - border-color: color-mix(in oklab, #06b6d4 15%, transparent); + border-color: color-mix(in oklab, #c026d3 15%, transparent); } .border-brand-b3\/60 { - border-color: color-mix(in oklab, #06b6d4 60%, transparent); + border-color: color-mix(in oklab, #c026d3 60%, transparent); } .border-brand-border { border-color: #e6ebf2; @@ -2030,28 +2030,28 @@ background-color: var(--color-blue-600); } .bg-brand-b1 { - background-color: #7c3aed; + background-color: #2563eb; } .bg-brand-b1\/5 { - background-color: color-mix(in oklab, #7c3aed 5%, transparent); + background-color: color-mix(in oklab, #2563eb 5%, transparent); } .bg-brand-b1\/10 { - background-color: color-mix(in oklab, #7c3aed 10%, transparent); + background-color: color-mix(in oklab, #2563eb 10%, transparent); } .bg-brand-b1\/15 { - background-color: color-mix(in oklab, #7c3aed 15%, transparent); + background-color: color-mix(in oklab, #2563eb 15%, transparent); } .bg-brand-b1\/\[0\.06\] { - background-color: color-mix(in oklab, #7c3aed 6%, transparent); + background-color: color-mix(in oklab, #2563eb 6%, transparent); } .bg-brand-b3 { - background-color: #06b6d4; + background-color: #c026d3; } .bg-brand-b3\/10 { - background-color: color-mix(in oklab, #06b6d4 10%, transparent); + background-color: color-mix(in oklab, #c026d3 10%, transparent); } .bg-brand-b3\/60 { - background-color: color-mix(in oklab, #06b6d4 60%, transparent); + background-color: color-mix(in oklab, #c026d3 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, #7c3aed 15%, transparent); + --tw-gradient-from: color-mix(in oklab, #2563eb 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, #7c3aed 6%, transparent); + --tw-gradient-from: color-mix(in oklab, #2563eb 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: #06b6d4; + --tw-gradient-from: #c026d3; --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: #7c3aed; + --tw-gradient-to: #2563eb; --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, #06b6d4 10%, transparent); + --tw-gradient-to: color-mix(in oklab, #c026d3 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, #06b6d4 4%, transparent); + --tw-gradient-to: color-mix(in oklab, #c026d3 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 { @@ -2998,31 +2998,31 @@ color: var(--color-blue-900); } .text-brand-b1 { - color: #7c3aed; + color: #2563eb; } .text-brand-b1\/45 { - color: color-mix(in oklab, #7c3aed 45%, transparent); + color: color-mix(in oklab, #2563eb 45%, transparent); } .text-brand-b1\/55 { - color: color-mix(in oklab, #7c3aed 55%, transparent); + color: color-mix(in oklab, #2563eb 55%, transparent); } .text-brand-b1\/60 { - color: color-mix(in oklab, #7c3aed 60%, transparent); + color: color-mix(in oklab, #2563eb 60%, transparent); } .text-brand-b1\/65 { - color: color-mix(in oklab, #7c3aed 65%, transparent); + color: color-mix(in oklab, #2563eb 65%, transparent); } .text-brand-b1\/70 { - color: color-mix(in oklab, #7c3aed 70%, transparent); + color: color-mix(in oklab, #2563eb 70%, transparent); } .text-brand-b1\/80 { - color: color-mix(in oklab, #7c3aed 80%, transparent); + color: color-mix(in oklab, #2563eb 80%, transparent); } .text-brand-b2 { - color: #a855f7; + color: #06b6d4; } .text-brand-b3 { - color: #06b6d4; + color: #c026d3; } .text-brand-navy { color: #060d1a; @@ -3324,7 +3324,7 @@ } } .accent-brand-b1 { - accent-color: #7c3aed; + accent-color: #2563eb; } .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\(124\,58\,237\,0\.35\)\] { - --tw-shadow: 0 0 28px var(--tw-shadow-color, rgba(124,58,237,0.35)); + .shadow-\[0_0_28px_rgba\(37\,99\,235\,0\.35\)\] { + --tw-shadow: 0 0 28px var(--tw-shadow-color, rgba(37,99,235,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(124, 58, 237, 0.28)); + --tw-shadow: 0 4px 20px var(--tw-shadow-color, rgba(37, 99, 235, 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: #7c3aed; + color: #2563eb; } } } @@ -3789,14 +3789,14 @@ .hover\:border-brand-b1 { &:hover { @media (hover: hover) { - border-color: #7c3aed; + border-color: #2563eb; } } } .hover\:border-brand-b1\/30 { &:hover { @media (hover: hover) { - border-color: color-mix(in oklab, #7c3aed 30%, transparent); + border-color: color-mix(in oklab, #2563eb 30%, transparent); } } } @@ -4150,7 +4150,7 @@ .hover\:from-brand-b1 { &:hover { @media (hover: hover) { - --tw-gradient-from: #7c3aed; + --tw-gradient-from: #2563eb; --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: #06b6d4; + --tw-gradient-to: #c026d3; --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: #7c3aed; + color: #2563eb; } } } @@ -4426,7 +4426,7 @@ .hover\:shadow-cta { &:hover { @media (hover: hover) { - --tw-shadow: 0 4px 20px var(--tw-shadow-color, rgba(124, 58, 237, 0.28)); + --tw-shadow: 0 4px 20px var(--tw-shadow-color, rgba(37, 99, 235, 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(124, 58, 237, 0.42)); + --tw-shadow: 0 8px 32px var(--tw-shadow-color, rgba(37, 99, 235, 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: #7c3aed; + outline-color: #2563eb; } } .focus-visible\:outline-red-700 { @@ -5890,13 +5890,13 @@ } @layer utilities { .grad-text { - background-image: linear-gradient(118deg, #7c3aed, #a855f7 52%, #06b6d4); + background-image: linear-gradient(118deg, #2563eb, #06b6d4 52%, #c026d3); -webkit-background-clip: text; background-clip: text; color: transparent; } .grad-bg { - background-image: linear-gradient(118deg, #7c3aed, #a855f7 52%, #06b6d4); + background-image: linear-gradient(118deg, #2563eb, #06b6d4 52%, #c026d3); color: var(--color-white); } .eyebrow { diff --git a/static/css/tailwind.config.js b/static/css/tailwind.config.js index 39cf8f9..4632382 100644 --- a/static/css/tailwind.config.js +++ b/static/css/tailwind.config.js @@ -6,9 +6,9 @@ module.exports = { extend: { colors: { brand: { - b1: '#7c3aed', - b2: '#a855f7', - b3: '#06b6d4', + b1: '#2563eb', + b2: '#06b6d4', + b3: '#c026d3', 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, #7c3aed, #a855f7 52%, #06b6d4)', + 'brand-grad': 'linear-gradient(118deg, #2563eb, #06b6d4 52%, #c026d3)', }, boxShadow: { - 'cta': '0 4px 20px rgba(124, 58, 237, 0.28)', - 'cta-hover': '0 8px 32px rgba(124, 58, 237, 0.42)', + 'cta': '0 4px 20px rgba(37, 99, 235, 0.28)', + 'cta-hover': '0 8px 32px rgba(37, 99, 235, 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(124, 58, 237, 0.28)' }, - '50%': { boxShadow: '0 8px 32px rgba(124, 58, 237, 0.42)' }, + '0%, 100%': { boxShadow: '0 4px 20px rgba(37, 99, 235, 0.28)' }, + '50%': { boxShadow: '0 8px 32px rgba(37, 99, 235, 0.42)' }, }, 'plus-breathe': { '0%, 100%': { transform: 'scale(1)' }, diff --git a/static/images/dictia-logo-128.png b/static/images/dictia-logo-128.png new file mode 100644 index 0000000..9d5c641 Binary files /dev/null and b/static/images/dictia-logo-128.png differ diff --git a/static/images/dictia-logo-fullres.png b/static/images/dictia-logo-fullres.png new file mode 100644 index 0000000..8e867ac Binary files /dev/null and b/static/images/dictia-logo-fullres.png differ diff --git a/static/images/dictia-logo-nom-fullres.png b/static/images/dictia-logo-nom-fullres.png new file mode 100644 index 0000000..559c345 Binary files /dev/null and b/static/images/dictia-logo-nom-fullres.png differ diff --git a/static/images/dictia-logo-nom.png b/static/images/dictia-logo-nom.png new file mode 100644 index 0000000..501f4b1 Binary files /dev/null and b/static/images/dictia-logo-nom.png differ diff --git a/static/images/dictia-logo-nom.svg b/static/images/dictia-logo-nom.svg new file mode 100644 index 0000000..8594b0a --- /dev/null +++ b/static/images/dictia-logo-nom.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/static/images/dictia-logo.png b/static/images/dictia-logo.png new file mode 100644 index 0000000..9d54f4b Binary files /dev/null and b/static/images/dictia-logo.png differ diff --git a/static/images/dictia-logo.svg b/static/images/dictia-logo.svg new file mode 100644 index 0000000..26a7309 --- /dev/null +++ b/static/images/dictia-logo.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/static/img/logo-dictia.png b/static/img/logo-dictia.png index 3ab0e3b..9d54f4b 100644 Binary files a/static/img/logo-dictia.png and b/static/img/logo-dictia.png differ diff --git a/templates/legal/_layout.html b/templates/legal/_layout.html index b4b360f..bba3e39 100644 --- a/templates/legal/_layout.html +++ b/templates/legal/_layout.html @@ -27,7 +27,7 @@ height: 4px; margin-top: 0.5rem; border-radius: 4px; - background: linear-gradient(118deg, #7c3aed, #a855f7 52%, #06b6d4); + background: linear-gradient(118deg, #2563eb, #06b6d4 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, #7c3aed, #a855f7 52%, #06b6d4); + background: linear-gradient(118deg, #2563eb, #06b6d4 52%, #06b6d4); -webkit-background-clip: text; background-clip: text; color: transparent; font-weight: 600; text-decoration: underline; - text-decoration-color: #7c3aed; + text-decoration-color: #2563eb; } .legal-content a:focus-visible { - outline: 2px solid #7c3aed; + outline: 2px solid #2563eb; outline-offset: 2px; border-radius: 2px; } @@ -95,7 +95,7 @@ background-color: #fafbfd; } .legal-content blockquote { - border-left: 4px solid #7c3aed; + border-left: 4px solid #2563eb; 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(124, 58, 237, 0.05); + background-color: rgba(37,99,235, 0.05); } .legal-toc a.is-active { - border-left-color: #7c3aed; - color: #7c3aed !important; - background-color: rgba(124, 58, 237, 0.06); + border-left-color: #2563eb; + color: #2563eb !important; + background-color: rgba(37,99,235, 0.06); } .legal-breadcrumb { position: sticky; diff --git a/templates/legal/index.html b/templates/legal/index.html index 026845c..84ecbe6 100644 --- a/templates/legal/index.html +++ b/templates/legal/index.html @@ -13,16 +13,16 @@ transform: translateY(-2px); } .legal-card:focus-visible { - outline: 2px solid #7c3aed; + outline: 2px solid #2563eb; outline-offset: 3px; } /* Icône circulaire avec dégradé de marque, contraste suffisant. */ .legal-card-icon { - background: linear-gradient(135deg, rgba(124,58,237,0.10), rgba(6,182,212,0.10)); - color: #7c3aed; + background: linear-gradient(135deg, rgba(37,99,235,0.10), rgba(6,182,212,0.10)); + color: #2563eb; } .legal-card.is-external .legal-card-icon { - background: linear-gradient(135deg, rgba(168,85,247,0.12), rgba(6,182,212,0.12)); + background: linear-gradient(135deg, rgba(6,182,212,0.12), rgba(6,182,212,0.12)); } /* Print : pas de bouton CTA, pas d'animations. */ @media print { diff --git a/templates/marketing/_footer.html b/templates/marketing/_footer.html index 43b8911..e24673d 100644 --- a/templates/marketing/_footer.html +++ b/templates/marketing/_footer.html @@ -5,7 +5,15 @@ {# Column 1 — Brand + contact #}

- DictIA + + + DictIA +

Transcription IA conforme Loi 25, conçue au Québec.

77 ch. de la Seigneurie
diff --git a/templates/marketing/base.html b/templates/marketing/base.html index ed5517b..1ab9e6c 100644 --- a/templates/marketing/base.html +++ b/templates/marketing/base.html @@ -31,7 +31,8 @@ - + + {% block schema %}{% endblock %} {% block head_extra %}{% endblock %} @@ -40,9 +41,17 @@
- - DictIA - Transcription + + + + DictIA + Transcription +
diff --git a/templates/marketing/landing.html b/templates/marketing/landing.html index 6e6251d..6c0ef4d 100644 --- a/templates/marketing/landing.html +++ b/templates/marketing/landing.html @@ -19,7 +19,7 @@ } .hero-flow-card.is-active { transform: scale(1.05); - box-shadow: 0 0 22px rgba(6, 182, 212, 0.45), 0 0 44px rgba(124, 58, 237, 0.18); + box-shadow: 0 0 22px rgba(6, 182, 212, 0.45), 0 0 44px rgba(37,99,235, 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(6,182,212,0.18) 0%, rgba(124,58,237,0.10) 50%, transparent 70%); + background: radial-gradient(circle, rgba(6,182,212,0.18) 0%, rgba(37,99,235,0.10) 50%, transparent 70%); animation: hero-shockwave 700ms cubic-bezier(0.2, 0.8, 0.2, 1) forwards; } /* ── Word-staggered title reveal ── */ @@ -148,7 +148,7 @@ {# Orb 2 — aqua, mid-right #}
@@ -160,7 +160,7 @@ 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;">
{# Horizontal accent line — gradient mauve to aqua to transparent #}
+ style="background: linear-gradient(90deg, transparent, rgba(37,99,235,0.3), rgba(6,182,212,0.2), transparent);">
{# 3D abstract orb — reacts to mouse via Alpine ox/oy → CSS variables #} @@ -174,14 +174,14 @@
{# Ambient blob #}
+ style="background: radial-gradient(ellipse at 40% 40%, rgba(96,165,250,0.14) 0%, rgba(6,182,212,0.07) 50%, transparent 75%); filter: blur(20px);">
{# Rotating mesh ring A #}
{# Rotating mesh ring B #}
{# Inner glow core #}
+ style="background: radial-gradient(circle, rgba(96,165,250,0.25) 0%, rgba(6,182,212,0.08) 60%, transparent 100%);"> @@ -273,7 +273,7 @@ {# Pulse halo behind the primary CTA #} {# Order bar — visible quand p ≈ 1 #} - + {% endfor %} {# Bouclier holographique (état ordre) #} @@ -1040,16 +1040,16 @@
+ :style="`color: ${p < 0.5 ? '#FF6B6B' : '#60a5fa'}`">
- Audio + Audio {# Icône Texte transcrit (droite) #} @@ -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(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); } + 0%, 100% { box-shadow: 0 0 26px rgba(6,182,212,0.55), 0 0 56px rgba(6,182,212,0.18); } + 50% { box-shadow: 0 0 38px rgba(6,182,212,0.75), 0 0 72px rgba(6,182,212,0.28); } } .hub-core { animation: hub-core-breathe 3.5s ease-in-out infinite; } /* Reduced motion : freeze everything */ @@ -1533,14 +1533,14 @@ {# Render bezier connections (visible strokes) — DictIA → Hubs (thick), Hub → Tools (thin) #} {# DictIA → Hubs #} - + {# Hub → Tool (lighter) #} - - - + + + @@ -1550,7 +1550,7 @@ {# Animated particles — DictIA → Hubs (bigger, dual particles) #} {% for hub in [ - ('docs', '#7c3aed', '0s', '2.4s'), + ('docs', '#2563eb', '0s', '2.4s'), ('comm', '#06b6d4', '0.8s', '2.4s'), ('auto', '#8b5cf6', '1.6s', '2.4s') ] %} @@ -1568,9 +1568,9 @@ {# Animated particles — Hub → Tool (smaller, fast) #} {% for tool in [ - ('word', '#7c3aed', '0s'), - ('google', '#7c3aed', '0.4s'), - ('obsidian', '#7c3aed', '0.8s'), + ('word', '#2563eb', '0s'), + ('google', '#2563eb', '0.4s'), + ('obsidian', '#2563eb', '0.8s'), ('outlook', '#06b6d4', '0.2s'), ('teams', '#06b6d4', '0.6s'), ('notion', '#06b6d4', '1.0s'), @@ -1602,7 +1602,7 @@ {# 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(124,58,237,0.10)', 'rgba(124,58,237,0.30)', 'text-violet-300'), + ('Documents', 'Word · Google Docs · Obsidian', '18.7%', 'rgba(37,99,235,0.10)', 'rgba(37,99,235,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') ] %} @@ -2148,7 +2148,7 @@ @@ -2225,15 +2225,15 @@
+ style="border-color: {{ 'rgba(239,68,68,0.20)' if reg.risk else 'rgba(37,99,235,0.15)' }};">
{{ reg.label }} + style="color: {{ '#dc2626' if reg.risk else '#2563eb' }};">{{ reg.label }} {{ reg.detail | safe }}
@@ -2513,7 +2513,7 @@ {# Two warm cosmic orbs to mirror the Hero — visual closure of the page #}
diff --git a/templates/marketing/tarifs.html b/templates/marketing/tarifs.html index 88e132a..e2bf139 100644 --- a/templates/marketing/tarifs.html +++ b/templates/marketing/tarifs.html @@ -117,7 +117,7 @@

diff --git a/tests/test_email_service_dictia.py b/tests/test_email_service_dictia.py index f4e6135..d6fd915 100644 --- a/tests/test_email_service_dictia.py +++ b/tests/test_email_service_dictia.py @@ -73,14 +73,20 @@ def test_email_template_uses_dictia_branding(): assert 'Loi' in html and '25' in html, 'Tagline must mention Loi 25' -def test_email_template_header_uses_brand_gradient_not_speakr_blue(): - """Header bg must use DictIA brand color #0062ff (or gradient), not the legacy - Speakr #2563eb.""" +def test_email_template_header_uses_brand_gradient(): + """Header bg must use the official DictIA brand gradient (blue → cyan → fuchsia, + matches the official logo). The legacy #0062ff/#00bdd8/#00c896 palette must be gone.""" with app.app_context(): from src.services.email import _get_email_template html, _ = _get_email_template('x', 'x', 'Test') - assert '#2563eb' not in html, 'Legacy Speakr header color must be removed' - assert '#0062ff' in html, 'DictIA brand blue must be present' + # Legacy palette must be removed + assert '#0062ff' not in html, 'Legacy header color #0062ff must be removed' + assert '#00bdd8' not in html, 'Legacy mid color #00bdd8 must be removed' + assert '#00c896' not in html, 'Legacy end color #00c896 must be removed' + # New official-logo palette must be present + assert '#2563eb' in html, 'DictIA brand blue (#2563eb) must be present' + assert '#06b6d4' in html, 'DictIA brand cyan (#06b6d4) must be present' + assert '#c026d3' in html, 'DictIA brand fuchsia (#c026d3) must be present' def test_verification_email_subject_is_french_with_dictia(): diff --git a/tests/test_marketing_landing_template.py b/tests/test_marketing_landing_template.py index b48c4d0..064abf7 100644 --- a/tests/test_marketing_landing_template.py +++ b/tests/test_marketing_landing_template.py @@ -110,11 +110,11 @@ def test_hero_has_dual_cta(): def test_hero_has_cosmic_orbs_background(): - """Hero has 3 radial gradient orbs (FlexiHub signature, mauve/aqua palette).""" + """Hero has 3 radial gradient orbs (FlexiHub signature, blue/aqua palette — matches official DictIA logo).""" client = app.test_client() body = client.get('/').data.decode('utf-8') - # 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" + # Look for the 3 orb opacities (16% blue, 7% aqua, 11% aqua accent) + assert 'rgba(37,99,235,0.16)' in body, "Missing primary blue 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"