Skip to content

feat(frontend): B2+B3+B4 combined — full LedgerCraft alignment series complete#236

Merged
dackclup merged 1 commit into
mainfrom
claude/compassionate-goodall-QLh3q
May 24, 2026
Merged

feat(frontend): B2+B3+B4 combined — full LedgerCraft alignment series complete#236
dackclup merged 1 commit into
mainfrom
claude/compassionate-goodall-QLh3q

Conversation

@dackclup
Copy link
Copy Markdown
Owner

Summary

Final follow-up of the post-A3 design-reviewer audit. Combined the three remaining LedgerCraft alignment scopes into one PR because they share five overlapping files (FairPriceBarChart, FairPriceCard, ManipulationRiskCard, Tier2EventCard, app/stock/[ticker]/page.tsx) — splitting would force later PRs to rebase after each merge.

After this lands the project is at full LedgerCraft palette + theme alignment across every UI surface.

Scope (10 files, ~30 className edits)

B2 — Card surface normalization (rounded-lgrounded, drop shadows)

File Surface
app/stock/[ticker]/page.tsx detail-data-pending banner · hero header (drop shadow-large) · empty-state placeholder · data-quality section (drop shadow-medium)
FairPriceBarChart.tsx outer section · headline card (drop shadow-medium) · per-method list (drop shadow-subtle)
FairPriceCard.tsx 2 section cards · inner table (rounded-mdrounded)
ManipulationRiskCard.tsx section card
PillarRadarChart.tsx section card (drop shadow-medium) · pillar bar track (rounded-mdrounded-sm)
RawMetricsTable.tsx outer container (drop shadow-medium)
Tier2EventCard.tsx section card

B3 — Chip shape squaring round 2 (rounded-full / rounded-mdrounded-sm)

File Chips squared
app/stock/[ticker]/page.tsx rank badge · filing-lag badge
FairPriceBarChart.tsx 3 tally pills (cheap/fair/pricey) · per-method verdict badge
FairPriceCard.tsx warning chip
ManipulationRiskCard.tsx severity chip
Tier2EventCard.tsx severity badge
PriceHistoryChart.tsx 2 off-chart Fair/Target reference chips
PriceTimePeriodSelector.tsx period button base
ThemeToggle.tsx row + icon layout buttons

B4 — Stripe + hover polish

File Change
RawMetricsTable.tsx alt-row even:bg-slate-50even:bg-slate-100 (Rule 5 #FFFFFF / #F1F5F9) · hover hover:bg-slate-100hover:bg-slate-200
FairPriceCard.tsx MethodRow hover hover:bg-slate-50hover:bg-slate-100
PriceTimePeriodSelector.tsx unselected hover hover:bg-slate-50hover:bg-slate-100

Preserved (LedgerCraft spec exceptions)

  • Status dots (h-1.5 w-1.5 rounded-full ${dot}) per Border-Radius spec line 51 ("Status dots / toggle switches: 9999px")
  • DualRange slider thumbs — toggle-switch family per same exception
  • MoSBadge SVG radial donut, MoSCell inline RGB diverging bar, PillarRadarChart inline RGB legend swatches — Rule 0 Recharts-equivalent adapter carve-out
  • StockLogo borderRadius: '50%' — logo container, not chip
  • Chart legend line swatches (h-0.5 w-3.5 rounded-full) — 2px-tall decorative segments, not chip bodies

Phase 4 LedgerCraft series complete

PR Commit Scope
A1 #232 5517b98 visual.ts SECTOR_COLORS neutralization (sector chip → steel + sector dots)
A2 #233 dc615ae 6-component chip family rounded-fullrounded-sm
A3 #234 1a9501c Table + frame polish (RankingTable / Sidebar / FilterDrawer / AppShell / page.tsx)
B1 #235 2b588c8 Score-tier teal+orange purge (emerald+amber step-down)
B2+B3+B4 this PR Detail-page chrome + 7 chart/card components final alignment

After this PR: restrained 4-family palette (forest/amber/steel/red), sharp ≤4px radii across every chip/button/input/card, borders-as-depth on every data surface, OKLCH soft sage/terracotta for positive/negative semantics. No schema / Python / scoring / valuation / output JSON change across the entire 5-PR series.

Test plan

  • CI Python (lint + test) green — no Python touched
  • CI Frontend build green
  • Vercel preview deploys cleanly
  • Spot-check on preview: every chip body 2px squared; every card 4px no-shadow; per-stock detail page hero + data-quality + ensemble + pillar + raw-metrics + manipulation + Tier-2 + price-history all flat with borders only

Risk

  • Low — className-only diff (10 files / ~30 edits, all string replacements). No JSX restructure, no schema, no Python. Visual continuity preserved (just sharper corners + flatter surfaces).

🤖 https://claude.ai/code/session_01Dk82y7Eswz745NuBQH3CaG


Generated by Claude Code

… complete

Final follow-up of the post-A3 design-reviewer audit. Combined the
three remaining alignment scopes into ONE PR because they share five
overlapping files (FairPriceBarChart · FairPriceCard ·
ManipulationRiskCard · Tier2EventCard · app/stock/[ticker]/page.tsx) —
splitting would force later PRs to rebase after each merge.

Scope (10 files, ~30 className edits)

app/stock/[ticker]/page.tsx
- detail-data-pending banner  rounded-lg                  → rounded
- hero header                 rounded-lg shadow-large     → rounded (no shadow)
- rank badge                  rounded-md                  → rounded-sm
- empty-state placeholder     rounded-lg                  → rounded
- data-quality section        rounded-lg shadow-medium    → rounded (no shadow)
- filing-lag badge            rounded-full                → rounded-sm

FairPriceBarChart.tsx
- outer section               rounded-lg                  → rounded
- headline card               rounded-lg shadow-medium    → rounded (no shadow)
- per-method list             rounded-lg shadow-subtle    → rounded (no shadow)
- 3 tally pills (cheap/fair/pricey)   rounded-full       → rounded-sm
- per-method verdict badge    rounded-full                → rounded-sm

FairPriceCard.tsx
- 2 section cards             rounded-lg                  → rounded
- inner table                 rounded-md                  → rounded
- warning chip                rounded-full                → rounded-sm
- MethodRow hover             hover:bg-slate-50           → hover:bg-slate-100

ManipulationRiskCard.tsx
- section card                rounded-lg                  → rounded
- severity chip               rounded-full                → rounded-sm

PillarRadarChart.tsx
- section card                rounded-lg shadow-medium    → rounded (no shadow)
- pillar bar track            rounded-md                  → rounded-sm

RawMetricsTable.tsx
- outer container             rounded-lg shadow-medium    → rounded (no shadow)
- alt-row even bg             bg-slate-50                 → bg-slate-100   (Rule 5)
- alt-row hover               hover:bg-slate-100          → hover:bg-slate-200

Tier2EventCard.tsx
- section card                rounded-lg                  → rounded
- severity badge              rounded-full                → rounded-sm

PriceHistoryChart.tsx
- 2 off-chart Fair/Target chips rounded-full              → rounded-sm

PriceTimePeriodSelector.tsx
- period button base          rounded-full                → rounded-sm
- unselected hover            hover:bg-slate-50           → hover:bg-slate-100

ThemeToggle.tsx
- row layout button           rounded-md                  → rounded-sm
- icon layout button          rounded-md                  → rounded-sm

Preserved (LedgerCraft spec exceptions)
- Status dots (h-1.5 w-1.5 rounded-full ${dot}) — Border-Radius
  spec line 51 "Status dots / toggle switches: 9999px"
- DualRange slider thumb pseudo-elements — toggle-switch family
- MoSBadge SVG radial donut — Recharts-equivalent adapter (Rule 0)
- MoSCell inline RGB on diverging bar fill — Rule 0
- StockLogo `borderRadius: '50%'` — logo container, not chip
- PillarRadarChart inline RGB legend swatches — Rule 0
- Chart legend line swatches (h-0.5 w-3.5 rounded-full) — 2px-tall
  decorative line segments, not chip bodies

Series wrap (Phase 4 LedgerCraft complete)
- A1 #232  visual.ts SECTOR_COLORS neutralization
- A2 #233  6-component chip family rounded-full → rounded-sm
- A3 #234  Table + frame polish (RankingTable/Sidebar/FilterDrawer
           /AppShell/page.tsx)
- B1 #235  Score-tier teal+orange purge (emerald+amber step-down)
- B2+B3+B4 (this PR) — 10 more files covering detail-page chrome
           + 7 chart/card components

After this PR the project is at full LedgerCraft palette + theme
alignment across every UI surface. No schema / Python / scoring /
valuation / output JSON change across the entire 5-PR series.

Lockstep
- CLAUDE.md §Phase status — B1 marked merged (#235 / 2b588c8), new
  combined B2+B3+B4 in-flight entry with full per-file edit table
- AGENTS.md §Phase + version state — corresponding cross-tool note
- tsc --noEmit errors visible in sandbox are env noise (no
  node_modules); CI runs with deps and will validate
- No new tests required (className-only diff)
@vercel
Copy link
Copy Markdown

vercel Bot commented May 24, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
quantrank Ready Ready Preview, Comment May 24, 2026 7:57am

@dackclup dackclup marked this pull request as ready for review May 24, 2026 08:05
@dackclup dackclup merged commit 08d7563 into main May 24, 2026
4 checks passed
@dackclup dackclup deleted the claude/compassionate-goodall-QLh3q branch May 24, 2026 08:06
dackclup added a commit that referenced this pull request May 24, 2026
…fix for parallel-PR collision) (#237)

Closes the structural follow-up tracked in PR #230's §Gotchas
"Parallel-PR §Phase status collision pattern". PR #230 itself hit
the collision 3 times in one session while iterating on the
simulate-cap fix — empirical proof that the doc-discipline
§Convention landed in PR #230 (rebase-before-Mark-Ready) is
necessary but NOT sufficient when 5+ PRs land on main in a single
hour.

Root cause (pre-2026-05-24): every PR was required to add a
"**X in flight (this PR)**" bullet to CLAUDE.md §Phase status +
AGENTS.md §Phase + version state per §Conventions "ship with every
PR" lockstep. Both blocks were append-shaped, with the new bullet
inserted at the SAME line (just before "**Next deliverables**" /
"## Claude-Code-specific tooling"). Two PRs opened in parallel
both touched that single anchor line → `mergeable_state: dirty` →
recurring "merge ไม่ได้ หลังแก้แล้วกลับมาเป็นอีก" frustration.

The conflict was BENIGN (both PRs added distinct entries at the
same insertion line; resolution was always "keep both") but
`git merge` cannot auto-detect that. PR #230 hit this 3 times:
- vs PR #229 (security WARN cleanup) mid-iteration
- vs PR #232 + #233 (LedgerCraft A1 + A2) before Mark-Ready
- vs PR #234 + #235 + #236 (LedgerCraft A3 + B1 + B2+B3+B4)
  during the simulate-fix re-push loop

Structural fix:

(1) NEW FILE — `PHASE_STATUS_INFLIGHT.md` at the repo root. Each
    PR appends its in-flight entry to the END of this file (the
    "In flight (current)" sub-section). Parallel PRs both append
    at disjoint last-lines → `git merge` auto-resolves → no more
    `mergeable_state: dirty` from this pattern.

(2) CLAUDE.md §Conventions — "ship with every PR" rule updated to
    point at PHASE_STATUS_INFLIGHT.md as the canonical destination
    for in-flight entries. Substance updates to CLAUDE.md / AGENTS.md
    sections still land directly (they're rare + cross-PR-coupled
    by nature).

(3) CLAUDE.md §Gotchas "Parallel-PR §Phase status collision pattern"
    marked as RESOLVED 2026-05-24 with a back-reference to the
    side-file adoption. The historical-symptom record stays for
    future readers' context.

(4) AGENTS.md mirror — same updates for cross-tool agents (Copilot /
    Cursor / Devin / VS Code Agent Mode). The side-file works
    regardless of which agent runtime authors the PR.

Trade-offs:

- Housekeeping workflow to drain merged entries from
  PHASE_STATUS_INFLIGHT.md into CLAUDE.md §Phase status proper
  DEFERRED — manual cleanup is fine for the first few weeks while
  the pattern proves itself. `tools/housekeep_phase_status.py`
  may land later once volume + shape are known.
- The rebase-before-Mark-Ready discipline (PR #230 §Conventions
  bullet) still applies as a backstop for OTHER conflict surfaces
  (shared code edits, workflow YAML, schema bumps) — it's no
  longer the recurring drag it used to be, but still good
  discipline.

No compute / schema / scoring / valuation / frontend / Python /
TS code change. Doc-only PR. ruff clean. schema_check clean.
CLAUDE.md + AGENTS.md lockstep satisfied via §Conventions +
§Gotchas substance updates (the "ship with every PR" rule now
points at the new file as the canonical destination, and this
PR's in-flight entry lives in PHASE_STATUS_INFLIGHT.md per the
new convention — dogfooding from commit #1).

https://claude.ai/code/session_01JwntEE4PNAXSMkZxRA9BB4

Co-authored-by: Claude <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants