feat(frontend): hero attribute tiles — 4-box category grid (lucide-react)#344
Merged
Conversation
…act) User asked for "กรอบสี่เหลี่ยมสี่อันในภาพ" — a reference stock app's 4 category tiles (icon-over-label boxes). A grill-me session locked the spec: match the structure but reskin to the QuantRank theme (light slate / dark slate, not the reference app's black boxes which break in light mode); 2 tiles carry data (Size = market-cap tier, Sector), 2 are intentional "Coming soon" placeholders (dashed border + sub-line — QuantRank has no dividend data, so the reference app's dividend tile can't be filled; the empty tile reads as reserved, not broken). Info tiles, not filters. Supersedes + closes PR #343 (the earlier inline-chip attempt — the user wanted the box grid, not a compact chip row). New dep lucide-react@^1.17.0 (the project's first icon library). Both dependency-auditor + security-reviewer SAFE: ISC license, React-18.3 peer, 0 transitive, 0 install-scripts, SLSA-attested, 0 CVE. Tree-shakes to ~1.5-2 KB gzipped via NAMED imports (never the import-* barrel); the stock-detail route went 113 -> 115 KB First Load JS as predicted. Not added to the dependabot ignore-list (normal flow); not added to THIRD_PARTY_NOTICES.md (that file is vendored-source/skills only — runtime npm deps like next/react/recharts aren't listed there). New HeroAttributeTiles.tsx pure server component: grid grid-cols-2 sm:grid-cols-4, 4 fixed tiles via a Tile sub-component (null value -> dashed reserved treatment). Own section under the hero, above the price chart. tsc clean, next build 506/506, NVDA HTML verified (Size->Mega cap, Sector->Information Technology, 2 Coming-soon placeholders, responsive grid, lucide inline SVG). No schema/Python/scoring/valuation change. https://claude.ai/code/session_0148EoMmL6zakDWqHXjqQ9yq
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
…a11y) frontend-design-reviewer found no blockers; folds in the SHOULD-FIX + NIT items: - S1 contrast: reserved-tile caption text-slate-400 -> text-slate-500 (~3.4:1, WCAG large/bold floor instead of the too-faint ~2.8:1). - S2 casing: reserved-tile caption now uses the same UPPERCASE tracking-wider vocabulary as a filled tile (de-emphasis via color only), so promoting a placeholder later won't flip the type treatment. - N1 icon: Sector icon Factory -> Layers (Factory connotes manufacturing specifically; Layers reads as a neutral "category" for all 11 GICS sectors, and stops blurring with Building2 on the Size tile). - N2 a11y: wrap the grid in <section aria-label="Company attributes"> with an sr-only <h2> so the tile block joins the document outline like every other detail-page section. tsc clean, next build 506/506, NVDA HTML verified (section + sr-only h2, Layers icon, uppercase reserved caption, Mega cap / Information Technology data tiles intact). No behavior change beyond the review polish. https://claude.ai/code/session_0148EoMmL6zakDWqHXjqQ9yq
Per user direction: the 4th placeholder tile is reserved for a future security-type signal (Common stock / ADR / etc. — the analog of the reference app's "Common · หุ้นสามัญ" tile), not a generic "More". Caption More -> Type, icon Gauge -> ScrollText (reads as a security certificate / type). Still a "Coming soon" reserved tile — QuantRank has no security-type field in the schema yet; when one lands, swapping the tile's value from null to the real field auto-promotes it out of the reserved state. tsc clean, next build 506/506, NVDA HTML: Type + Dividend reserved tiles present, More gone. CLAUDE.md gotcha updated to match. https://claude.ai/code/session_0148EoMmL6zakDWqHXjqQ9yq
…#7 The two reserved HeroAttributeTiles slots (Dividend + Type, PR #344) now have a planned data path on the roadmap so they're a tracked deliverable, not an open-ended "Coming soon": - 7a Dividend — dividend_yield_pct / pays_dividend from yfinance (already in the stack via compute/ingest/prices.py, no new dep) + schema triple + Metadata.dividend_coverage_pct observability-first. - 7b Security-type — Common / ADR / REIT label from yfinance quoteType / SEC filer flags + schema triple, same observability discipline. Both are display-only (fill the reserved tiles; no ranking/scoring/veto impact). Each sequenced behind a *_coverage_pct diagnostic cron before the tile reads live data (the Phase 4h -> 4h.2 observability-before-wiring precedent). Tiles auto-promote out of the reserved state when the field lands. Documented in PHASE_STATUS.md §Next deliverables #7 + CLAUDE.md + AGENTS.md inventory note + PHASE_STATUS_INFLIGHT.md. Doc-only — no compute/schema/scoring/frontend code change. https://claude.ai/code/session_0148EoMmL6zakDWqHXjqQ9yq
…item docs-reviewer verified the roadmap #7 field names against the yfinance actually installed and found three wrong: - .info["quoteType"] is retired into fast_info on current yfinance -> use fast_info.quote_type (kept as a "NOT this" warning in the text). - .info["legalType"] is funds-only (None for all S&P 500 equities) -> dropped. - IsForeignPrivateIssuer is not a real SEC field -> use dei:DocumentType == "20-F" or the EDGAR submissions entityType field (already fetched by compute/ingest/sec_health.py) for ADR/FPI detection. - the dividend .info ingest anchor was mis-attributed to prices.py (yf.download OHLCV-only) -> corrected to cross_source.py, which already uses yf.Ticker().info + caches under YFINANCE_INFO_CACHE_DIR. Roadmap framing (display-only, observability-before-wiring, no scoring impact, schema-triple lockstep) was confirmed accurate; only the API field names + ingest-file attribution were fixed across PHASE_STATUS.md + CLAUDE.md + PHASE_STATUS_INFLIGHT.md. Doc-only. https://claude.ai/code/session_0148EoMmL6zakDWqHXjqQ9yq
dackclup
added a commit
that referenced
this pull request
Jun 1, 2026
…ccable document) (#354) Full regenerate of the impeccable design-context (created in #350) against the current code. The creative decisions locked in #350 (North Star, palette, typography, Named Rules, the 4 anti-references) are preserved verbatim; only the spec's accuracy had drifted, fixed here: - Elevation: DESIGN.md/sidecar claimed cards rest on shadow-medium and the hero on shadow-large. Reality (post-A3 reskin): only shadow-overlay is used anywhere (FilterDrawer) -- every card/table/hero is border-only `rounded`. Rewrote the Elevation section + sidecar shadow purposes so Subtle/Medium/Large read as defined-but-unused; an agent will no longer reach for a resting shadow. - Components: added ListingChips (#351 country/exchange chips) + HeroAttributeTiles (#344 4-box tile grid) to DESIGN.md and the sidecar, plus an Icons subsection (lucide named-import / country-flag-icons per-country tree-shake discipline) and the signature Score Gauge as the 8th sidecar entry. - Motion: corrected two sidecar easings -- gauge-sweep cubic-bezier(.22,1,.36,1) -> ease-in-out, hover-lift ease-out -> ease-in-out (the app-wide single curve, #330). - Sidecar Card css dropped its stale box-shadow (border-only); Recommendation Chip now uses the soft-OKLCH values that actually render after the globals.css override (expert-user-explorer-measured) instead of raw emerald hex. Added a Colors + Do's note on the soft-override allowlist (the bg-rose-600 gap from #352) + the gauge-stroke inline-rgb carve-out to the Tailwind-Class Rule. Doc-only (root DESIGN.md + .impeccable/design.json + PHASE_STATUS_INFLIGHT.md) -- no compute / schema / scoring / valuation / frontend-code change. JSON validated (schemaVersion 2, 8 components); the 6 Stitch headers present in order; YAML frontmatter parses. https://claude.ai/code/session_012xxKfyR939bZDmbxxqMFZi Co-authored-by: Claude <noreply@anthropic.com>
dackclup
added a commit
that referenced
this pull request
Jun 1, 2026
… MoS labels · warning hierarchy) (#355) * fix(frontend): a11y + clarity punch-down from $impeccable audit+critique Implements the full P1+P2+P3 punch-down from the whole-app audit+critique (read-only review; this PR is the fixes). Placeholder hero tiles kept as reserved per the user's PR #344 decision. P1: - FilterDrawer: trap Tab/Shift+Tab within the dialog, move focus in on open, restore to the trigger on close (WCAG 2.4.3); + type="button" on close X. - Touch targets >= 44px (min-h-[44px] / h-11 w-11): Sidebar nav + mobile-close + brand link, AppShell hamburger, ThemeToggle, FilterDrawer buttons + search, RankingTable Filters/search/pagination, PriceTimePeriodSelector, DualRange (44px grab zone + h-5 thumbs), detail back-link. P2: - MoS-anchor labels: FairPriceCard "Margin of safety (vs fair value)" + FairPriceBarChart "vs today's price" -- the two %s on one page no longer read as a contradiction. - Warning-card hierarchy: Tier2EventCard + RiskSummaryCard <h2> take a severity tone (rose veto / amber annotate, else neutral) so they outweigh the neutral data-section eyebrows. P3: - DualRange min/max aria-label; Disclaimer role=alert -> role=note + aria-expanded on more/less; price-chart section aria-label + sr-only latest-price summary (the Recharts SVG is opaque to AT). Skipped as verified false positives: dark loss-chance (the !important text-red-700 remap wins in dark -> already soft); period aria-pressed (already role=radio+aria-checked); sort first-click (chevron moves); StockLogo alt (alt="" aria-hidden); loss-chance color-only (badge aria-label carries the band). Verified: tsc --noEmit clean + next build 506 routes. Also commits the critique snapshot so $impeccable polish can read it next session. No compute / schema / scoring / valuation change. https://claude.ai/code/session_012xxKfyR939bZDmbxxqMFZi * fix(frontend): review-gate follow-up — back-link + period-selector 44px targets Two touch-target gaps the design + browser review caught on the punch-down: - stock-detail happy-path back-link (page.tsx) was missing min-h-[44px] (the earlier replace_all only caught the not-found branch — the two were not byte-identical); the primary back-link was ~20px. - PriceTimePeriodSelector period buttons (1M/6M/YTD/1Y/5Y) were 24px; added min-h-[44px] to the base class (items-center already centers the label, so the visual chip height is unchanged, only the hit area grows). tsc --noEmit clean + next build 506 routes. https://claude.ai/code/session_012xxKfyR939bZDmbxxqMFZi --------- Co-authored-by: Claude <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
The user asked for "กรอบสี่เหลี่ยมสี่อันในภาพ" — a reference stock app's 4 category tiles (icon-over-label boxes). A
/grill-mesession locked the spec across 6 decisions.Renders a 4-box grid in its own section under the hero (above the price chart):
market_cap→ Mega/Large/Mid/Smalldetail.sectorKey decisions (from grill-me)
grid grid-cols-2 sm:grid-cols-4like the reference app, but light slate / dark slate surfaces, NOT black boxes (those break in light mode). LedgerCraftrounded≤4px, border-as-depth, paireddark:.lucide-react(the project's first icon library).New dependency —
lucide-react@^1.17.0Both dependency-auditor + security-reviewer SAFE: ISC license (MIT-tier), React-18.3 peer, 0 transitive deps, 0 install-scripts, SLSA-attested, 0 CVE. Tree-shakes to ~1.5-2 KB gzipped via NAMED imports only (never the
import * as Iconsbarrel = 224 KB). Stock-detail route went 113 → 115 KB First Load JS as predicted. Not added to the dependabot ignore-list (normal flow); not added toTHIRD_PARTY_NOTICES.md(that file is vendored-source/skills only — runtime npm deps like next/react/recharts aren't listed there).Verification (real data)
tsc --noEmitclean ·next build506/506 pagesgrid-cols-2+sm:grid-cols-4present, lucide icons render as inline SVG (tree-shaken)Scope
Frontend. No schema / Python / scoring / valuation / output-JSON change — 1 new dep + 1 new server component + hero wiring. CLAUDE.md §Gotcha ×2 (lucide import discipline + the tiles) + AGENTS.md inventory + PHASE_STATUS_INFLIGHT.md.
https://claude.ai/code/session_0148EoMmL6zakDWqHXjqQ9yq
Generated by Claude Code