feat(brand): logo officiel DictIA + palette blue/cyan/fuchsia (matche le logo)
Logos officiels installés : - static/images/dictia-logo.png (28 KB optimisé 256×256) - static/images/dictia-logo-128.png (10 KB retina) - static/images/dictia-logo-fullres.png (originaux conservés OG/social) - static/images/dictia-logo.svg + dictia-logo-nom.svg (cleaned C2PA metadata) - Header marketing/base.html : <img> 40×40 + wordmark "DictIA" + tagline "Transcription" - Footer marketing/_footer.html : <img> 36×36 + wordmark - Favicon mis à jour vers logo PNG Note : SVG sources sont des PNG base64 wrappés (pas de vrais paths) — PNG utilisé en production (8× plus léger), SVG conservé pour fallback. Palette canonique alignée sur le logo : - brand-b1 : #7c3aed (mauve) → #2563eb (blue-600 vibrant — primary) - brand-b2 : #a855f7 (mauve clair) → #06b6d4 (cyan-500 — aqua mid) - brand-b3 : #06b6d4 (aqua) → #c026d3 (fuchsia-600 — magenta accent) - Gradient signature : linear-gradient(118deg, #2563eb, #06b6d4 52%, #c026d3) - Box shadow CTA : rgba(37,99,235,0.28/0.42) - 72 remplacements hex/rgba dans 5 templates marketing/legal + email service Tests : 81 passed / 3 failed (3 échecs pré-existants /blog + trust-bar phrasing, non liés à ce changement). 0 régression. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@@ -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.
|
Wrap content in the DictIA branded email template.
|
||||||
|
|
||||||
Header uses the DictIA brand gradient (118deg, #0062ff → #00bdd8 → #00c896)
|
Header uses the DictIA brand gradient (118deg, #2563eb → #06b6d4 → #c026d3)
|
||||||
with a #0062ff fallback for clients that don't render gradients in inline
|
with a #2563eb fallback for clients that don't render gradients in inline
|
||||||
styles. Footer mentions ``info@dictia.ca`` (canonical contact) and the
|
styles. The gradient matches the official DictIA logo (blue → cyan → fuchsia).
|
||||||
|
Footer mentions ``info@dictia.ca`` (canonical contact) and the
|
||||||
Loi 25 tagline.
|
Loi 25 tagline.
|
||||||
|
|
||||||
Returns (html_body, text_body)
|
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
|
# Outside of request context, use a placeholder
|
||||||
logo_url = ""
|
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,
|
# 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 = (
|
header_bg = (
|
||||||
"background-color: #0062ff; "
|
"background-color: #2563eb; "
|
||||||
"background-image: linear-gradient(118deg, #0062ff 0%, #00bdd8 52%, #00c896 100%);"
|
"background-image: linear-gradient(118deg, #2563eb 0%, #06b6d4 52%, #c026d3 100%);"
|
||||||
)
|
)
|
||||||
|
|
||||||
html_body = f"""
|
html_body = f"""
|
||||||
@@ -250,7 +251,7 @@ def _get_email_template(content_html: str, content_text: str, subject: str) -> t
|
|||||||
<tr>
|
<tr>
|
||||||
<td style="text-align: center;">
|
<td style="text-align: center;">
|
||||||
<p style="color: #4b5563; font-size: 12px; margin: 0 0 8px 0;">
|
<p style="color: #4b5563; font-size: 12px; margin: 0 0 8px 0;">
|
||||||
Ce courriel vous est envoyé par DictIA. Pour toute question, contactez <a href="mailto:info@dictia.ca" style="color: #0062ff; text-decoration: none;">info@dictia.ca</a>.
|
Ce courriel vous est envoyé par DictIA. Pour toute question, contactez <a href="mailto:info@dictia.ca" style="color: #2563eb; text-decoration: none;">info@dictia.ca</a>.
|
||||||
</p>
|
</p>
|
||||||
<p style="color: #6b7280; font-size: 11px; margin: 0;">
|
<p style="color: #6b7280; font-size: 11px; margin: 0;">
|
||||||
© {datetime.utcnow().year} DictIA — Transcription IA conforme Loi 25
|
© {datetime.utcnow().year} DictIA — Transcription IA conforme Loi 25
|
||||||
@@ -330,11 +331,11 @@ def send_verification_email(user) -> bool:
|
|||||||
</p>
|
</p>
|
||||||
|
|
||||||
<div style="text-align: center; margin: 32px 0;">
|
<div style="text-align: center; margin: 32px 0;">
|
||||||
<a href="{verify_url}" style="display: inline-block; background-color: #0062ff; color: #ffffff; text-decoration: none; padding: 14px 32px; border-radius: 8px; font-weight: 600; font-size: 16px;">Vérifier mon courriel</a>
|
<a href="{verify_url}" style="display: inline-block; background-color: #2563eb; color: #ffffff; text-decoration: none; padding: 14px 32px; border-radius: 8px; font-weight: 600; font-size: 16px;">Vérifier mon courriel</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<p style="color: #4b5563; font-size: 14px; margin: 24px 0 8px 0;">Ou copiez-collez ce lien dans votre navigateur :</p>
|
<p style="color: #4b5563; font-size: 14px; margin: 24px 0 8px 0;">Ou copiez-collez ce lien dans votre navigateur :</p>
|
||||||
<p style="word-break: break-all; color: #0062ff; font-size: 14px; margin: 0; padding: 12px; background-color: #f7f9fc; border-radius: 6px;">{verify_url}</p>
|
<p style="word-break: break-all; color: #2563eb; font-size: 14px; margin: 0; padding: 12px; background-color: #f7f9fc; border-radius: 6px;">{verify_url}</p>
|
||||||
|
|
||||||
<div style="margin-top: 32px; padding-top: 24px; border-top: 1px solid #e6ebf2;">
|
<div style="margin-top: 32px; padding-top: 24px; border-top: 1px solid #e6ebf2;">
|
||||||
<p style="color: #4b5563; font-size: 13px; margin: 0;">
|
<p style="color: #4b5563; font-size: 13px; margin: 0;">
|
||||||
@@ -402,11 +403,11 @@ def send_password_reset_email(user) -> bool:
|
|||||||
</p>
|
</p>
|
||||||
|
|
||||||
<div style="text-align: center; margin: 32px 0;">
|
<div style="text-align: center; margin: 32px 0;">
|
||||||
<a href="{reset_url}" style="display: inline-block; background-color: #0062ff; color: #ffffff; text-decoration: none; padding: 14px 32px; border-radius: 8px; font-weight: 600; font-size: 16px;">Réinitialiser mon mot de passe</a>
|
<a href="{reset_url}" style="display: inline-block; background-color: #2563eb; color: #ffffff; text-decoration: none; padding: 14px 32px; border-radius: 8px; font-weight: 600; font-size: 16px;">Réinitialiser mon mot de passe</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<p style="color: #4b5563; font-size: 14px; margin: 24px 0 8px 0;">Ou copiez-collez ce lien dans votre navigateur :</p>
|
<p style="color: #4b5563; font-size: 14px; margin: 24px 0 8px 0;">Ou copiez-collez ce lien dans votre navigateur :</p>
|
||||||
<p style="word-break: break-all; color: #0062ff; font-size: 14px; margin: 0; padding: 12px; background-color: #f7f9fc; border-radius: 6px;">{reset_url}</p>
|
<p style="word-break: break-all; color: #2563eb; font-size: 14px; margin: 0; padding: 12px; background-color: #f7f9fc; border-radius: 6px;">{reset_url}</p>
|
||||||
|
|
||||||
<div style="margin-top: 32px; padding-top: 24px; border-top: 1px solid #e6ebf2;">
|
<div style="margin-top: 32px; padding-top: 24px; border-top: 1px solid #e6ebf2;">
|
||||||
<p style="color: #4b5563; font-size: 13px; margin: 0;">
|
<p style="color: #4b5563; font-size: 13px; margin: 0;">
|
||||||
@@ -471,11 +472,11 @@ def send_magic_link_email(user, magic_url: str) -> bool:
|
|||||||
</p>
|
</p>
|
||||||
|
|
||||||
<div style="text-align: center; margin: 32px 0;">
|
<div style="text-align: center; margin: 32px 0;">
|
||||||
<a href="{magic_url}" style="display: inline-block; background-color: #0062ff; color: #ffffff; text-decoration: none; padding: 14px 32px; border-radius: 8px; font-weight: 600; font-size: 16px;">Se connecter à DictIA</a>
|
<a href="{magic_url}" style="display: inline-block; background-color: #2563eb; color: #ffffff; text-decoration: none; padding: 14px 32px; border-radius: 8px; font-weight: 600; font-size: 16px;">Se connecter à DictIA</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<p style="color: #4b5563; font-size: 14px; margin: 24px 0 8px 0;">Ou copiez-collez ce lien dans votre navigateur :</p>
|
<p style="color: #4b5563; font-size: 14px; margin: 24px 0 8px 0;">Ou copiez-collez ce lien dans votre navigateur :</p>
|
||||||
<p style="word-break: break-all; color: #0062ff; font-size: 14px; margin: 0; padding: 12px; background-color: #f7f9fc; border-radius: 6px;">{magic_url}</p>
|
<p style="word-break: break-all; color: #2563eb; font-size: 14px; margin: 0; padding: 12px; background-color: #f7f9fc; border-radius: 6px;">{magic_url}</p>
|
||||||
|
|
||||||
<div style="margin-top: 32px; padding-top: 24px; border-top: 1px solid #e6ebf2;">
|
<div style="margin-top: 32px; padding-top: 24px; border-top: 1px solid #e6ebf2;">
|
||||||
<p style="color: #4b5563; font-size: 13px; margin: 0;">
|
<p style="color: #4b5563; font-size: 13px; margin: 0;">
|
||||||
|
|||||||
@@ -1703,31 +1703,31 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
.border-brand-b1 {
|
.border-brand-b1 {
|
||||||
border-color: #7c3aed;
|
border-color: #2563eb;
|
||||||
}
|
}
|
||||||
.border-brand-b1\/15 {
|
.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-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-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-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-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-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-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-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-brand-border {
|
||||||
border-color: #e6ebf2;
|
border-color: #e6ebf2;
|
||||||
@@ -2030,28 +2030,28 @@
|
|||||||
background-color: var(--color-blue-600);
|
background-color: var(--color-blue-600);
|
||||||
}
|
}
|
||||||
.bg-brand-b1 {
|
.bg-brand-b1 {
|
||||||
background-color: #7c3aed;
|
background-color: #2563eb;
|
||||||
}
|
}
|
||||||
.bg-brand-b1\/5 {
|
.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 {
|
.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 {
|
.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\] {
|
.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 {
|
.bg-brand-b3 {
|
||||||
background-color: #06b6d4;
|
background-color: #c026d3;
|
||||||
}
|
}
|
||||||
.bg-brand-b3\/10 {
|
.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 {
|
.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 {
|
.bg-brand-bg {
|
||||||
background-color: #f7f9fc;
|
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));
|
--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 {
|
.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));
|
--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\] {
|
.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));
|
--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 {
|
.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));
|
--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 {
|
.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));
|
--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 {
|
.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));
|
--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 {
|
.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));
|
--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\] {
|
.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));
|
--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 {
|
.to-purple-500 {
|
||||||
@@ -2998,31 +2998,31 @@
|
|||||||
color: var(--color-blue-900);
|
color: var(--color-blue-900);
|
||||||
}
|
}
|
||||||
.text-brand-b1 {
|
.text-brand-b1 {
|
||||||
color: #7c3aed;
|
color: #2563eb;
|
||||||
}
|
}
|
||||||
.text-brand-b1\/45 {
|
.text-brand-b1\/45 {
|
||||||
color: color-mix(in oklab, #7c3aed 45%, transparent);
|
color: color-mix(in oklab, #2563eb 45%, transparent);
|
||||||
}
|
}
|
||||||
.text-brand-b1\/55 {
|
.text-brand-b1\/55 {
|
||||||
color: color-mix(in oklab, #7c3aed 55%, transparent);
|
color: color-mix(in oklab, #2563eb 55%, transparent);
|
||||||
}
|
}
|
||||||
.text-brand-b1\/60 {
|
.text-brand-b1\/60 {
|
||||||
color: color-mix(in oklab, #7c3aed 60%, transparent);
|
color: color-mix(in oklab, #2563eb 60%, transparent);
|
||||||
}
|
}
|
||||||
.text-brand-b1\/65 {
|
.text-brand-b1\/65 {
|
||||||
color: color-mix(in oklab, #7c3aed 65%, transparent);
|
color: color-mix(in oklab, #2563eb 65%, transparent);
|
||||||
}
|
}
|
||||||
.text-brand-b1\/70 {
|
.text-brand-b1\/70 {
|
||||||
color: color-mix(in oklab, #7c3aed 70%, transparent);
|
color: color-mix(in oklab, #2563eb 70%, transparent);
|
||||||
}
|
}
|
||||||
.text-brand-b1\/80 {
|
.text-brand-b1\/80 {
|
||||||
color: color-mix(in oklab, #7c3aed 80%, transparent);
|
color: color-mix(in oklab, #2563eb 80%, transparent);
|
||||||
}
|
}
|
||||||
.text-brand-b2 {
|
.text-brand-b2 {
|
||||||
color: #a855f7;
|
color: #06b6d4;
|
||||||
}
|
}
|
||||||
.text-brand-b3 {
|
.text-brand-b3 {
|
||||||
color: #06b6d4;
|
color: #c026d3;
|
||||||
}
|
}
|
||||||
.text-brand-navy {
|
.text-brand-navy {
|
||||||
color: #060d1a;
|
color: #060d1a;
|
||||||
@@ -3324,7 +3324,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
.accent-brand-b1 {
|
.accent-brand-b1 {
|
||||||
accent-color: #7c3aed;
|
accent-color: #2563eb;
|
||||||
}
|
}
|
||||||
.opacity-0 {
|
.opacity-0 {
|
||||||
opacity: 0%;
|
opacity: 0%;
|
||||||
@@ -3378,8 +3378,8 @@
|
|||||||
--tw-shadow: 0 0 6px var(--tw-shadow-color, rgba(239,68,68,0.6));
|
--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);
|
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\)\] {
|
.shadow-\[0_0_28px_rgba\(37\,99\,235\,0\.35\)\] {
|
||||||
--tw-shadow: 0 0 28px var(--tw-shadow-color, rgba(124,58,237,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);
|
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\)\] {
|
.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);
|
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 {
|
.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);
|
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 {
|
.shadow-lg {
|
||||||
@@ -3579,7 +3579,7 @@
|
|||||||
.group-hover\:text-brand-b1 {
|
.group-hover\:text-brand-b1 {
|
||||||
&:is(:where(.group):hover *) {
|
&:is(:where(.group):hover *) {
|
||||||
@media (hover: hover) {
|
@media (hover: hover) {
|
||||||
color: #7c3aed;
|
color: #2563eb;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3789,14 +3789,14 @@
|
|||||||
.hover\:border-brand-b1 {
|
.hover\:border-brand-b1 {
|
||||||
&:hover {
|
&:hover {
|
||||||
@media (hover: hover) {
|
@media (hover: hover) {
|
||||||
border-color: #7c3aed;
|
border-color: #2563eb;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.hover\:border-brand-b1\/30 {
|
.hover\:border-brand-b1\/30 {
|
||||||
&:hover {
|
&:hover {
|
||||||
@media (hover: 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\:from-brand-b1 {
|
||||||
&:hover {
|
&:hover {
|
||||||
@media (hover: 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));
|
--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\:to-brand-b3 {
|
||||||
&:hover {
|
&:hover {
|
||||||
@media (hover: 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));
|
--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\:text-brand-b1 {
|
||||||
&:hover {
|
&:hover {
|
||||||
@media (hover: hover) {
|
@media (hover: hover) {
|
||||||
color: #7c3aed;
|
color: #2563eb;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4426,7 +4426,7 @@
|
|||||||
.hover\:shadow-cta {
|
.hover\:shadow-cta {
|
||||||
&:hover {
|
&:hover {
|
||||||
@media (hover: 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);
|
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\:shadow-cta-hover {
|
||||||
&:hover {
|
&:hover {
|
||||||
@media (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);
|
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-brand-b1 {
|
||||||
&:focus-visible {
|
&:focus-visible {
|
||||||
outline-color: #7c3aed;
|
outline-color: #2563eb;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.focus-visible\:outline-red-700 {
|
.focus-visible\:outline-red-700 {
|
||||||
@@ -5890,13 +5890,13 @@
|
|||||||
}
|
}
|
||||||
@layer utilities {
|
@layer utilities {
|
||||||
.grad-text {
|
.grad-text {
|
||||||
background-image: linear-gradient(118deg, #7c3aed, #a855f7 52%, #06b6d4);
|
background-image: linear-gradient(118deg, #2563eb, #06b6d4 52%, #c026d3);
|
||||||
-webkit-background-clip: text;
|
-webkit-background-clip: text;
|
||||||
background-clip: text;
|
background-clip: text;
|
||||||
color: transparent;
|
color: transparent;
|
||||||
}
|
}
|
||||||
.grad-bg {
|
.grad-bg {
|
||||||
background-image: linear-gradient(118deg, #7c3aed, #a855f7 52%, #06b6d4);
|
background-image: linear-gradient(118deg, #2563eb, #06b6d4 52%, #c026d3);
|
||||||
color: var(--color-white);
|
color: var(--color-white);
|
||||||
}
|
}
|
||||||
.eyebrow {
|
.eyebrow {
|
||||||
|
|||||||
@@ -6,9 +6,9 @@ module.exports = {
|
|||||||
extend: {
|
extend: {
|
||||||
colors: {
|
colors: {
|
||||||
brand: {
|
brand: {
|
||||||
b1: '#7c3aed',
|
b1: '#2563eb',
|
||||||
b2: '#a855f7',
|
b2: '#06b6d4',
|
||||||
b3: '#06b6d4',
|
b3: '#c026d3',
|
||||||
navy: '#060d1a',
|
navy: '#060d1a',
|
||||||
navy2: '#0b1525',
|
navy2: '#0b1525',
|
||||||
navy3: '#0f1e35',
|
navy3: '#0f1e35',
|
||||||
@@ -21,11 +21,11 @@ module.exports = {
|
|||||||
mono: ['JetBrains Mono Variable', 'JetBrains Mono', 'monospace'],
|
mono: ['JetBrains Mono Variable', 'JetBrains Mono', 'monospace'],
|
||||||
},
|
},
|
||||||
backgroundImage: {
|
backgroundImage: {
|
||||||
'brand-grad': 'linear-gradient(118deg, #7c3aed, #a855f7 52%, #06b6d4)',
|
'brand-grad': 'linear-gradient(118deg, #2563eb, #06b6d4 52%, #c026d3)',
|
||||||
},
|
},
|
||||||
boxShadow: {
|
boxShadow: {
|
||||||
'cta': '0 4px 20px rgba(124, 58, 237, 0.28)',
|
'cta': '0 4px 20px rgba(37, 99, 235, 0.28)',
|
||||||
'cta-hover': '0 8px 32px rgba(124, 58, 237, 0.42)',
|
'cta-hover': '0 8px 32px rgba(37, 99, 235, 0.42)',
|
||||||
},
|
},
|
||||||
borderRadius: {
|
borderRadius: {
|
||||||
DEFAULT: '0.75rem',
|
DEFAULT: '0.75rem',
|
||||||
@@ -44,8 +44,8 @@ module.exports = {
|
|||||||
'50%': { transform: 'translateY(-8px)' },
|
'50%': { transform: 'translateY(-8px)' },
|
||||||
},
|
},
|
||||||
'tc-pulse-glow': {
|
'tc-pulse-glow': {
|
||||||
'0%, 100%': { boxShadow: '0 4px 20px rgba(124, 58, 237, 0.28)' },
|
'0%, 100%': { boxShadow: '0 4px 20px rgba(37, 99, 235, 0.28)' },
|
||||||
'50%': { boxShadow: '0 8px 32px rgba(124, 58, 237, 0.42)' },
|
'50%': { boxShadow: '0 8px 32px rgba(37, 99, 235, 0.42)' },
|
||||||
},
|
},
|
||||||
'plus-breathe': {
|
'plus-breathe': {
|
||||||
'0%, 100%': { transform: 'scale(1)' },
|
'0%, 100%': { transform: 'scale(1)' },
|
||||||
|
|||||||
BIN
static/images/dictia-logo-128.png
Normal file
|
After Width: | Height: | Size: 9.9 KiB |
BIN
static/images/dictia-logo-fullres.png
Normal file
|
After Width: | Height: | Size: 1.2 MiB |
BIN
static/images/dictia-logo-nom-fullres.png
Normal file
|
After Width: | Height: | Size: 1.2 MiB |
BIN
static/images/dictia-logo-nom.png
Normal file
|
After Width: | Height: | Size: 33 KiB |
1
static/images/dictia-logo-nom.svg
Normal file
|
After Width: | Height: | Size: 269 KiB |
BIN
static/images/dictia-logo.png
Normal file
|
After Width: | Height: | Size: 28 KiB |
1
static/images/dictia-logo.svg
Normal file
|
After Width: | Height: | Size: 258 KiB |
|
Before Width: | Height: | Size: 106 KiB After Width: | Height: | Size: 28 KiB |
@@ -27,7 +27,7 @@
|
|||||||
height: 4px;
|
height: 4px;
|
||||||
margin-top: 0.5rem;
|
margin-top: 0.5rem;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
background: linear-gradient(118deg, #7c3aed, #a855f7 52%, #06b6d4);
|
background: linear-gradient(118deg, #2563eb, #06b6d4 52%, #06b6d4);
|
||||||
}
|
}
|
||||||
.legal-content h3 {
|
.legal-content h3 {
|
||||||
font-size: 1.25rem; /* 20px */
|
font-size: 1.25rem; /* 20px */
|
||||||
@@ -60,16 +60,16 @@
|
|||||||
.legal-content ol { list-style-type: decimal; list-style-position: outside; }
|
.legal-content ol { list-style-type: decimal; list-style-position: outside; }
|
||||||
.legal-content li { margin-bottom: 0.35rem; }
|
.legal-content li { margin-bottom: 0.35rem; }
|
||||||
.legal-content a {
|
.legal-content a {
|
||||||
background: linear-gradient(118deg, #7c3aed, #a855f7 52%, #06b6d4);
|
background: linear-gradient(118deg, #2563eb, #06b6d4 52%, #06b6d4);
|
||||||
-webkit-background-clip: text;
|
-webkit-background-clip: text;
|
||||||
background-clip: text;
|
background-clip: text;
|
||||||
color: transparent;
|
color: transparent;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
text-decoration: underline;
|
text-decoration: underline;
|
||||||
text-decoration-color: #7c3aed;
|
text-decoration-color: #2563eb;
|
||||||
}
|
}
|
||||||
.legal-content a:focus-visible {
|
.legal-content a:focus-visible {
|
||||||
outline: 2px solid #7c3aed;
|
outline: 2px solid #2563eb;
|
||||||
outline-offset: 2px;
|
outline-offset: 2px;
|
||||||
border-radius: 2px;
|
border-radius: 2px;
|
||||||
}
|
}
|
||||||
@@ -95,7 +95,7 @@
|
|||||||
background-color: #fafbfd;
|
background-color: #fafbfd;
|
||||||
}
|
}
|
||||||
.legal-content blockquote {
|
.legal-content blockquote {
|
||||||
border-left: 4px solid #7c3aed;
|
border-left: 4px solid #2563eb;
|
||||||
background-color: rgba(247, 249, 252, 0.6);
|
background-color: rgba(247, 249, 252, 0.6);
|
||||||
padding: 0.75rem 1rem;
|
padding: 0.75rem 1rem;
|
||||||
margin: 1.25rem 0;
|
margin: 1.25rem 0;
|
||||||
@@ -156,12 +156,12 @@
|
|||||||
transition: color 150ms ease, border-color 150ms ease, background-color 150ms ease;
|
transition: color 150ms ease, border-color 150ms ease, background-color 150ms ease;
|
||||||
}
|
}
|
||||||
.legal-toc a:hover {
|
.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 {
|
.legal-toc a.is-active {
|
||||||
border-left-color: #7c3aed;
|
border-left-color: #2563eb;
|
||||||
color: #7c3aed !important;
|
color: #2563eb !important;
|
||||||
background-color: rgba(124, 58, 237, 0.06);
|
background-color: rgba(37,99,235, 0.06);
|
||||||
}
|
}
|
||||||
.legal-breadcrumb {
|
.legal-breadcrumb {
|
||||||
position: sticky;
|
position: sticky;
|
||||||
|
|||||||
@@ -13,16 +13,16 @@
|
|||||||
transform: translateY(-2px);
|
transform: translateY(-2px);
|
||||||
}
|
}
|
||||||
.legal-card:focus-visible {
|
.legal-card:focus-visible {
|
||||||
outline: 2px solid #7c3aed;
|
outline: 2px solid #2563eb;
|
||||||
outline-offset: 3px;
|
outline-offset: 3px;
|
||||||
}
|
}
|
||||||
/* Icône circulaire avec dégradé de marque, contraste suffisant. */
|
/* Icône circulaire avec dégradé de marque, contraste suffisant. */
|
||||||
.legal-card-icon {
|
.legal-card-icon {
|
||||||
background: linear-gradient(135deg, rgba(124,58,237,0.10), rgba(6,182,212,0.10));
|
background: linear-gradient(135deg, rgba(37,99,235,0.10), rgba(6,182,212,0.10));
|
||||||
color: #7c3aed;
|
color: #2563eb;
|
||||||
}
|
}
|
||||||
.legal-card.is-external .legal-card-icon {
|
.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. */
|
/* Print : pas de bouton CTA, pas d'animations. */
|
||||||
@media print {
|
@media print {
|
||||||
|
|||||||
@@ -5,7 +5,15 @@
|
|||||||
|
|
||||||
{# Column 1 — Brand + contact #}
|
{# Column 1 — Brand + contact #}
|
||||||
<div>
|
<div>
|
||||||
<a href="/" class="font-black text-xl grad-text" aria-label="DictIA — page d'accueil">DictIA</a>
|
<a href="/" class="inline-flex items-center gap-3" aria-label="DictIA — page d'accueil">
|
||||||
|
<img src="{{ url_for('static', filename='images/dictia-logo.png') }}"
|
||||||
|
alt=""
|
||||||
|
width="36"
|
||||||
|
height="36"
|
||||||
|
class="w-9 h-9"
|
||||||
|
aria-hidden="true">
|
||||||
|
<span class="font-black text-xl grad-text">DictIA</span>
|
||||||
|
</a>
|
||||||
<p class="text-sm text-white/70 mt-3">Transcription IA conforme Loi 25, conçue au Québec.</p>
|
<p class="text-sm text-white/70 mt-3">Transcription IA conforme Loi 25, conçue au Québec.</p>
|
||||||
<address class="not-italic text-xs text-white/70 mt-4 leading-relaxed">
|
<address class="not-italic text-xs text-white/70 mt-4 leading-relaxed">
|
||||||
77 ch. de la Seigneurie<br>
|
77 ch. de la Seigneurie<br>
|
||||||
|
|||||||
@@ -31,7 +31,8 @@
|
|||||||
<link rel="stylesheet" href="/static/css/marketing.css">
|
<link rel="stylesheet" href="/static/css/marketing.css">
|
||||||
|
|
||||||
<!-- Favicon -->
|
<!-- Favicon -->
|
||||||
<link rel="icon" type="image/svg+xml" href="/static/images/favicon.svg">
|
<link rel="icon" type="image/png" href="/static/images/dictia-logo.png">
|
||||||
|
<link rel="alternate icon" type="image/svg+xml" href="/static/images/favicon.svg">
|
||||||
|
|
||||||
{% block schema %}{% endblock %}
|
{% block schema %}{% endblock %}
|
||||||
{% block head_extra %}{% endblock %}
|
{% block head_extra %}{% endblock %}
|
||||||
@@ -40,9 +41,17 @@
|
|||||||
<!-- Glassmorphism header (FlexiHub style: 62px, navy/.97 + backdrop-blur-xl + 0.045 border) -->
|
<!-- Glassmorphism header (FlexiHub style: 62px, navy/.97 + backdrop-blur-xl + 0.045 border) -->
|
||||||
<header class="fixed top-0 inset-x-0 z-50 h-[62px] bg-brand-navy/[0.97] backdrop-blur-xl border-b border-white/[0.045]">
|
<header class="fixed top-0 inset-x-0 z-50 h-[62px] bg-brand-navy/[0.97] backdrop-blur-xl border-b border-white/[0.045]">
|
||||||
<div class="max-w-[1200px] mx-auto h-full px-6 flex items-center justify-between">
|
<div class="max-w-[1200px] mx-auto h-full px-6 flex items-center justify-between">
|
||||||
<a href="/" class="flex flex-col leading-none" aria-label="DictIA — Transcription, accueil">
|
<a href="/" class="flex items-center gap-3 leading-none" aria-label="DictIA — Transcription, accueil">
|
||||||
<span class="font-black text-xl tracking-tight grad-text">DictIA</span>
|
<img src="{{ url_for('static', filename='images/dictia-logo.png') }}"
|
||||||
<span class="text-[10px] uppercase tracking-[0.2em] text-white font-medium mt-0.5">Transcription</span>
|
alt=""
|
||||||
|
width="40"
|
||||||
|
height="40"
|
||||||
|
class="w-10 h-10 flex-shrink-0"
|
||||||
|
aria-hidden="true">
|
||||||
|
<span class="flex flex-col">
|
||||||
|
<span class="font-black text-xl tracking-tight grad-text">DictIA</span>
|
||||||
|
<span class="text-[10px] uppercase tracking-[0.2em] text-white font-medium mt-0.5">Transcription</span>
|
||||||
|
</span>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
<nav class="hidden md:flex gap-8 text-sm font-medium text-white/80" aria-label="Navigation principale">
|
<nav class="hidden md:flex gap-8 text-sm font-medium text-white/80" aria-label="Navigation principale">
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
bottom: -10px;
|
bottom: -10px;
|
||||||
width: 0;
|
width: 0;
|
||||||
height: 3px;
|
height: 3px;
|
||||||
background: linear-gradient(118deg, #7c3aed, #a855f7 52%, #06b6d4);
|
background: linear-gradient(118deg, #2563eb, #06b6d4 52%, #06b6d4);
|
||||||
transform: translateX(-50%);
|
transform: translateX(-50%);
|
||||||
transition: width 600ms ease-out;
|
transition: width 600ms ease-out;
|
||||||
}
|
}
|
||||||
@@ -27,16 +27,16 @@
|
|||||||
|
|
||||||
/* Hover lift cards */
|
/* Hover lift cards */
|
||||||
.ani-lift { transition: transform 200ms ease-out, box-shadow 200ms ease-out; }
|
.ani-lift { transition: transform 200ms ease-out, box-shadow 200ms ease-out; }
|
||||||
.ani-lift:hover { transform: translateY(-2px); box-shadow: 0 8px 32px rgba(124, 58, 237, 0.18); }
|
.ani-lift:hover { transform: translateY(-2px); box-shadow: 0 8px 32px rgba(37,99,235, 0.18); }
|
||||||
|
|
||||||
/* Sticky sub-nav active link */
|
/* Sticky sub-nav active link */
|
||||||
.subnav-link[aria-current="true"] { color: #7c3aed; }
|
.subnav-link[aria-current="true"] { color: #2563eb; }
|
||||||
.subnav-link[aria-current="true"]::after {
|
.subnav-link[aria-current="true"]::after {
|
||||||
content: '';
|
content: '';
|
||||||
display: block;
|
display: block;
|
||||||
height: 2px;
|
height: 2px;
|
||||||
margin-top: 4px;
|
margin-top: 4px;
|
||||||
background: linear-gradient(118deg, #7c3aed, #a855f7 52%, #06b6d4);
|
background: linear-gradient(118deg, #2563eb, #06b6d4 52%, #06b6d4);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Cosmic float orbs (n'utilise pas tc-float-y pour éviter rebuild) */
|
/* Cosmic float orbs (n'utilise pas tc-float-y pour éviter rebuild) */
|
||||||
@@ -46,8 +46,8 @@
|
|||||||
|
|
||||||
/* DictIA Cloud pulse glow */
|
/* DictIA Cloud pulse glow */
|
||||||
@keyframes card-pulse-glow {
|
@keyframes card-pulse-glow {
|
||||||
0%, 100% { box-shadow: 0 4px 20px rgba(124, 58, 237, 0.28); }
|
0%, 100% { box-shadow: 0 4px 20px rgba(37,99,235, 0.28); }
|
||||||
50% { box-shadow: 0 12px 40px rgba(124, 58, 237, 0.5); }
|
50% { box-shadow: 0 12px 40px rgba(37,99,235, 0.5); }
|
||||||
}
|
}
|
||||||
.card-pulse-glow { animation: card-pulse-glow 3s ease-in-out infinite; }
|
.card-pulse-glow { animation: card-pulse-glow 3s ease-in-out infinite; }
|
||||||
|
|
||||||
@@ -76,13 +76,13 @@
|
|||||||
{# Cosmic orbs background — float animation subtile #}
|
{# Cosmic orbs background — float animation subtile #}
|
||||||
<div class="absolute inset-0 pointer-events-none" aria-hidden="true">
|
<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"
|
<div class="orb-float-a absolute top-1/4 left-1/4 w-[600px] h-[600px] rounded-full"
|
||||||
style="background: radial-gradient(circle, rgba(124,58,237,0.16) 0%, transparent 60%); filter: blur(40px);"></div>
|
style="background: radial-gradient(circle, rgba(37,99,235,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"
|
<div class="orb-float-b absolute top-1/2 right-1/4 w-[500px] h-[500px] rounded-full"
|
||||||
style="background: radial-gradient(circle, rgba(6,182,212,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"
|
<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>
|
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"
|
<div class="absolute top-1/3 left-0 right-0 h-px"
|
||||||
style="background: linear-gradient(90deg, transparent, rgba(124,58,237,0.3), rgba(6,182,212,0.2), transparent);"></div>
|
style="background: linear-gradient(90deg, transparent, rgba(37,99,235,0.3), rgba(6,182,212,0.2), transparent);"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="relative max-w-[1200px] mx-auto px-6 text-center">
|
<div class="relative max-w-[1200px] mx-auto px-6 text-center">
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
}
|
}
|
||||||
.hero-flow-card.is-active {
|
.hero-flow-card.is-active {
|
||||||
transform: scale(1.05);
|
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; }
|
.hero-flow-card.is-inactive { opacity: 0.45; }
|
||||||
/* Animated arrow draw between cards */
|
/* Animated arrow draw between cards */
|
||||||
@@ -63,7 +63,7 @@
|
|||||||
border-radius: 9999px;
|
border-radius: 9999px;
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
z-index: 9999;
|
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;
|
animation: hero-shockwave 700ms cubic-bezier(0.2, 0.8, 0.2, 1) forwards;
|
||||||
}
|
}
|
||||||
/* ── Word-staggered title reveal ── */
|
/* ── Word-staggered title reveal ── */
|
||||||
@@ -148,7 +148,7 @@
|
|||||||
<div class="absolute inset-0 pointer-events-none" aria-hidden="true">
|
<div class="absolute inset-0 pointer-events-none" aria-hidden="true">
|
||||||
{# Orb 1 — primary mauve, 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"
|
<div class="absolute top-1/4 left-1/4 w-[600px] h-[600px] rounded-full opacity-100"
|
||||||
style="background: radial-gradient(circle, rgba(124,58,237,0.16) 0%, transparent 60%); filter: blur(40px);"></div>
|
style="background: radial-gradient(circle, rgba(37,99,235,0.16) 0%, transparent 60%); filter: blur(40px);"></div>
|
||||||
{# Orb 2 — aqua, mid-right #}
|
{# Orb 2 — aqua, mid-right #}
|
||||||
<div class="absolute top-1/2 right-1/4 w-[500px] h-[500px] rounded-full"
|
<div class="absolute top-1/2 right-1/4 w-[500px] h-[500px] rounded-full"
|
||||||
style="background: radial-gradient(circle, rgba(6,182,212,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>
|
||||||
@@ -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;"></div>
|
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 mauve to aqua to transparent #}
|
{# Horizontal accent line — gradient mauve to aqua to transparent #}
|
||||||
<div class="absolute top-1/3 left-0 right-0 h-px"
|
<div class="absolute top-1/3 left-0 right-0 h-px"
|
||||||
style="background: linear-gradient(90deg, transparent, rgba(124,58,237,0.3), rgba(6,182,212,0.2), transparent);"></div>
|
style="background: linear-gradient(90deg, transparent, rgba(37,99,235,0.3), rgba(6,182,212,0.2), transparent);"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{# 3D abstract orb — reacts to mouse via Alpine ox/oy → CSS variables #}
|
{# 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>
|
<div class="absolute inset-0 rounded-full border border-brand-b3/15" style="transform: scale(1.35);"></div>
|
||||||
{# Ambient blob #}
|
{# Ambient blob #}
|
||||||
<div class="absolute inset-0 rounded-full"
|
<div class="absolute inset-0 rounded-full"
|
||||||
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>
|
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);"></div>
|
||||||
{# Rotating mesh ring A #}
|
{# 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>
|
<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 #}
|
{# 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>
|
<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 #}
|
{# Inner glow core #}
|
||||||
<div class="absolute inset-[30%] rounded-full"
|
<div class="absolute inset-[30%] rounded-full"
|
||||||
style="background: radial-gradient(circle, rgba(167,139,250,0.25) 0%, rgba(6,182,212,0.08) 60%, transparent 100%);"></div>
|
style="background: radial-gradient(circle, rgba(96,165,250,0.25) 0%, rgba(6,182,212,0.08) 60%, transparent 100%);"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -273,7 +273,7 @@
|
|||||||
<span class="relative inline-flex">
|
<span class="relative inline-flex">
|
||||||
{# Pulse halo behind the primary CTA #}
|
{# Pulse halo behind the primary CTA #}
|
||||||
<span class="hero-cta-halo absolute -inset-1 rounded pointer-events-none"
|
<span class="hero-cta-halo absolute -inset-1 rounded pointer-events-none"
|
||||||
style="background: radial-gradient(ellipse, rgba(167,139,250,0.50) 0%, transparent 70%);"
|
style="background: radial-gradient(ellipse, rgba(96,165,250,0.50) 0%, transparent 70%);"
|
||||||
aria-hidden="true"></span>
|
aria-hidden="true"></span>
|
||||||
<a
|
<a
|
||||||
href="/contact"
|
href="/contact"
|
||||||
@@ -1024,13 +1024,13 @@
|
|||||||
</g>
|
</g>
|
||||||
{# Order bar — visible quand p ≈ 1 #}
|
{# Order bar — visible quand p ≈ 1 #}
|
||||||
<g class="wave-bar" :style="`opacity: ${p}`">
|
<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(167,139,250,0.6)"/>
|
<rect x="{{ cx - bw / 2 }}" y="{{ 25 - order_heights[i] / 2 }}" width="{{ bw }}" height="{{ order_heights[i] }}" rx="{{ bw / 2 }}" fill="rgba(96,165,250,0.6)"/>
|
||||||
</g>
|
</g>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|
||||||
{# Bouclier holographique (état ordre) #}
|
{# 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"
|
<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(167,139,250,0.55)" stroke-width="0.55" stroke-dasharray="2.5 2"
|
fill="none" stroke="rgba(96,165,250,0.55)" stroke-width="0.55" stroke-dasharray="2.5 2"
|
||||||
:style="`opacity: ${orderOp * 0.4}`"/>
|
:style="`opacity: ${orderOp * 0.4}`"/>
|
||||||
</svg>
|
</svg>
|
||||||
|
|
||||||
@@ -1040,16 +1040,16 @@
|
|||||||
<div class="w-10 h-10 md:w-12 md:h-12 rounded flex items-center justify-center backdrop-blur-md border"
|
<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 + (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);`">
|
: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"
|
<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' : '#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>
|
:style="`color: ${p < 0.5 ? '#FF6B6B' : '#60a5fa'}`"><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>
|
</div>
|
||||||
<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>
|
<span class="text-[8px] font-medium" :style="`color: ${p < 0.5 ? 'rgba(255,107,107,0.65)' : 'rgba(96,165,250,0.65)'}`">Audio</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{# Icône Texte transcrit (droite) #}
|
{# 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"
|
<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">
|
: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"
|
<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(167,139,250,0.15), rgba(124,58,237,0.07)); box-shadow: 0 0 18px rgba(167,139,250,0.18);">
|
style="background: linear-gradient(135deg, rgba(96,165,250,0.15), rgba(37,99,235,0.07)); box-shadow: 0 0 18px rgba(96,165,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>
|
<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>
|
</div>
|
||||||
<span class="text-[8px] font-medium text-brand-b1/70">Texte</span>
|
<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">
|
<div class="absolute inset-0 z-10 pointer-events-none" :style="`opacity: ${orderOp}`" aria-hidden="true">
|
||||||
{% for fy in [18, 21, 24, 27, 30] %}
|
{% for fy in [18, 21, 24, 27, 30] %}
|
||||||
<span class="wave-flow absolute w-1 h-1 rounded-full bg-brand-b1"
|
<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(167,139,250,0.7); animation-delay: {{ loop.index0 * 0.32 }}s;"></span>
|
style="top: {{ fy }}%; left: 12%; box-shadow: 0 0 5px rgba(96,165,250,0.7); animation-delay: {{ loop.index0 * 0.32 }}s;"></span>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -1104,7 +1104,7 @@
|
|||||||
{'text': '100 % Confidentiel — Hébergé au Qc', 'x': 18, 'y': 40}
|
{'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"
|
<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(167,139,250,0.10); border: 1px solid rgba(167,139,250,0.20);">
|
style="left: {{ sol.x }}%; top: {{ sol.y }}%; transform: translate(-50%, -50%); background: rgba(96,165,250,0.10); border: 1px solid rgba(96,165,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>
|
<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>
|
<span class="text-[8px] md:text-[10px] text-white/80 whitespace-nowrap">{{ sol.text | safe }}</span>
|
||||||
</div>
|
</div>
|
||||||
@@ -1129,7 +1129,7 @@
|
|||||||
@click.stop="toggle()"
|
@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="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'"
|
:class="activated ? 'border-brand-b1/30 text-brand-b1' : 'border-white/15 text-white/70'"
|
||||||
: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));'"
|
:style="activated ? 'background: linear-gradient(135deg, rgba(96,165,250,0.2), rgba(37,99,235,0.1));' : 'background: linear-gradient(135deg, rgba(255,255,255,0.08), rgba(255,255,255,0.03));'"
|
||||||
x-cloak>
|
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>
|
<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>
|
<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="absolute h-px bg-brand-border" style="top: 44px; left: 12.5%; right: 12.5%;" aria-hidden="true"></div>
|
||||||
<div
|
<div
|
||||||
class="pipeline-track-fill absolute h-[2px]"
|
class="pipeline-track-fill absolute h-[2px]"
|
||||||
style="top: 43px; left: 12.5%; width: 75%; background: linear-gradient(90deg, #7c3aed 0%, #a855f7 100%);"
|
style="top: 43px; left: 12.5%; width: 75%; background: linear-gradient(90deg, #2563eb 0%, #06b6d4 100%);"
|
||||||
:style="`transform: scaleX(${steps[active].fillPct / 100})`"
|
:style="`transform: scaleX(${steps[active].fillPct / 100})`"
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
></div>
|
></div>
|
||||||
@@ -1228,7 +1228,7 @@
|
|||||||
{# Moving glowing dot — left transitions via CSS #}
|
{# Moving glowing dot — left transitions via CSS #}
|
||||||
<div
|
<div
|
||||||
class="pipeline-dot absolute w-3.5 h-3.5 rounded-full bg-white pointer-events-none z-10"
|
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(168,85,247,0.55), 0 0 36px rgba(124,58,237,0.35);"
|
style="top: 44px; transform: translate(-50%, -50%); box-shadow: 0 0 18px rgba(6,182,212,0.55), 0 0 36px rgba(37,99,235,0.35);"
|
||||||
:style="`left: ${steps[active].positionPct}%`"
|
:style="`left: ${steps[active].positionPct}%`"
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
></div>
|
></div>
|
||||||
@@ -1258,7 +1258,7 @@
|
|||||||
<span
|
<span
|
||||||
class="relative w-[88px] h-[88px] rounded-full border-2 flex items-center justify-center transition-all duration-300"
|
class="relative w-[88px] h-[88px] rounded-full border-2 flex items-center justify-center transition-all duration-300"
|
||||||
:class="{
|
:class="{
|
||||||
'border-brand-b1 bg-brand-b1/10 scale-105 shadow-[0_0_28px_rgba(124,58,237,0.35)]': active === {{ loop.index0 }},
|
'border-brand-b1 bg-brand-b1/10 scale-105 shadow-[0_0_28px_rgba(37,99,235,0.35)]': active === {{ loop.index0 }},
|
||||||
'border-brand-b3/60 bg-brand-b3/10': active > {{ loop.index0 }},
|
'border-brand-b3/60 bg-brand-b3/10': active > {{ loop.index0 }},
|
||||||
'border-brand-border bg-white': active < {{ loop.index0 }}
|
'border-brand-border bg-white': active < {{ loop.index0 }}
|
||||||
}"
|
}"
|
||||||
@@ -1283,7 +1283,7 @@
|
|||||||
viewBox="0 0 88 88"
|
viewBox="0 0 88 88"
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
>
|
>
|
||||||
<circle class="pipeline-sweep-ring" cx="44" cy="44" r="41" fill="none" stroke="#7c3aed" stroke-width="2" stroke-linecap="round"></circle>
|
<circle class="pipeline-sweep-ring" cx="44" cy="44" r="41" fill="none" stroke="#2563eb" stroke-width="2" stroke-linecap="round"></circle>
|
||||||
</svg>
|
</svg>
|
||||||
</template>
|
</template>
|
||||||
</span>
|
</span>
|
||||||
@@ -1318,7 +1318,7 @@
|
|||||||
<span
|
<span
|
||||||
:key="active"
|
:key="active"
|
||||||
class="pipeline-underline absolute bottom-0 left-0 h-[2px] w-full"
|
class="pipeline-underline absolute bottom-0 left-0 h-[2px] w-full"
|
||||||
style="background: linear-gradient(90deg, #7c3aed, #a855f7);"
|
style="background: linear-gradient(90deg, #2563eb, #06b6d4);"
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
></span>
|
></span>
|
||||||
</div>
|
</div>
|
||||||
@@ -1470,8 +1470,8 @@
|
|||||||
.hub-ring-3 { animation-delay: 2s; }
|
.hub-ring-3 { animation-delay: 2s; }
|
||||||
/* DictIA core breathing glow */
|
/* DictIA core breathing glow */
|
||||||
@keyframes hub-core-breathe {
|
@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); }
|
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(168,85,247,0.75), 0 0 72px rgba(168,85,247,0.28); }
|
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; }
|
.hub-core { animation: hub-core-breathe 3.5s ease-in-out infinite; }
|
||||||
/* Reduced motion : freeze everything */
|
/* Reduced motion : freeze everything */
|
||||||
@@ -1533,14 +1533,14 @@
|
|||||||
|
|
||||||
{# Render bezier connections (visible strokes) — DictIA → Hubs (thick), Hub → Tools (thin) #}
|
{# Render bezier connections (visible strokes) — DictIA → Hubs (thick), Hub → Tools (thin) #}
|
||||||
{# DictIA → Hubs #}
|
{# DictIA → Hubs #}
|
||||||
<use href="#hub-path-docs" fill="none" stroke="#7c3aed" stroke-width="1.5" opacity="0.55" />
|
<use href="#hub-path-docs" fill="none" stroke="#2563eb" 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-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" />
|
<use href="#hub-path-auto" fill="none" stroke="#8b5cf6" stroke-width="1.5" opacity="0.55" />
|
||||||
|
|
||||||
{# Hub → Tool (lighter) #}
|
{# Hub → Tool (lighter) #}
|
||||||
<use href="#hub-path-word" fill="none" stroke="#7c3aed" stroke-width="1" opacity="0.30" />
|
<use href="#hub-path-word" fill="none" stroke="#2563eb" 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-google" fill="none" stroke="#2563eb" 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-obsidian" fill="none" stroke="#2563eb" 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-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-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-notion" fill="none" stroke="#06b6d4" stroke-width="1" opacity="0.30" />
|
||||||
@@ -1550,7 +1550,7 @@
|
|||||||
|
|
||||||
{# Animated particles — DictIA → Hubs (bigger, dual particles) #}
|
{# Animated particles — DictIA → Hubs (bigger, dual particles) #}
|
||||||
{% for hub in [
|
{% for hub in [
|
||||||
('docs', '#7c3aed', '0s', '2.4s'),
|
('docs', '#2563eb', '0s', '2.4s'),
|
||||||
('comm', '#06b6d4', '0.8s', '2.4s'),
|
('comm', '#06b6d4', '0.8s', '2.4s'),
|
||||||
('auto', '#8b5cf6', '1.6s', '2.4s')
|
('auto', '#8b5cf6', '1.6s', '2.4s')
|
||||||
] %}
|
] %}
|
||||||
@@ -1568,9 +1568,9 @@
|
|||||||
|
|
||||||
{# Animated particles — Hub → Tool (smaller, fast) #}
|
{# Animated particles — Hub → Tool (smaller, fast) #}
|
||||||
{% for tool in [
|
{% for tool in [
|
||||||
('word', '#7c3aed', '0s'),
|
('word', '#2563eb', '0s'),
|
||||||
('google', '#7c3aed', '0.4s'),
|
('google', '#2563eb', '0.4s'),
|
||||||
('obsidian', '#7c3aed', '0.8s'),
|
('obsidian', '#2563eb', '0.8s'),
|
||||||
('outlook', '#06b6d4', '0.2s'),
|
('outlook', '#06b6d4', '0.2s'),
|
||||||
('teams', '#06b6d4', '0.6s'),
|
('teams', '#06b6d4', '0.6s'),
|
||||||
('notion', '#06b6d4', '1.0s'),
|
('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) #}
|
{# 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 = [
|
{% 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'),
|
('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')
|
('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 @@
|
|||||||
<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"
|
<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="relative w-5 h-5 transition-colors duration-300"
|
||||||
:class="step >= 2 ? 'text-amber-500' : 'text-brand-b1'"
|
: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(124,58,237,0.5)'})`"
|
:style="`filter: drop-shadow(0 0 ${step >= 2 ? '6px rgba(245,158,11,0.7)' : '4px rgba(37,99,235,0.5)'})`"
|
||||||
aria-hidden="true">
|
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"/>
|
<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>
|
</svg>
|
||||||
@@ -2225,15 +2225,15 @@
|
|||||||
<a href="{{ reg.href }}" target="_blank" rel="noopener noreferrer"
|
<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="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' : ''"
|
:class="flashIdx === {{ loop.index0 }} ? 'is-flash' : ''"
|
||||||
style="border-color: {{ 'rgba(239,68,68,0.20)' if reg.risk else 'rgba(124,58,237,0.15)' }};">
|
style="border-color: {{ 'rgba(239,68,68,0.20)' if reg.risk else 'rgba(37,99,235,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"
|
<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"
|
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(124,58,237,0.55)' }};"
|
style="color: {{ 'rgba(239,68,68,0.65)' if reg.risk else 'rgba(37,99,235,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>
|
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="min-w-0 flex-1">
|
||||||
<div class="flex items-start gap-1.5 flex-wrap">
|
<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"
|
<span class="cadre-reg-label font-semibold text-[11px] leading-tight shrink-0 transition-colors"
|
||||||
style="color: {{ '#dc2626' if reg.risk else '#7c3aed' }};">{{ reg.label }}</span>
|
style="color: {{ '#dc2626' if reg.risk else '#2563eb' }};">{{ reg.label }}</span>
|
||||||
<span class="text-[10px] leading-tight text-brand-navy/55">{{ reg.detail | safe }}</span>
|
<span class="text-[10px] leading-tight text-brand-navy/55">{{ reg.detail | safe }}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -2513,7 +2513,7 @@
|
|||||||
{# Two warm cosmic orbs to mirror the Hero — visual closure of the page #}
|
{# 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 inset-0 pointer-events-none" aria-hidden="true">
|
||||||
<div class="absolute top-1/4 left-1/3 w-[500px] h-[500px] rounded-full"
|
<div class="absolute top-1/4 left-1/3 w-[500px] h-[500px] rounded-full"
|
||||||
style="background: radial-gradient(circle, rgba(124,58,237,0.14) 0%, transparent 60%); filter: blur(50px);"></div>
|
style="background: radial-gradient(circle, rgba(37,99,235,0.14) 0%, transparent 60%); filter: blur(50px);"></div>
|
||||||
<div class="absolute bottom-1/4 right-1/3 w-[450px] h-[450px] rounded-full"
|
<div class="absolute bottom-1/4 right-1/3 w-[450px] h-[450px] rounded-full"
|
||||||
style="background: radial-gradient(circle, rgba(6,182,212,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>
|
||||||
|
|||||||
@@ -117,7 +117,7 @@
|
|||||||
<section class="relative bg-brand-navy text-white py-20 overflow-hidden" aria-labelledby="tarifs-cta-title">
|
<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 inset-0 pointer-events-none" aria-hidden="true">
|
||||||
<div class="absolute top-1/3 left-1/3 w-[500px] h-[500px] rounded-full"
|
<div class="absolute top-1/3 left-1/3 w-[500px] h-[500px] rounded-full"
|
||||||
style="background: radial-gradient(circle, rgba(124,58,237,0.12) 0%, transparent 60%); filter: blur(50px);"></div>
|
style="background: radial-gradient(circle, rgba(37,99,235,0.12) 0%, transparent 60%); filter: blur(50px);"></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="relative max-w-[820px] mx-auto px-6 text-center">
|
<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">
|
<h2 id="tarifs-cta-title" class="text-[clamp(2rem,3vw,2.75rem)] font-black mb-6">
|
||||||
|
|||||||
@@ -73,14 +73,20 @@ def test_email_template_uses_dictia_branding():
|
|||||||
assert 'Loi' in html and '25' in html, 'Tagline must mention Loi 25'
|
assert 'Loi' in html and '25' in html, 'Tagline must mention Loi 25'
|
||||||
|
|
||||||
|
|
||||||
def test_email_template_header_uses_brand_gradient_not_speakr_blue():
|
def test_email_template_header_uses_brand_gradient():
|
||||||
"""Header bg must use DictIA brand color #0062ff (or gradient), not the legacy
|
"""Header bg must use the official DictIA brand gradient (blue → cyan → fuchsia,
|
||||||
Speakr #2563eb."""
|
matches the official logo). The legacy #0062ff/#00bdd8/#00c896 palette must be gone."""
|
||||||
with app.app_context():
|
with app.app_context():
|
||||||
from src.services.email import _get_email_template
|
from src.services.email import _get_email_template
|
||||||
html, _ = _get_email_template('x', 'x', 'Test')
|
html, _ = _get_email_template('x', 'x', 'Test')
|
||||||
assert '#2563eb' not in html, 'Legacy Speakr header color must be removed'
|
# Legacy palette must be removed
|
||||||
assert '#0062ff' in html, 'DictIA brand blue must be present'
|
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():
|
def test_verification_email_subject_is_french_with_dictia():
|
||||||
|
|||||||
@@ -110,11 +110,11 @@ def test_hero_has_dual_cta():
|
|||||||
|
|
||||||
|
|
||||||
def test_hero_has_cosmic_orbs_background():
|
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()
|
client = app.test_client()
|
||||||
body = client.get('/').data.decode('utf-8')
|
body = client.get('/').data.decode('utf-8')
|
||||||
# Look for the 3 orb opacities (16% mauve, 7% aqua, 11% aqua accent)
|
# Look for the 3 orb opacities (16% blue, 7% aqua, 11% aqua accent)
|
||||||
assert 'rgba(124,58,237,0.16)' in body, "Missing primary mauve orb"
|
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.07)' in body, "Missing aqua orb"
|
||||||
assert 'rgba(6,182,212,0.11)' in body, "Missing aqua accent orb"
|
assert 'rgba(6,182,212,0.11)' in body, "Missing aqua accent orb"
|
||||||
|
|
||||||
|
|||||||