fix(marketing): contraste/lisibilité 'Comment ça marche' — feature card + grid buttons WCAG AA

Audit complet : 2 incohérences fond/texte critiques sur fond CLAIR `bg-brand-bg`
(#f7f9fc) où des conteneurs `bg-white` à faible opacité rendaient le texte
quasi-invisible.

Fixes :

1. Bottom feature info card (sous le phone) — INVISIBLE
   `bg-white/[0.06] border-white/[0.10]` sur section claire = blanc 6%/10%
   sur near-white = card et bordure invisibles. Texte intérieur `text-white`
   et `text-white/65` aussi invisibles.
   → `bg-brand-navy` SOLIDE + `border-white/10` (extension visuelle naturelle
   du phone shell). Texte blanc maintenant lisible avec contraste WCAG AA.

2. Right panel feature grid 6 boutons — État ACTIF invisible
   Quand actif, fond `${color}14` (8% opacité du color sur section claire)
   = très light tint. Label `rgba(255,255,255,0.95)` sur fond clair tinté
   = quasi-invisible. Idem pour inactif text à 0.65 — bordure subtile.
   → Fond TOUJOURS dark `rgba(8,12,24,0.85-0.95)` (actif/inactif), avec
   différenciation via border + glow + scale + drop-shadow du color brand.
   Label porté à 0.98/0.70 pour AA garanti.

Test adapté : assertion `bg-white/[0.06]` remplacée par
`dictia-feature-card rounded-xl px-4 py-3 relative bg-brand-navy`.

29/29 tests pertinents passent ; 5 échecs pré-existants sur /conformite et
/landing sans rapport avec /fonctionnalites.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Allison
2026-04-29 11:03:37 -04:00
parent 7d3348c3fd
commit 323f0c81c4
3 changed files with 8 additions and 16 deletions

View File

@@ -2893,21 +2893,12 @@
font-size: var(--text-xs); font-size: var(--text-xs);
line-height: var(--tw-leading, var(--text-xs--line-height)); line-height: var(--tw-leading, var(--text-xs--line-height));
} }
.text-\[6\.5px\] {
font-size: 6.5px;
}
.text-\[6px\] { .text-\[6px\] {
font-size: 6px; font-size: 6px;
} }
.text-\[7\.5px\] {
font-size: 7.5px;
}
.text-\[7px\] { .text-\[7px\] {
font-size: 7px; font-size: 7px;
} }
.text-\[8\.5px\] {
font-size: 8.5px;
}
.text-\[8px\] { .text-\[8px\] {
font-size: 8px; font-size: 8px;
} }

View File

@@ -999,9 +999,9 @@
</div>{# /dictia-phone-shell #} </div>{# /dictia-phone-shell #}
</div>{# /phone wrapper (glow ring) #} </div>{# /phone wrapper (glow ring) #}
{# Feature info card sous le phone — uniform bg-white/[0.06] + accent border-left tab indicator #} {# Feature info card sous le phone — fond bg-brand-navy SOLIDE (extension visuelle du phone, contraste WCAG AA garanti sur section claire) + accent border-left tab indicator #}
<div style="min-height:64px;width:280px;max-width:100%;" class="mt-3 mx-auto"> <div style="min-height:64px;width:280px;max-width:100%;" class="mt-3 mx-auto">
<div class="dictia-feature-card rounded-xl px-4 py-3 relative bg-white/[0.06] border border-white/[0.10] overflow-hidden" <div class="dictia-feature-card rounded-xl px-4 py-3 relative bg-brand-navy border border-white/10 overflow-hidden"
:style="`box-shadow: 0 6px 24px rgba(0,0,0,0.20);`"> :style="`box-shadow: 0 6px 24px rgba(0,0,0,0.20);`">
{# Border-left 3px accent — style tab indicator #} {# Border-left 3px accent — style tab indicator #}
<span class="absolute left-0 top-0 bottom-0" aria-hidden="true" <span class="absolute left-0 top-0 bottom-0" aria-hidden="true"
@@ -1155,19 +1155,19 @@
</div> </div>
</div> </div>
{# Feature grid 3 cols × 6 buttons #} {# Feature grid 3 cols × 6 buttons — fond TOUJOURS dark navy (actif/inactif) pour garantir contraste WCAG AA blanc-sur-dark sur section claire #}
<div class="grid grid-cols-3 gap-2"> <div class="grid grid-cols-3 gap-2">
<template x-for="i in [1,2,3,4,5,6]" :key="i"> <template x-for="i in [1,2,3,4,5,6]" :key="i">
<button type="button" @click="handleManualSelect(i)" <button type="button" @click="handleManualSelect(i)"
class="flex flex-col items-center gap-1.5 rounded-xl py-3 px-2 outline-none transition-all focus-visible:ring-2 focus-visible:ring-white/40" class="flex flex-col items-center gap-1.5 rounded-xl py-3 px-2 outline-none transition-all focus-visible:ring-2 focus-visible:ring-white/40"
:style="`border: 1px solid ${selectedFeature === i ? FEATURES[i].color + '60' : 'rgba(255,255,255,0.10)'}; background-color: ${selectedFeature === i ? FEATURES[i].color + '14' : 'rgba(8,12,24,0.85)'}; box-shadow: ${selectedFeature === i ? '0 0 16px ' + FEATURES[i].color + '30, inset 0 0 12px ' + FEATURES[i].color + '10' : 'none'}; cursor: pointer;`" :style="`border: 1px solid ${selectedFeature === i ? FEATURES[i].color + '70' : 'rgba(255,255,255,0.10)'}; background-color: ${selectedFeature === i ? 'rgba(8,12,24,0.95)' : 'rgba(8,12,24,0.85)'}; box-shadow: ${selectedFeature === i ? '0 0 16px ' + FEATURES[i].color + '40, inset 0 0 16px ' + FEATURES[i].color + '20' : 'none'}; cursor: pointer;`"
:aria-pressed="selectedFeature === i ? 'true' : 'false'" :aria-pressed="selectedFeature === i ? 'true' : 'false'"
:aria-label="`Sélectionner : ${FEATURES[i].title}`"> :aria-label="`Sélectionner : ${FEATURES[i].title}`">
<span :style="`color: ${selectedFeature === i ? FEATURES[i].color : 'rgba(255,255,255,0.55)'}; filter: ${selectedFeature === i ? 'drop-shadow(0 0 6px ' + FEATURES[i].color + 'BB)' : 'none'}; transform: scale(${selectedFeature === i ? 1.20 : 1}) translateY(${selectedFeature === i ? -1 : 0}px); transition: all 0.2s; display:inline-block;`"> <span :style="`color: ${selectedFeature === i ? FEATURES[i].color : 'rgba(255,255,255,0.55)'}; filter: ${selectedFeature === i ? 'drop-shadow(0 0 6px ' + FEATURES[i].color + 'BB)' : 'none'}; transform: scale(${selectedFeature === i ? 1.20 : 1}) translateY(${selectedFeature === i ? -1 : 0}px); transition: all 0.2s; display:inline-block;`">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="width:18px;height:18px;" aria-hidden="true" x-html="featureIconPath(i)"></svg> <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="width:18px;height:18px;" aria-hidden="true" x-html="featureIconPath(i)"></svg>
</span> </span>
<span class="text-[10px] font-semibold text-center leading-tight" <span class="text-[10px] font-semibold text-center leading-tight"
:style="`color: ${selectedFeature === i ? 'rgba(255,255,255,0.95)' : 'rgba(255,255,255,0.65)'}; transition: color 0.2s;`" :style="`color: ${selectedFeature === i ? 'rgba(255,255,255,0.98)' : 'rgba(255,255,255,0.70)'}; transition: color 0.2s;`"
x-text="FEATURES[i].title"></span> x-text="FEATURES[i].title"></span>
</button> </button>
</template> </template>

View File

@@ -266,8 +266,9 @@ def test_fonctionnalites_how_it_works_reactor_section():
# Inner screen seam (effet "écran encastré") # Inner screen seam (effet "écran encastré")
assert 'dictia-phone-screen-seam' in body, "Missing inner screen seam (encastré effect)" assert 'dictia-phone-screen-seam' in body, "Missing inner screen seam (encastré effect)"
# Uniform feature info card — bg-white/[0.06] + accent border-left # Uniform feature info card — bg-brand-navy SOLIDE (extension visuelle du phone, WCAG AA garanti sur section claire) + accent border-left
assert 'bg-white/[0.06]' in body, "Missing uniform white/0.06 bg on feature card" assert 'dictia-feature-card rounded-xl px-4 py-3 relative bg-brand-navy' in body, \
"Missing solid bg-brand-navy on feature info card (must be dark, not transparent on light bg)"
# Sovereignty bullets : icon dans cercle 20×20 brand-b3/[0.15] # Sovereignty bullets : icon dans cercle 20×20 brand-b3/[0.15]
assert 'bg-brand-b3/[0.15]' in body, "Missing brand-b3 circle bg on sovereignty bullets" assert 'bg-brand-b3/[0.15]' in body, "Missing brand-b3 circle bg on sovereignty bullets"
# Performance metrics : 3 cells with grad-text for 0ms / 24/7 # Performance metrics : 3 cells with grad-text for 0ms / 24/7