feat(5.16+5.17): tipografie/antet branded + tipuri cont, planuri si enforcement
PRD 5.16 — propagare design finalizata (system font stack, fara IBM Plex self-hostat): - US-001/002/008: tokeni --font-ui/--font-mono (system stack) + scala --fs-*; zero @font-face si zero /static/fonts/; landing aliniat la acelasi stack - US-003: RAR online = dot compact in antet + meniu burger; banda rosie DOAR pe blocat (invariant zero-silent-failures pastrat) - US-010: antet "ROMFAST AUTOPASS" + nume service + /login brandeit 2 coloane + badge plan; meniu burger cu separatoare; gate strict pe is_authenticated - US-011: selector tema pill icon+eticheta (reuse THEMES) - US-004/005/006/007: bug-fix editor prestatii (picker cod+denumire, add_extra in mod operatii, cod ales se salveaza fara "+", Renunta inchide via closest) - US-012/013: landing Autentificare->/login; wizard import colapsat + 4 pasi pe tokeni - fix VERIFY E2E: contoare duplicate pe 390px (inline display:flex batea @media) -> CSS + test-lock PRD 5.17 — tipuri de cont + trial Pro 30z + enforcement DUR: - US-001/002/008: accounts.tier + trial_until (migrare aditiva defensiva); app/plans.py sursa unica (PLANS, FREE_MONTHLY_LIMIT=60, effective_tier(now injectabil), monthly_usage, CONSUMED_STATUSES); create_account trial Pro 30z; CLI set-tier (protejat id=1, audit) - US-003/004/005: enforce volum 60/luna INAINTE de build_key pe ambele canale (PLAN_LIMITA_LUNARA, 3 niveluri + log_event); gate API Pro+ (PLAN_FARA_API 403 actionabil); valideaza/nomenclator raman permise; downgrade lazy; flag AUTOPASS_ENFORCE_PLANS (kill-switch) - US-006: badge plan antet + linie burger + consum N/60 + warn>=80% + 6 stari + copy RO pluralizat + banner one-time trial->Gratuit + pagina Cont Regresie: 1380 passed, 0 failed, 1 deselected (live). E2E browser pe 390/1280 confirmat. Backend trimitere (worker/masina stari/idempotenta/contract RAR) NEATINS. Lucrul 5.18 (corpus kNN) ramane separat, necomis. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -14,55 +14,84 @@
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{# === D6: Strip sanatate mereu-vizibil DEASUPRA contoarelor ===
|
||||
Verde: worker viu + RAR ok → "Declaratiile curg normal"
|
||||
Rosu: worker oprit SAU RAR inaccesibil → "Blocat: ... — declaratiile NU pleaca"
|
||||
Glife accesibile ✓/✗ (nu doar culoare). Layout: glifa+text stanga, ultima auth dreapta.
|
||||
{# US-006 (5.17) — Banner one-time trial->Gratuit (T-DES-1): afisat la prima incarcare
|
||||
dupa expirarea trial-ului. Discret, non-blocant; dismissibil via sessionStorage.
|
||||
Nu acopera stripul de sanatate (apare inainte de health strip, la acelasi nivel). #}
|
||||
{% if trial_expirat_recent|default(false) %}
|
||||
<div id="banner-trial-expirat"
|
||||
role="status"
|
||||
style="margin-bottom:10px; padding:7px 12px;
|
||||
border-left:3px solid var(--warn);
|
||||
background:color-mix(in srgb, var(--warn) 10%, var(--card));
|
||||
border-radius:6px; font-size:var(--fs-sm);
|
||||
display:flex; align-items:center; justify-content:space-between; gap:8px;">
|
||||
<span>Trial Pro expirat — esti pe Gratuit, 60/luna</span>
|
||||
<button onclick="sessionStorage.setItem('tfx','1'); document.getElementById('banner-trial-expirat').style.display='none';"
|
||||
style="background:transparent; border:none; color:var(--muted); cursor:pointer;
|
||||
font-size:18px; padding:0 4px; line-height:1; flex-shrink:0;"
|
||||
aria-label="Inchide bannerul">×</button>
|
||||
</div>
|
||||
<script>(function(){ if(sessionStorage.getItem('tfx')){ var el=document.getElementById('banner-trial-expirat'); if(el) el.style.display='none'; } })();</script>
|
||||
{% endif %}
|
||||
|
||||
{# === US-003 (PRD 5.16): Banda de stare RAR — NUMAI cand BLOCAT (rosu, lat de 100%).
|
||||
OK = dot verde in antet (base.html); banda nu mai apare cand totul e ok.
|
||||
Elementul id="strip-sanatate" ramane in DOM mereu, dar goleste continutul cand OK,
|
||||
astfel "hidden" + fara continut eroare in sursa = nu pica testele de prezenta id-ului.
|
||||
#}
|
||||
{% if sanatate_ok %}
|
||||
<div id="strip-sanatate" role="status" aria-live="polite" hidden></div>
|
||||
{% else %}
|
||||
<div id="strip-sanatate"
|
||||
role="status"
|
||||
aria-live="polite"
|
||||
style="display:flex; align-items:center; justify-content:space-between; gap:12px; flex-wrap:wrap;
|
||||
padding:10px 14px; border-radius:8px; margin-bottom:14px;
|
||||
{% if sanatate_ok %}background:color-mix(in srgb, var(--ok) 13%, transparent); border:1px solid color-mix(in srgb, var(--ok) 30%, transparent);
|
||||
{% else %}background:color-mix(in srgb, var(--err) 16%, var(--card)); border:1px solid color-mix(in srgb, var(--err) 40%, transparent);
|
||||
{% endif %}">
|
||||
background:color-mix(in srgb, var(--err) 16%, var(--card)); border:1px solid color-mix(in srgb, var(--err) 40%, transparent);">
|
||||
<div style="display:flex; align-items:center; gap:9px;">
|
||||
{% if sanatate_ok %}
|
||||
<span aria-hidden="true" style="font-weight:700; font-size:15px; color:var(--ok);">✓</span>
|
||||
{% else %}
|
||||
<span aria-hidden="true" style="font-weight:700; font-size:15px; color:var(--err);">✗</span>
|
||||
{% endif %}
|
||||
<span style="font-weight:700; font-size:13px;">{{ sanatate_text }}</span>
|
||||
</div>
|
||||
<span style="font:400 11px/1.4 'IBM Plex Mono',ui-monospace,monospace; color:var(--muted); white-space:nowrap;">
|
||||
<span style="font-family:var(--font-mono); font-size:var(--fs-xs); color:var(--muted); white-space:nowrap;">
|
||||
{{ eticheta_ultima_auth }}: {{ last_login }}
|
||||
</span>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{# === D4: 3 carduri-contor (mockup exact: Trimise / In coada / De corectat) ===
|
||||
Responsive: flex-wrap => 3 pe rand desktop, 2/stivuite pe mobil (min-width:120px).
|
||||
Trimise: all-time (cifra mare) + sub-linie "luna N · azi N" (D4 + E7).
|
||||
De corectat: rosu cand >0 (s-error), muted cand 0.
|
||||
{# === US-002 (PRD 5.16): 5 carduri-contor separate (desktop) + bara compacta (mobil <=560px).
|
||||
Total / Luna asta / Azi / In coada / De corectat.
|
||||
#}
|
||||
<div style="display:flex; gap:12px; flex-wrap:wrap; margin-bottom:14px;">
|
||||
{# Desktop: 5 carduri side-by-side. display:flex + layout stau in CSS (.contoare-desktop in
|
||||
base.html), NU inline, ca media query-ul <=560px sa le poata ascunde pe mobil (bara compacta). #}
|
||||
<div class="contoare-desktop">
|
||||
|
||||
{# Trimise (all-time principal, luna/azi secundar) #}
|
||||
<div class="contor-card" style="flex:1; min-width:120px;">
|
||||
{# Total trimise (all-time) #}
|
||||
<div class="contor-card" style="flex:1; min-width:100px;">
|
||||
<div class="contor-cifra">{{ counts_sent }}</div>
|
||||
<div class="contor-label">Trimise (total)</div>
|
||||
<div class="contor-sub">luna {{ sent_month }} · azi {{ sent_today }}</div>
|
||||
<div class="contor-label">Total</div>
|
||||
</div>
|
||||
|
||||
{# In coada (accent/albastru) #}
|
||||
<div class="contor-card" style="flex:1; min-width:120px;">
|
||||
{# Luna asta #}
|
||||
<div class="contor-card" style="flex:1; min-width:100px;">
|
||||
<div class="contor-cifra s-accent">{{ sent_month }}</div>
|
||||
<div class="contor-label">Luna asta</div>
|
||||
</div>
|
||||
|
||||
{# Azi #}
|
||||
<div class="contor-card" style="flex:1; min-width:80px;">
|
||||
<div class="contor-cifra s-accent">{{ sent_today }}</div>
|
||||
<div class="contor-label">Azi</div>
|
||||
</div>
|
||||
|
||||
{# In coada #}
|
||||
<div class="contor-card" style="flex:1; min-width:80px;">
|
||||
<div class="contor-cifra s-queued">{{ counts_queued }}</div>
|
||||
<div class="contor-label">In coada</div>
|
||||
</div>
|
||||
|
||||
{# De corectat (rosu daca >0, muted la 0; link catre lista) #}
|
||||
<a href="/" class="contor-card"
|
||||
style="flex:1; min-width:120px; text-decoration:none; display:block; cursor:pointer;"
|
||||
style="flex:1; min-width:80px; text-decoration:none; display:block; cursor:pointer;"
|
||||
aria-label="De corectat: {{ blocate_total }} — click pentru lista de trimiteri">
|
||||
<div class="contor-cifra {{ 's-error' if blocate_total else 'muted' }}">{{ blocate_total }}</div>
|
||||
<div class="contor-label">De corectat</div>
|
||||
@@ -70,6 +99,30 @@
|
||||
|
||||
</div>
|
||||
|
||||
{# Mobil (<=560px): bara compacta — numerele + etichete scurte in-line #}
|
||||
<div class="contoare-compact">
|
||||
<div class="compact-item">
|
||||
<div class="compact-nr">{{ counts_sent }}</div>
|
||||
<div class="compact-lbl">Total</div>
|
||||
</div>
|
||||
<div class="compact-item">
|
||||
<div class="compact-nr s-accent">{{ sent_month }}</div>
|
||||
<div class="compact-lbl">Luna</div>
|
||||
</div>
|
||||
<div class="compact-item">
|
||||
<div class="compact-nr s-accent">{{ sent_today }}</div>
|
||||
<div class="compact-lbl">Azi</div>
|
||||
</div>
|
||||
<div class="compact-item">
|
||||
<div class="compact-nr s-queued">{{ counts_queued }}</div>
|
||||
<div class="compact-lbl">Coada</div>
|
||||
</div>
|
||||
<a class="compact-item" href="/" style="text-decoration:none; color:inherit;">
|
||||
<div class="compact-nr {{ 's-error' if blocate_total else 'muted' }}">{{ blocate_total }}</div>
|
||||
<div class="compact-lbl">Erori</div>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
{# === Navigatie rapida: Trimiteri + Mapari cu badge needs_mapping ===
|
||||
Pastrata exact ca inainte (US-005): tab_activ determina marcajul activ.
|
||||
#}
|
||||
@@ -84,4 +137,20 @@
|
||||
class="status-nav-link{% if _tab == 'mapari' %} status-nav-activ{% endif %}">Mapari{% if mapari_badge %}<span class="tab-badge" aria-hidden="true" style="display:inline-flex; align-items:center; justify-content:center; min-width:16px; height:16px; margin-left:4px; padding:0 4px; border-radius:99px; background:var(--err); color:#fff; font-size:11px; font-weight:700;">{{ mapari_badge }}</span>{% endif %}</a>
|
||||
</nav>
|
||||
|
||||
{# US-006 (5.17): linia de plan — consum/trial (secundar, sub navigatie, non-blocant).
|
||||
Warn=culoare+text (accesibilitate): >=80% -> --warn; limita atinsa -> --err.
|
||||
Ierarhie: nu concureaza cu stripul de sanatate (E zero-silent-failures pastrat). #}
|
||||
{% if plan_linie is defined and plan_linie %}
|
||||
<div class="plan-status-line"
|
||||
style="font-size:var(--fs-sm); margin-top:6px; padding-top:6px;
|
||||
border-top:1px solid var(--line2);
|
||||
color:{% if plan_limita_atinsa|default(false) %}var(--err){% elif plan_warn|default(false) %}var(--warn){% else %}var(--muted){% endif %};
|
||||
{% if plan_warn|default(false) %}font-weight:600;{% endif %}">
|
||||
{{ plan_linie }}
|
||||
{% if plan_limita_atinsa|default(false) or plan_warn|default(false) %}
|
||||
<a href="/?tab=cont" style="font-size:var(--fs-xs); font-weight:400; color:var(--accent);">Detalii plan</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user