feat(home,sidebar): brand hero + sidebar = footer style + PNG icon

Bundles a handful of UX cleanups:

- Findings-card chevron moved to the LEFT side of the head. CSS still
  rotates it 90° between collapsed/expanded states.

- Tool-link buttons in findings rows (``Clean Text →`` etc.) are now
  left-justified against the icon column with minimal surrounding
  whitespace. Action column ratio dropped from 1.8 → 1.4 and the
  button switched from ``width="stretch"`` (centered text) to
  ``width="content"`` (shrinks to fit, left-aligned within column).

- Home-page hero now mirrors the sidebar brand block: 56px ink "D"
  chip on the left + "UNALOGIX" eyebrow stacked above "DataTools"
  wordmark, then the "Clean. Normalize. Transform." tagline beneath.
  New ``.dt-page-brand / -row / -words / -mark / -eyebrow /
  -wordmark`` rules in ``_DESIGN_TOKENS_CSS``. Streamlit wraps h1
  elements in an emotion-cache div with extra padding; a descendant
  flattener (``.dt-page-brand-words *`` margin:0 / padding:0) keeps
  the eyebrow + wordmark stack the same height as the chip so they
  center-align cleanly.

- Sidebar nav restyled to match the sticky-footer Help/Close buttons
  exactly: 13px / 500 / 1.3 line-height, 5×10px padding, 8px gap
  between icon and label, transparent background. Active item gets
  the same ``rgba(0,0,0,0.04)`` tint as the hover state (no white
  pill, no shadow), only the heavier weight + ink text distinguishes
  it.

- OS app icon (page_icon) switched from SVG to a Pillow-rendered
  ``datatools_icon_256.png`` so Windows / macOS taskbar+dock pick
  it up reliably (some OS shells fall back to a default icon for
  SVG favicons). Rounded-square ink ground with cream "D" centered —
  same mark as the sidebar chip + hero chip.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-19 02:04:53 +00:00
parent 6c3939d21b
commit 1016a4d2c4
5 changed files with 120 additions and 34 deletions

View File

@@ -172,7 +172,7 @@ def _home_page() -> None:
from src.i18n import t
from pathlib import Path as _Path
_ICON_PATH = str(_Path(__file__).parent / "assets" / "datatools_icon.svg")
_ICON_PATH = str(_Path(__file__).parent / "assets" / "datatools_icon_256.png")
st.set_page_config(
page_title=t("home.page_title"),
page_icon=_ICON_PATH,
@@ -182,17 +182,22 @@ def _home_page() -> None:
render_sticky_footer()
import html as _html
# Page header — h1 + body subtitle on the left, privacy pill on
# the right (mockup §page-header). Rendered as a single HTML block
# so the title/subtitle/pill share one flex row; ``st.title`` +
# ``st.caption`` + ``st.divider`` would stack vertically and lose
# the right-aligned pill. Bottom border replaces the explicit
# ``st.divider`` that used to sit below the caption.
# Page header — brand block (D icon + "UNALOGIX" eyebrow over
# "DataTools" wordmark + tagline) on the left, privacy pill on
# the right. Matches the sidebar brand chip scaled up for the
# hero. Bottom border replaces the explicit ``st.divider`` that
# used to sit below the caption.
privacy_label = _html.escape(t("home.privacy_pill"))
st.markdown(
'<header class="dt-page-header">'
'<div>'
f'<h1>{_html.escape(t("home.title"))}</h1>'
'<div class="dt-page-brand">'
'<div class="dt-page-brand-row">'
'<div class="dt-page-brand-mark">D</div>'
'<div class="dt-page-brand-words">'
'<span class="dt-page-eyebrow">UNALOGIX</span>'
'<h1 class="dt-page-wordmark">DataTools</h1>'
'</div>'
'</div>'
f'<p class="dt-page-subtitle">{_html.escape(t("home.caption"))}</p>'
'</div>'
'<span class="dt-privacy-pill">'