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() { + +
+ {/* GMX's landing is dark-only (docs/gf_3/001_theme_update.md §7), so + this swatch forces the `.dark` token scope the same way the + landing route itself does, independent of the gallery's own + theme toggle. */} +
+
+

text-heading-1

+

Perpetual markets.

+
+
+

text-heading-2

+

Built for traders.

+
+
+

text-heading-3

+

Card titles

+
+
+

text-heading-4

+

Small card titles

+
+
+

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-landing

+ +
+
+
) } diff --git a/apps/web/src/routes/index.tsx b/apps/web/src/routes/index.tsx index 1cec8902..88adca85 100644 --- a/apps/web/src/routes/index.tsx +++ b/apps/web/src/routes/index.tsx @@ -16,7 +16,10 @@ export const Route = createFileRoute("/")({ component: LandingPage }) function LandingPage() { return ( -
+ // GMX's landing is dark-only — force the `.dark` token scope on this + // subtree regardless of the user's theme setting (docs/gf_3/001_theme_update.md §7), + // without touching so /trade, /pools, etc. keep honoring it. +
diff --git a/apps/web/src/styles/landing.css b/apps/web/src/styles/landing.css index df119ab1..695527b1 100644 --- a/apps/web/src/styles/landing.css +++ b/apps/web/src/styles/landing.css @@ -96,8 +96,3 @@ font-family: "Geist Mono", ui-monospace, monospace; font-feature-settings: "tnum" 1, "zero" 1; } - -/* Trading feature settings for body copy */ -.font-trading { - font-feature-settings: "ss01", "cv11"; -} diff --git a/apps/web/src/ui/Navbar.tsx b/apps/web/src/ui/Navbar.tsx index f5320904..debb1d76 100644 --- a/apps/web/src/ui/Navbar.tsx +++ b/apps/web/src/ui/Navbar.tsx @@ -88,7 +88,7 @@ export function Navbar({ variant }: Props) { {!isApp && ( )} diff --git a/apps/web/src/ui/landing/features.tsx b/apps/web/src/ui/landing/features.tsx index c8ff6f28..06625da3 100644 --- a/apps/web/src/ui/landing/features.tsx +++ b/apps/web/src/ui/landing/features.tsx @@ -81,15 +81,12 @@ export function Features() { Engine
-

+

Built for traders{" "} who care{" "} where their fills come from.

-

+

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() {

{icon}
-

- {title} -

-

{body}

+

{title}

+

{body}

{statKey} diff --git a/apps/web/src/ui/landing/final-cta.tsx b/apps/web/src/ui/landing/final-cta.tsx index e2472642..ddde7363 100644 --- a/apps/web/src/ui/landing/final-cta.tsx +++ b/apps/web/src/ui/landing/final-cta.tsx @@ -4,23 +4,20 @@ export function FinalCTA() { return (
-

+

The book is{" "} open.
You're a wallet away.

-

+

No signup. No email. No deposit minimum. Connect and trade — or fork the contracts and run your own venue.

-
-

+

From wallet to fill in{" "} three steps.

-

+

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() {
{num}
-

- {title} -

-

{body}

+

{title}

+

{body}

))} diff --git a/apps/web/src/ui/landing/infrastructure.tsx b/apps/web/src/ui/landing/infrastructure.tsx index c1fa3af0..7c9d54da 100644 --- a/apps/web/src/ui/landing/infrastructure.tsx +++ b/apps/web/src/ui/landing/infrastructure.tsx @@ -34,15 +34,12 @@ export function Infrastructure() { Infrastructure
-

+

An{" "} app-specific chain{" "} with one job: settle perps.

-

+

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

-

+

184 perpetuals.{" "} One book.

-

+

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;