feat: redesign routed ZarinPal merchant dashboard
This commit is contained in:
104
DESIGN.md
104
DESIGN.md
@@ -15,22 +15,22 @@ The authenticated panel screenshots are the primary behavioral reference: fixed
|
||||
|
||||
### Color tokens
|
||||
|
||||
| Token | Value | Use |
|
||||
|---|---:|---|
|
||||
| `--color-brand-600` | `#0A33FF` | Primary actions, active navigation, links, selected chart series |
|
||||
| `--color-brand-700` | `#0828CC` | Hover/pressed brand state |
|
||||
| `--color-accent-400` | `#FFD400` | Small ZarinPal-like accent, highlights; never body text on white |
|
||||
| `--color-ink-950` | `#19191A` | Primary text, dark panels |
|
||||
| `--color-ink-700` | `#3D3D42` | Secondary strong text |
|
||||
| `--color-ink-500` | `#6B6B73` | Supporting text |
|
||||
| `--color-canvas` | `#F1F1F3` | Application background |
|
||||
| `--color-surface` | `#FFFFFF` | Cards, drawer, dialogs |
|
||||
| `--color-surface-muted` | `#F7F7F8` | Nested panels, table headers |
|
||||
| `--color-border` | `#E3E3E7` | Dividers and neutral outlines |
|
||||
| `--color-success-600` | `#248061` | Success states and positive semantic data |
|
||||
| `--color-warning-600` | `#A86700` | Warnings; paired with text/icon, never color alone |
|
||||
| `--color-danger-500` | `#FF5C5D` | Errors and destructive actions |
|
||||
| `--color-info-surface` | `#E7F2FF` | Informational callouts |
|
||||
| Token | Value | Use |
|
||||
| ----------------------- | --------: | ---------------------------------------------------------------- |
|
||||
| `--color-brand-600` | `#0A33FF` | Primary actions, active navigation, links, selected chart series |
|
||||
| `--color-brand-700` | `#0828CC` | Hover/pressed brand state |
|
||||
| `--color-accent-400` | `#FFD400` | Small ZarinPal-like accent, highlights; never body text on white |
|
||||
| `--color-ink-950` | `#19191A` | Primary text, dark panels |
|
||||
| `--color-ink-700` | `#3D3D42` | Secondary strong text |
|
||||
| `--color-ink-500` | `#6B6B73` | Supporting text |
|
||||
| `--color-canvas` | `#F1F1F3` | Application background |
|
||||
| `--color-surface` | `#FFFFFF` | Cards, drawer, dialogs |
|
||||
| `--color-surface-muted` | `#F7F7F8` | Nested panels, table headers |
|
||||
| `--color-border` | `#E3E3E7` | Dividers and neutral outlines |
|
||||
| `--color-success-600` | `#248061` | Success states and positive semantic data |
|
||||
| `--color-warning-600` | `#A86700` | Warnings; paired with text/icon, never color alone |
|
||||
| `--color-danger-500` | `#FF5C5D` | Errors and destructive actions |
|
||||
| `--color-info-surface` | `#E7F2FF` | Informational callouts |
|
||||
|
||||
All text/background pairs must meet WCAG 2.2 AA contrast. Chart palettes require patterns, labels, or shapes in addition to hue.
|
||||
|
||||
@@ -38,22 +38,22 @@ All text/background pairs must meet WCAG 2.2 AA contrast. Chart palettes require
|
||||
|
||||
Light and dark modes are first-class variants of the same semantic token system. Components consume role tokens rather than raw palette values; dark mode is not a color inversion or an after-launch skin.
|
||||
|
||||
| Semantic role | Light | Dark | Notes |
|
||||
|---|---:|---:|---|
|
||||
| `--color-canvas` | `#F1F1F3` | `#0F0F10` | Application workspace |
|
||||
| `--color-surface` | `#FFFFFF` | `#19191A` | Cards, drawers, dialogs |
|
||||
| `--color-surface-muted` | `#F7F7F8` | `#28282A` | Nested panels and table headers |
|
||||
| `--color-text-primary` | `#19191A` | `#FFFFFF` | Primary content |
|
||||
| `--color-text-secondary` | `#3D3D42` | `#D1D1D6` | Supporting content |
|
||||
| `--color-text-muted` | `#6B6B73` | `#A7A7AF` | Metadata; contrast must be verified at actual size |
|
||||
| `--color-border` | `#E3E3E7` | `#3A3A3D` | Dividers and neutral outlines |
|
||||
| `--color-brand-action` | `#0A33FF` | `#90AEF4` | Primary action and active state |
|
||||
| `--color-on-brand` | `#FFFFFF` | `#0A0A0A` | Content on brand action |
|
||||
| `--color-focus-ring` | `#0A33FF` | `#90AEF4` | Keyboard focus |
|
||||
| `--color-semantic-success` | `#248061` | `#6FD6AE` | Positive values with text/icon support |
|
||||
| `--color-semantic-warning` | `#8A5300` | `#F3BE5B` | Caution and incomplete verification |
|
||||
| `--color-semantic-danger` | `#C93637` | `#FF8A8B` | Error and destructive meaning |
|
||||
| `--color-semantic-info` | `#0A33FF` | `#90AEF4` | Informational emphasis |
|
||||
| Semantic role | Light | Dark | Notes |
|
||||
| -------------------------- | --------: | --------: | -------------------------------------------------- |
|
||||
| `--color-canvas` | `#F1F1F3` | `#0F0F10` | Application workspace |
|
||||
| `--color-surface` | `#FFFFFF` | `#19191A` | Cards, drawers, dialogs |
|
||||
| `--color-surface-muted` | `#F7F7F8` | `#28282A` | Nested panels and table headers |
|
||||
| `--color-text-primary` | `#19191A` | `#FFFFFF` | Primary content |
|
||||
| `--color-text-secondary` | `#3D3D42` | `#D1D1D6` | Supporting content |
|
||||
| `--color-text-muted` | `#6B6B73` | `#A7A7AF` | Metadata; contrast must be verified at actual size |
|
||||
| `--color-border` | `#E3E3E7` | `#3A3A3D` | Dividers and neutral outlines |
|
||||
| `--color-brand-action` | `#0A33FF` | `#90AEF4` | Primary action and active state |
|
||||
| `--color-on-brand` | `#FFFFFF` | `#0A0A0A` | Content on brand action |
|
||||
| `--color-focus-ring` | `#0A33FF` | `#90AEF4` | Keyboard focus |
|
||||
| `--color-semantic-success` | `#248061` | `#6FD6AE` | Positive values with text/icon support |
|
||||
| `--color-semantic-warning` | `#8A5300` | `#F3BE5B` | Caution and incomplete verification |
|
||||
| `--color-semantic-danger` | `#C93637` | `#FF8A8B` | Error and destructive meaning |
|
||||
| `--color-semantic-info` | `#0A33FF` | `#90AEF4` | Informational emphasis |
|
||||
|
||||
- The initial theme follows `prefers-color-scheme` unless the user has explicitly selected light or dark. The explicit choice is persisted locally because it is presentation-only and non-sensitive.
|
||||
- Theme selection is applied before first paint to avoid a light/dark flash. The toggle remains keyboard and screen-reader operable and exposes its current state.
|
||||
@@ -183,26 +183,26 @@ Navigation labels should describe merchant tasks, not internal database concepts
|
||||
|
||||
## Current decisions and change log
|
||||
|
||||
| Version | Date | Decision |
|
||||
|---|---|---|
|
||||
| 0.4.0 | 2026-08-20 | Adopted the supplied current ZarinPal panel as the closer interaction reference: added the top wordmark bar, 256/72 px collapsible right sidebar, less-rounded 8 px data surfaces, routed sections, URL-backed period/terminal filters, payment-history chart, filtered transaction table, routed attempt history, formula help, and supportive human-readable insights. |
|
||||
| 0.3.3 | 2026-08-20 | Replaced merchant/cohort revision freshness language with the approved immutable completed-import dataset snapshot. This changes trace labels only; cache age still does not imply stale data. |
|
||||
| 0.3.2 | 2026-08-20 | Made the licensed Iran Yekan X FaNum variable WOFF2 and its required license file Git-tracked frontend assets, eliminating a separate private build-injection path. |
|
||||
| 0.3.1 | 2026-08-20 | Verified the purchased Iran Yekan X Professional FaNum variable assets and required a private, reproducible injection path for public repositories. Added merchant-owned detail CSV export as an MVP component contract. |
|
||||
| 0.3.0 | 2026-08-20 | Approved Iran Yekan X Professional FaNum variable typography, Persian digits, Rial-only values, and first-class light/dark semantic themes. Added the deterministic insight eligibility threshold. |
|
||||
| 0.2.4 | 2026-08-20 | Fixed the static-demo default period, comparison fallback, overview KPI priority, and safe read-only drill-down scope; added accurate `NoAttempt`/`InBank` stage language from the CTO data guide. |
|
||||
| 0.2.3 | 2026-08-20 | Kept authentication UX intentionally demo-sized: generic and throttled username/password login now, with a clean replacement boundary for ZarinPal SSO after acceptance. |
|
||||
| 0.2.2 | 2026-08-20 | Defined backend-owned session UX: authentication tokens remain inaccessible to the frontend, and expiry/revocation returns the user to login with a generic, accessible message. |
|
||||
| 0.2.1 | 2026-08-20 | Defined same-category peer cards as an equal-per-merchant median plus direction-aware percentile. This prevents the dataset's largest merchants from dominating what should represent a typical peer. |
|
||||
| 0.2.0 | 2026-08-20 | Corrected payment lifecycle semantics from CTO guidance: `Paid` and `Verified` are bank-payment successes, `Paid` remains unverified, and session-level fees are real Rial amounts. |
|
||||
| 0.1.9 | 2026-08-20 | Added rate-limit UX, 15-second SSE heartbeat/recovery, one-hour replay, and failed-section-only manual retry. |
|
||||
| 0.1.8 | 2026-08-20 | Fixed the four parallel section ids, 30-day cache, idempotent start/SSE flow, and section timeout/retry behavior. |
|
||||
| 0.1.7 | 2026-08-20 | Moved analytics results to high-TTL Redis and defined partial, parallel section delivery through authenticated SSE. |
|
||||
| 0.1.6 | 2026-08-20 | Replaced time-based analytics freshness with lazy first-access calculation and revision-based merchant/cohort cache states; defined Saturday–Friday weeks. |
|
||||
| 0.1.5 | 2026-08-20 | Removed holiday/event reporting; limited period controls to daily, weekly, Jalali-month, and Persian-season views. |
|
||||
| 0.1.2 | 2026-08-20 | Added the insufficient-data state and visibility threshold for anonymized peer comparisons. |
|
||||
| 0.1.1 | 2026-08-20 | Fixed merchant-facing time presentation to the Jalali calendar in `Asia/Tehran`, with explicit UTC API instants. |
|
||||
| 0.1.0 | 2026-08-20 | Established ZarinPal-inspired RTL foundation from supplied public/panel screenshots; fixed SvelteKit/Svelte/TypeScript/Tailwind stack; defined responsive shell, core components, accessibility, chart, and motion rules. |
|
||||
| Version | Date | Decision |
|
||||
| ------- | ---------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
||||
| 0.4.0 | 2026-08-20 | Adopted the supplied current ZarinPal panel as the closer interaction reference: added the top wordmark bar, 256/72 px collapsible right sidebar, less-rounded 8 px data surfaces, routed sections, URL-backed period/terminal filters, payment-history chart, filtered transaction table, routed attempt history, formula help, and supportive human-readable insights. |
|
||||
| 0.3.3 | 2026-08-20 | Replaced merchant/cohort revision freshness language with the approved immutable completed-import dataset snapshot. This changes trace labels only; cache age still does not imply stale data. |
|
||||
| 0.3.2 | 2026-08-20 | Made the licensed Iran Yekan X FaNum variable WOFF2 and its required license file Git-tracked frontend assets, eliminating a separate private build-injection path. |
|
||||
| 0.3.1 | 2026-08-20 | Verified the purchased Iran Yekan X Professional FaNum variable assets and required a private, reproducible injection path for public repositories. Added merchant-owned detail CSV export as an MVP component contract. |
|
||||
| 0.3.0 | 2026-08-20 | Approved Iran Yekan X Professional FaNum variable typography, Persian digits, Rial-only values, and first-class light/dark semantic themes. Added the deterministic insight eligibility threshold. |
|
||||
| 0.2.4 | 2026-08-20 | Fixed the static-demo default period, comparison fallback, overview KPI priority, and safe read-only drill-down scope; added accurate `NoAttempt`/`InBank` stage language from the CTO data guide. |
|
||||
| 0.2.3 | 2026-08-20 | Kept authentication UX intentionally demo-sized: generic and throttled username/password login now, with a clean replacement boundary for ZarinPal SSO after acceptance. |
|
||||
| 0.2.2 | 2026-08-20 | Defined backend-owned session UX: authentication tokens remain inaccessible to the frontend, and expiry/revocation returns the user to login with a generic, accessible message. |
|
||||
| 0.2.1 | 2026-08-20 | Defined same-category peer cards as an equal-per-merchant median plus direction-aware percentile. This prevents the dataset's largest merchants from dominating what should represent a typical peer. |
|
||||
| 0.2.0 | 2026-08-20 | Corrected payment lifecycle semantics from CTO guidance: `Paid` and `Verified` are bank-payment successes, `Paid` remains unverified, and session-level fees are real Rial amounts. |
|
||||
| 0.1.9 | 2026-08-20 | Added rate-limit UX, 15-second SSE heartbeat/recovery, one-hour replay, and failed-section-only manual retry. |
|
||||
| 0.1.8 | 2026-08-20 | Fixed the four parallel section ids, 30-day cache, idempotent start/SSE flow, and section timeout/retry behavior. |
|
||||
| 0.1.7 | 2026-08-20 | Moved analytics results to high-TTL Redis and defined partial, parallel section delivery through authenticated SSE. |
|
||||
| 0.1.6 | 2026-08-20 | Replaced time-based analytics freshness with lazy first-access calculation and revision-based merchant/cohort cache states; defined Saturday–Friday weeks. |
|
||||
| 0.1.5 | 2026-08-20 | Removed holiday/event reporting; limited period controls to daily, weekly, Jalali-month, and Persian-season views. |
|
||||
| 0.1.2 | 2026-08-20 | Added the insufficient-data state and visibility threshold for anonymized peer comparisons. |
|
||||
| 0.1.1 | 2026-08-20 | Fixed merchant-facing time presentation to the Jalali calendar in `Asia/Tehran`, with explicit UTC API instants. |
|
||||
| 0.1.0 | 2026-08-20 | Established ZarinPal-inspired RTL foundation from supplied public/panel screenshots; fixed SvelteKit/Svelte/TypeScript/Tailwind stack; defined responsive shell, core components, accessibility, chart, and motion rules. |
|
||||
|
||||
Any material token/component/interaction change increments this version and adds a row describing why it changed. A surprising or difficult-to-reverse change also receives an ADR.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user