diff --git a/DESIGN.md b/DESIGN.md
index 70a805dd..a3efe4d3 100644
--- a/DESIGN.md
+++ b/DESIGN.md
@@ -185,6 +185,12 @@ The visual regression suite (`e2e/design-system-visual.spec.ts`) captures galler
`packages/ui/src/styles/globals.css` carries a namespaced `--color-gmx-*` palette, landing font stacks (`--font-landing-sans` = Archivo, the OFL stand-in for GMX's paid TTHoves; `--font-landing-code` = Space Mono), landing typography/button utilities (`text-heading-1…4`, `text-subheadline`, `text-description`, `btn-landing`), and helpers (`border-hairline`, `scrollbar-hide`, `animate-pause`, `--animate-scroll`). These are **source material for the GrantFox 3 theme revamp**, not tokens for general app use — app components keep using the semantic tokens above; only the dark theme (GF3-001) and the landing route consume the `gmx-*` set. The full GMX token reference, licensing notes, and the GMX→SO4 mapping table live in [`docs/gf_3/001_theme_update.md`](./docs/gf_3/001_theme_update.md); the landing spec in [`docs/gf_3/002_landing_page.md`](./docs/gf_3/002_landing_page.md).
+### Dark theme (GF3-001)
+
+`.dark` in `globals.css` had been removed at some point, so toggling to dark mode silently fell back to the light values above. GF3-001 (re)introduces it, this time derived from the GMX reference palette instead of an arbitrary dark scale — surfaces, text roles, `border`/`input`, `primary`/`ring`, and `accent` all resolve to a `--color-gmx-*` value per the mapping table in [`001_theme_update.md` §8.2](./docs/gf_3/001_theme_update.md#82-layer-2--semantic-dark-theme-what-gf3-001-applies). Trading-state colors (`long`/`short`/`liquidation`, `success`/`warning`/`danger`, `neutral`) are not GMX concepts, so their foreground values are untouched — only their `subtle`/`border` fill pairs are re-lightened in `.dark`, because the `:root` pairs were tuned to sit on a white page and read as almost-black on the new slate-800/900 surfaces. `--info` is the one status color that does move, to `--color-gmx-blue-400`, since "informational blue" is the same concept as GMX's brand blue. The light theme (`:root`) is unchanged.
+
+The landing route (`apps/web/src/routes/index.tsx`) forces this `.dark` scope on its own root element regardless of the user's theme setting — GMX's landing has no light variant — by adding the `dark` class directly rather than touching ``, so the override never leaks into `/trade`, `/pools`, `/earn`, `/referrals`, or `/faucet`.
+
## Audit history
- **DS-050** (this pass): found and fixed 268 arbitrary-value violations (229 arbitrary font sizes, 38 raw hex colors, 1 arbitrary radius) across ~40 files. Of these:
diff --git a/apps/web/src/features/gallery/components/gallery-page.tsx b/apps/web/src/features/gallery/components/gallery-page.tsx
index 23afcae1..f9d11e41 100644
--- a/apps/web/src/features/gallery/components/gallery-page.tsx
+++ b/apps/web/src/features/gallery/components/gallery-page.tsx
@@ -540,6 +540,48 @@ export function GalleryPage() {
+
+ text-heading-1 text-heading-2 text-heading-3 text-heading-4 text-subheadline Supporting copy under a call to action. text-description
+ Body copy on a dark card surface, set in Archivo at 16px with GMX's
+ tracking and line height.
+ btn-landingPerpetual markets.
+ Built for traders.
+ Card titles
+ Small card titles
+
+
so4 runs a unified liquidity layer — one pool backs every market, with deterministic settlement on every fill. No hidden routes, no opaque MM rebates. @@ -106,10 +103,8 @@ export function Features() {
{body}
+{body}
+
No signup. No email. No deposit minimum. Connect and trade — or fork the contracts and run your own venue.
+
A unified-liquidity perp DEX. Deep books, sub-second matching, and self-custodied risk — built for traders who care where their fills come from.
+
No KYC, no email, no signup form. Connect a wallet and the orderbook is open — your collateral never leaves your control.
@@ -84,10 +81,8 @@ export function HowItWorks() {{body}
+{body}
+
so4 runs on a custom L1 tuned for orderbook throughput. We don't share blockspace with NFT mints or memecoin launches — your fill is the only thing in the queue. diff --git a/apps/web/src/ui/landing/markets.tsx b/apps/web/src/ui/landing/markets.tsx index bed3c884..fe045295 100644 --- a/apps/web/src/ui/landing/markets.tsx +++ b/apps/web/src/ui/landing/markets.tsx @@ -101,14 +101,11 @@ export function Markets() { Markets
+
Crypto, FX, rates, and commodity perps — all settled in USDC, all backed by the same unified liquidity layer.
diff --git a/e2e/design-system-visual.spec.ts-snapshots/gallery-dark-desktop-chromium-linux.png b/e2e/design-system-visual.spec.ts-snapshots/gallery-dark-desktop-chromium-linux.png new file mode 100644 index 00000000..c8da60ce Binary files /dev/null and b/e2e/design-system-visual.spec.ts-snapshots/gallery-dark-desktop-chromium-linux.png differ diff --git a/e2e/design-system-visual.spec.ts-snapshots/gallery-dark-ltr-desktop-chromium-linux.png b/e2e/design-system-visual.spec.ts-snapshots/gallery-dark-ltr-desktop-chromium-linux.png new file mode 100644 index 00000000..c8da60ce Binary files /dev/null and b/e2e/design-system-visual.spec.ts-snapshots/gallery-dark-ltr-desktop-chromium-linux.png differ diff --git a/e2e/design-system-visual.spec.ts-snapshots/gallery-dark-ltr-mobile-chromium-linux.png b/e2e/design-system-visual.spec.ts-snapshots/gallery-dark-ltr-mobile-chromium-linux.png new file mode 100644 index 00000000..0534734b Binary files /dev/null and b/e2e/design-system-visual.spec.ts-snapshots/gallery-dark-ltr-mobile-chromium-linux.png differ diff --git a/e2e/design-system-visual.spec.ts-snapshots/gallery-dark-mobile-chromium-linux.png b/e2e/design-system-visual.spec.ts-snapshots/gallery-dark-mobile-chromium-linux.png new file mode 100644 index 00000000..0534734b Binary files /dev/null and b/e2e/design-system-visual.spec.ts-snapshots/gallery-dark-mobile-chromium-linux.png differ diff --git a/e2e/design-system-visual.spec.ts-snapshots/gallery-dark-rtl-desktop-chromium-linux.png b/e2e/design-system-visual.spec.ts-snapshots/gallery-dark-rtl-desktop-chromium-linux.png new file mode 100644 index 00000000..c4b04aef Binary files /dev/null and b/e2e/design-system-visual.spec.ts-snapshots/gallery-dark-rtl-desktop-chromium-linux.png differ diff --git a/e2e/design-system-visual.spec.ts-snapshots/gallery-dark-rtl-mobile-chromium-linux.png b/e2e/design-system-visual.spec.ts-snapshots/gallery-dark-rtl-mobile-chromium-linux.png new file mode 100644 index 00000000..8a11a110 Binary files /dev/null and b/e2e/design-system-visual.spec.ts-snapshots/gallery-dark-rtl-mobile-chromium-linux.png differ diff --git a/e2e/design-system-visual.spec.ts-snapshots/gallery-light-desktop-chromium-linux.png b/e2e/design-system-visual.spec.ts-snapshots/gallery-light-desktop-chromium-linux.png new file mode 100644 index 00000000..140cd6d7 Binary files /dev/null and b/e2e/design-system-visual.spec.ts-snapshots/gallery-light-desktop-chromium-linux.png differ diff --git a/e2e/design-system-visual.spec.ts-snapshots/gallery-light-ltr-desktop-chromium-linux.png b/e2e/design-system-visual.spec.ts-snapshots/gallery-light-ltr-desktop-chromium-linux.png new file mode 100644 index 00000000..140cd6d7 Binary files /dev/null and b/e2e/design-system-visual.spec.ts-snapshots/gallery-light-ltr-desktop-chromium-linux.png differ diff --git a/e2e/design-system-visual.spec.ts-snapshots/gallery-light-ltr-mobile-chromium-linux.png b/e2e/design-system-visual.spec.ts-snapshots/gallery-light-ltr-mobile-chromium-linux.png new file mode 100644 index 00000000..0e7c69d1 Binary files /dev/null and b/e2e/design-system-visual.spec.ts-snapshots/gallery-light-ltr-mobile-chromium-linux.png differ diff --git a/e2e/design-system-visual.spec.ts-snapshots/gallery-light-mobile-chromium-linux.png b/e2e/design-system-visual.spec.ts-snapshots/gallery-light-mobile-chromium-linux.png new file mode 100644 index 00000000..0e7c69d1 Binary files /dev/null and b/e2e/design-system-visual.spec.ts-snapshots/gallery-light-mobile-chromium-linux.png differ diff --git a/e2e/design-system-visual.spec.ts-snapshots/gallery-light-rtl-desktop-chromium-linux.png b/e2e/design-system-visual.spec.ts-snapshots/gallery-light-rtl-desktop-chromium-linux.png new file mode 100644 index 00000000..23a4b39f Binary files /dev/null and b/e2e/design-system-visual.spec.ts-snapshots/gallery-light-rtl-desktop-chromium-linux.png differ diff --git a/e2e/design-system-visual.spec.ts-snapshots/gallery-light-rtl-mobile-chromium-linux.png b/e2e/design-system-visual.spec.ts-snapshots/gallery-light-rtl-mobile-chromium-linux.png new file mode 100644 index 00000000..a585fc6d Binary files /dev/null and b/e2e/design-system-visual.spec.ts-snapshots/gallery-light-rtl-mobile-chromium-linux.png differ diff --git a/e2e/design-system-visual.spec.ts-snapshots/landing-dark-desktop-chromium-linux.png b/e2e/design-system-visual.spec.ts-snapshots/landing-dark-desktop-chromium-linux.png new file mode 100644 index 00000000..3555a191 Binary files /dev/null and b/e2e/design-system-visual.spec.ts-snapshots/landing-dark-desktop-chromium-linux.png differ diff --git a/e2e/design-system-visual.spec.ts-snapshots/landing-dark-mobile-chromium-linux.png b/e2e/design-system-visual.spec.ts-snapshots/landing-dark-mobile-chromium-linux.png new file mode 100644 index 00000000..2d009e82 Binary files /dev/null and b/e2e/design-system-visual.spec.ts-snapshots/landing-dark-mobile-chromium-linux.png differ diff --git a/e2e/design-system-visual.spec.ts-snapshots/landing-light-desktop-chromium-linux.png b/e2e/design-system-visual.spec.ts-snapshots/landing-light-desktop-chromium-linux.png new file mode 100644 index 00000000..cc1a0f2c Binary files /dev/null and b/e2e/design-system-visual.spec.ts-snapshots/landing-light-desktop-chromium-linux.png differ diff --git a/e2e/design-system-visual.spec.ts-snapshots/landing-light-mobile-chromium-linux.png b/e2e/design-system-visual.spec.ts-snapshots/landing-light-mobile-chromium-linux.png new file mode 100644 index 00000000..da399fb6 Binary files /dev/null and b/e2e/design-system-visual.spec.ts-snapshots/landing-light-mobile-chromium-linux.png differ diff --git a/packages/ui/src/styles/globals.css b/packages/ui/src/styles/globals.css index 94ef8cf0..13f12c95 100644 --- a/packages/ui/src/styles/globals.css +++ b/packages/ui/src/styles/globals.css @@ -393,6 +393,88 @@ --sidebar-ring: oklch(0.556 0 0); } +/* + * Dark theme (GF3-001) — GMX-derived. + * + * Re-introduces `.dark` (previously absent, so dark mode fell back to the + * light values above). Surfaces, text roles, border, primary/ring, and accent + * are sourced straight from the GMX reference palette per the mapping table + * in docs/gf_3/001_theme_update.md §8.2 — trading-state foreground colors + * (long/short/liquidation/success/warning/danger/neutral) are intentionally + * NOT GMX concepts and are left untouched, inherited from :root. Only their + * `subtle`/`border` fill pairs are re-lightened here so a badge still reads + * as a distinct tint against the new slate-800/900 surfaces instead of + * blending into them (the :root pairs were tuned for a white canvas). + */ +.dark { + --background: var(--color-gmx-slate-900); + --foreground: oklch(1 0 0); + --card: var(--color-gmx-slate-800); + --card-foreground: oklch(1 0 0); + --popover: var(--color-gmx-slate-800); + --popover-foreground: oklch(1 0 0); + --primary: var(--color-gmx-blue-400); + --primary-foreground: oklch(1 0 0); + --secondary: var(--color-gmx-slate-700); + --secondary-foreground: oklch(1 0 0); + --muted: var(--color-gmx-slate-700); + --muted-foreground: var(--color-gmx-slate-400); + --accent: var(--color-gmx-blue-300); + --accent-foreground: oklch(1 0 0); + --destructive-foreground: oklch(1 0 0); + --border: var(--color-gmx-stroke-primary); + --input: var(--color-gmx-stroke-primary); + --ring: var(--color-gmx-blue-400); + + --surface-canvas: var(--color-gmx-slate-900); + --surface-sunken: var(--color-gmx-slate-950); + --surface-raised: var(--color-gmx-slate-800); + --surface-overlay: var(--color-gmx-slate-800); + --surface-interactive: var(--color-gmx-slate-650); + + --text-primary: oklch(1 0 0); + --text-secondary: var(--color-gmx-slate-400); + --text-tertiary: var(--color-gmx-slate-500); + --text-inverse: oklch(1 0 0); + --text-link: var(--color-gmx-blue-400); + + --info: var(--color-gmx-blue-400); + --sidebar-primary: var(--color-gmx-blue-400); + + --sidebar: var(--color-gmx-slate-800); + --sidebar-foreground: oklch(1 0 0); + --sidebar-primary-foreground: oklch(1 0 0); + --sidebar-accent: var(--color-gmx-slate-650); + --sidebar-accent-foreground: oklch(1 0 0); + --sidebar-border: var(--color-gmx-stroke-primary); + --sidebar-ring: var(--color-gmx-blue-400); + + --chart-surface: var(--color-gmx-slate-800); + --chart-text: var(--color-gmx-slate-400); + --chart-grid: var(--color-gmx-stroke-primary); + --chart-crosshair: var(--color-gmx-slate-500); + --chart-crosshair-label: var(--color-gmx-slate-700); + --chart-border: var(--color-gmx-stroke-primary); + + /* Trading-state subtle/border — rebalanced, see file comment above */ + --long-subtle: oklch(0.26 0.07 163.225); + --long-border: oklch(0.42 0.12 163.225); + --short-subtle: oklch(0.26 0.07 27.325); + --short-border: oklch(0.42 0.12 27.325); + --liquidation-subtle: oklch(0.26 0.07 75.834); + --liquidation-border: oklch(0.42 0.12 75.834); + --success-subtle: oklch(0.26 0.07 163.225); + --success-border: oklch(0.42 0.12 163.225); + --warning-subtle: oklch(0.26 0.07 75.834); + --warning-border: oklch(0.42 0.12 75.834); + --info-subtle: oklch(0.26 0.09 268.08); + --info-border: oklch(0.42 0.16 268.08); + --danger-subtle: oklch(0.26 0.07 27.325); + --danger-border: oklch(0.42 0.12 27.325); + --neutral-subtle: oklch(0.28 0 0); + --neutral-border: oklch(0.40 0 0); +} + @layer base { * { @apply border-border outline-ring/50;