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:
Ou copiez-collez ce lien dans votre navigateur :
-{verify_url}
+{verify_url}
@@ -402,11 +403,11 @@ def send_password_reset_email(user) -> bool:
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:
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 #}
Transcription IA conforme Loi 25, conçue au Québec.
77 ch. de la Seigneurie