From 329319ff8a65aaf3ae4188c0194e7a7d91c92a3c Mon Sep 17 00:00:00 2001 From: Ahmed Mahmud Date: Sun, 11 Oct 2026 11:21:46 +0100 Subject: [PATCH 1/2] feat(ui): adopt approved brand and foundation tokens Implements UI-FE-001 (#572). Installs the canonical Evidence Shield assets unchanged, binds legacy semantic aliases to the approved V2 palette, documents the foundation, and adds Storybook plus regression coverage. --- .storybook/preview.tsx | 26 ++- docs/ux/DESIGN_SYSTEM.md | 21 ++ public/brand/truthbounty-app-icon.svg | 14 ++ public/brand/truthbounty-glyph-monochrome.svg | 5 + public/brand/truthbounty-glyph.svg | 13 ++ public/brand/truthbounty-landscape-dark.svg | 21 ++ public/brand/truthbounty-landscape-light.svg | 21 ++ .../design-system/brand-foundation.test.ts | 38 ++++ src/app/globals.css | 191 +++++++++++++++++- src/app/layout.tsx | 7 +- .../ui/brand/BrandFoundation.stories.tsx | 59 ++++++ src/lib/brand.ts | 16 ++ src/lib/design-tokens.ts | 89 +++----- 13 files changed, 441 insertions(+), 80 deletions(-) create mode 100644 public/brand/truthbounty-app-icon.svg create mode 100644 public/brand/truthbounty-glyph-monochrome.svg create mode 100644 public/brand/truthbounty-glyph.svg create mode 100644 public/brand/truthbounty-landscape-dark.svg create mode 100644 public/brand/truthbounty-landscape-light.svg create mode 100644 src/__tests__/design-system/brand-foundation.test.ts create mode 100644 src/components/ui/brand/BrandFoundation.stories.tsx create mode 100644 src/lib/brand.ts diff --git a/.storybook/preview.tsx b/.storybook/preview.tsx index 1173715c..0dc4df5b 100644 --- a/.storybook/preview.tsx +++ b/.storybook/preview.tsx @@ -1,5 +1,6 @@ import type { Preview } from '@storybook/nextjs-vite'; import React from 'react'; +import '../src/app/globals.css'; const preview: Preview = { parameters: { @@ -9,28 +10,33 @@ const preview: Preview = { date: /Date$/i, }, }, - layout: 'centered', - + backgrounds: { + default: 'Ink Navy', + values: [ + { name: 'Ink Navy', value: '#070A12' }, + { name: 'Frost White', value: '#F7F9FC' }, + ], + }, a11y: { - // 'error' - fail CI on a11y violations - // 'todo' - show violations in test UI only - // 'off' - skip a11y checks entirely test: 'error', }, }, decorators: [ - // Add decorator to wrap components with necessary providers (Story) => React.createElement( 'div', { + className: 'dark', + 'data-theme': 'dark', style: { minWidth: '320px', maxWidth: '100%', - padding: '24px', - background: '#ffffff', - borderRadius: '8px', + padding: 'var(--tb-space-6)', + color: 'var(--tb-text)', + background: 'var(--tb-canvas)', + border: '1px solid var(--tb-border)', + borderRadius: 'var(--tb-radius-lg)', }, }, React.createElement(Story, null), @@ -38,4 +44,4 @@ const preview: Preview = { ], }; -export default preview; \ No newline at end of file +export default preview; diff --git a/docs/ux/DESIGN_SYSTEM.md b/docs/ux/DESIGN_SYSTEM.md index 42231956..434e0b59 100644 --- a/docs/ux/DESIGN_SYSTEM.md +++ b/docs/ux/DESIGN_SYSTEM.md @@ -120,3 +120,24 @@ Storybook coverage: `src/components/ui/primitives/StatusBadge.stories.tsx`. - disabled buttons without an accessible explanation; - raw wallet/RPC errors shown directly to users; - importing test mocks into production modules. + + +## Approved V2 brand foundation (UI-FE-001) + +The production token layer now follows Protocol PRs #17 and #18. The canonical +Evidence Shield assets live in `public/brand` and are addressed through +`src/lib/brand.ts`; consumers must not redraw, distort, split, or recolour the +mark. Geist is loaded before landscape lockups render. + +- Signal Cyan `#22D3EE`: evidence and focus. +- Proof Blue `#4F7CFF`: primary actions and resolved context. +- Ink Navy `#070A12` and Deep Slate `#101522`: dark-first canvas and surfaces. +- Frost White `#F7F9FC`: primary dark-theme text and light canvas. +- Bounty Gold `#F5B942`: rewards and staking only. +- Green, amber, red and information blue retain distinct state semantics. + +The compatibility variables used by existing components remain available, but +are rebound to the approved palette. Purple and lavender are not active V2 +identity tokens. Spacing, control heights, radii and motion durations follow the +approved machine-readable foundation, and reduced-motion preferences collapse +non-essential animation to 1 ms. diff --git a/public/brand/truthbounty-app-icon.svg b/public/brand/truthbounty-app-icon.svg new file mode 100644 index 00000000..51b3c364 --- /dev/null +++ b/public/brand/truthbounty-app-icon.svg @@ -0,0 +1,14 @@ + + TruthBounty application icon + Evidence Shield on an Ink Navy rounded-square application tile. + + + + + + + + + + + diff --git a/public/brand/truthbounty-glyph-monochrome.svg b/public/brand/truthbounty-glyph-monochrome.svg new file mode 100644 index 00000000..3b0a35cf --- /dev/null +++ b/public/brand/truthbounty-glyph-monochrome.svg @@ -0,0 +1,5 @@ + + TruthBounty Evidence Shield monochrome glyph + Monochrome Evidence Shield using the current text colour. + + diff --git a/public/brand/truthbounty-glyph.svg b/public/brand/truthbounty-glyph.svg new file mode 100644 index 00000000..506c7a8d --- /dev/null +++ b/public/brand/truthbounty-glyph.svg @@ -0,0 +1,13 @@ + + TruthBounty Evidence Shield glyph + Two evidence paths converge at a diamond verification point and resolve into one output inside a shield. + + + + + + + + + + diff --git a/public/brand/truthbounty-landscape-dark.svg b/public/brand/truthbounty-landscape-dark.svg new file mode 100644 index 00000000..2c316cec --- /dev/null +++ b/public/brand/truthbounty-landscape-dark.svg @@ -0,0 +1,21 @@ + + TruthBounty landscape logo for dark backgrounds + Evidence Shield followed by the TruthBounty wordmark. + + + + + + + + + + + + + + + + Truth + Bounty + diff --git a/public/brand/truthbounty-landscape-light.svg b/public/brand/truthbounty-landscape-light.svg new file mode 100644 index 00000000..8244a4a2 --- /dev/null +++ b/public/brand/truthbounty-landscape-light.svg @@ -0,0 +1,21 @@ + + TruthBounty landscape logo for light backgrounds + Evidence Shield followed by the TruthBounty wordmark. + + + + + + + + + + + + + + + + Truth + Bounty + diff --git a/src/__tests__/design-system/brand-foundation.test.ts b/src/__tests__/design-system/brand-foundation.test.ts new file mode 100644 index 00000000..1d6a773e --- /dev/null +++ b/src/__tests__/design-system/brand-foundation.test.ts @@ -0,0 +1,38 @@ +import fs from 'node:fs'; +import path from 'node:path'; + +import { + BRAND_COLOR_TOKENS, + CONTROL_HEIGHT_TOKENS, + MOTION_TOKENS, + RADIUS_TOKENS, + SEMANTIC_STATE_TOKENS, + SPACING_TOKENS, +} from '@/lib/design-tokens'; +import { TRUTHBOUNTY_BRAND_ASSETS } from '@/lib/brand'; + +const globalsCss = fs.readFileSync(path.resolve(__dirname, '../../app/globals.css'), 'utf8'); + +describe('approved brand assets and foundation tokens (UI-FE-001)', () => { + it.each(Object.values(TRUTHBOUNTY_BRAND_ASSETS))('installs %s as an undistorted SVG', (assetPath) => { + const svg = fs.readFileSync(path.resolve(process.cwd(), 'public', assetPath.slice(1)), 'utf8'); + expect(svg).toContain(' { + for (const value of [...Object.values(BRAND_COLOR_TOKENS), ...Object.values(SEMANTIC_STATE_TOKENS)]) { + expect(globalsCss.toLowerCase()).toContain(value.toLowerCase()); + } + expect(globalsCss.toLowerCase()).not.toContain('#5b5bf6'); + expect(globalsCss.toLowerCase()).not.toContain('#7c7cf7'); + }); + + it('exposes the approved spacing, radius, control and motion scales', () => { + expect(SPACING_TOKENS).toEqual([4, 8, 12, 16, 24, 32, 48, 64]); + expect(RADIUS_TOKENS).toEqual([8, 12, 16, 20]); + expect(CONTROL_HEIGHT_TOKENS).toEqual({ compact: 36, default: 44, large: 52 }); + expect(MOTION_TOKENS).toEqual({ feedback: 120, component: 180, drawer: 240 }); + expect(globalsCss).toContain('--tb-touch-min: 2.75rem'); + }); +}); diff --git a/src/app/globals.css b/src/app/globals.css index dd98e8ff..2ef2526f 100644 --- a/src/app/globals.css +++ b/src/app/globals.css @@ -38,6 +38,15 @@ --color-popover: var(--popover); --color-card-foreground: var(--card-foreground); --color-card: var(--card); + /* Approved TruthBounty V2 brand roles (Protocol PRs #17–#18). */ + --color-signal: var(--tb-signal-cyan); + --color-proof: var(--tb-proof-blue); + --color-reward: var(--tb-bounty-gold); + --color-canvas-brand: var(--tb-canvas); + --color-surface-brand: var(--tb-surface); + --color-surface-raised: var(--tb-surface-raised); + --color-text-brand: var(--tb-text); + --color-text-muted-brand: var(--tb-text-muted); /* V2 semantic tokens (V2-FE-121) — mapped to Tailwind utilities. Roles per docs/ux/DESIGN_SYSTEM.md: surfaces, text, action/focus, feedback, transaction lifecycle, and lines/disabled. */ @@ -99,7 +108,49 @@ a { } :root { - --radius: 0.625rem; + /* Approved V2 foundation values. Keep these names stable for product code. */ + --tb-signal-cyan: #22d3ee; + --tb-proof-blue: #4f7cff; + --tb-ink-navy: #070a12; + --tb-deep-slate: #101522; + --tb-frost-white: #f7f9fc; + --tb-bounty-gold: #f5b942; + --tb-success: #41d39a; + --tb-attention: #f4b860; + --tb-danger: #ff6b7a; + --tb-info: #74a7ff; + + --tb-space-1: 0.25rem; + --tb-space-2: 0.5rem; + --tb-space-3: 0.75rem; + --tb-space-4: 1rem; + --tb-space-6: 1.5rem; + --tb-space-8: 2rem; + --tb-space-12: 3rem; + --tb-space-16: 4rem; + + --tb-radius-sm: 0.5rem; + --tb-radius-md: 0.75rem; + --tb-radius-lg: 1rem; + --tb-radius-xl: 1.25rem; + --tb-radius-pill: 999px; + + --tb-control-sm: 2.25rem; + --tb-control-md: 2.75rem; + --tb-control-lg: 3.25rem; + --tb-touch-min: 2.75rem; + --tb-sidebar-width: 16rem; + --tb-topbar-height: 4rem; + --tb-content-max: 90rem; + + --tb-elevation-01: 0 1px 2px rgb(7 10 18 / 0.16); + --tb-elevation-02: 0 12px 36px rgb(0 0 0 / 0.22); + --tb-motion-feedback: 120ms; + --tb-motion-component: 180ms; + --tb-motion-drawer: 240ms; + --tb-ease-standard: cubic-bezier(0.2, 0, 0, 1); + + --radius: var(--tb-radius-sm); --card: oklch(1 0 0); --card-foreground: oklch(0.145 0 0); --popover: oklch(1 0 0); @@ -169,7 +220,8 @@ a { --gutter: 1rem; } -.dark { +.dark, +[data-theme='dark'] { --background: oklch(0.145 0 0); --foreground: oklch(0.985 0 0); --card: oklch(0.205 0 0); @@ -226,6 +278,127 @@ a { --disabled: oklch(0.556 0 0); } +/* Canonical theme binding. Legacy semantic names remain as compatibility aliases, + but their active values are governed by the approved cyan/blue foundation. */ +:root, +.light, +[data-theme='light'] { + --tb-canvas: #f7f9fc; + --tb-surface: #ffffff; + --tb-surface-raised: #eef3f8; + --tb-text: #070a12; + --tb-text-muted: #58647a; + --tb-border: #dce2eb; + + --background: var(--tb-canvas); + --foreground: var(--tb-text); + --card: var(--tb-surface); + --card-foreground: var(--tb-text); + --popover: var(--tb-surface); + --popover-foreground: var(--tb-text); + --primary: var(--tb-proof-blue); + --primary-foreground: #ffffff; + --secondary: var(--tb-surface-raised); + --secondary-foreground: var(--tb-text); + --muted: var(--tb-surface-raised); + --muted-foreground: var(--tb-text-muted); + --accent: color-mix(in srgb, var(--tb-signal-cyan) 14%, var(--tb-surface)); + --accent-foreground: var(--tb-text); + --destructive: var(--tb-danger); + --border: var(--tb-border); + --input: var(--tb-border); + --ring: var(--tb-signal-cyan); + --sidebar: var(--tb-surface); + --sidebar-foreground: var(--tb-text); + --sidebar-primary: var(--tb-proof-blue); + --sidebar-primary-foreground: #ffffff; + --sidebar-accent: var(--tb-surface-raised); + --sidebar-accent-foreground: var(--tb-text); + --sidebar-border: var(--tb-border); + --sidebar-ring: var(--tb-signal-cyan); + + --canvas: var(--tb-canvas); + --surface: var(--tb-surface); + --elevated: var(--tb-surface-raised); + --ink: var(--tb-text); + --ink-secondary: #344056; + --ink-muted: var(--tb-text-muted); + --action: var(--tb-proof-blue); + --action-hover: color-mix(in srgb, var(--tb-proof-blue) 86%, var(--tb-ink-navy)); + --action-ink: #ffffff; + --focus: var(--tb-signal-cyan); + --success: #147a55; + --warning: #8a5700; + --danger: #b42335; + --info: #285cc4; + --pending: #8a5700; + --confirmed: #285cc4; + --finalized: #147a55; + --orphaned: #b42335; + --divider: var(--tb-border); + --disabled: #8792a5; + color-scheme: light; +} + +.dark, +[data-theme='dark'] { + --tb-canvas: #070a12; + --tb-surface: #101522; + --tb-surface-raised: #151c2b; + --tb-text: #f7f9fc; + --tb-text-muted: #9aa7bd; + --tb-border: #273149; + + --background: var(--tb-canvas); + --foreground: var(--tb-text); + --card: var(--tb-surface); + --card-foreground: var(--tb-text); + --popover: var(--tb-surface-raised); + --popover-foreground: var(--tb-text); + --primary: var(--tb-proof-blue); + --primary-foreground: #ffffff; + --secondary: var(--tb-surface-raised); + --secondary-foreground: var(--tb-text); + --muted: var(--tb-surface-raised); + --muted-foreground: var(--tb-text-muted); + --accent: color-mix(in srgb, var(--tb-signal-cyan) 12%, var(--tb-surface)); + --accent-foreground: var(--tb-text); + --destructive: var(--tb-danger); + --border: var(--tb-border); + --input: #33405b; + --ring: var(--tb-signal-cyan); + --sidebar: var(--tb-deep-slate); + --sidebar-foreground: var(--tb-text); + --sidebar-primary: var(--tb-proof-blue); + --sidebar-primary-foreground: #ffffff; + --sidebar-accent: var(--tb-surface-raised); + --sidebar-accent-foreground: var(--tb-text); + --sidebar-border: var(--tb-border); + --sidebar-ring: var(--tb-signal-cyan); + + --canvas: var(--tb-canvas); + --surface: var(--tb-surface); + --elevated: var(--tb-surface-raised); + --ink: var(--tb-text); + --ink-secondary: #dce4f1; + --ink-muted: var(--tb-text-muted); + --action: var(--tb-proof-blue); + --action-hover: color-mix(in srgb, var(--tb-proof-blue) 82%, var(--tb-signal-cyan)); + --action-ink: #ffffff; + --focus: var(--tb-signal-cyan); + --success: var(--tb-success); + --warning: var(--tb-attention); + --danger: var(--tb-danger); + --info: var(--tb-info); + --pending: var(--tb-attention); + --confirmed: var(--tb-info); + --finalized: var(--tb-success); + --orphaned: var(--tb-danger); + --divider: var(--tb-border); + --disabled: #66738a; + color-scheme: dark; +} + @layer base { * { @apply border-border outline-ring/50; @@ -332,7 +505,7 @@ a { } input:focus, textarea:focus, select:focus, button:focus { - outline: 2px solid #5b5bf6; + outline: 2px solid var(--focus); outline-offset: 2px; } @@ -375,7 +548,7 @@ input:focus-visible, textarea:focus-visible, select:focus-visible, [tabindex]:focus-visible { - outline: 2px solid #5b5bf6; + outline: 2px solid var(--focus); outline-offset: 2px; border-radius: 4px; } @@ -383,7 +556,7 @@ select:focus-visible, [role="button"]:focus-visible, [role="tab"]:focus-visible, [role="menuitem"]:focus-visible { - outline: 2px solid #5b5bf6; + outline: 2px solid var(--focus); outline-offset: 2px; } @@ -391,8 +564,8 @@ select:focus-visible, position: absolute; top: -40px; left: 0; - background: #5b5bf6; - color: white; + background: var(--action); + color: var(--action-ink); padding: 8px 16px; z-index: 100; text-decoration: none; @@ -419,11 +592,11 @@ select:focus-visible, .dark textarea:focus-visible, .dark select:focus-visible, .dark [tabindex]:focus-visible { - outline-color: #7c7cf7; + outline-color: var(--focus); } :focus-visible { - outline: 2px solid #2563eb; + outline: 2px solid var(--focus); outline-offset: 2px; } diff --git a/src/app/layout.tsx b/src/app/layout.tsx index 79edb64a..8412ab96 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -18,7 +18,12 @@ const geistMono = Geist_Mono({ export const metadata: Metadata = { title: "Truth Bounty - Decentralized Claim Verification", - description: "A decentralized protocol for verifying claims through community consensus and staking", + description: "Evidence-first claim verification with transparent protocol outcomes.", + icons: { + icon: "/brand/truthbounty-app-icon.svg", + shortcut: "/brand/truthbounty-app-icon.svg", + apple: "/brand/truthbounty-app-icon.svg", + }, }; export default async function RootLayout({ diff --git a/src/components/ui/brand/BrandFoundation.stories.tsx b/src/components/ui/brand/BrandFoundation.stories.tsx new file mode 100644 index 00000000..631a805a --- /dev/null +++ b/src/components/ui/brand/BrandFoundation.stories.tsx @@ -0,0 +1,59 @@ +import type { Meta, StoryObj } from '@storybook/react'; +import Image from 'next/image'; + +import { BRAND_COLOR_TOKENS, SEMANTIC_STATE_TOKENS } from '@/lib/design-tokens'; +import { TRUTHBOUNTY_BRAND_ASSETS } from '@/lib/brand'; + +const palette = { ...BRAND_COLOR_TOKENS, ...SEMANTIC_STATE_TOKENS }; + +function BrandFoundation() { + return ( +
+
+

Approved wordmarks

+
+
+ TruthBounty +
+
+ TruthBounty +
+
+
+ +
+

Evidence Shield assets

+
+ TruthBounty + TruthBounty application icon +
+ TruthBounty monochrome mark +
+
+
+ +
+

Approved colour tokens

+
+ {Object.entries(palette).map(([name, value]) => ( +
+ + ))} +
+
+
+ ); +} + +const meta = { + title: 'Foundation/Brand and tokens', + component: BrandFoundation, + parameters: { layout: 'padded' }, +} satisfies Meta; + +export default meta; +type Story = StoryObj; +export const ApprovedFoundation: Story = {}; diff --git a/src/lib/brand.ts b/src/lib/brand.ts new file mode 100644 index 00000000..ffa5eda6 --- /dev/null +++ b/src/lib/brand.ts @@ -0,0 +1,16 @@ +/** Canonical Evidence Shield assets copied unchanged from protocol authority. */ +export const TRUTHBOUNTY_BRAND_ASSETS = { + appIcon: '/brand/truthbounty-app-icon.svg', + glyph: '/brand/truthbounty-glyph.svg', + glyphMonochrome: '/brand/truthbounty-glyph-monochrome.svg', + landscapeDark: '/brand/truthbounty-landscape-dark.svg', + landscapeLight: '/brand/truthbounty-landscape-light.svg', +} as const; + +export type TruthBountyBrandAsset = keyof typeof TRUTHBOUNTY_BRAND_ASSETS; + +export function truthBountyWordmarkForTheme(theme: 'dark' | 'light'): string { + return theme === 'dark' + ? TRUTHBOUNTY_BRAND_ASSETS.landscapeDark + : TRUTHBOUNTY_BRAND_ASSETS.landscapeLight; +} diff --git a/src/lib/design-tokens.ts b/src/lib/design-tokens.ts index 598c732e..e97cf744 100644 --- a/src/lib/design-tokens.ts +++ b/src/lib/design-tokens.ts @@ -1,75 +1,44 @@ -/** - * V2 Design Token contract (V2-FE-121) - * - * Single source of truth for the semantic token names that MUST exist in - * `src/app/globals.css` (as CSS variables) and be mapped into the Tailwind - * `@theme inline` block (as `--color-*` utilities). - * - * The design-system test suite reads these arrays and asserts that every - * declared role is present in both themes and mapped to a Tailwind colour - * utility, keeping tokens and code synchronised. - */ +/** Approved TruthBounty V2 design-token contract (UI-FE-001). */ + +export const BRAND_COLOR_TOKENS = { + signalCyan: '#22D3EE', + proofBlue: '#4F7CFF', + inkNavy: '#070A12', + deepSlate: '#101522', + frostWhite: '#F7F9FC', + bountyGold: '#F5B942', +} as const; + +export const SEMANTIC_STATE_TOKENS = { + success: '#41D39A', + attention: '#F4B860', + danger: '#FF6B7A', + info: '#74A7FF', +} as const; + +export const SPACING_TOKENS = [4, 8, 12, 16, 24, 32, 48, 64] as const; +export const RADIUS_TOKENS = [8, 12, 16, 20] as const; +export const CONTROL_HEIGHT_TOKENS = { compact: 36, default: 44, large: 52 } as const; +export const MOTION_TOKENS = { feedback: 120, component: 180, drawer: 240 } as const; -/** Surface + text + action/focus semantic colour roles. */ export const SEMANTIC_COLOR_TOKENS = [ - 'canvas', - 'surface', - 'elevated', - 'ink', - 'ink-secondary', - 'ink-muted', - 'action', - 'action-hover', - 'action-ink', - 'focus', - 'success', - 'warning', - 'danger', - 'info', - 'pending', - 'confirmed', - 'finalized', - 'orphaned', - 'divider', - 'disabled', + 'canvas', 'surface', 'elevated', 'ink', 'ink-secondary', 'ink-muted', + 'action', 'action-hover', 'action-ink', 'focus', 'success', 'warning', + 'danger', 'info', 'pending', 'confirmed', 'finalized', 'orphaned', + 'divider', 'disabled', ] as const; - export type SemanticColorToken = (typeof SEMANTIC_COLOR_TOKENS)[number]; -/** Type-scale roles (4px-friendly rem scale). */ export const TYPE_SCALE_TOKENS = [ - 'display', - 'title', - 'section', - 'body', - 'small', - 'label', - 'code', - 'data', + 'display', 'title', 'section', 'body', 'small', 'label', 'code', 'data', ] as const; - export type TypeScaleToken = (typeof TYPE_SCALE_TOKENS)[number]; -/** Layout / responsive tokens. */ export const LAYOUT_TOKENS = ['touch-target', 'content-width', 'gutter'] as const; - export type LayoutToken = (typeof LAYOUT_TOKENS)[number]; -/** - * Status tones exposed by the `StatusBadge` primitive. Each tone maps to a - * semantic colour role plus a distinct icon glyph so colour never carries - * meaning alone (WCAG 1.4.1). - */ export const STATUS_TONES = [ - 'neutral', - 'pending', - 'confirmed', - 'finalized', - 'orphaned', - 'success', - 'warning', - 'danger', - 'info', + 'neutral', 'pending', 'confirmed', 'finalized', 'orphaned', + 'success', 'warning', 'danger', 'info', ] as const; - export type StatusToneName = (typeof STATUS_TONES)[number]; From 5351523a2f98e1e754971dd873ce7a5b2b290173 Mon Sep 17 00:00:00 2001 From: Ahmed Mahmud Date: Sun, 11 Oct 2026 11:23:20 +0100 Subject: [PATCH 2/2] fix(ci): reconcile TypeScript peer snapshots in lockfile The post-Wave-9 lockfile still referenced a removed typescript@7.0.2 root package from 39 peer snapshots, causing every frozen-install CI job to fail before validation. --- pnpm-lock.yaml | 78 +++++++++++++++++++++++++------------------------- 1 file changed, 39 insertions(+), 39 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ffde1135..598136ba 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -7333,7 +7333,7 @@ snapshots: react-docgen-typescript: 2.4.0(typescript@6.0.3) vite: 8.3.1(@types/node@26.6.3)(esbuild@0.28.2)(jiti@2.7.0) optionalDependencies: - typescript: 7.0.2 + typescript: 6.0.3 '@jridgewell/gen-mapping@0.3.13': dependencies: @@ -8284,7 +8284,7 @@ snapshots: optionalDependencies: '@types/react': 19.3.0 '@types/react-dom': 19.3.0(@types/react@19.3.0) - typescript: 7.0.2 + typescript: 6.0.3 transitivePeerDependencies: - '@babel/core' - babel-plugin-macros @@ -8316,7 +8316,7 @@ snapshots: tsconfig-paths: 4.2.0 vite: 8.3.1(@types/node@26.6.3)(esbuild@0.28.2)(jiti@2.7.0) optionalDependencies: - typescript: 7.0.2 + typescript: 6.0.3 transitivePeerDependencies: - '@types/react' - '@types/react-dom' @@ -8335,7 +8335,7 @@ snapshots: optionalDependencies: '@types/react': 19.3.0 '@types/react-dom': 19.3.0(@types/react@19.3.0) - typescript: 7.0.2 + typescript: 6.0.3 transitivePeerDependencies: - supports-color @@ -8703,7 +8703,7 @@ snapshots: ignore: 7.0.10 natural-compare: 1.4.0 ts-api-utils: 2.5.0(typescript@6.0.3) - typescript: 7.0.2 + typescript: 6.0.3 transitivePeerDependencies: - supports-color @@ -8715,7 +8715,7 @@ snapshots: '@typescript-eslint/visitor-keys': 8.71.0 debug: 4.4.3 eslint: 10.11.0(jiti@2.7.0) - typescript: 7.0.2 + typescript: 6.0.3 transitivePeerDependencies: - supports-color @@ -8724,7 +8724,7 @@ snapshots: '@typescript-eslint/tsconfig-utils': 8.71.0(typescript@6.0.3) '@typescript-eslint/types': 8.71.0 debug: 4.4.3 - typescript: 7.0.2 + typescript: 6.0.3 transitivePeerDependencies: - supports-color @@ -8733,7 +8733,7 @@ snapshots: '@typescript-eslint/tsconfig-utils': 8.71.0(typescript@6.0.3) '@typescript-eslint/types': 8.71.0 debug: 4.4.3 - typescript: 7.0.2 + typescript: 6.0.3 transitivePeerDependencies: - supports-color @@ -8749,11 +8749,11 @@ snapshots: '@typescript-eslint/tsconfig-utils@8.70.1(typescript@6.0.3)': dependencies: - typescript: 7.0.2 + typescript: 6.0.3 '@typescript-eslint/tsconfig-utils@8.71.0(typescript@6.0.3)': dependencies: - typescript: 7.0.2 + typescript: 6.0.3 '@typescript-eslint/type-utils@8.71.0(eslint@10.11.0(jiti@2.7.0))(typescript@6.0.3)': dependencies: @@ -8763,7 +8763,7 @@ snapshots: debug: 4.4.3 eslint: 10.11.0(jiti@2.7.0) ts-api-utils: 2.5.0(typescript@6.0.3) - typescript: 7.0.2 + typescript: 6.0.3 transitivePeerDependencies: - supports-color @@ -8782,7 +8782,7 @@ snapshots: semver: 7.8.5 tinyglobby: 0.2.17 ts-api-utils: 2.5.0(typescript@6.0.3) - typescript: 7.0.2 + typescript: 6.0.3 transitivePeerDependencies: - supports-color @@ -8797,7 +8797,7 @@ snapshots: semver: 7.8.5 tinyglobby: 0.2.17 ts-api-utils: 2.5.0(typescript@6.0.3) - typescript: 7.0.2 + typescript: 6.0.3 transitivePeerDependencies: - supports-color @@ -8808,7 +8808,7 @@ snapshots: '@typescript-eslint/types': 8.70.1 '@typescript-eslint/typescript-estree': 8.70.1(typescript@6.0.3) eslint: 10.11.0(jiti@2.7.0) - typescript: 7.0.2 + typescript: 6.0.3 transitivePeerDependencies: - supports-color @@ -8819,7 +8819,7 @@ snapshots: '@typescript-eslint/types': 8.71.0 '@typescript-eslint/typescript-estree': 8.71.0(typescript@6.0.3) eslint: 10.11.0(jiti@2.7.0) - typescript: 7.0.2 + typescript: 6.0.3 transitivePeerDependencies: - supports-color @@ -9121,7 +9121,7 @@ snapshots: '@safe-global/safe-apps-provider': 0.18.6(bufferutil@4.1.0)(typescript@6.0.3)(utf-8-validate@5.0.10)(zod@4.6.5) '@safe-global/safe-apps-sdk': 9.1.0(bufferutil@4.1.0)(typescript@6.0.3)(utf-8-validate@5.0.10)(zod@4.6.5) '@walletconnect/ethereum-provider': 2.21.1(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(typescript@6.0.3)(utf-8-validate@5.0.10)(zod@4.6.5) - typescript: 7.0.2 + typescript: 6.0.3 '@wagmi/core@3.6.5(@tanstack/query-core@5.104.0)(@types/react@19.3.0)(immer@11.1.18)(react@19.3.0)(typescript@6.0.3)(use-sync-external-store@1.4.0(react@19.3.0))(viem@2.56.9(bufferutil@4.1.0)(typescript@6.0.3)(utf-8-validate@5.0.10)(zod@4.6.5))': dependencies: @@ -9131,7 +9131,7 @@ snapshots: zustand: 5.0.0(@types/react@19.3.0)(immer@11.1.18)(react@19.3.0)(use-sync-external-store@1.4.0(react@19.3.0)) optionalDependencies: '@tanstack/query-core': 5.104.0 - typescript: 7.0.2 + typescript: 6.0.3 transitivePeerDependencies: - '@types/react' - immer @@ -9146,7 +9146,7 @@ snapshots: zustand: 5.0.0(@types/react@19.3.0)(immer@11.1.18)(react@19.3.0)(use-sync-external-store@1.7.0(react@19.3.0)) optionalDependencies: '@tanstack/query-core': 5.104.0 - typescript: 7.0.2 + typescript: 6.0.3 transitivePeerDependencies: - '@types/react' - immer @@ -9738,30 +9738,30 @@ snapshots: abitype@1.0.8(typescript@6.0.3)(zod@4.6.5): optionalDependencies: - typescript: 7.0.2 + typescript: 6.0.3 zod: 4.6.5 optional: true abitype@1.2.3(typescript@6.0.3)(zod@3.22.4): optionalDependencies: - typescript: 7.0.2 + typescript: 6.0.3 zod: 3.22.4 optional: true abitype@1.2.3(typescript@6.0.3)(zod@4.6.5): optionalDependencies: - typescript: 7.0.2 + typescript: 6.0.3 zod: 4.6.5 abitype@1.3.0(typescript@6.0.3)(zod@3.22.4): optionalDependencies: - typescript: 7.0.2 + typescript: 6.0.3 zod: 3.22.4 optional: true abitype@1.3.0(typescript@6.0.3)(zod@4.6.5): optionalDependencies: - typescript: 7.0.2 + typescript: 6.0.3 zod: 4.6.5 acorn-jsx@5.3.2(acorn@8.18.0): @@ -10206,7 +10206,7 @@ snapshots: react: 19.3.0 react-dom: 19.3.0(react@19.3.0) optionalDependencies: - typescript: 7.0.2 + typescript: 6.0.3 d3-array@3.2.4: dependencies: @@ -10579,7 +10579,7 @@ snapshots: globals: 16.4.0 typescript-eslint: 8.71.0(eslint@10.11.0(jiti@2.7.0))(typescript@6.0.3) optionalDependencies: - typescript: 7.0.2 + typescript: 6.0.3 transitivePeerDependencies: - '@typescript-eslint/parser' - eslint-import-resolver-webpack @@ -11983,7 +11983,7 @@ snapshots: mipd@0.0.7(typescript@6.0.3): optionalDependencies: - typescript: 7.0.2 + typescript: 6.0.3 modern-ahocorasick@1.1.0: {} @@ -12011,7 +12011,7 @@ snapshots: yargs: 18.2.0 optionalDependencies: graphql: 16.14.2 - typescript: 7.0.2 + typescript: 6.0.3 vite: 8.3.1(@types/node@26.6.3)(esbuild@0.28.2)(jiti@2.7.0) transitivePeerDependencies: - '@types/node' @@ -12222,7 +12222,7 @@ snapshots: abitype: 1.3.0(typescript@6.0.3)(zod@3.22.4) eventemitter3: 5.0.1 optionalDependencies: - typescript: 7.0.2 + typescript: 6.0.3 transitivePeerDependencies: - zod optional: true @@ -12238,7 +12238,7 @@ snapshots: abitype: 1.3.0(typescript@6.0.3)(zod@4.6.5) eventemitter3: 5.0.1 optionalDependencies: - typescript: 7.0.2 + typescript: 6.0.3 transitivePeerDependencies: - zod @@ -12252,7 +12252,7 @@ snapshots: abitype: 1.3.0(typescript@6.0.3)(zod@4.6.5) eventemitter3: 5.0.1 optionalDependencies: - typescript: 7.0.2 + typescript: 6.0.3 transitivePeerDependencies: - zod optional: true @@ -12267,7 +12267,7 @@ snapshots: abitype: 1.3.0(typescript@6.0.3)(zod@4.6.5) eventemitter3: 5.0.1 optionalDependencies: - typescript: 7.0.2 + typescript: 6.0.3 transitivePeerDependencies: - zod optional: true @@ -12523,7 +12523,7 @@ snapshots: react-docgen-typescript@2.4.0(typescript@6.0.3): dependencies: - typescript: 7.0.2 + typescript: 6.0.3 react-docgen@8.0.4: dependencies: @@ -13182,13 +13182,13 @@ snapshots: ts-api-utils@2.5.0(typescript@6.0.3): dependencies: - typescript: 7.0.2 + typescript: 6.0.3 ts-dedent@2.3.0: {} tsconfck@3.1.6(typescript@6.0.3): optionalDependencies: - typescript: 7.0.2 + typescript: 6.0.3 tsconfig-paths@3.15.0: dependencies: @@ -13261,7 +13261,7 @@ snapshots: '@typescript-eslint/typescript-estree': 8.71.0(typescript@6.0.3) '@typescript-eslint/utils': 8.71.0(eslint@10.11.0(jiti@2.7.0))(typescript@6.0.3) eslint: 10.11.0(jiti@2.7.0) - typescript: 7.0.2 + typescript: 6.0.3 transitivePeerDependencies: - supports-color @@ -13468,7 +13468,7 @@ snapshots: ox: 0.6.7(typescript@6.0.3)(zod@4.6.5) ws: 8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10) optionalDependencies: - typescript: 7.0.2 + typescript: 6.0.3 transitivePeerDependencies: - bufferutil - utf-8-validate @@ -13486,7 +13486,7 @@ snapshots: ox: 0.14.45(typescript@6.0.3)(zod@3.22.4) ws: 8.21.0(bufferutil@4.1.0)(utf-8-validate@5.0.10) optionalDependencies: - typescript: 7.0.2 + typescript: 6.0.3 transitivePeerDependencies: - bufferutil - utf-8-validate @@ -13504,7 +13504,7 @@ snapshots: ox: 0.14.45(typescript@6.0.3)(zod@4.6.5) ws: 8.21.0(bufferutil@4.1.0)(utf-8-validate@5.0.10) optionalDependencies: - typescript: 7.0.2 + typescript: 6.0.3 transitivePeerDependencies: - bufferutil - utf-8-validate @@ -13591,7 +13591,7 @@ snapshots: use-sync-external-store: 1.4.0(react@19.3.0) viem: 2.56.9(bufferutil@4.1.0)(typescript@6.0.3)(utf-8-validate@5.0.10)(zod@4.6.5) optionalDependencies: - typescript: 7.0.2 + typescript: 6.0.3 transitivePeerDependencies: - '@base-org/account' - '@coinbase/wallet-sdk'