feat(marketing): bento grid 6 features (style FlexiHub)
This commit is contained in:
File diff suppressed because one or more lines are too long
12
templates/macros/bento.html
Normal file
12
templates/macros/bento.html
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
{# Reusable bento card macro. FlexiHub style: dark navy2 surface, decorative watermark number, gradient icon corner. #}
|
||||||
|
{% macro bento_card(number, title, description, icon='✦', span='1') %}
|
||||||
|
<div class="relative bg-brand-navy2 p-6 rounded-[18px] overflow-hidden col-span-{{ span }}"
|
||||||
|
style="border: 1px solid rgba(255,255,255,0.045)">
|
||||||
|
<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>
|
||||||
|
<h3 class="text-lg font-bold mb-2 text-white">{{ title }}</h3>
|
||||||
|
<p class="text-sm text-white/70">{{ description }}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endmacro %}
|
||||||
@@ -184,4 +184,26 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
{# ===== BENTO FEATURES ===== #}
|
||||||
|
<section class="bg-white py-20" aria-labelledby="bento-title">
|
||||||
|
<div class="max-w-[1060px] mx-auto px-6">
|
||||||
|
<div class="text-center max-w-2xl mx-auto mb-12">
|
||||||
|
<p class="eyebrow grad-text mb-4">FONCTIONNALITÉS</p>
|
||||||
|
<h2 id="bento-title" class="text-[clamp(2rem,3vw,2.75rem)] font-black text-brand-navy">
|
||||||
|
Tout ce dont vous avez besoin, <span class="grad-text">rien que vous n'ayez besoin</span>.
|
||||||
|
</h2>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{% 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">
|
||||||
|
{{ 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.', '👥') }}
|
||||||
|
{{ 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.', '📝') }}
|
||||||
|
{{ bento_card('04', 'Q&R sur enregistrement', 'Posez des questions à vos réunions. RAG local sur embeddings sentence-transformers.', '💬') }}
|
||||||
|
{{ bento_card('05', 'Exports multiples', 'DOCX, PDF, SRT, VTT, TXT, JSON, MD. Formats avocat, notaire, CPA.', '📄') }}
|
||||||
|
{{ bento_card('06', 'Intégrations', 'Word, Outlook, Teams, Notion, Obsidian, Zapier, Make, n8n.', '🔌') }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|||||||
@@ -235,3 +235,49 @@ def test_pas_uses_wcag_safe_text_opacity():
|
|||||||
assert 'text-brand-navy/70 leading-relaxed' in body or 'text-brand-navy/70 mb-3' in body
|
assert 'text-brand-navy/70 leading-relaxed' in body or 'text-brand-navy/70 mb-3' in body
|
||||||
# No regression to /40 in this section
|
# No regression to /40 in this section
|
||||||
# (Other sections may use /40 for decorative text — we just verify the new content uses /70)
|
# (Other sections may use /40 for decorative text — we just verify the new content uses /70)
|
||||||
|
|
||||||
|
|
||||||
|
def test_bento_section_present():
|
||||||
|
"""Bento features section is present after Solution section."""
|
||||||
|
client = app.test_client()
|
||||||
|
body = client.get('/').data.decode('utf-8')
|
||||||
|
assert 'FONCTIONNALIT' in body, "Missing Fonctionnalités eyebrow"
|
||||||
|
assert 'bento-title' in body, "Missing bento section anchor"
|
||||||
|
assert "rien que vous n'ayez besoin" in body, "Missing bento H2 differentiator"
|
||||||
|
|
||||||
|
|
||||||
|
def test_bento_has_6_features():
|
||||||
|
"""Bento grid renders 6 distinct feature cards."""
|
||||||
|
client = app.test_client()
|
||||||
|
body = client.get('/').data.decode('utf-8')
|
||||||
|
for feature in ['WhisperX', 'Diarisation', 'Mistral 7B', 'RAG local', 'DOCX, PDF, SRT', 'Outlook, Teams']:
|
||||||
|
assert feature in body, f"Missing bento feature: {feature}"
|
||||||
|
# Watermark numbers 01..06
|
||||||
|
for n in ['01', '02', '03', '04', '05', '06']:
|
||||||
|
assert f'>{n}<' in body, f"Missing bento watermark number {n}"
|
||||||
|
|
||||||
|
|
||||||
|
def test_bento_uses_flexihub_styling():
|
||||||
|
"""Bento uses FlexiHub spec: max-w-[1060px], gap-[1.5px], bg-brand-navy2, /[0.04] watermark."""
|
||||||
|
client = app.test_client()
|
||||||
|
body = client.get('/').data.decode('utf-8')
|
||||||
|
assert 'max-w-[1060px]' in body, "Missing FlexiHub bento container width 1060px"
|
||||||
|
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"
|
||||||
|
|
||||||
|
|
||||||
|
def test_bento_responsive_grid():
|
||||||
|
"""Bento grid responsive: 1 col mobile, 2 cols sm, 3 cols md+."""
|
||||||
|
client = app.test_client()
|
||||||
|
body = client.get('/').data.decode('utf-8')
|
||||||
|
assert 'grid-cols-1 sm:grid-cols-2 md:grid-cols-3' in body, \
|
||||||
|
"Missing responsive grid breakpoints (1/2/3 cols)"
|
||||||
|
|
||||||
|
|
||||||
|
def test_bento_uses_wcag_safe_text_on_dark():
|
||||||
|
"""Bento card descriptions use text-white/70 (WCAG AA on bg-brand-navy2)."""
|
||||||
|
client = app.test_client()
|
||||||
|
body = client.get('/').data.decode('utf-8')
|
||||||
|
assert 'text-white/70' in body, "Missing WCAG-safe /70 text opacity on dark cards"
|
||||||
|
|||||||
Reference in New Issue
Block a user