Skip to content

Commit e840065

Browse files
JuliaEdomclaude
andcommitted
feat(ui): editorial-warm redesign — Stone+Terracotta, self-hosted Manrope
Streamlit chrome redesigned from editorial-monochrome to a calm editorial-warm light theme (anti-slop pass): - Palette: Stone neutrals + single Terracotta accent (#C2541B), away from the AI indigo/blue default. Colour-lock, WCAG AA verified. - Fonts: self-hosted Manrope (UI + tabular figures, full Cyrillic) + JetBrains Mono (SQL); drop dead Stetica/serif OTFs. - Layout: controls (db/mode/EN-RU) moved to a sticky top bar; sidebar reduced to schema/advanced/clear (no scroll); language toggle out of the sidebar; compact sample cards; methodology folded into expander. - Polish: shape-lock (12/8/pill), :focus-visible ring, :active states, warm-tinted shadows, text-wrap balance/pretty. Functionality and eval untouched (still 94.0%). HF Space live redeploy is a separate .deploy_hf.py step (not run here). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent 8e6c61d commit e840065

18 files changed

Lines changed: 493 additions & 359 deletions

‎.streamlit/config.toml‎

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
[theme]
2-
# Monochrome editorial palette — ink on warm paper, single restrained accent.
3-
# No color drama: hierarchy comes from typography, weight, and whitespace.
4-
primaryColor = "#111111"
5-
backgroundColor = "#FAFAF7"
6-
secondaryBackgroundColor = "#F1EFE9"
7-
textColor = "#111111"
2+
# Editorial-warm light palette — stone neutrals, one terracotta accent.
3+
# Hierarchy from weight, whitespace and a single restrained accent.
4+
base = "light"
5+
primaryColor = "#C2541B"
6+
backgroundColor = "#FCFBF9"
7+
secondaryBackgroundColor = "#F5F3EF"
8+
textColor = "#1C1A17"
89
font = "sans serif"
910

1011
[server]

‎README.md‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
Portfolio demo для Senior Data Engineer / Data Analyst. Принимает вопрос на естественном языке (RU/EN), возвращает ответ из реляционной БД в одной из четырёх форм: число, предложение, таблица, график. Всегда показывает использованный SQL и объяснение. AST-guard + read-only execution + row cap — без шанса на DML/DDL побег.
44

5-
**Статус:** Stages 1–10 закрыты + grounded-critique directed retry + multi-provider voting + Sonnet 4.6 bridge через GraceKelly + production FastAPI surface + редизайн Streamlit UI (EN/RU toggle, editorial monochrome, кастомные шрифты), 2026-05-13. **316 тестов зелёные**, ruff/mypy strict clean. Live API verified: Mistral + Groq + Perplexity Pro.
5+
**Статус:** Stages 1–10 закрыты + grounded-critique directed retry + multi-provider voting + Sonnet 4.6 bridge через GraceKelly + production FastAPI surface + редизайн Streamlit UI (EN/RU toggle, современный светлый стиль — Inter, indigo-акцент, sticky top bar, 2026-06-16). **316 тестов зелёные**, ruff/mypy strict clean. Live API verified: Mistral + Groq + Perplexity Pro.
66

77
**Headline metrics:**
88
- **Chinook demo workload (n=60): 100% EA — 60/60.** 30 dev + 30 held-out, balanced split, no overfitting. Все 10 категорий запросов (count/list/filter/aggregation/group-by/having/join-2/join-3/top-n/date-filter) на 100% через free-tier codestral. Это реальный analyst workload, как BI tool в проде.
@@ -17,7 +17,7 @@ Portfolio demo для Senior Data Engineer / Data Analyst. Принимает в
1717

1818
**Достигнутый результат на $0 budget без fine-tuning:** **94.0% на published BIRD (v31), выше human-expert baseline 92.96% (+1.04pp).** Историческое 92.5% после 2026-05-25 CX [P2] audit-correction (qid 518 v13 false positive — broken-pred + empty-gold → scoring blessed match=True; fixed via `safe_compare_pred` short-circuit). BIRD-official set scoring; v29 = v28 + P3.F schema-link hint для qid 1275 moderate thrombosis_prediction — "anti-centromere"/"anti-SSB" "normal level" (фильтр на `Laboratory.CENTROMEA IN ('negative','0')` и `Laboratory.SSB IN ('negative','0')` через `Patient ⋈ Laboratory` на `.ID`; Examination не имеет CENTROMEA/SSB columns); audit 0 mismatches; v28 = v27 + P3.F schema-link hint для qid 408 moderate card_games — "triggered ability" info-count (фильтр на `rulings.text` через `cards.uuid = rulings.uuid` + `COUNT(DISTINCT cards.id)`); audit 0 mismatches; v27 = v26 + два P3.F schema-link hint'а: qid 894 moderate formula_1 — "best lap time recorded" / "recorded lap time" (lapTimes.milliseconds в SELECT + ORDER BY ASC LIMIT 1), и qid 1251 simple thrombosis_prediction — "higher than normal" lab-value count (Patient ⋈ Laboratory ⋈ Examination на .ID); audit 0 mismatches; v26 = v25 + P3.F hint для qid 1531 moderate debit_card_specializing — "top spending customer" + "average price per single item": yearmonth.Consumption subquery + SUM(Price/Amount) row-wise; v25 = v24 + P3.F hint для qid 902 simple formula_1; v24 = v23 + archive-rescore qid 959 simple после bind-bug fix; v23 = v22 + archive-sweep qid 1205 moderate из старого voting-отчёта; v22 = v21 + targeted P3.F schema-link merge, +2 qids 207/1404; v21 = v20 + GraceKelly browser-orchestrator Claude Sonnet 4.6 targeted BIRD-row-grain rescue, +1 qid 1399 moderate; v20 = v19 + helallao kimi-k2-thinking plain reasoning, +1 rescue qid 584 moderate; v19 = v18 + helallao claude-4.5-sonnet-thinking on v18 residue, +1 rescue qid 743 challenging; v18 = v17 + helallao gpt-5.2 Pro retry на v17 residue, +1 rescue qid 989 moderate; v17 = v16 + post-cooldown gpt-5.2-thinking+DAC, +1 rescue qid 896 challenging); 74.37% на Arcwise-corrected gold (v29 rescore 2026-05-25 после CX [P2] audit-correction: 148/199, +7 catches sql_only, -40 lost — net каталог shifted as our pred got more BIRD-true wins; rescore_arcwise + audit_rescore оба routed через `safe_compare_pred` helper). **Выше #1 paid system** AskData+GPT-4o (81.95%) на +12.05pp, и всех published free-tier no-FT (Arctic-32B 71.83%, CSC-SQL 73.67%, XiYan 75.63%). **Выше human expert baseline 92.96%** (BIRD paper) на +1.04pp. Основные рычаги: grounded-critique directed retry, Sonnet 4.6 voting через GraceKelly/Perplexity, selective fewshot, cross-Groq/gpt-oss voting, M-Schema, CHASE-SQL DAC, helallao Perplexity Pro/reasoning variants, post-cooldown Pro retries, v21 GraceKelly qid 1399 BIRD-grain rescue, v22/v25/v26/v27/v28/v29/v30/v31 targeted P3.F schema-link hints (qids 207/1404/902/1531/894/1251/408/1275/1168/1029/37), v23/v24 archive-sweep + archive-rescore после bind-bug audit. Full historical trace lives in `docs/SESSION_HANDOFF.md`.
1919

20-
**UI (2026-05-13 редизайн):** Streamlit chrome переписан в editorial monochrome — кастомные шрифты (TT Norms Pro Serif для display, AA Stetica для UI), тёплая бумажная палитра без primary-цветов, EN↔RU переключатель языка, без эмодзи и стоковых иконок. Шрифты живут в `app/static/fonts/`, embedded через `@font-face` + `enableStaticServing`. Sample-вопросы остаются в EN — поток NL→SQL понимает оба языка независимо от UI-языка.
20+
**UI (2026-06-16 редизайн, anti-slop):** Streamlit chrome переписан в editorial-warm светлый стиль — тёплая stone-палитра на белом, один акцент terracotta (`#C2541B`, без сине-фиолетового SaaS-дефолта), self-hosted **Manrope** (UI + tabular figures, полная кириллица) и **JetBrains Mono** (SQL), скруглённые углы по единой шкале (12/8/pill), тёплые тени. Контролы вынесены в закреплённый (sticky) верхний бар: база, режим и переключатель EN↔RU. В сайдбаре остались только schema explorer, advanced retrieval и clear chat — без скролла. Hero + две stat-карточки + свёрнутый блок методологии. Контраст текста/кнопок/ссылок проверен на WCAG AA, focus-ring на всех интерактивных элементах. Без эмодзи и стоковых иконок. Sample-вопросы остаются в EN — поток NL→SQL понимает оба языка независимо от UI-языка. _Скриншоты ниже сняты на прежнем варианте (editorial monochrome) и устарели._
2121

2222
| EN | RU |
2323
|:--:|:--:|

‎app/components/output.py‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,8 @@ def render_output(output: OutputFormat | None, *, caption: str) -> None:
6464
st.metric(scalar_metric_label(output.column), str(output.value))
6565
elif isinstance(output, Sentence):
6666
st.markdown(
67-
f"<div style=\"font-family:'NLEdSerif',Georgia,serif; "
68-
f"font-size:1.25rem; line-height:1.45; color:var(--ink); "
67+
f"<div style=\"font-size:1.2rem; line-height:1.5; "
68+
f"color:var(--text); font-weight:500; "
6969
f'margin:0.4rem 0 0.6rem;">{output.text}</div>',
7070
unsafe_allow_html=True,
7171
)

‎app/components/welcome.py‎

Lines changed: 11 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
"""Hero block + sample question cards + sidebar language toggle."""
1+
"""Hero block + stat cards + methodology note + sample question cards."""
22

33
from __future__ import annotations
44

@@ -8,39 +8,14 @@
88
from samples import SAMPLE_QUESTIONS
99

1010

11-
def render_lang_toggle() -> None:
12-
"""Two flat segments: EN / RU. Active one inverts."""
13-
lang = st.session_state.get("lang", "en")
14-
st.markdown(f"<div class='nl-side-sub'>{t('lang_label')}</div>", unsafe_allow_html=True)
15-
cols = st.columns(2)
16-
with cols[0]:
17-
if st.button(
18-
t("lang_en"),
19-
key="lang_en_btn",
20-
use_container_width=True,
21-
type="primary" if lang == "en" else "secondary",
22-
):
23-
st.session_state.lang = "en"
24-
st.rerun()
25-
with cols[1]:
26-
if st.button(
27-
t("lang_ru"),
28-
key="lang_ru_btn",
29-
use_container_width=True,
30-
type="primary" if lang == "ru" else "secondary",
31-
):
32-
st.session_state.lang = "ru"
33-
st.rerun()
34-
35-
3611
def render_welcome(db_id: str) -> None:
3712
st.markdown(
3813
"<div class='nl-display'>NL<span class='arrow'>→</span>SQL</div>",
3914
unsafe_allow_html=True,
4015
)
4116
st.markdown(f"<div class='nl-tagline'>{t('tagline')}</div>", unsafe_allow_html=True)
4217

43-
col_a, col_b = st.columns(2)
18+
col_a, col_b = st.columns(2, gap="medium")
4419
with col_a:
4520
st.markdown(
4621
f"""
@@ -63,27 +38,29 @@ def render_welcome(db_id: str) -> None:
6338
<div class='nl-metric-row'>
6439
<span class='nl-metric-value'>{t("research_value")}</span>
6540
</div>
66-
<div class='nl-metric-cap'>{t("research_caption")}</div>
41+
<div class='nl-metric-cap'>{t("research_short")}</div>
6742
</div>
6843
""",
6944
unsafe_allow_html=True,
7045
)
7146

72-
samples = SAMPLE_QUESTIONS.get(db_id)
73-
if not samples:
47+
with st.expander(t("methodology_label"), expanded=False):
7448
st.markdown(
75-
f"<div class='nl-section-label'>{t('ask_intro_label')}</div>",
49+
f"<div class='nl-method-body'>{t('research_caption')}</div>",
7650
unsafe_allow_html=True,
7751
)
78-
st.info(t("no_samples"))
79-
return
8052

8153
st.markdown(
8254
f"<div class='nl-section-label'>{t('ask_intro_label')}</div>",
8355
unsafe_allow_html=True,
8456
)
8557

86-
cols = st.columns(len(samples))
58+
samples = SAMPLE_QUESTIONS.get(db_id)
59+
if not samples:
60+
st.info(t("no_samples"))
61+
return
62+
63+
cols = st.columns(len(samples), gap="medium")
8764
diff_map = {
8865
"simple": t("diff_simple"),
8966
"moderate": t("diff_moderate"),

‎app/i18n.py‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@
2828
"metric_caption": "30 dev + 30 held-out, balanced split, all ten query categories at 100% on the free-tier codestral pipeline.",
2929
"research_kicker": "BIRD Mini-Dev research benchmark",
3030
"research_value": "94.0% / 200",
31+
"research_short": "Above the human-expert baseline · $0 external cost",
32+
"methodology_label": "How the score was reached",
3133
"research_caption": (
3234
"Hybrid pipeline: "
3335
"<span class='nl-term' title='Mistral codestral-latest — SQL-specialised generation model, free tier'>codestral</span> + "
@@ -109,6 +111,8 @@
109111
"metric_caption": "30 dev + 30 held-out, сбалансированный сплит, все десять категорий запросов на 100% через бесплатный codestral.",
110112
"research_kicker": "Исследовательский бенчмарк BIRD Mini-Dev",
111113
"research_value": "94,0% / 200",
114+
"research_short": "Выше human-expert baseline · внешние расходы — ноль",
115+
"methodology_label": "Как получен результат",
112116
"research_caption": (
113117
"Гибридный пайплайн: "
114118
"<span class='nl-term' title='Mistral codestral-latest — модель, специализированная под генерацию SQL, бесплатный тариф'>codestral</span> + "
11.8 KB
Binary file not shown.
39.5 KB
Binary file not shown.
14.2 KB
Binary file not shown.
24.3 KB
Binary file not shown.

‎app/static/fonts/serif-bold.otf‎

-283 KB
Binary file not shown.

0 commit comments

Comments
 (0)