First deployment
Some checks failed
quality-gates / lint-and-test (push) Has been cancelled
quality-gates / security-scan (push) Has been cancelled

This commit is contained in:
2026-02-13 09:14:04 -05:00
parent 0e21e035f5
commit 679561bcdb
128 changed files with 3479 additions and 120 deletions

View File

@@ -0,0 +1,2 @@
schema: spec-driven
created: 2026-02-13

View File

@@ -0,0 +1,58 @@
## Context
Recent usability enhancements introduced regressions in modal consistency, footer/header behavior, and share/contact visibility. The issues are cross-cutting: SPA URL state, modal lifecycle handling, theme contrast, sticky surface behavior, and image relevance heuristics. The fixes must remain incremental and avoid feature re-architecture.
## Goals / Non-Goals
**Goals:**
- Restore modal parity for hero and feed deep links, including image loading and Escape-close behavior.
- Ensure contact email is rendered when configured and share controls are visible in light mode.
- Introduce copy-to-clipboard sharing and remove redundant card permalink affordance.
- Implement floating Back-to-Top and compact sticky footer.
- Implement sticky, shrinking, elevated glass header behavior on scroll.
- Tighten image relevance fallback behavior for finance/market stories.
**Non-Goals:**
- Full UI redesign.
- New backend image provider integrations.
- New analytics taxonomy.
## Decisions
### Decision 1: Normalize deep-link modal resolution path
Use one resolver for both hero and feed items, and open modal only after item context is guaranteed.
### Decision 2: Decouple modal close from item existence
Escape and backdrop close should dismiss the modal even if modal item resolution is partially failed.
### Decision 3: Theme-safe icon tokens
Share icon foreground/background tokens are split per theme to guarantee visibility in light mode.
### Decision 4: Sticky surfaces with conservative footprint
Header remains sticky and shrinks slightly with blur/elevation on scroll; footer remains sticky with minimal height and readable contrast.
### Decision 5: Finance-aware image fallback guard
If query contains market/finance intent, reject obviously unrelated animal/person close-up imagery via keyword guards and force finance-safe fallback query.
## Risks / Trade-offs
- **[Risk] Sticky footer could occlude content** -> Mitigation: add bottom spacing to main content and reduce footer height.
- **[Risk] Header animation jank on low-end devices** -> Mitigation: simple transform/opacity transitions only.
- **[Risk] Stricter image relevance may reduce variety** -> Mitigation: constrain guardrails to high-confidence finance terms only.
## Migration Plan
1. Patch modal/deep-link lifecycle and close semantics in frontend state handlers.
2. Patch share/contact visibility and add copy-link control.
3. Implement sticky header/footer visual behavior.
4. Patch image-query relevance guard in backend image selection.
5. Validate with manual regression checklist.
Rollback:
- Revert header/footer sticky behavior.
- Revert modal resolver and share changes.
- Revert image guardrails to prior fallback logic.
## Open Questions
- Should copy-link action include transient toast feedback in this change or next UX pass?

View File

@@ -0,0 +1,34 @@
## Why
Several regressions and UX defects slipped in after recent enhancements, affecting modal behavior, sharing visibility, footer/header usability, and image relevance. Fixing these together will restore trust, readability, and navigation quality without introducing new product scope.
## What Changes
- Fix permalink-to-hero modal behavior so image rendering and keyboard close (`Escape`) work consistently.
- Restore footer contact email visibility and ensure env-driven contact link rendering is reliable.
- Fix light-theme contrast for social share icons and add a copy-to-clipboard action alongside X, WhatsApp, and LinkedIn.
- Replace inline footer "Back to Top" text button with a floating island-style control.
- Make footer persistently sticky and compact while preserving reading comfort.
- Make header persistently sticky with subtle shrink, elevation, and glass effect on scroll.
- Tighten article-image relevance to avoid clearly unrelated images for finance/market stories.
- Remove unnecessary per-card "Link" affordance from feed cards.
## Capabilities
### New Capabilities
- None.
### Modified Capabilities
- `article-permalinks-and-deep-link-modal`: Correct deep-link modal open-state parity for hero/feed targets and keyboard close behavior.
- `share-and-contact-microinteractions`: Fix share-icon visibility in light mode, add copy-link action, and restore contact-email presence.
- `footer-policy-links`: Update footer interaction model for sticky compact layout and floating back-to-top control.
- `responsive-device-agnostic-layout`: Apply sticky header/footer behavior and ensure readability is not degraded.
- `news-image-relevance-and-fallbacks`: Improve relevance guardrails to reduce obviously mismatched fallback/provider image outcomes.
- `hero-display`: Remove redundant card-level permalink text affordance where it harms clarity.
## Impact
- **Frontend UI:** `frontend/index.html` modal behaviors, keyboard handling, share controls, footer/header interactions, and card affordances.
- **Backend config/data:** contact link exposure verification through `/config` payload and env handling.
- **Image pipeline:** backend relevance and fallback heuristics in image selection paths.
- **UX quality:** stronger consistency across themes and navigation paths, especially for permalink and sharing flows.

View File

@@ -0,0 +1,19 @@
## MODIFIED Requirements
### Requirement: Deep-link loads article modal in open state
The system SHALL open the matching article modal when the page is loaded with a valid article permalink, regardless of whether the target is hero or feed content.
#### Scenario: Hero permalink opens parity modal
- **WHEN** a user lands with a permalink for the current hero article
- **THEN** the modal opens with the same structure and behaviors as feed-opened modal
- **AND** summary image render path is executed normally
#### Scenario: Escape closes deep-linked modal
- **WHEN** a modal opened from permalink is focused
- **THEN** pressing `Escape` closes the modal
- **AND** URL deep-link state is cleared consistently
#### Scenario: Invalid permalink fails safely
- **WHEN** permalink article id does not resolve to an existing item
- **THEN** modal is not opened
- **AND** main page remains fully usable

View File

@@ -0,0 +1,14 @@
## MODIFIED Requirements
### Requirement: Footer exposes policy navigation links
The system SHALL keep policy links while supporting sticky compact footer behavior and floating back-to-top control.
#### Scenario: Sticky compact footer
- **WHEN** user scrolls through content
- **THEN** footer remains sticky at viewport bottom
- **AND** footer height stays compact enough to avoid readability obstruction
#### Scenario: Floating back-to-top island
- **WHEN** page is scrolled beyond initial viewport
- **THEN** a floating back-to-top control is visible
- **AND** activating it returns viewport to top smoothly

View File

@@ -0,0 +1,16 @@
## MODIFIED Requirements
### Requirement: Infinite scroll news feed
The system SHALL display feed cards without redundant per-card permalink text link when primary CTA and source link are present.
#### Scenario: Card chrome remains minimal
- **WHEN** feed cards are rendered
- **THEN** redundant small "Link" affordance is not shown
- **AND** card still exposes required source and TL;DR interactions
### Requirement: Hero block display
The system SHALL maintain hero-to-modal behavior parity with feed cards.
#### Scenario: Hero-origin modal consistency
- **WHEN** modal opens from hero context (including permalink-triggered entry)
- **THEN** modal image, content, and close controls behave consistently with feed-origin modal flows

View File

@@ -0,0 +1,14 @@
## MODIFIED Requirements
### Requirement: Fallback behavior remains context-aware first
The system SHALL apply stricter relevance guardrails before accepting summary images for finance/market stories.
#### Scenario: Finance-story relevance guard
- **WHEN** article topic contains finance/market terms (for example stocks, shares, plunge, earnings)
- **THEN** image selection rejects obviously unrelated animal/portrait outcomes
- **AND** system retries with finance-safe query refinements before final fallback
#### Scenario: Guarded fallback remains deterministic
- **WHEN** provider chain cannot return a relevant finance-safe image
- **THEN** system uses deterministic generic fallback that is topic-safe
- **AND** avoids unrelated imagery classes flagged by guardrails

View File

@@ -0,0 +1,14 @@
## MODIFIED Requirements
### Requirement: Core layout is device-agnostic and responsive
The system SHALL preserve responsive readability while enabling sticky header and footer surfaces.
#### Scenario: Sticky shrinking glass header
- **WHEN** user scrolls downward
- **THEN** header remains sticky with slight height reduction, subtle elevation, and glass blur effect
- **AND** controls remain readable and usable at all breakpoints
#### Scenario: Sticky footer does not overlap core reading zones
- **WHEN** footer is sticky
- **THEN** content remains readable and interactive controls are not obscured
- **AND** mobile/tablet/desktop layouts stay overflow-safe

View File

@@ -0,0 +1,22 @@
## MODIFIED Requirements
### Requirement: Modal/footer exposes minimal icon-based share actions
The system SHALL provide visible, accessible icon-only share actions for article permalinks.
#### Scenario: Light-theme icon visibility
- **WHEN** the site is in light mode
- **THEN** share icons remain visibly distinguishable with accessible contrast
- **AND** icon controls remain keyboard focusable
#### Scenario: Copy-link share action
- **WHEN** a user activates the copy-to-clipboard share control
- **THEN** the article permalink is written to clipboard
- **AND** action succeeds without navigating away
### Requirement: Footer supports env-driven GitHub and contact links
The system SHALL render contact email link when `CONTACT_EMAIL` is configured.
#### Scenario: Contact link visible when configured
- **WHEN** `CONTACT_EMAIL` is present in frontend config payload
- **THEN** footer shows the contact email affordance
- **AND** hover microcopy behavior remains enabled

View File

@@ -0,0 +1,30 @@
## 1. Permalink Modal Regression Fixes
- [x] 1.1 Fix deep-link modal open path for hero targets so modal structure and image loading match feed behavior.
- [x] 1.2 Restore `Escape` close behavior for permalink-opened modal state.
- [x] 1.3 Ensure invalid permalink handling does not break page interaction.
## 2. Share and Contact Fixes
- [x] 2.1 Fix light-mode social icon contrast tokens for X/WhatsApp/LinkedIn controls.
- [x] 2.2 Add copy-to-clipboard share action for article permalink.
- [x] 2.3 Restore footer contact email rendering from `/config` payload when `CONTACT_EMAIL` is set.
## 3. Header/Footer Usability Fixes
- [x] 3.1 Replace inline back-to-top text control with floating island control.
- [x] 3.2 Make footer sticky and compact while preserving content readability.
- [x] 3.3 Make header sticky with subtle shrink, elevation, and glass effect on scroll.
## 4. Content Relevance and Card Cleanup
- [x] 4.1 Add finance-story image relevance guardrails to avoid unrelated image classes.
- [x] 4.2 Add finance-safe query retry/fallback refinement path.
- [x] 4.3 Remove redundant card-level "Link" affordance from feed cards.
## 5. Verification
- [x] 5.1 Verify hero permalink opens modal with correct image and closing behavior.
- [x] 5.2 Verify footer email presence and share icon visibility in light/dark themes.
- [x] 5.3 Verify floating back-to-top, sticky footer, and sticky shrinking header on desktop/mobile.
- [x] 5.4 Verify finance-story image relevance behavior and fallback safety.