refactor(ui): modernize button + input border radii (rounded-lg/md/xl, sharper SaaS aesthetic)
Aligns DictIA marketing/auth/legal/billing templates with modern SaaS visual conventions (Linear, Vercel, Stripe Dashboard, Notion). Old radii (12-18px) felt dated; new system uses 6-12px for tighter, more contemporary corners. Border radius system: - Buttons (CTA, submit, secondary): rounded-[0.75rem] (12px) -> rounded-lg (8px) - Form inputs (text/email/password/select/textarea/checkbox): rounded-[0.5rem] -> rounded-md (6px) - Cards (pricing, bento, modals, content panels): rounded-[18px]/[14px]/[12px] -> rounded-xl (12px) - Pricing card outer gradient frame: rounded-[20px] -> rounded-xl (matches inner) - Pills / badges / status chips: KEEP rounded-full - Avatars / circular icon containers: KEEP rounded-full - Code blocks: KEEP rounded (4px) Decision tree applied for ambiguous cases: - Button-like clickable CTA -> rounded-lg - Form input -> rounded-md - Card / panel / modal -> rounded-xl - Badge / pill / chip / avatar -> rounded-full (preserved) In-scope templates modified (23): - macros/button.html (central macro, cascades to all callers) - macros/pricing_card.html, macros/bento.html - marketing/landing.html, tarifs.html, fonctionnalites.html, conformite.html, contact.html - auth/check_email.html, forgot_password.html, magic_link_request.html, oauth_finish_signup.html, passkey_setup.html, reset_password.html, totp_setup.html, totp_verify.html, verify_success.html - billing/cancel.html, billing/success.html - legal/_layout.html, legal/index.html - register.html, login.html Out of scope (untouched): index.html, account.html, admin.html, share.html, inquire.html, group-admin.html, components/**, includes/**, modals/** (all legacy Speakr Vue surfaces). Tests: test_marketing_landing_template.py — 2 assertions updated to match new bento icon (rounded-md) and pricing card frame (rounded-xl). All 18 legal tests + 58 marketing landing tests + 9 signup_loi25 tests still pass. Decorative rounded-full preserved on hero cosmic orbs and ordres-pros avatar circles. Diff: 94 insertions / 94 deletions (1:1 mechanical replacement, no class drift). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -5,7 +5,7 @@
|
||||
|
||||
{% block content %}
|
||||
<section class="min-h-[calc(100vh-62px)] bg-brand-bg py-16 px-4" aria-labelledby="check-email-title">
|
||||
<div class="max-w-md mx-auto bg-white p-8 rounded-[18px] border border-brand-border shadow-cta text-center">
|
||||
<div class="max-w-md mx-auto bg-white p-8 rounded-xl border border-brand-border shadow-cta text-center">
|
||||
<div class="mx-auto mb-6 w-16 h-16 rounded-full grad-bg flex items-center justify-center text-white text-2xl" aria-hidden="true">✉</div>
|
||||
|
||||
<h1 id="check-email-title" class="text-2xl font-black text-brand-navy mb-2">
|
||||
@@ -45,7 +45,7 @@
|
||||
<form method="POST" action="{{ url_for('auth.resend_verification') }}" class="mb-4">
|
||||
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
|
||||
<input type="hidden" name="email" value="{{ email }}">
|
||||
<button type="submit" class="w-full grad-bg text-white font-semibold py-3 rounded-[0.75rem] shadow-cta hover:shadow-cta-hover transition focus-visible:outline-2 focus-visible:outline-brand-b1 focus-visible:outline-offset-2">
|
||||
<button type="submit" class="w-full grad-bg text-white font-semibold py-3 rounded-lg shadow-cta hover:shadow-cta-hover transition focus-visible:outline-2 focus-visible:outline-brand-b1 focus-visible:outline-offset-2">
|
||||
Renvoyer le lien de vérification
|
||||
</button>
|
||||
</form>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
{% block content %}
|
||||
<section class="min-h-[calc(100vh-62px)] bg-brand-bg py-16 px-4" aria-labelledby="forgot-title">
|
||||
<div class="max-w-md mx-auto bg-white p-8 rounded-[18px] border border-brand-border shadow-cta">
|
||||
<div class="max-w-md mx-auto bg-white p-8 rounded-xl border border-brand-border shadow-cta">
|
||||
<h1 id="forgot-title" class="text-3xl font-black text-brand-navy mb-2">Mot de passe oublié</h1>
|
||||
<p class="text-sm text-brand-navy/70 mb-6">{{ "Entrez votre adresse courriel. Si un compte existe, nous vous enverrons un lien sécurisé pour réinitialiser votre mot de passe (valide 1 heure)." | safe }}</p>
|
||||
|
||||
@@ -29,11 +29,11 @@
|
||||
<div>
|
||||
<label for="email" class="block text-sm font-medium text-brand-navy mb-1">Courriel <span class="text-red-600" aria-hidden="true">*</span></label>
|
||||
<input type="email" id="email" name="email" autocomplete="email" required aria-required="true"
|
||||
class="w-full px-3 py-2 border border-brand-border rounded-[0.5rem] text-brand-navy focus-visible:outline-2 focus-visible:outline-brand-b1 focus-visible:outline-offset-2"
|
||||
class="w-full px-3 py-2 border border-brand-border rounded-md text-brand-navy focus-visible:outline-2 focus-visible:outline-brand-b1 focus-visible:outline-offset-2"
|
||||
placeholder="vous@cabinet.qc.ca">
|
||||
</div>
|
||||
|
||||
<button type="submit" class="w-full grad-bg text-white font-semibold py-3 rounded-[0.75rem] shadow-cta hover:shadow-cta-hover transition focus-visible:outline-2 focus-visible:outline-brand-b1 focus-visible:outline-offset-2">
|
||||
<button type="submit" class="w-full grad-bg text-white font-semibold py-3 rounded-lg shadow-cta hover:shadow-cta-hover transition focus-visible:outline-2 focus-visible:outline-brand-b1 focus-visible:outline-offset-2">
|
||||
Recevoir un lien de réinitialisation
|
||||
</button>
|
||||
</form>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
{% block content %}
|
||||
<section class="min-h-[calc(100vh-62px)] bg-brand-bg py-16 px-4" aria-labelledby="magic-title">
|
||||
<div class="max-w-md mx-auto bg-white p-8 rounded-[18px] border border-brand-border shadow-cta">
|
||||
<div class="max-w-md mx-auto bg-white p-8 rounded-xl border border-brand-border shadow-cta">
|
||||
<h1 id="magic-title" class="text-3xl font-black text-brand-navy mb-2">Lien de connexion</h1>
|
||||
<p class="text-sm text-brand-navy/70 mb-6">{{ "Recevez un lien par courriel pour vous connecter sans mot de passe. Le lien expire dans 15 minutes." | safe }}</p>
|
||||
|
||||
@@ -29,11 +29,11 @@
|
||||
<div>
|
||||
<label for="email" class="block text-sm font-medium text-brand-navy mb-1">Courriel <span class="text-red-600" aria-hidden="true">*</span></label>
|
||||
<input type="email" id="email" name="email" autocomplete="email" required aria-required="true"
|
||||
class="w-full px-3 py-2 border border-brand-border rounded-[0.5rem] text-brand-navy focus-visible:outline-2 focus-visible:outline-brand-b1 focus-visible:outline-offset-2"
|
||||
class="w-full px-3 py-2 border border-brand-border rounded-md text-brand-navy focus-visible:outline-2 focus-visible:outline-brand-b1 focus-visible:outline-offset-2"
|
||||
placeholder="vous@cabinet.qc.ca">
|
||||
</div>
|
||||
|
||||
<button type="submit" class="w-full grad-bg text-white font-semibold py-3 rounded-[0.75rem] shadow-cta hover:shadow-cta-hover transition focus-visible:outline-2 focus-visible:outline-brand-b1 focus-visible:outline-offset-2">
|
||||
<button type="submit" class="w-full grad-bg text-white font-semibold py-3 rounded-lg shadow-cta hover:shadow-cta-hover transition focus-visible:outline-2 focus-visible:outline-brand-b1 focus-visible:outline-offset-2">
|
||||
{{ "Recevoir le lien (expire dans 15 minutes)" | safe }}
|
||||
</button>
|
||||
</form>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
{% block content %}
|
||||
<section class="min-h-[calc(100vh-62px)] bg-brand-bg py-16 px-4" aria-labelledby="finish-title">
|
||||
<div class="max-w-md mx-auto bg-white p-8 rounded-[18px] border border-brand-border shadow-cta">
|
||||
<div class="max-w-md mx-auto bg-white p-8 rounded-xl border border-brand-border shadow-cta">
|
||||
<h1 id="finish-title" class="text-3xl font-black text-brand-navy mb-2">Finaliser votre inscription</h1>
|
||||
<p class="text-sm text-brand-navy/70 mb-6">
|
||||
Vous vous inscrivez via <strong>{{ provider_display or provider | capitalize }}</strong>. Avant de créer votre compte DictIA, nous devons obtenir vos consentements conformément à la {{ "Loi 25" | safe }} du Québec.
|
||||
@@ -26,7 +26,7 @@
|
||||
{% endwith %}
|
||||
|
||||
{# Pre-filled email from OAuth provider — display only, not editable #}
|
||||
<div class="bg-brand-bg border border-brand-border rounded-[0.5rem] p-3 mb-6 text-sm">
|
||||
<div class="bg-brand-bg border border-brand-border rounded-md p-3 mb-6 text-sm">
|
||||
<p class="text-brand-navy/70 mb-1">Compte fédéré :</p>
|
||||
<p class="text-brand-navy font-semibold break-all">{{ userinfo.email }}</p>
|
||||
{% if userinfo.name %}<p class="text-brand-navy/80 text-xs mt-1">{{ userinfo.name }}</p>{% endif %}
|
||||
@@ -66,7 +66,7 @@
|
||||
</label>
|
||||
</fieldset>
|
||||
|
||||
<button type="submit" class="w-full grad-bg text-white font-semibold py-3 rounded-[0.75rem] shadow-cta hover:shadow-cta-hover transition focus-visible:outline-2 focus-visible:outline-brand-b1 focus-visible:outline-offset-2">
|
||||
<button type="submit" class="w-full grad-bg text-white font-semibold py-3 rounded-lg shadow-cta hover:shadow-cta-hover transition focus-visible:outline-2 focus-visible:outline-brand-b1 focus-visible:outline-offset-2">
|
||||
Créer mon compte DictIA
|
||||
</button>
|
||||
</form>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
{% block content %}
|
||||
<section class="min-h-[calc(100vh-62px)] bg-brand-bg py-16 px-4" aria-labelledby="passkey-setup-title">
|
||||
<div class="max-w-2xl mx-auto bg-white p-8 rounded-[18px] border border-brand-border shadow-cta">
|
||||
<div class="max-w-2xl mx-auto bg-white p-8 rounded-xl border border-brand-border shadow-cta">
|
||||
<h1 id="passkey-setup-title" class="text-3xl font-black text-brand-navy mb-2">Mes passkeys</h1>
|
||||
<p class="text-sm text-brand-navy/70 mb-6">{{ "Une passkey est un second facteur sans mot de passe (clé matérielle YubiKey, biométrie de votre appareil, etc.). Conforme Loi 25." | safe }}</p>
|
||||
|
||||
@@ -48,8 +48,8 @@
|
||||
<h2 class="text-base font-semibold text-brand-navy mb-3">Ajouter une passkey</h2>
|
||||
<div class="space-y-3">
|
||||
<label for="passkey-label" class="block text-sm font-medium text-brand-navy">Nom de la passkey (optionnel)</label>
|
||||
<input id="passkey-label" type="text" maxlength="80" placeholder="ex. YubiKey 5C, MacBook Touch ID..." class="w-full px-3 py-2 border border-brand-border rounded-[0.5rem] text-brand-navy focus-visible:outline-2 focus-visible:outline-brand-b1 focus-visible:outline-offset-2">
|
||||
<button id="passkey-register-btn" type="button" class="w-full grad-bg text-white font-semibold py-3 rounded-[0.75rem] shadow-cta hover:shadow-cta-hover transition focus-visible:outline-2 focus-visible:outline-brand-b1 focus-visible:outline-offset-2">
|
||||
<input id="passkey-label" type="text" maxlength="80" placeholder="ex. YubiKey 5C, MacBook Touch ID..." class="w-full px-3 py-2 border border-brand-border rounded-md text-brand-navy focus-visible:outline-2 focus-visible:outline-brand-b1 focus-visible:outline-offset-2">
|
||||
<button id="passkey-register-btn" type="button" class="w-full grad-bg text-white font-semibold py-3 rounded-lg shadow-cta hover:shadow-cta-hover transition focus-visible:outline-2 focus-visible:outline-brand-b1 focus-visible:outline-offset-2">
|
||||
Enregistrer une passkey
|
||||
</button>
|
||||
<p id="passkey-register-status" class="text-xs text-brand-navy/70" role="status" aria-live="polite"></p>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
{% block content %}
|
||||
<section class="min-h-[calc(100vh-62px)] bg-brand-bg py-16 px-4" aria-labelledby="reset-title">
|
||||
<div class="max-w-md mx-auto bg-white p-8 rounded-[18px] border border-brand-border shadow-cta">
|
||||
<div class="max-w-md mx-auto bg-white p-8 rounded-xl border border-brand-border shadow-cta">
|
||||
<h1 id="reset-title" class="text-3xl font-black text-brand-navy mb-2">Nouveau mot de passe</h1>
|
||||
<p class="text-sm text-brand-navy/70 mb-6">Choisissez un mot de passe robuste pour sécuriser votre compte DictIA.</p>
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
<div>
|
||||
<label for="password" class="block text-sm font-medium text-brand-navy mb-1">Nouveau mot de passe <span class="text-red-600" aria-hidden="true">*</span></label>
|
||||
<input type="password" id="password" name="password" autocomplete="new-password" minlength="8" required aria-required="true" aria-describedby="password-help"
|
||||
class="w-full px-3 py-2 border border-brand-border rounded-[0.5rem] text-brand-navy focus-visible:outline-2 focus-visible:outline-brand-b1 focus-visible:outline-offset-2"
|
||||
class="w-full px-3 py-2 border border-brand-border rounded-md text-brand-navy focus-visible:outline-2 focus-visible:outline-brand-b1 focus-visible:outline-offset-2"
|
||||
placeholder="••••••••">
|
||||
<p id="password-help" class="text-xs text-brand-navy/70 mt-1">{{ "8 caractères minimum, dont une majuscule, une minuscule, un chiffre et un caractère spécial." | safe }}</p>
|
||||
</div>
|
||||
@@ -37,11 +37,11 @@
|
||||
<div>
|
||||
<label for="confirm_password" class="block text-sm font-medium text-brand-navy mb-1">Confirmer le mot de passe <span class="text-red-600" aria-hidden="true">*</span></label>
|
||||
<input type="password" id="confirm_password" name="confirm_password" autocomplete="new-password" minlength="8" required aria-required="true"
|
||||
class="w-full px-3 py-2 border border-brand-border rounded-[0.5rem] text-brand-navy focus-visible:outline-2 focus-visible:outline-brand-b1 focus-visible:outline-offset-2"
|
||||
class="w-full px-3 py-2 border border-brand-border rounded-md text-brand-navy focus-visible:outline-2 focus-visible:outline-brand-b1 focus-visible:outline-offset-2"
|
||||
placeholder="••••••••">
|
||||
</div>
|
||||
|
||||
<button type="submit" class="w-full grad-bg text-white font-semibold py-3 rounded-[0.75rem] shadow-cta hover:shadow-cta-hover transition focus-visible:outline-2 focus-visible:outline-brand-b1 focus-visible:outline-offset-2">
|
||||
<button type="submit" class="w-full grad-bg text-white font-semibold py-3 rounded-lg shadow-cta hover:shadow-cta-hover transition focus-visible:outline-2 focus-visible:outline-brand-b1 focus-visible:outline-offset-2">
|
||||
Définir mon nouveau mot de passe
|
||||
</button>
|
||||
</form>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
{% block content %}
|
||||
<section class="min-h-[calc(100vh-62px)] bg-brand-bg py-16 px-4" aria-labelledby="totp-setup-title">
|
||||
<div class="max-w-2xl mx-auto bg-white p-8 rounded-[18px] border border-brand-border shadow-cta">
|
||||
<div class="max-w-2xl mx-auto bg-white p-8 rounded-xl border border-brand-border shadow-cta">
|
||||
<h1 id="totp-setup-title" class="text-3xl font-black text-brand-navy mb-2">Configurer la double authentification</h1>
|
||||
<p class="text-sm text-brand-navy/70 mb-6">{{ "La double authentification (2FA) ajoute une seconde étape lors de la connexion, en plus de votre mot de passe. Une exigence forte recommandée pour les comptes traitant des données confidentielles (Loi 25)." | safe }}</p>
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
<li>
|
||||
<h2 class="text-lg font-bold text-brand-navy mb-2"><span class="grad-text">2.</span> Scannez le code QR</h2>
|
||||
<div class="flex flex-col md:flex-row gap-6 items-start">
|
||||
<div class="bg-brand-bg border border-brand-border rounded-[0.75rem] p-4 flex-shrink-0">
|
||||
<div class="bg-brand-bg border border-brand-border rounded-lg p-4 flex-shrink-0">
|
||||
<img src="{{ qr_data_url }}" alt="Code QR pour configurer DictIA dans votre application authenticator" class="w-48 h-48 mx-auto block">
|
||||
</div>
|
||||
<div class="text-sm text-brand-navy/80 space-y-2">
|
||||
@@ -49,11 +49,11 @@
|
||||
|
||||
<li>
|
||||
<h2 class="text-lg font-bold text-brand-navy mb-2"><span class="grad-text">3.</span> Conservez vos codes de récupération</h2>
|
||||
<div role="alert" class="bg-amber-50 border border-amber-200 rounded-[0.75rem] p-4 mb-3">
|
||||
<div role="alert" class="bg-amber-50 border border-amber-200 rounded-lg p-4 mb-3">
|
||||
<p class="text-sm font-semibold text-amber-900 mb-2">Important — ces codes ne seront affichés qu'une seule fois.</p>
|
||||
<p class="text-xs text-amber-900/90">Imprimez-les ou enregistrez-les dans votre gestionnaire de mots de passe. Chaque code est à usage unique et permettra de vous reconnecter si vous perdez l'accès à votre application authenticator.</p>
|
||||
</div>
|
||||
<pre id="recovery-codes" class="bg-brand-navy text-white text-sm font-mono p-4 rounded-[0.75rem] whitespace-pre-wrap select-all">{% for c in recovery_codes %}{{ c }}
|
||||
<pre id="recovery-codes" class="bg-brand-navy text-white text-sm font-mono p-4 rounded-lg whitespace-pre-wrap select-all">{% for c in recovery_codes %}{{ c }}
|
||||
{% endfor %}</pre>
|
||||
<button type="button" onclick="(function(){var t=document.getElementById('recovery-codes').innerText;if(navigator.clipboard){navigator.clipboard.writeText(t);}var b=document.getElementById('copy-btn');b.textContent='Copié dans le presse-papiers';setTimeout(function(){b.textContent='Copier les codes';},2000);})();"
|
||||
id="copy-btn"
|
||||
@@ -74,11 +74,11 @@
|
||||
<input type="text" id="code" name="code" required aria-required="true"
|
||||
inputmode="numeric" autocomplete="one-time-code"
|
||||
pattern="[0-9]{6}" maxlength="6"
|
||||
class="w-full md:w-48 px-3 py-2 border border-brand-border rounded-[0.5rem] text-brand-navy text-center text-xl font-mono tracking-widest focus-visible:outline-2 focus-visible:outline-brand-b1 focus-visible:outline-offset-2"
|
||||
class="w-full md:w-48 px-3 py-2 border border-brand-border rounded-md text-brand-navy text-center text-xl font-mono tracking-widest focus-visible:outline-2 focus-visible:outline-brand-b1 focus-visible:outline-offset-2"
|
||||
placeholder="000000" autofocus>
|
||||
</div>
|
||||
|
||||
<button type="submit" class="grad-bg text-white font-semibold py-3 px-6 rounded-[0.75rem] shadow-cta hover:shadow-cta-hover transition focus-visible:outline-2 focus-visible:outline-brand-b1 focus-visible:outline-offset-2">
|
||||
<button type="submit" class="grad-bg text-white font-semibold py-3 px-6 rounded-lg shadow-cta hover:shadow-cta-hover transition focus-visible:outline-2 focus-visible:outline-brand-b1 focus-visible:outline-offset-2">
|
||||
Activer la double authentification
|
||||
</button>
|
||||
</form>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
{% block content %}
|
||||
<section class="min-h-[calc(100vh-62px)] bg-brand-bg py-16 px-4" aria-labelledby="totp-verify-title">
|
||||
<div class="max-w-md mx-auto bg-white p-8 rounded-[18px] border border-brand-border shadow-cta">
|
||||
<div class="max-w-md mx-auto bg-white p-8 rounded-xl border border-brand-border shadow-cta">
|
||||
<h1 id="totp-verify-title" class="text-3xl font-black text-brand-navy mb-2">Vérification en deux étapes</h1>
|
||||
<p class="text-sm text-brand-navy/70 mb-6">Entrez le code à 6 chiffres affiché dans votre application authenticator pour terminer la connexion.</p>
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
{% if has_passkeys %}
|
||||
<section class="mb-6" aria-labelledby="passkey-section-title">
|
||||
<h2 id="passkey-section-title" class="text-base font-semibold text-brand-navy mb-3">Connexion par Passkey</h2>
|
||||
<button id="passkey-auth-btn" type="button" class="w-full grad-bg text-white font-semibold py-3 rounded-[0.75rem] shadow-cta hover:shadow-cta-hover transition focus-visible:outline-2 focus-visible:outline-brand-b1 focus-visible:outline-offset-2">
|
||||
<button id="passkey-auth-btn" type="button" class="w-full grad-bg text-white font-semibold py-3 rounded-lg shadow-cta hover:shadow-cta-hover transition focus-visible:outline-2 focus-visible:outline-brand-b1 focus-visible:outline-offset-2">
|
||||
Utiliser ma Passkey
|
||||
</button>
|
||||
<p id="passkey-status" class="text-xs text-brand-navy/70 mt-2" role="status" aria-live="polite"></p>
|
||||
@@ -54,11 +54,11 @@
|
||||
<input type="text" id="code" name="code"
|
||||
inputmode="numeric" autocomplete="one-time-code"
|
||||
pattern="[0-9]{6}" maxlength="6"
|
||||
class="w-full px-3 py-3 border border-brand-border rounded-[0.5rem] text-brand-navy text-center text-2xl font-mono tracking-widest focus-visible:outline-2 focus-visible:outline-brand-b1 focus-visible:outline-offset-2"
|
||||
class="w-full px-3 py-3 border border-brand-border rounded-md text-brand-navy text-center text-2xl font-mono tracking-widest focus-visible:outline-2 focus-visible:outline-brand-b1 focus-visible:outline-offset-2"
|
||||
placeholder="000000" autofocus>
|
||||
</div>
|
||||
|
||||
<button type="submit" class="w-full grad-bg text-white font-semibold py-3 rounded-[0.75rem] shadow-cta hover:shadow-cta-hover transition focus-visible:outline-2 focus-visible:outline-brand-b1 focus-visible:outline-offset-2">
|
||||
<button type="submit" class="w-full grad-bg text-white font-semibold py-3 rounded-lg shadow-cta hover:shadow-cta-hover transition focus-visible:outline-2 focus-visible:outline-brand-b1 focus-visible:outline-offset-2">
|
||||
Vérifier et se connecter
|
||||
</button>
|
||||
</form>
|
||||
@@ -74,11 +74,11 @@
|
||||
<label for="recovery_code" class="block text-sm font-medium text-brand-navy mb-1">Code de récupération <span class="text-red-600" aria-hidden="true">*</span></label>
|
||||
<input type="text" id="recovery_code" name="recovery_code"
|
||||
autocomplete="off"
|
||||
class="w-full px-3 py-2 border border-brand-border rounded-[0.5rem] text-brand-navy font-mono uppercase focus-visible:outline-2 focus-visible:outline-brand-b1 focus-visible:outline-offset-2"
|
||||
class="w-full px-3 py-2 border border-brand-border rounded-md text-brand-navy font-mono uppercase focus-visible:outline-2 focus-visible:outline-brand-b1 focus-visible:outline-offset-2"
|
||||
placeholder="XXXXX-XXXXX">
|
||||
<p class="text-xs text-brand-navy/60 mt-1">Format : 5 caractères + tiret + 5 caractères. Chaque code est à usage unique.</p>
|
||||
</div>
|
||||
<button type="submit" class="w-full bg-brand-navy text-white font-semibold py-3 rounded-[0.75rem] hover:bg-brand-navy2 transition focus-visible:outline-2 focus-visible:outline-brand-b1 focus-visible:outline-offset-2">
|
||||
<button type="submit" class="w-full bg-brand-navy text-white font-semibold py-3 rounded-lg hover:bg-brand-navy2 transition focus-visible:outline-2 focus-visible:outline-brand-b1 focus-visible:outline-offset-2">
|
||||
Utiliser le code de récupération
|
||||
</button>
|
||||
<p class="text-xs text-brand-navy/60 text-center" aria-live="polite">{{ recovery_codes_remaining }} code{{ 's' if recovery_codes_remaining != 1 else '' }} de récupération restant{{ 's' if recovery_codes_remaining != 1 else '' }}.</p>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
{% block content %}
|
||||
<section class="min-h-[calc(100vh-62px)] bg-brand-bg py-16 px-4" aria-labelledby="verify-success-title">
|
||||
<div class="max-w-md mx-auto bg-white p-8 rounded-[18px] border border-brand-border shadow-cta text-center">
|
||||
<div class="max-w-md mx-auto bg-white p-8 rounded-xl border border-brand-border shadow-cta text-center">
|
||||
<div class="mx-auto mb-6 w-16 h-16 rounded-full bg-green-100 text-green-700 flex items-center justify-center text-3xl font-black" aria-hidden="true">✓</div>
|
||||
|
||||
<h1 id="verify-success-title" class="text-2xl font-black text-brand-navy mb-2">Votre courriel a été vérifié</h1>
|
||||
@@ -14,7 +14,7 @@
|
||||
</p>
|
||||
|
||||
<a href="{{ url_for('auth.login') }}"
|
||||
class="inline-block w-full grad-bg text-white font-semibold py-3 rounded-[0.75rem] shadow-cta hover:shadow-cta-hover transition focus-visible:outline-2 focus-visible:outline-brand-b1 focus-visible:outline-offset-2">
|
||||
class="inline-block w-full grad-bg text-white font-semibold py-3 rounded-lg shadow-cta hover:shadow-cta-hover transition focus-visible:outline-2 focus-visible:outline-brand-b1 focus-visible:outline-offset-2">
|
||||
Se connecter
|
||||
</a>
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
<div class="max-w-[820px] mx-auto px-6">
|
||||
<h2 id="info-title" class="sr-only">Que faire ensuite</h2>
|
||||
|
||||
<div class="bg-white p-8 rounded-[18px] border border-brand-border mb-8">
|
||||
<div class="bg-white p-8 rounded-xl border border-brand-border mb-8">
|
||||
<h3 class="text-lg font-bold mb-3 text-brand-navy">Pourquoi avoir hésité ?</h3>
|
||||
<p class="text-sm text-brand-navy/80 leading-relaxed mb-4">
|
||||
Si vous avez une question sur les forfaits, la conformité Loi 25 ou la mise en service, notre équipe peut vous accompagner sans pression commerciale.
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
</h2>
|
||||
|
||||
<ol class="space-y-6">
|
||||
<li class="bg-white p-6 rounded-[18px] border border-brand-border flex gap-4">
|
||||
<li class="bg-white p-6 rounded-xl border border-brand-border flex gap-4">
|
||||
<span class="grad-bg text-white font-black w-10 h-10 rounded-full flex items-center justify-center flex-shrink-0 shadow-cta" aria-hidden="true">1</span>
|
||||
<div>
|
||||
<h3 class="font-bold text-brand-navy mb-1">Confirmation par courriel</h3>
|
||||
@@ -37,7 +37,7 @@
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<li class="bg-white p-6 rounded-[18px] border border-brand-border flex gap-4">
|
||||
<li class="bg-white p-6 rounded-xl border border-brand-border flex gap-4">
|
||||
<span class="grad-bg text-white font-black w-10 h-10 rounded-full flex items-center justify-center flex-shrink-0 shadow-cta" aria-hidden="true">2</span>
|
||||
<div>
|
||||
<h3 class="font-bold text-brand-navy mb-1">Activation de votre abonnement</h3>
|
||||
@@ -47,7 +47,7 @@
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<li class="bg-white p-6 rounded-[18px] border border-brand-border flex gap-4">
|
||||
<li class="bg-white p-6 rounded-xl border border-brand-border flex gap-4">
|
||||
<span class="grad-bg text-white font-black w-10 h-10 rounded-full flex items-center justify-center flex-shrink-0 shadow-cta" aria-hidden="true">3</span>
|
||||
<div>
|
||||
<h3 class="font-bold text-brand-navy mb-1">Mise en service</h3>
|
||||
|
||||
@@ -221,7 +221,7 @@
|
||||
<article id="main-content"
|
||||
role="main"
|
||||
aria-labelledby="legal-title"
|
||||
class="bg-white p-6 md:p-10 rounded-[18px] border border-brand-border shadow-cta order-1">
|
||||
class="bg-white p-6 md:p-10 rounded-xl border border-brand-border shadow-cta order-1">
|
||||
<header class="mb-8 pb-6 border-b border-brand-border">
|
||||
<p class="text-xs uppercase tracking-wider text-brand-navy/70 mb-2">Document légal DictIA</p>
|
||||
<h1 id="legal-title" class="text-3xl md:text-4xl font-black text-brand-navy mb-4 tracking-tight">{{ title }}</h1>
|
||||
@@ -244,8 +244,8 @@
|
||||
</header>
|
||||
|
||||
{# TOC mobile (collapsible) — visible < lg seulement #}
|
||||
<details class="lg:hidden mb-6 border border-brand-border rounded-[12px] bg-brand-bg/50">
|
||||
<summary class="cursor-pointer px-4 py-3 text-sm font-semibold text-brand-navy flex items-center justify-between focus-visible:outline-2 focus-visible:outline-brand-b1 focus-visible:outline-offset-2 rounded-[12px]">
|
||||
<details class="lg:hidden mb-6 border border-brand-border rounded-xl bg-brand-bg/50">
|
||||
<summary class="cursor-pointer px-4 py-3 text-sm font-semibold text-brand-navy flex items-center justify-between focus-visible:outline-2 focus-visible:outline-brand-b1 focus-visible:outline-offset-2 rounded-xl">
|
||||
<span>Sur cette page</span>
|
||||
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
|
||||
stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
|
||||
@@ -268,7 +268,7 @@
|
||||
{% if prev_page %}
|
||||
<a href="{{ url_for('legal.legal_page', page=prev_page) }}"
|
||||
rel="prev"
|
||||
class="block p-4 bg-brand-bg/60 border border-brand-border rounded-[12px] hover:border-brand-b1 hover:bg-white transition focus-visible:outline-2 focus-visible:outline-brand-b1 focus-visible:outline-offset-2">
|
||||
class="block p-4 bg-brand-bg/60 border border-brand-border rounded-xl hover:border-brand-b1 hover:bg-white transition focus-visible:outline-2 focus-visible:outline-brand-b1 focus-visible:outline-offset-2">
|
||||
<span class="block text-xs uppercase tracking-wider text-brand-navy/60 mb-1">
|
||||
<span aria-hidden="true">←</span> Précédent
|
||||
</span>
|
||||
@@ -281,7 +281,7 @@
|
||||
{% if next_page %}
|
||||
<a href="{{ url_for('legal.legal_page', page=next_page) }}"
|
||||
rel="next"
|
||||
class="block p-4 bg-brand-bg/60 border border-brand-border rounded-[12px] hover:border-brand-b1 hover:bg-white transition focus-visible:outline-2 focus-visible:outline-brand-b1 focus-visible:outline-offset-2 sm:text-right">
|
||||
class="block p-4 bg-brand-bg/60 border border-brand-border rounded-xl hover:border-brand-b1 hover:bg-white transition focus-visible:outline-2 focus-visible:outline-brand-b1 focus-visible:outline-offset-2 sm:text-right">
|
||||
<span class="block text-xs uppercase tracking-wider text-brand-navy/60 mb-1">
|
||||
Suivant <span aria-hidden="true">→</span>
|
||||
</span>
|
||||
@@ -304,7 +304,7 @@
|
||||
aria-label="Table des matières">
|
||||
<div x-data="legalToc()"
|
||||
x-init="init()"
|
||||
class="legal-toc bg-white border border-brand-border rounded-[14px] p-5 mt-0">
|
||||
class="legal-toc bg-white border border-brand-border rounded-xl p-5 mt-0">
|
||||
<h2 class="text-xs font-bold uppercase tracking-wider text-brand-navy/70 mb-3">
|
||||
Sur cette page
|
||||
</h2>
|
||||
|
||||
@@ -68,10 +68,10 @@
|
||||
<a href="{{ page.url }}"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
class="legal-card is-external group block h-full p-5 md:p-6 bg-white border border-brand-border rounded-[14px] hover:border-brand-b1 hover:shadow-cta focus-visible:outline-2 focus-visible:outline-brand-b1 focus-visible:outline-offset-2 relative">
|
||||
class="legal-card is-external group block h-full p-5 md:p-6 bg-white border border-brand-border rounded-xl hover:border-brand-b1 hover:shadow-cta focus-visible:outline-2 focus-visible:outline-brand-b1 focus-visible:outline-offset-2 relative">
|
||||
{% else %}
|
||||
<a href="{{ url_for('legal.legal_page', page=page.slug) }}"
|
||||
class="legal-card group block h-full p-5 md:p-6 bg-white border border-brand-border rounded-[14px] hover:border-brand-b1 hover:shadow-cta focus-visible:outline-2 focus-visible:outline-brand-b1 focus-visible:outline-offset-2 relative">
|
||||
class="legal-card group block h-full p-5 md:p-6 bg-white border border-brand-border rounded-xl hover:border-brand-b1 hover:shadow-cta focus-visible:outline-2 focus-visible:outline-brand-b1 focus-visible:outline-offset-2 relative">
|
||||
{% endif %}
|
||||
<div class="flex items-start gap-4">
|
||||
<div class="legal-card-icon shrink-0 inline-flex items-center justify-center w-12 h-12 rounded-xl">
|
||||
@@ -97,7 +97,7 @@
|
||||
</ul>
|
||||
|
||||
{# Bloc info pied — signature, contact, sous-processeurs #}
|
||||
<aside class="mt-12 max-w-3xl mx-auto bg-white border border-brand-border rounded-[14px] p-6 md:p-7"
|
||||
<aside class="mt-12 max-w-3xl mx-auto bg-white border border-brand-border rounded-xl p-6 md:p-7"
|
||||
aria-label="Informations complémentaires sur les documents légaux">
|
||||
<p class="text-sm text-brand-navy/80 leading-relaxed mb-3">
|
||||
Documents signés numériquement par <strong class="text-brand-navy">Allison Rioux</strong>,
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
{% block content %}
|
||||
<section class="min-h-[calc(100vh-62px)] bg-brand-bg py-16 px-4" aria-labelledby="login-title">
|
||||
<div class="max-w-md mx-auto bg-white p-8 rounded-[18px] border border-brand-border shadow-cta">
|
||||
<div class="max-w-md mx-auto bg-white p-8 rounded-xl border border-brand-border shadow-cta">
|
||||
<h1 id="login-title" class="text-3xl font-black text-brand-navy mb-2">Connexion</h1>
|
||||
<p class="text-sm text-brand-navy/70 mb-6">{{ "Bienvenue sur DictIA — la transcription IA conforme à la Loi 25." | safe }}</p>
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
<div class="space-y-3 mb-6" aria-label="Connexion fédérée">
|
||||
{% if oauth_microsoft_enabled %}
|
||||
<a href="{{ url_for('auth.oauth_provider_login', provider='microsoft') }}"
|
||||
class="w-full inline-flex items-center justify-center gap-3 px-4 py-3 bg-white border border-brand-border rounded-[0.75rem] text-brand-navy font-semibold hover:bg-brand-bg transition focus-visible:outline-2 focus-visible:outline-brand-b1 focus-visible:outline-offset-2">
|
||||
class="w-full inline-flex items-center justify-center gap-3 px-4 py-3 bg-white border border-brand-border rounded-lg text-brand-navy font-semibold hover:bg-brand-bg transition focus-visible:outline-2 focus-visible:outline-brand-b1 focus-visible:outline-offset-2">
|
||||
{# Official Microsoft 4-square logo #}
|
||||
<svg width="20" height="20" viewBox="0 0 21 21" aria-hidden="true" focusable="false">
|
||||
<rect x="1" y="1" width="9" height="9" fill="#F25022"/>
|
||||
@@ -42,7 +42,7 @@
|
||||
|
||||
{% if oauth_google_enabled %}
|
||||
<a href="{{ url_for('auth.oauth_provider_login', provider='google') }}"
|
||||
class="w-full inline-flex items-center justify-center gap-3 px-4 py-3 bg-white border border-brand-border rounded-[0.75rem] text-brand-navy font-semibold hover:bg-brand-bg transition focus-visible:outline-2 focus-visible:outline-brand-b1 focus-visible:outline-offset-2">
|
||||
class="w-full inline-flex items-center justify-center gap-3 px-4 py-3 bg-white border border-brand-border rounded-lg text-brand-navy font-semibold hover:bg-brand-bg transition focus-visible:outline-2 focus-visible:outline-brand-b1 focus-visible:outline-offset-2">
|
||||
{# Official Google "G" logo #}
|
||||
<svg width="20" height="20" viewBox="0 0 24 24" aria-hidden="true" focusable="false">
|
||||
<path fill="#4285F4" d="M22.56 12.25c0-.78-.07-1.53-.2-2.25H12v4.26h5.92a5.06 5.06 0 0 1-2.2 3.32v2.76h3.56c2.08-1.92 3.28-4.74 3.28-8.09Z"/>
|
||||
@@ -56,7 +56,7 @@
|
||||
|
||||
{% if sso_enabled %}
|
||||
<a href="{{ url_for('auth.sso_login') }}"
|
||||
class="w-full inline-flex items-center justify-center gap-3 px-4 py-3 bg-white border border-brand-border rounded-[0.75rem] text-brand-navy font-semibold hover:bg-brand-bg transition focus-visible:outline-2 focus-visible:outline-brand-b1 focus-visible:outline-offset-2">
|
||||
class="w-full inline-flex items-center justify-center gap-3 px-4 py-3 bg-white border border-brand-border rounded-lg text-brand-navy font-semibold hover:bg-brand-bg transition focus-visible:outline-2 focus-visible:outline-brand-b1 focus-visible:outline-offset-2">
|
||||
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
|
||||
<rect x="3" y="11" width="18" height="11" rx="2"/>
|
||||
<path d="M7 11V7a5 5 0 0 1 10 0v4"/>
|
||||
@@ -81,13 +81,13 @@
|
||||
|
||||
<div>
|
||||
<label for="email" class="block text-sm font-medium text-brand-navy mb-1">Courriel <span class="text-red-600" aria-hidden="true">*</span></label>
|
||||
{{ form.email(id='email', type='email', autocomplete='email', required=true, **{'aria-required':'true', 'class':'w-full px-3 py-2 border border-brand-border rounded-[0.5rem] text-brand-navy focus-visible:outline-2 focus-visible:outline-brand-b1 focus-visible:outline-offset-2'}) }}
|
||||
{{ form.email(id='email', type='email', autocomplete='email', required=true, **{'aria-required':'true', 'class':'w-full px-3 py-2 border border-brand-border rounded-md text-brand-navy focus-visible:outline-2 focus-visible:outline-brand-b1 focus-visible:outline-offset-2'}) }}
|
||||
{% if form.email.errors %}<p class="text-xs text-red-700 mt-1" role="alert">{{ form.email.errors[0] }}</p>{% endif %}
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label for="password" class="block text-sm font-medium text-brand-navy mb-1">Mot de passe <span class="text-red-600" aria-hidden="true">*</span></label>
|
||||
{{ form.password(id='password', autocomplete='current-password', required=true, **{'aria-required':'true', 'class':'w-full px-3 py-2 border border-brand-border rounded-[0.5rem] text-brand-navy focus-visible:outline-2 focus-visible:outline-brand-b1 focus-visible:outline-offset-2'}) }}
|
||||
{{ form.password(id='password', autocomplete='current-password', required=true, **{'aria-required':'true', 'class':'w-full px-3 py-2 border border-brand-border rounded-md text-brand-navy focus-visible:outline-2 focus-visible:outline-brand-b1 focus-visible:outline-offset-2'}) }}
|
||||
{% if form.password.errors %}<p class="text-xs text-red-700 mt-1" role="alert">{{ form.password.errors[0] }}</p>{% endif %}
|
||||
</div>
|
||||
|
||||
@@ -99,7 +99,7 @@
|
||||
<a href="{{ url_for('auth.forgot_password') }}" class="grad-text font-semibold hover:underline">Mot de passe oublié ?</a>
|
||||
</div>
|
||||
|
||||
<button type="submit" class="w-full grad-bg text-white font-semibold py-3 rounded-[0.75rem] shadow-cta hover:shadow-cta-hover transition focus-visible:outline-2 focus-visible:outline-brand-b1 focus-visible:outline-offset-2">
|
||||
<button type="submit" class="w-full grad-bg text-white font-semibold py-3 rounded-lg shadow-cta hover:shadow-cta-hover transition focus-visible:outline-2 focus-visible:outline-brand-b1 focus-visible:outline-offset-2">
|
||||
Se connecter
|
||||
</button>
|
||||
</form>
|
||||
|
||||
@@ -3,10 +3,10 @@
|
||||
so dynamic `col-span-{{ span }}` would produce dead classes — the lookup keeps the utilities discoverable). #}
|
||||
{% macro bento_card(number, title, description, icon='✦', span='1') %}
|
||||
{%- set span_classes = {'1': 'col-span-1', '2': 'sm:col-span-2', '3': 'sm:col-span-2 md:col-span-3'} -%}
|
||||
<div class="relative bg-brand-navy2 p-6 rounded-[18px] overflow-hidden border border-white/[0.045] {{ span_classes.get(span, 'col-span-1') }}">
|
||||
<div class="relative bg-brand-navy2 p-6 rounded-xl overflow-hidden border border-white/[0.045] {{ span_classes.get(span, 'col-span-1') }}">
|
||||
<div class="absolute top-2 right-4 text-[80px] font-black text-white/[0.04]" aria-hidden="true">{{ number }}</div>
|
||||
<div class="relative">
|
||||
<div class="w-10 h-10 grad-bg rounded-[0.5rem] mb-4 flex items-center justify-center text-lg">{{ icon }}</div>
|
||||
<div class="w-10 h-10 grad-bg rounded-md mb-4 flex items-center justify-center text-lg">{{ icon }}</div>
|
||||
<h3 class="text-lg font-bold mb-2 text-white">{{ title | safe }}</h3>
|
||||
<p class="text-sm text-white/70">{{ description | safe }}</p>
|
||||
</div>
|
||||
|
||||
@@ -14,13 +14,13 @@
|
||||
{%- set sizing = sizes.get(size, sizes['md']) -%}
|
||||
{%- if as_button -%}
|
||||
<button type="{{ type }}"
|
||||
class="inline-flex items-center justify-center gap-2 rounded-[0.75rem] font-semibold transition-all duration-200 {{ classes }} {{ sizing }}">
|
||||
class="inline-flex items-center justify-center gap-2 rounded-lg font-semibold transition-all duration-200 {{ classes }} {{ sizing }}">
|
||||
<span>{{ text }}</span>
|
||||
{%- if icon -%}<span class="ml-0.5" aria-hidden="true">{{ icon | safe }}</span>{%- endif -%}
|
||||
</button>
|
||||
{%- else -%}
|
||||
<a href="{{ href }}"
|
||||
class="inline-flex items-center justify-center gap-2 rounded-[0.75rem] font-semibold transition-all duration-200 {{ classes }} {{ sizing }}"
|
||||
class="inline-flex items-center justify-center gap-2 rounded-lg font-semibold transition-all duration-200 {{ classes }} {{ sizing }}"
|
||||
{% if target %}target="{{ target }}"{% endif %}
|
||||
{% if rel %}rel="{{ rel }}"{% endif %}>
|
||||
<span>{{ text }}</span>
|
||||
|
||||
@@ -15,9 +15,9 @@
|
||||
The button macro autoescapes its `text` arg, so `name` MUST NOT contain HTML entities
|
||||
(verified: "DictIA 8", "DictIA 16", "DictIA Cloud" are all entity-free). #}
|
||||
{%- macro pricing_card(slug, name, price_setup, price_monthly, target, features, recommended=False, cta_url='/checkout') -%}
|
||||
<div class="relative {% if recommended %}grad-bg p-[1.5px] rounded-[20px]{% endif %}">
|
||||
<div class="relative {% if recommended %}grad-bg p-[1.5px] rounded-xl{% endif %}">
|
||||
{% if recommended %}<span class="absolute -top-3 left-1/2 -translate-x-1/2 grad-bg text-white text-xs font-bold px-3 py-1 rounded-full shadow-cta">★ RECOMMANDÉ</span>{% endif %}
|
||||
<div class="bg-white p-8 rounded-[18px] border border-brand-border h-full flex flex-col">
|
||||
<div class="bg-white p-8 rounded-xl border border-brand-border h-full flex flex-col">
|
||||
<div class="mb-6">
|
||||
<h3 class="text-xl font-black mb-1 text-brand-navy">{{ name | safe }}</h3>
|
||||
<p class="text-sm text-brand-navy/70">{{ target | safe }}</p>
|
||||
|
||||
@@ -52,8 +52,8 @@
|
||||
'desc': 'Fork du projet open source Speakr — architecture entièrement auditable sur <a href="https://gitea.dictia.ca/Innova-AI/dictia-public" target="_blank" rel="noopener" class="underline hover:text-brand-navy">Gitea public</a>. Aucune boîte noire. Vos auditeurs peuvent examiner chaque ligne.'
|
||||
}
|
||||
] %}
|
||||
<article class="bg-brand-bg p-6 rounded-[14px] border border-brand-border">
|
||||
<div class="w-10 h-10 grad-bg rounded-[0.5rem] mb-4 flex items-center justify-center text-lg shadow-cta" aria-hidden="true">{{ card.icon }}</div>
|
||||
<article class="bg-brand-bg p-6 rounded-xl border border-brand-border">
|
||||
<div class="w-10 h-10 grad-bg rounded-md mb-4 flex items-center justify-center text-lg shadow-cta" aria-hidden="true">{{ card.icon }}</div>
|
||||
<h3 class="text-lg font-bold mb-2 text-brand-navy">{{ card.title | safe }}</h3>
|
||||
<p class="text-sm text-brand-navy/80 leading-relaxed">{{ card.desc | safe }}</p>
|
||||
</article>
|
||||
@@ -93,7 +93,7 @@
|
||||
'desc': 'Avant tout enregistrement, DictIA exige une confirmation que les participants ont consenti à l\'enregistrement et à la transcription IA. Le consentement est tracé dans le journal d\'audit. Vous pouvez configurer une demande de consentement automatique en début de session.'
|
||||
}
|
||||
] %}
|
||||
<article class="bg-white p-6 rounded-[14px] border border-brand-border">
|
||||
<article class="bg-white p-6 rounded-xl border border-brand-border">
|
||||
<div class="flex flex-col md:flex-row md:items-start gap-4">
|
||||
<div class="flex-shrink-0">
|
||||
<span class="inline-block bg-brand-navy text-white text-xs font-black px-3 py-1.5 rounded-md">{{ art.num | safe }}</span>
|
||||
|
||||
@@ -25,8 +25,8 @@
|
||||
<div class="grid md:grid-cols-3 gap-6">
|
||||
|
||||
{# Email card #}
|
||||
<article class="bg-white p-8 rounded-[18px] border border-brand-border flex flex-col">
|
||||
<div class="w-12 h-12 grad-bg rounded-[0.5rem] mb-4 flex items-center justify-center text-2xl shadow-cta" aria-hidden="true">✉️</div>
|
||||
<article class="bg-white p-8 rounded-xl border border-brand-border flex flex-col">
|
||||
<div class="w-12 h-12 grad-bg rounded-md mb-4 flex items-center justify-center text-2xl shadow-cta" aria-hidden="true">✉️</div>
|
||||
<h3 class="text-lg font-bold mb-2 text-brand-navy">Courriel</h3>
|
||||
<p class="text-sm text-brand-navy/80 mb-4 leading-relaxed flex-grow">
|
||||
Privilégiez le courriel pour : pré-inscription, devis, démonstration, dossier de conformité, partenariats.
|
||||
@@ -35,8 +35,8 @@
|
||||
</article>
|
||||
|
||||
{# Phone card #}
|
||||
<article class="bg-white p-8 rounded-[18px] border border-brand-border flex flex-col">
|
||||
<div class="w-12 h-12 grad-bg rounded-[0.5rem] mb-4 flex items-center justify-center text-2xl shadow-cta" aria-hidden="true">☎️</div>
|
||||
<article class="bg-white p-8 rounded-xl border border-brand-border flex flex-col">
|
||||
<div class="w-12 h-12 grad-bg rounded-md mb-4 flex items-center justify-center text-2xl shadow-cta" aria-hidden="true">☎️</div>
|
||||
<h3 class="text-lg font-bold mb-2 text-brand-navy">Téléphone</h3>
|
||||
<p class="text-sm text-brand-navy/80 mb-4 leading-relaxed flex-grow">
|
||||
Du lundi au vendredi, 9 h à 17 h (heure de l'Est). Laissez un message en dehors de ces heures.
|
||||
@@ -45,8 +45,8 @@
|
||||
</article>
|
||||
|
||||
{# Mailing address card #}
|
||||
<article class="bg-white p-8 rounded-[18px] border border-brand-border flex flex-col">
|
||||
<div class="w-12 h-12 grad-bg rounded-[0.5rem] mb-4 flex items-center justify-center text-2xl shadow-cta" aria-hidden="true">📬</div>
|
||||
<article class="bg-white p-8 rounded-xl border border-brand-border flex flex-col">
|
||||
<div class="w-12 h-12 grad-bg rounded-md mb-4 flex items-center justify-center text-2xl shadow-cta" aria-hidden="true">📬</div>
|
||||
<h3 class="text-lg font-bold mb-2 text-brand-navy">Bureau</h3>
|
||||
<p class="text-sm text-brand-navy/80 mb-4 leading-relaxed flex-grow">
|
||||
Sur rendez-vous uniquement. Visites en personne pour démonstrations on-premise et déploiements DictIA 16 corporatifs.
|
||||
@@ -83,7 +83,7 @@
|
||||
{'label': 'Question média / presse', 'subject': 'Question%20m%C3%A9dia', 'icon': '📰'}
|
||||
] %}
|
||||
<a href="mailto:info@dictia.ca?subject={{ shortcut.subject }}"
|
||||
class="flex items-center gap-3 bg-brand-bg p-4 rounded-[14px] border border-brand-border hover:bg-white hover:border-brand-b1/30 transition-colors focus-visible:outline-2 focus-visible:outline-brand-b1 focus-visible:outline-offset-2">
|
||||
class="flex items-center gap-3 bg-brand-bg p-4 rounded-xl border border-brand-border hover:bg-white hover:border-brand-b1/30 transition-colors focus-visible:outline-2 focus-visible:outline-brand-b1 focus-visible:outline-offset-2">
|
||||
<span class="text-2xl flex-shrink-0" aria-hidden="true">{{ shortcut.icon }}</span>
|
||||
<span class="text-sm font-semibold text-brand-navy">{{ shortcut.label | safe }}</span>
|
||||
</a>
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
{# NOTE: bento card content is duplicated between landing.html and fonctionnalites.html.
|
||||
When editing, sync both files. Future refactor: extract to _partials/_bento_features.html. #}
|
||||
{% from 'macros/bento.html' import bento_card %}
|
||||
<div class="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 gap-[1.5px] bg-brand-border rounded-[18px] overflow-hidden">
|
||||
<div class="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 gap-[1.5px] bg-brand-border rounded-xl overflow-hidden">
|
||||
{{ bento_card('01', 'Transcription WhisperX', 'Large-v3 fine-tuné FR-CA. Précision 95 %+ sur réunions, dictées, audiences (méthodologie disponible sur demande).', '🎙️') }}
|
||||
{{ bento_card('02', 'Diarisation 8 locuteurs', 'pyannote sépare automatiquement les intervenants. Identification par embeddings vocaux.', '👥') }}
|
||||
{{ bento_card('03', 'Résumés Mistral 7B', 'IA locale génère résumés, points d\'action et procès-verbaux. Aucune connexion cloud.', '📝') }}
|
||||
@@ -55,7 +55,7 @@
|
||||
{'ext': 'JSON', 'use': 'Pipeline développeur'},
|
||||
{'ext': 'MD', 'use': 'Notion, Obsidian, GitHub'}
|
||||
] %}
|
||||
<div class="bg-white p-4 rounded-[12px] border border-brand-border text-center">
|
||||
<div class="bg-white p-4 rounded-xl border border-brand-border text-center">
|
||||
<p class="text-base font-black text-brand-navy">{{ fmt.ext }}</p>
|
||||
<p class="text-xs text-brand-navy/70 mt-1">{{ fmt.use | safe }}</p>
|
||||
</div>
|
||||
@@ -87,7 +87,7 @@
|
||||
{'name': 'Make (Integromat)', 'desc': 'Scénarios visuels'},
|
||||
{'name': 'n8n', 'desc': 'Open source self-host'}
|
||||
] %}
|
||||
<div class="bg-brand-bg p-5 rounded-[14px] border border-brand-border text-center">
|
||||
<div class="bg-brand-bg p-5 rounded-xl border border-brand-border text-center">
|
||||
<p class="text-base font-bold text-brand-navy">{{ integ.name | safe }}</p>
|
||||
<p class="text-xs text-brand-navy/70 mt-1">{{ integ.desc | safe }}</p>
|
||||
</div>
|
||||
@@ -117,7 +117,7 @@
|
||||
{'title': 'Audio supportés', 'desc': 'WAV, MP3, M4A, FLAC, OGG, WebM — jusqu\'à 8 h par fichier. Conversion ffmpeg automatique.'},
|
||||
{'title': 'Langues', 'desc': 'Optimisé français québécois. Aussi : français de France, anglais (canadien et US), espagnol, allemand, mandarin, russe.'}
|
||||
] %}
|
||||
<article class="bg-white/[0.05] backdrop-blur-sm p-6 rounded-[0.75rem] border border-white/[0.08]">
|
||||
<article class="bg-white/[0.05] backdrop-blur-sm p-6 rounded-lg border border-white/[0.08]">
|
||||
<h3 class="text-lg font-bold mb-2 text-white">{{ spec.title | safe }}</h3>
|
||||
<p class="text-sm text-white/80 leading-relaxed">{{ spec.desc | safe }}</p>
|
||||
</article>
|
||||
|
||||
@@ -140,7 +140,7 @@
|
||||
('Loi 25 — biométrie', 'Sanctions CAI jusqu\'à 25 M$', 'La voix est une donnée biométrique au sens des articles 44-45 de la LCCJTI et un renseignement sensible au sens de la Loi 25 (art. 12 LSP). Tout traitement nécessite un consentement explicite, une déclaration préalable à la CAI et un transfert vers un territoire offrant une protection équivalente — ce que les États-Unis n\'offrent pas.', '🛡️'),
|
||||
('Sanctions disciplinaires', '~250 000 pros réglementés QC (CIQ)', 'Les ordres professionnels québécois — au premier rang desquels le Barreau, la Chambre des notaires et CPA Québec — exigent une obligation stricte de confidentialité. Le transfert de données client hors-juridiction sans consentement explicite peut être qualifié de manquement, jusqu\'à la radiation pour les fautes graves.', '⚠️')
|
||||
] %}
|
||||
<article class="bg-white p-6 rounded-[0.75rem] border border-brand-border">
|
||||
<article class="bg-white p-6 rounded-lg border border-brand-border">
|
||||
<div class="text-3xl mb-4" aria-hidden="true">{{ card[3] }}</div>
|
||||
<h3 class="text-lg font-bold mb-1 text-brand-navy">{{ card[0] }}</h3>
|
||||
<p class="text-xs uppercase tracking-wider text-brand-navy/70 mb-3 font-semibold">{{ card[1] | safe }}</p>
|
||||
@@ -175,8 +175,8 @@
|
||||
('Conforme Loi 25', 'Audit trail intégré (qui a écouté quoi, quand). Déclaration CAI prête. Consentement explicite tracé pour chaque enregistrement. Code source AGPL v3 — transparence vérifiable.'),
|
||||
('Précision FR-CA', 'WhisperX Large-v3 fine-tuné français québécois. Diarisation pyannote 8 locuteurs. Résumés Mistral 7B local — aucune connexion OpenAI/Google/Microsoft.')
|
||||
] %}
|
||||
<article class="bg-white/[0.05] backdrop-blur-sm p-6 rounded-[0.75rem] border border-white/[0.08]">
|
||||
<div class="w-10 h-10 grad-bg rounded-[0.5rem] mb-4 flex items-center justify-center font-black text-white shadow-cta" aria-hidden="true">✓</div>
|
||||
<article class="bg-white/[0.05] backdrop-blur-sm p-6 rounded-lg border border-white/[0.08]">
|
||||
<div class="w-10 h-10 grad-bg rounded-md mb-4 flex items-center justify-center font-black text-white shadow-cta" aria-hidden="true">✓</div>
|
||||
<h3 class="text-lg font-bold mb-2 text-white">{{ pillar[0] | safe }}</h3>
|
||||
<p class="text-sm text-white/70 leading-relaxed">{{ pillar[1] | safe }}</p>
|
||||
</article>
|
||||
@@ -198,7 +198,7 @@
|
||||
{# NOTE: bento card content is duplicated between landing.html and fonctionnalites.html.
|
||||
When editing, sync both files. Future refactor: extract to _partials/_bento_features.html. #}
|
||||
{% from 'macros/bento.html' import bento_card %}
|
||||
<div class="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 gap-[1.5px] bg-brand-border rounded-[18px] overflow-hidden">
|
||||
<div class="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 gap-[1.5px] bg-brand-border rounded-xl overflow-hidden">
|
||||
{{ bento_card('01', 'Transcription WhisperX', 'Large-v3 fine-tuné FR-CA. Précision 95 %+ sur réunions, dictées, audiences (méthodologie disponible sur demande).', '🎙️') }}
|
||||
{{ bento_card('02', 'Diarisation 8 locuteurs', 'pyannote sépare automatiquement les intervenants. Identification par embeddings vocaux.', '👥') }}
|
||||
{{ bento_card('03', 'Résumés Mistral 7B', 'IA locale génère résumés, points d\'action et procès-verbaux. Aucune connexion cloud.', '📝') }}
|
||||
@@ -225,7 +225,7 @@
|
||||
{% include 'marketing/_partials/_pricing_tiers.html' %}
|
||||
|
||||
{# ROI CALCULATOR — Alpine.js, hypotheses transparentes pour LPC art. 219 hygiene #}
|
||||
<div x-data="roiCalculator()" class="mt-16 max-w-3xl mx-auto bg-white p-8 rounded-[18px] border border-brand-border" aria-labelledby="roi-title">
|
||||
<div x-data="roiCalculator()" class="mt-16 max-w-3xl mx-auto bg-white p-8 rounded-xl border border-brand-border" aria-labelledby="roi-title">
|
||||
<p class="eyebrow text-center grad-text mb-2">CALCULATEUR ROI</p>
|
||||
<h3 id="roi-title" class="text-2xl font-black text-center mb-6 text-brand-navy">Combien DictIA peut vous faire économiser ?</h3>
|
||||
<div class="grid sm:grid-cols-3 gap-4 mb-6">
|
||||
@@ -272,7 +272,7 @@
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="overflow-x-auto rounded-[18px] border border-brand-border">
|
||||
<div class="overflow-x-auto rounded-xl border border-brand-border">
|
||||
<table class="w-full min-w-[720px] text-sm">
|
||||
<caption class="sr-only">Comparaison DictIA, Microsoft Teams Premium, Otter.ai Business, Whisper local sur 6 critères</caption>
|
||||
<thead class="bg-brand-bg">
|
||||
@@ -390,8 +390,8 @@
|
||||
'desc': 'Architecture entièrement auditable sur <a href="https://gitea.innova-ai.ca/Innova-AI/dictia-public" target="_blank" rel="noopener" class="underline hover:text-white">Gitea public</a>. Aucune boîte noire. Vos auditeurs peuvent examiner chaque ligne.'
|
||||
}
|
||||
] %}
|
||||
<article class="bg-white/[0.05] backdrop-blur-sm p-6 rounded-[0.75rem] border border-white/[0.08]">
|
||||
<div class="w-10 h-10 grad-bg rounded-[0.5rem] mb-4 flex items-center justify-center text-lg shadow-cta" aria-hidden="true">{{ card.icon }}</div>
|
||||
<article class="bg-white/[0.05] backdrop-blur-sm p-6 rounded-lg border border-white/[0.08]">
|
||||
<div class="w-10 h-10 grad-bg rounded-md mb-4 flex items-center justify-center text-lg shadow-cta" aria-hidden="true">{{ card.icon }}</div>
|
||||
<h3 class="text-lg font-bold mb-2 text-white">{{ card.title | safe }}</h3>
|
||||
<p class="text-sm text-white/80 leading-relaxed">{{ card.desc | safe }}</p>
|
||||
</article>
|
||||
@@ -421,7 +421,7 @@
|
||||
|
||||
<div class="grid md:grid-cols-3 gap-6">
|
||||
{% for t in testimonials %}
|
||||
<article class="bg-white p-6 rounded-[18px] border border-brand-border flex flex-col items-center text-center"
|
||||
<article class="bg-white p-6 rounded-xl border border-brand-border flex flex-col items-center text-center"
|
||||
aria-label="Témoignage {{ t.placeholder_label }} à venir">
|
||||
<div class="w-16 h-16 rounded-full grad-bg flex items-center justify-center mb-4 shadow-cta" aria-hidden="true">
|
||||
{%- if t.persona == 'avocat' -%}<span class="text-2xl">⚖️</span>
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
</h2>
|
||||
</div>
|
||||
|
||||
<div class="overflow-x-auto rounded-[18px] border border-brand-border">
|
||||
<div class="overflow-x-auto rounded-xl border border-brand-border">
|
||||
<table class="w-full min-w-[720px] text-sm">
|
||||
<caption class="sr-only">Comparaison détaillée des 3 forfaits DictIA sur 8 caractéristiques</caption>
|
||||
<thead class="bg-brand-bg">
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
{% block content %}
|
||||
<section class="min-h-[calc(100vh-62px)] bg-brand-bg py-16 px-4" aria-labelledby="signup-title">
|
||||
<div class="max-w-md mx-auto bg-white p-8 rounded-[18px] border border-brand-border shadow-cta">
|
||||
<div class="max-w-md mx-auto bg-white p-8 rounded-xl border border-brand-border shadow-cta">
|
||||
<h1 id="signup-title" class="text-3xl font-black text-brand-navy mb-2">Créer un compte</h1>
|
||||
<p class="text-sm text-brand-navy/70 mb-6">{{ "Conformité Loi 25 incluse — consentement granulaire, hébergement au Québec." | safe }}</p>
|
||||
|
||||
@@ -28,45 +28,45 @@
|
||||
|
||||
<div>
|
||||
<label for="email" class="block text-sm font-medium text-brand-navy mb-1">Courriel <span class="text-red-600" aria-hidden="true">*</span></label>
|
||||
{{ form.email(id='email', type='email', autocomplete='email', required=true, **{'aria-required':'true', 'class':'w-full px-3 py-2 border border-brand-border rounded-[0.5rem] text-brand-navy focus-visible:outline-2 focus-visible:outline-brand-b1 focus-visible:outline-offset-2'}) }}
|
||||
{{ form.email(id='email', type='email', autocomplete='email', required=true, **{'aria-required':'true', 'class':'w-full px-3 py-2 border border-brand-border rounded-md text-brand-navy focus-visible:outline-2 focus-visible:outline-brand-b1 focus-visible:outline-offset-2'}) }}
|
||||
{% if form.email.errors %}<p class="text-xs text-red-700 mt-1">{{ form.email.errors[0] }}</p>{% endif %}
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label for="password" class="block text-sm font-medium text-brand-navy mb-1">Mot de passe <span class="text-red-600" aria-hidden="true">*</span></label>
|
||||
{{ form.password(id='password', autocomplete='new-password', required=true, minlength=8, **{'aria-required':'true', 'aria-describedby':'password-help', 'class':'w-full px-3 py-2 border border-brand-border rounded-[0.5rem] text-brand-navy focus-visible:outline-2 focus-visible:outline-brand-b1 focus-visible:outline-offset-2'}) }}
|
||||
{{ form.password(id='password', autocomplete='new-password', required=true, minlength=8, **{'aria-required':'true', 'aria-describedby':'password-help', 'class':'w-full px-3 py-2 border border-brand-border rounded-md text-brand-navy focus-visible:outline-2 focus-visible:outline-brand-b1 focus-visible:outline-offset-2'}) }}
|
||||
{% if form.password.errors %}<p class="text-xs text-red-900 mt-1">{{ form.password.errors[0] }}</p>{% endif %}
|
||||
<p id="password-help" class="text-xs text-brand-navy/70 mt-1">8 caractères minimum, dont une majuscule, une minuscule, un chiffre et un caractère spécial.</p>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label for="confirm_password" class="block text-sm font-medium text-brand-navy mb-1">Confirmer le mot de passe <span class="text-red-600" aria-hidden="true">*</span></label>
|
||||
{{ form.confirm_password(id='confirm_password', autocomplete='new-password', required=true, **{'aria-required':'true', 'class':'w-full px-3 py-2 border border-brand-border rounded-[0.5rem] text-brand-navy focus-visible:outline-2 focus-visible:outline-brand-b1 focus-visible:outline-offset-2'}) }}
|
||||
{{ form.confirm_password(id='confirm_password', autocomplete='new-password', required=true, **{'aria-required':'true', 'class':'w-full px-3 py-2 border border-brand-border rounded-md text-brand-navy focus-visible:outline-2 focus-visible:outline-brand-b1 focus-visible:outline-offset-2'}) }}
|
||||
{% if form.confirm_password.errors %}<p class="text-xs text-red-700 mt-1">{{ form.confirm_password.errors[0] }}</p>{% endif %}
|
||||
</div>
|
||||
|
||||
<div class="grid grid-cols-2 gap-3">
|
||||
<div>
|
||||
<label for="first_name" class="block text-sm font-medium text-brand-navy mb-1">Prénom <span class="text-red-600" aria-hidden="true">*</span></label>
|
||||
{{ form.first_name(id='first_name', autocomplete='given-name', required=true, **{'aria-required':'true', 'class':'w-full px-3 py-2 border border-brand-border rounded-[0.5rem] text-brand-navy focus-visible:outline-2 focus-visible:outline-brand-b1 focus-visible:outline-offset-2'}) }}
|
||||
{{ form.first_name(id='first_name', autocomplete='given-name', required=true, **{'aria-required':'true', 'class':'w-full px-3 py-2 border border-brand-border rounded-md text-brand-navy focus-visible:outline-2 focus-visible:outline-brand-b1 focus-visible:outline-offset-2'}) }}
|
||||
{% if form.first_name.errors %}<p class="text-xs text-red-700 mt-1">{{ form.first_name.errors[0] }}</p>{% endif %}
|
||||
</div>
|
||||
<div>
|
||||
<label for="last_name" class="block text-sm font-medium text-brand-navy mb-1">Nom <span class="text-red-600" aria-hidden="true">*</span></label>
|
||||
{{ form.last_name(id='last_name', autocomplete='family-name', required=true, **{'aria-required':'true', 'class':'w-full px-3 py-2 border border-brand-border rounded-[0.5rem] text-brand-navy focus-visible:outline-2 focus-visible:outline-brand-b1 focus-visible:outline-offset-2'}) }}
|
||||
{{ form.last_name(id='last_name', autocomplete='family-name', required=true, **{'aria-required':'true', 'class':'w-full px-3 py-2 border border-brand-border rounded-md text-brand-navy focus-visible:outline-2 focus-visible:outline-brand-b1 focus-visible:outline-offset-2'}) }}
|
||||
{% if form.last_name.errors %}<p class="text-xs text-red-700 mt-1">{{ form.last_name.errors[0] }}</p>{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label for="cabinet" class="block text-sm font-medium text-brand-navy mb-1">Cabinet / Organisation</label>
|
||||
{{ form.cabinet(id='cabinet', autocomplete='organization', **{'class':'w-full px-3 py-2 border border-brand-border rounded-[0.5rem] text-brand-navy focus-visible:outline-2 focus-visible:outline-brand-b1 focus-visible:outline-offset-2'}) }}
|
||||
{{ form.cabinet(id='cabinet', autocomplete='organization', **{'class':'w-full px-3 py-2 border border-brand-border rounded-md text-brand-navy focus-visible:outline-2 focus-visible:outline-brand-b1 focus-visible:outline-offset-2'}) }}
|
||||
{% if form.cabinet.errors %}<p class="text-xs text-red-700 mt-1">{{ form.cabinet.errors[0] }}</p>{% endif %}
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label for="ordre_pro" class="block text-sm font-medium text-brand-navy mb-1">Ordre professionnel</label>
|
||||
{{ form.ordre_pro(id='ordre_pro', **{'class':'w-full px-3 py-2 border border-brand-border rounded-[0.5rem] text-brand-navy bg-white focus-visible:outline-2 focus-visible:outline-brand-b1 focus-visible:outline-offset-2'}) }}
|
||||
{{ form.ordre_pro(id='ordre_pro', **{'class':'w-full px-3 py-2 border border-brand-border rounded-md text-brand-navy bg-white focus-visible:outline-2 focus-visible:outline-brand-b1 focus-visible:outline-offset-2'}) }}
|
||||
</div>
|
||||
|
||||
{# 4 SEPARATE consent checkboxes — Loi 25 art. 14 (consent must be granular, free, informed) #}
|
||||
@@ -96,7 +96,7 @@
|
||||
</label>
|
||||
</fieldset>
|
||||
|
||||
{{ form.submit(**{'class':'w-full grad-bg text-white font-semibold py-3 rounded-[0.75rem] shadow-cta hover:shadow-cta-hover transition focus-visible:outline-2 focus-visible:outline-brand-b1 focus-visible:outline-offset-2'}) }}
|
||||
{{ form.submit(**{'class':'w-full grad-bg text-white font-semibold py-3 rounded-lg shadow-cta hover:shadow-cta-hover transition focus-visible:outline-2 focus-visible:outline-brand-b1 focus-visible:outline-offset-2'}) }}
|
||||
</form>
|
||||
|
||||
<p class="text-center text-sm text-brand-navy/70 mt-6">Déjà un compte ? <a href="{{ url_for('auth.login') }}" class="grad-text font-semibold">Se connecter</a></p>
|
||||
|
||||
@@ -268,7 +268,7 @@ def test_bento_uses_flexihub_styling():
|
||||
assert 'gap-[1.5px]' in body, "Missing FlexiHub ultrafin separator gap"
|
||||
assert 'bg-brand-navy2' in body, "Missing dark card background"
|
||||
assert 'text-white/[0.04]' in body, "Missing FlexiHub watermark opacity"
|
||||
assert 'grad-bg rounded-[0.5rem]' in body, "Missing gradient icon corner"
|
||||
assert 'grad-bg rounded-md' in body, "Missing gradient icon corner"
|
||||
|
||||
|
||||
def test_bento_responsive_grid():
|
||||
@@ -333,8 +333,8 @@ def test_pricing_recommended_tier_is_dictia_16():
|
||||
client = app.test_client()
|
||||
body = client.get('/').data.decode('utf-8')
|
||||
assert 'RECOMMAND' in body, "Missing RECOMMANDÉ badge"
|
||||
# The recommended tier wraps in grad-bg p-[1.5px] rounded-[20px] FlexiHub style
|
||||
assert 'grad-bg p-[1.5px] rounded-[20px]' in body, "Missing FlexiHub gradient frame on recommended tier"
|
||||
# The recommended tier wraps in grad-bg p-[1.5px] rounded-xl FlexiHub style (12px modern)
|
||||
assert 'grad-bg p-[1.5px] rounded-xl' in body, "Missing FlexiHub gradient frame on recommended tier"
|
||||
|
||||
|
||||
def test_pricing_cta_uses_reserver_pre_launch_wording():
|
||||
|
||||
Reference in New Issue
Block a user