diff --git a/.github/workflows/deploy-app-walrus.yml b/.github/workflows/deploy-app-walrus.yml
index ce08b483..cff43005 100644
--- a/.github/workflows/deploy-app-walrus.yml
+++ b/.github/workflows/deploy-app-walrus.yml
@@ -68,6 +68,12 @@ jobs:
VITE_DOCS_URL: ${{ vars.VITE_DOCS_URL }}
VITE_DEMO_URLS: ${{ vars.VITE_DEMO_URLS }}
VITE_GA_MEASUREMENT_ID: ${{ vars.VITE_GA_MEASUREMENT_ID }}
+ VITE_GTM_CONTAINER_ID: ${{ vars.VITE_GTM_CONTAINER_ID }}
+ VITE_ANALYTICS_ALLOWED_HOSTS: ${{ vars.VITE_ANALYTICS_ALLOWED_HOSTS }}
+ VITE_POSTHOG_PROJECT_API_KEY: ${{ vars.VITE_POSTHOG_PROJECT_API_KEY }}
+ VITE_POSTHOG_KEY: ${{ vars.VITE_POSTHOG_KEY }}
+ VITE_POSTHOG_HOST: ${{ vars.VITE_POSTHOG_HOST }}
+ VITE_POSTHOG_UI_HOST: ${{ vars.VITE_POSTHOG_UI_HOST }}
- name: Deploy to Walrus Site (Mainnet)
id: deploy-mainnet
diff --git a/apps/app/.env.example b/apps/app/.env.example
index 0399df70..c608bfb7 100644
--- a/apps/app/.env.example
+++ b/apps/app/.env.example
@@ -24,6 +24,18 @@ VITE_DEMO_URLS=
# Google Analytics 4 Measurement ID. Leave blank to disable analytics.
VITE_GA_MEASUREMENT_ID=
+# Google Tag Manager Container ID. Set to GTM-KPDDH5DX in production.
+VITE_GTM_CONTAINER_ID=
+
+# Analytics only sends on these production hosts. Applies to GTM, GA4, and PostHog.
+# Use * for local analytics testing.
+VITE_ANALYTICS_ALLOWED_HOSTS=walrus.xyz,www.walrus.xyz
+
+# PostHog Project API key. Leave blank to disable PostHog.
+VITE_POSTHOG_PROJECT_API_KEY=
+VITE_POSTHOG_HOST=https://t.walrus.xyz
+VITE_POSTHOG_UI_HOST=https://us.posthog.com
+
# ══════════════════════════════════════════════════════════════
# ▷ INACTIVE: MAINNET (uncomment below, comment out TESTNET above)
# ══════════════════════════════════════════════════════════════
diff --git a/apps/app/Dockerfile b/apps/app/Dockerfile
index 0fdd6a42..8007e333 100644
--- a/apps/app/Dockerfile
+++ b/apps/app/Dockerfile
@@ -37,6 +37,12 @@ ARG VITE_GOOGLE_CLIENT_ID
ARG VITE_DOCS_URL
ARG VITE_DEMO_URLS
ARG VITE_GA_MEASUREMENT_ID
+ARG VITE_GTM_CONTAINER_ID
+ARG VITE_ANALYTICS_ALLOWED_HOSTS
+ARG VITE_POSTHOG_PROJECT_API_KEY
+ARG VITE_POSTHOG_KEY
+ARG VITE_POSTHOG_HOST
+ARG VITE_POSTHOG_UI_HOST
ENV VITE_MEMWAL_SERVER_URL=$VITE_MEMWAL_SERVER_URL
ENV VITE_MEMWAL_PACKAGE_ID=$VITE_MEMWAL_PACKAGE_ID
@@ -47,20 +53,25 @@ ENV VITE_GOOGLE_CLIENT_ID=$VITE_GOOGLE_CLIENT_ID
ENV VITE_DOCS_URL=$VITE_DOCS_URL
ENV VITE_DEMO_URLS=$VITE_DEMO_URLS
ENV VITE_GA_MEASUREMENT_ID=$VITE_GA_MEASUREMENT_ID
+ENV VITE_GTM_CONTAINER_ID=$VITE_GTM_CONTAINER_ID
+ENV VITE_ANALYTICS_ALLOWED_HOSTS=$VITE_ANALYTICS_ALLOWED_HOSTS
+ENV VITE_POSTHOG_PROJECT_API_KEY=$VITE_POSTHOG_PROJECT_API_KEY
+ENV VITE_POSTHOG_KEY=$VITE_POSTHOG_KEY
+ENV VITE_POSTHOG_HOST=$VITE_POSTHOG_HOST
+ENV VITE_POSTHOG_UI_HOST=$VITE_POSTHOG_UI_HOST
RUN pnpm --filter @memwal/app build
# ── Stage 2: Serve static files ─────────────────────────────
FROM node:22-alpine AS runtime
-RUN npm install -g serve
-
WORKDIR /app
COPY --from=builder /app/apps/app/dist ./dist
+COPY --from=builder /app/apps/app/server.mjs ./server.mjs
-ENV PORT=${PORT}
-EXPOSE ${PORT}
+ENV PORT=3000
+EXPOSE 3000
-# SPA mode — all routes fallback to index.html
-CMD sh -c "serve -s -l ${PORT} dist"
+# SPA mode for app routes only. File-like paths never fall back to index.html.
+CMD ["node", "server.mjs"]
diff --git a/apps/app/index.html b/apps/app/index.html
index 5434daf8..72b9b0d6 100644
--- a/apps/app/index.html
+++ b/apps/app/index.html
@@ -8,25 +8,37 @@
+
+ content="Walrus Memory is portable memory for reliable AI agents across apps and sessions." />
+
+
+
-
-
-
+
+
+
+
+
+
+
+
+
+
-
-
-
+
+
+
+
-
') ||
+ !missingCacheControl.includes('no-store') ||
+ missingContentType.includes('text/html')
+ ) {
+ throw new Error(
+ `missing asset fallback is unsafe: ${missingAsset.status} ${missingContentType} ${missingCacheControl}`,
+ )
+ }
+
+ console.log('[verify-static-server] static server returns real assets and no-store 404s for missing assets')
+} finally {
+ stopServer()
+}
diff --git a/apps/app/server.mjs b/apps/app/server.mjs
new file mode 100644
index 00000000..30956d8c
--- /dev/null
+++ b/apps/app/server.mjs
@@ -0,0 +1,167 @@
+import { createReadStream } from 'node:fs'
+import { stat } from 'node:fs/promises'
+import { createServer } from 'node:http'
+import path from 'node:path'
+import { fileURLToPath } from 'node:url'
+
+const appDir = path.dirname(fileURLToPath(import.meta.url))
+const distDir = path.resolve(appDir, 'dist')
+const distPrefix = `${distDir}${path.sep}`
+const port = Number(process.env.PORT || 4173)
+const host = process.env.HOST || '0.0.0.0'
+
+const contentTypes = new Map([
+ ['.css', 'text/css; charset=utf-8'],
+ ['.gif', 'image/gif'],
+ ['.html', 'text/html; charset=utf-8'],
+ ['.ico', 'image/x-icon'],
+ ['.jpeg', 'image/jpeg'],
+ ['.jpg', 'image/jpeg'],
+ ['.js', 'application/javascript; charset=utf-8'],
+ ['.json', 'application/json; charset=utf-8'],
+ ['.map', 'application/json; charset=utf-8'],
+ ['.png', 'image/png'],
+ ['.svg', 'image/svg+xml; charset=utf-8'],
+ ['.ttf', 'font/ttf'],
+ ['.wasm', 'application/wasm'],
+ ['.webmanifest', 'application/manifest+json; charset=utf-8'],
+ ['.webp', 'image/webp'],
+ ['.woff', 'font/woff'],
+ ['.woff2', 'font/woff2'],
+])
+
+const fileLikeRequestPattern = /\/[^/?#]+\.[^/?#]+$/
+
+function cacheControlFor(pathname, servingIndex) {
+ if (servingIndex) {
+ return 'no-store'
+ }
+
+ if (pathname.startsWith('/assets/')) {
+ return 'public, max-age=31536000, immutable'
+ }
+
+ if (pathname.startsWith('/fonts/')) {
+ return 'public, max-age=86400, must-revalidate'
+ }
+
+ return 'public, max-age=300, must-revalidate'
+}
+
+function sendText(res, statusCode, body, cacheControl = 'no-store') {
+ res.writeHead(statusCode, {
+ 'Cache-Control': cacheControl,
+ 'Content-Type': 'text/plain; charset=utf-8',
+ 'X-Content-Type-Options': 'nosniff',
+ })
+ res.end(body)
+}
+
+function resolveDistPath(pathname) {
+ const relativePath = pathname.replace(/^\/+/, '')
+ const resolved = path.resolve(distDir, relativePath)
+
+ if (resolved !== distDir && !resolved.startsWith(distPrefix)) {
+ return null
+ }
+
+ return resolved
+}
+
+async function serveFile(req, res, filePath, pathname, servingIndex = false) {
+ const fileStat = await stat(filePath)
+ if (!fileStat.isFile()) {
+ return false
+ }
+
+ const ext = path.extname(filePath).toLowerCase()
+ const contentType = contentTypes.get(ext) || 'application/octet-stream'
+
+ res.writeHead(200, {
+ 'Accept-Ranges': 'bytes',
+ 'Cache-Control': cacheControlFor(pathname, servingIndex),
+ 'Content-Length': fileStat.size,
+ 'Content-Type': contentType,
+ 'X-Content-Type-Options': 'nosniff',
+ })
+
+ if (req.method === 'HEAD') {
+ res.end()
+ return true
+ }
+
+ createReadStream(filePath)
+ .on('error', () => {
+ if (!res.headersSent) {
+ sendText(res, 500, 'Internal server error')
+ } else {
+ res.destroy()
+ }
+ })
+ .pipe(res)
+
+ return true
+}
+
+const server = createServer(async (req, res) => {
+ if (!['GET', 'HEAD'].includes(req.method || '')) {
+ res.writeHead(405, {
+ 'Allow': 'GET, HEAD',
+ 'Cache-Control': 'no-store',
+ 'Content-Type': 'text/plain; charset=utf-8',
+ 'X-Content-Type-Options': 'nosniff',
+ })
+ res.end('Method not allowed')
+ return
+ }
+
+ let pathname
+ try {
+ pathname = decodeURIComponent(new URL(req.url || '/', 'http://localhost').pathname)
+ } catch {
+ sendText(res, 400, 'Bad request')
+ return
+ }
+
+ if (pathname.includes('\0')) {
+ sendText(res, 400, 'Bad request')
+ return
+ }
+
+ const staticPath = resolveDistPath(pathname)
+ if (!staticPath) {
+ sendText(res, 403, 'Forbidden')
+ return
+ }
+
+ try {
+ if (await serveFile(req, res, staticPath, pathname)) {
+ return
+ }
+ } catch (error) {
+ if (error?.code !== 'ENOENT') {
+ console.error('[static-server] failed to serve file', { pathname, error })
+ sendText(res, 500, 'Internal server error')
+ return
+ }
+ }
+
+ if (fileLikeRequestPattern.test(pathname)) {
+ sendText(res, 404, 'Not found')
+ return
+ }
+
+ const indexPath = path.join(distDir, 'index.html')
+ try {
+ if (!(await serveFile(req, res, indexPath, pathname, true))) {
+ sendText(res, 500, 'Internal server error')
+ }
+ } catch (error) {
+ console.error('[static-server] failed to serve SPA fallback', { pathname, error })
+ sendText(res, 500, 'Internal server error')
+ }
+})
+
+server.listen(port, host, () => {
+ console.log(`[static-server] serving ${distDir} on http://${host}:${port}`)
+})
diff --git a/apps/app/src/App.tsx b/apps/app/src/App.tsx
index af9c7a2c..8240b039 100644
--- a/apps/app/src/App.tsx
+++ b/apps/app/src/App.tsx
@@ -10,6 +10,7 @@ import {
createNetworkConfig,
SuiClientProvider,
WalletProvider,
+ useAutoConnectWallet,
useCurrentAccount,
useDisconnectWallet,
useSuiClientContext,
@@ -196,24 +197,38 @@ function RegisterEnokiWallets() {
// App content — route based on auth + key state
// ============================================================
+function RoutePending() {
+ return (
+
+

+
+ )
+}
+
function AppContent() {
const currentAccount = useCurrentAccount()
+ const autoConnectStatus = useAutoConnectWallet()
const { delegateKey } = useDelegateKey()
+ const authPending = autoConnectStatus === 'idle'
+
+ const requireAccount = (element: React.ReactNode) => {
+ if (authPending) return
+ return currentAccount ? element :
+ }
return (
- } />
- :
+ :
+ currentAccount ? :
} />
- :
+ )} />
+ :
- } />
- :
+ )} />
+ :
- } />
+ )} />
} />
} />
diff --git a/apps/app/src/components/Card.tsx b/apps/app/src/components/Card.tsx
new file mode 100644
index 00000000..d6672b1c
--- /dev/null
+++ b/apps/app/src/components/Card.tsx
@@ -0,0 +1,60 @@
+import type { CSSProperties, ReactNode } from 'react'
+
+interface CardProps {
+ /** Extra class(es) appended to the base `card` class (e.g. `dashboard-keys-card`, `demo-step`). */
+ className?: string
+ style?: CSSProperties
+ title?: ReactNode
+ subtitle?: ReactNode
+ /** Right-aligned header content (toggles, action buttons, etc.). */
+ action?: ReactNode
+ /** Content rendered before the title group (e.g. a step badge). */
+ leading?: ReactNode
+ /** When `leading` is set, the leading + title group are wrapped in a row with this class. */
+ leadingRowClassName?: string
+ children?: ReactNode
+}
+
+/**
+ * Shared card shell used across the Dashboard and Playground.
+ * Renders the same DOM the pages used inline (`.card` > `.card-header` > title group + action),
+ * so existing CSS applies unchanged while keeping padding/margin/radius consistent in one place.
+ */
+export function Card({
+ className,
+ style,
+ title,
+ subtitle,
+ action,
+ leading,
+ leadingRowClassName,
+ children,
+}: CardProps) {
+ const titleGroup = title != null || subtitle != null ? (
+
+ {title != null &&
{title}
}
+ {subtitle != null &&
{subtitle}
}
+
+ ) : null
+
+ const headerLeft = leading != null ? (
+
+ {leading}
+ {titleGroup}
+
+ ) : titleGroup
+
+ const hasHeader = title != null || subtitle != null || action != null || leading != null
+
+ return (
+
+ {hasHeader && (
+
+ {headerLeft}
+ {action}
+
+ )}
+ {children}
+
+ )
+}
diff --git a/apps/app/src/config.ts b/apps/app/src/config.ts
index 5ec70054..0ef49285 100644
--- a/apps/app/src/config.ts
+++ b/apps/app/src/config.ts
@@ -1,6 +1,15 @@
/**
* App-wide configuration from environment variables
*/
+const DEFAULT_ANALYTICS_ALLOWED_HOSTS = 'walrus.xyz,www.walrus.xyz'
+
+function parseCsv(value: string | undefined, fallback = '') {
+ return (value || fallback)
+ .split(',')
+ .map(s => s.trim())
+ .filter(Boolean)
+}
+
export const config = {
enokiApiKey: import.meta.env.VITE_ENOKI_API_KEY as string || '',
googleClientId: import.meta.env.VITE_GOOGLE_CLIENT_ID as string || '',
@@ -14,7 +23,19 @@ export const config = {
.split(',').map(s => s.trim()).filter(Boolean) as string[],
sidecarUrl: import.meta.env.VITE_SIDECAR_URL as string || 'http://localhost:9000',
docsUrl: import.meta.env.VITE_DOCS_URL as string || '',
+ gtmContainerId: import.meta.env.VITE_GTM_CONTAINER_ID as string || '',
gaMeasurementId: import.meta.env.VITE_GA_MEASUREMENT_ID as string || '',
+ posthogProjectApiKey: (
+ (import.meta.env.VITE_POSTHOG_PROJECT_API_KEY as string | undefined) ||
+ (import.meta.env.VITE_POSTHOG_KEY as string | undefined) ||
+ ''
+ ),
+ posthogHost: import.meta.env.VITE_POSTHOG_HOST as string || 'https://t.walrus.xyz',
+ posthogUiHost: import.meta.env.VITE_POSTHOG_UI_HOST as string || 'https://us.posthog.com',
+ analyticsAllowedHosts: parseCsv(
+ import.meta.env.VITE_ANALYTICS_ALLOWED_HOSTS as string | undefined,
+ DEFAULT_ANALYTICS_ALLOWED_HOSTS,
+ ),
demoUrls: (import.meta.env.VITE_DEMO_URLS as string || '')
.split(',').map(s => s.trim()).filter(Boolean)
.map(entry => {
diff --git a/apps/app/src/index.css b/apps/app/src/index.css
index 2dae54f2..26215f89 100644
--- a/apps/app/src/index.css
+++ b/apps/app/src/index.css
@@ -7,6 +7,7 @@
font-display: swap;
}
+
:root {
--bg-primary: #FAF8F5;
--bg-secondary: #F5F3F0;
@@ -29,6 +30,7 @@
--color-violet-soft: rgba(202, 177, 255, 0.30);
--color-yellow-soft: rgba(232, 255, 117, 0.45);
--gradient-brand: linear-gradient(135deg, #CAB1FF, #E8FF75);
+ --wordmark-memory-gradient: linear-gradient(90deg, #575cff 0%, #8771ff 50%, #cd91ff 100%);
--success: #166534;
--success-border: #22c55e;
@@ -86,7 +88,7 @@ body,
body {
background-image: none;
- overflow-x: hidden;
+ overflow-x: clip;
}
h1, h2, h3 {
@@ -100,8 +102,36 @@ h1, h2, h3 {
display: flex;
flex-direction: column;
position: relative;
- background: linear-gradient(180deg, #CAB1FF 0%, #E8FF75 100%);
+ background: #000000;
+ min-height: 100vh;
+}
+
+.wm-route-pending {
min-height: 100vh;
+ min-height: 100dvh;
+ display: grid;
+ place-items: center;
+ background: #000000;
+}
+
+.wm-route-pending img {
+ width: 137px;
+ height: auto;
+ opacity: 0.82;
+ animation: wmRoutePendingBreathe 1.4s ease-in-out infinite;
+}
+
+@keyframes wmRoutePendingBreathe {
+ 0%,
+ 100% {
+ opacity: 0.62;
+ transform: translateY(0) scale(0.98);
+ }
+
+ 50% {
+ opacity: 1;
+ transform: translateY(-2px) scale(1);
+ }
}
/* Floating Docs Button */
@@ -181,12 +211,36 @@ h1, h2, h3 {
font-weight: 700;
font-size: 1.15rem;
letter-spacing: -0.02em;
+ color: inherit;
+ text-decoration: none;
}
.nav-brand span {
color: var(--text-primary);
}
+.walrus-memory-wordmark {
+ display: inline-flex;
+ flex-direction: column;
+ line-height: 0.86;
+ font-size: 1.35rem;
+ font-weight: 900;
+ letter-spacing: 0;
+ text-transform: lowercase;
+ color: #000000;
+}
+
+.walrus-memory-wordmark span:first-child {
+ color: currentColor;
+}
+
+.walrus-memory-wordmark span:last-child {
+ color: transparent;
+ background: var(--wordmark-memory-gradient);
+ -webkit-background-clip: text;
+ background-clip: text;
+}
+
.nav-user {
display: flex;
align-items: center;
@@ -662,6 +716,33 @@ h1, h2, h3 {
flex-wrap: wrap;
}
+.lp-legal-copy {
+ margin: 16px 0 28px !important;
+ color: rgba(0, 0, 0, 0.62) !important;
+ font-size: 0.82rem !important;
+ line-height: 1.5 !important;
+}
+
+.lp-trusted-copy {
+ display: flex;
+ flex-wrap: wrap;
+ align-items: center;
+ gap: 10px 14px;
+ max-width: 560px;
+ color: rgba(0, 0, 0, 0.58);
+ font-size: 0.8rem;
+ line-height: 1.4;
+}
+
+.lp-trusted-copy span {
+ flex: 1 0 100%;
+}
+
+.lp-trusted-copy strong {
+ color: #000000;
+ font-weight: 700;
+}
+
.lp-btn-yellow {
background: #E8FF75;
color: #000000;
@@ -999,7 +1080,7 @@ h1, h2, h3 {
.dashboard-header h2 {
font-size: 1.5rem;
font-weight: 800;
- letter-spacing: -0.03em;
+ letter-spacing: 0;
margin-bottom: 6px;
color: #000000;
}
@@ -1312,6 +1393,255 @@ h1, h2, h3 {
box-shadow: 1px 1px 0 #000000;
}
+/* ========== Setup classic flow ========== */
+
+.app:has(.setup-classic) {
+ background: #000000;
+ color: #faf8f5;
+}
+
+.setup-classic {
+ min-height: 100vh;
+ background:
+ radial-gradient(circle at 50% 0%, rgba(232, 255, 117, 0.08), transparent 36%),
+ #000000;
+ color: #faf8f5;
+}
+
+.setup-classic-nav {
+ background: #000000;
+ border-bottom: 1px solid rgba(250, 248, 245, 0.1);
+}
+
+.setup-classic-nav .walrus-memory-wordmark,
+.playground-nav .walrus-memory-wordmark {
+ color: #faf8f5;
+}
+
+.setup-classic-nav .walrus-memory-wordmark span:last-child,
+.playground-nav .walrus-memory-wordmark span:last-child {
+ color: transparent;
+ background: var(--wordmark-memory-gradient);
+ -webkit-background-clip: text;
+ background-clip: text;
+}
+
+.setup-classic-nav .nav-address {
+ background: #262b30;
+ color: #faf8f5;
+}
+
+.setup-classic-nav .lp-nav-cta {
+ background: #faf8f5;
+ color: #000000;
+ border: 1px solid #faf8f5;
+ box-shadow: none;
+}
+
+.setup-classic-nav .lp-nav-cta:hover {
+ background: #e8ff75;
+ border-color: #e8ff75;
+ transform: translateY(-1px);
+ box-shadow: none;
+}
+
+.setup-classic-container {
+ min-height: calc(100vh - 72px);
+ padding: 58px 24px 88px;
+ display: flex;
+ align-items: flex-start;
+ justify-content: center;
+}
+
+.setup-classic-panel {
+ width: min(520px, 100%);
+ margin: 0 auto;
+}
+
+.setup-classic-intro {
+ text-align: center;
+}
+
+.setup-classic-title {
+ margin: 0 0 12px;
+ color: #faf8f5;
+ font-size: 1.6rem;
+ font-weight: 700;
+ letter-spacing: 0;
+ line-height: 1.1;
+}
+
+.setup-classic-description {
+ margin: 0 0 32px;
+ color: #c7c5c1;
+ line-height: 1.6;
+}
+
+.setup-classic-feature-card {
+ margin-bottom: 24px;
+ text-align: left;
+ background: #0a0a0a;
+ border: 1px solid #54575a;
+ border-radius: 12px;
+ box-shadow: none;
+ color: #faf8f5;
+}
+
+.setup-classic-feature {
+ display: flex;
+ gap: 12px;
+ margin-bottom: 16px;
+}
+
+.setup-classic-feature:last-child {
+ margin-bottom: 0;
+}
+
+.setup-classic-feature strong {
+ color: #faf8f5;
+ font-size: 0.9rem;
+ font-weight: 700;
+}
+
+.setup-classic-feature p {
+ margin: 4px 0 0;
+ color: #8f9294;
+ font-size: 0.8rem;
+ line-height: 1.35;
+}
+
+.setup-classic-generate {
+ margin: 0 auto;
+ background: #faf8f5;
+ color: #000000;
+ border: 1px solid #faf8f5;
+ border-radius: 999px;
+ box-shadow: none;
+}
+
+.setup-classic-generate:hover {
+ background: #e8ff75;
+ border-color: #e8ff75;
+ transform: translateY(-1px);
+ box-shadow: none;
+}
+
+.setup-classic-divider {
+ margin: 28px 0 18px;
+ color: #8f9294;
+ font-size: 0.78rem;
+ text-align: center;
+}
+
+.setup-classic-import {
+ text-align: left;
+}
+
+.setup-classic .setup-import-textarea {
+ min-height: 88px;
+ font-family: var(--font-mono);
+ resize: vertical;
+ background: #050505;
+ color: #faf8f5;
+ border: 1px solid #54575a;
+ box-shadow: none;
+}
+
+.setup-classic .setup-import-textarea:focus {
+ border-color: #e8ff75;
+ box-shadow: 0 0 0 3px rgba(232, 255, 117, 0.12);
+}
+
+.setup-classic .setup-import-textarea::placeholder {
+ color: #8f9294;
+}
+
+.setup-classic .setup-import-button {
+ min-height: 46px;
+ background: #e8ff75;
+ color: #000000;
+ border: 1px solid #e8ff75;
+ border-radius: 999px;
+ box-shadow: none;
+}
+
+.setup-classic .setup-import-button:hover:not(:disabled) {
+ transform: translateY(-1px);
+ box-shadow: none;
+}
+
+.setup-classic .setup-import-button:active:not(:disabled) {
+ transform: translateY(0);
+ box-shadow: none;
+}
+
+/* Key-generated step: match the dashboard's dark credential cards
+ (the base .key-display is light #fff; setup is dark-themed so override).
+ Values mirror `.dash-page .key-display--white` so /setup and /dashboard
+ read as the same component. */
+.setup-classic .key-display {
+ background: rgba(255, 255, 255, 0.08);
+ border: 1px solid var(--dash-card-border, #2a2d2f);
+ border-radius: 16px;
+ box-shadow: none;
+}
+
+.setup-classic .key-display .key-label {
+ color: #e8ff75;
+}
+
+.setup-classic .key-display .key-value {
+ color: #faf8f5;
+}
+
+.setup-classic .key-display .btn-secondary {
+ background: rgba(255, 255, 255, 0.12);
+ border: 1px solid rgba(255, 255, 255, 0.16);
+ color: #faf8f5;
+ box-shadow: none;
+ transition: background 0.12s ease, border-color 0.12s ease;
+}
+
+.setup-classic .key-display .btn-secondary:hover:not(:disabled) {
+ background: rgba(255, 255, 255, 0.24);
+ border-color: rgba(255, 255, 255, 0.34);
+ transform: none;
+ box-shadow: none;
+}
+
+/* Warning box: match the dashboard's lime-filled treatment (the light-theme
+ base was cream + orange border, which looked off on the dark setup page). */
+.setup-classic .warning-box {
+ background: #e8ff75;
+ border: 0;
+ border-radius: 12px;
+ box-shadow: none;
+}
+
+.setup-classic .warning-box p,
+.setup-classic .warning-box strong {
+ color: #000000;
+}
+
+@media (max-width: 640px) {
+ .setup-classic-nav {
+ padding: 0 20px;
+ }
+
+ .setup-classic-container {
+ min-height: calc(100vh - 72px);
+ padding: 42px 18px 72px;
+ }
+
+ .setup-classic-title {
+ font-size: 1.35rem;
+ }
+
+ .setup-classic-feature-card {
+ padding: 22px 20px;
+ }
+}
+
/* ========== Spinner ========== */
.spinner {
@@ -1790,3 +2120,9125 @@ h1, h2, h3 {
gap: 20px;
}
}
+
+/* ========== Walrus Memory Figma dashboard rebuild ========== */
+
+.dash-page {
+ --bg-secondary: #101418;
+ --bg-card: #000000;
+ --bg-card-hover: rgba(255, 255, 255, 0.08);
+ --text-primary: #faf8f5;
+ --text-secondary: #c7c5c1;
+ --text-muted: #8f9294;
+ --border: 1px solid #54575a;
+ --border-light: 1px solid rgba(250, 248, 245, 0.12);
+ min-height: 100vh;
+ overflow-x: clip;
+ background: #000000;
+ color: #faf8f5;
+}
+
+.dash-nav {
+ min-height: 128px;
+ padding: 34px 49px 0;
+ background: #000000;
+}
+
+.dash-nav-inner {
+ width: 100%;
+ max-width: 1342px;
+ margin: 0 auto;
+ display: flex;
+ align-items: flex-start;
+ justify-content: space-between;
+ gap: 24px;
+}
+
+.dash-logo {
+ display: grid;
+ width: fit-content;
+ gap: 0;
+ text-decoration: none;
+ text-transform: lowercase;
+ font-size: 1.72rem;
+ font-weight: 850;
+ line-height: 0.76;
+ letter-spacing: 0;
+}
+
+.dash-logo span:first-child {
+ color: #faf8f5;
+}
+
+.dash-logo span:last-child {
+ color: transparent;
+ font-weight: 500;
+ background: var(--wordmark-memory-gradient);
+ -webkit-background-clip: text;
+ background-clip: text;
+}
+
+.dash-nav-actions {
+ display: flex;
+ align-items: center;
+ gap: 22px;
+}
+
+.dash-address {
+ min-height: 28px;
+ display: inline-flex;
+ align-items: center;
+ padding: 0 12px;
+ border-radius: 4px;
+ background: #262b30;
+ color: #faf8f5;
+ font-family: var(--font-mono);
+ font-size: 12px;
+ font-weight: 500;
+ line-height: 0.84;
+ letter-spacing: 0.6px;
+ white-space: nowrap;
+}
+
+.dash-outline-button {
+ min-height: 52px;
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ gap: 10px;
+ padding: 0 28px;
+ border: 1px solid #faf8f5;
+ border-radius: 999px;
+ background: #000000;
+ color: #faf8f5;
+ font-family: var(--font-sans);
+ font-size: 1.04rem;
+ font-weight: 500;
+ line-height: 1;
+ cursor: pointer;
+ transition: background 0.16s ease, color 0.16s ease, transform 0.16s ease;
+}
+
+.dash-outline-button:hover {
+ background: #faf8f5;
+ color: #000000;
+ transform: translateY(-1px);
+}
+
+.dash-shell {
+ width: min(1240px, calc(100% - 48px));
+ margin: 0 auto;
+ padding: 75px 0 96px;
+ display: flex;
+ flex-direction: column;
+}
+
+.dash-page .dashboard-header {
+ order: 0;
+ margin-bottom: 40px;
+}
+
+.dash-page .dashboard-header--compact {
+ margin-bottom: 28px;
+}
+
+.dash-page .dashboard-header h2 {
+ margin: 0 0 14px;
+ color: #faf8f5;
+ font-size: clamp(3.05rem, 4vw, 3.32rem);
+ font-weight: 520;
+ line-height: 0.88;
+ letter-spacing: 0;
+}
+
+.dash-page .dashboard-header--compact h2 {
+ margin-bottom: 0;
+}
+
+.dash-page .dashboard-header p {
+ max-width: 923px;
+ color: #8f9294;
+ font-size: 1.24rem;
+ font-weight: 500;
+ line-height: 1.3;
+}
+
+.dash-alert {
+ order: 1;
+ min-height: 65px;
+ position: relative;
+ display: flex;
+ align-items: center;
+ margin-bottom: 48px !important;
+ padding: 16px 24px 16px 68px;
+ border-radius: 4px;
+ background: #e8ff75;
+ color: #000000;
+}
+
+.dash-alert::before {
+ content: "!";
+ position: absolute;
+ left: 28px;
+ top: 50%;
+ width: 19px;
+ height: 19px;
+ display: grid;
+ place-items: center;
+ border: 1.5px solid #000000;
+ border-radius: 50%;
+ color: #000000;
+ font-size: 0.82rem;
+ font-weight: 800;
+ line-height: 1;
+ transform: translateY(-50%);
+}
+
+.dash-alert p {
+ margin: 0;
+ color: #000000;
+ font-size: 1.24rem;
+ font-weight: 500;
+ line-height: 1.3;
+}
+
+.dash-page .dashboard-cta-row {
+ order: 2;
+ grid-template-columns: repeat(2, minmax(0, 1fr));
+ gap: 30px;
+ margin-bottom: 54px;
+}
+
+.dash-page .dashboard-cta-row > :only-child {
+ grid-column: 1 / -1;
+}
+
+.dash-page .dashboard-cta {
+ min-height: 114px;
+ margin: 0;
+ padding: 25px 29px;
+ border: 1px solid rgba(250, 248, 245, 0.1);
+ border-radius: 24px;
+ background: rgba(255, 255, 255, 0.08);
+ box-shadow: none;
+ color: #faf8f5;
+ transition: background 0.16s ease, transform 0.16s ease, border-color 0.16s ease;
+}
+
+.dash-page .dashboard-cta:hover {
+ transform: translateY(-2px);
+ border-color: rgba(250, 248, 245, 0.22);
+ background: rgba(255, 255, 255, 0.12);
+ box-shadow: none;
+}
+
+.dash-page .dashboard-cta:active {
+ transform: translateY(0);
+ box-shadow: none;
+}
+
+.dash-page .dashboard-cta > div:first-child {
+ min-width: 0;
+ display: grid;
+ grid-template-columns: 40px minmax(0, 1fr);
+ column-gap: 19px;
+ row-gap: 3px;
+ align-items: start;
+}
+
+.dash-page .dashboard-cta-icon {
+ grid-row: 1 / 3;
+ margin-top: 2px;
+ color: #8f9294;
+}
+
+.dash-page .dashboard-cta-title {
+ color: #faf8f5;
+ font-size: 1.42rem;
+ font-weight: 750;
+ line-height: 1.28;
+}
+
+.dash-page .dashboard-cta-subtitle {
+ color: #c7c5c1;
+ font-size: 1.06rem;
+ font-weight: 500;
+ line-height: 1.35;
+}
+
+.dash-page .dashboard-cta-arrow {
+ color: #faf8f5;
+ font-size: 1.4rem;
+}
+
+.dash-page .dashboard-cta--disabled {
+ opacity: 0.7;
+}
+
+.dash-page .card {
+ width: 100%;
+ margin-bottom: 36px !important;
+ padding: 40px;
+ border: 1px solid #54575a;
+ border-radius: 24px;
+ background: #000000;
+ box-shadow: none;
+ color: #faf8f5;
+}
+
+.dash-page .card:hover {
+ box-shadow: none;
+}
+
+.dash-page .dashboard-keys-card {
+ order: 4;
+ min-height: 277px;
+ margin-bottom: 36px !important;
+}
+
+.dash-page .dashboard-keys-card .card-title {
+ font-size: 2.25rem;
+ font-weight: 500;
+ line-height: 0.88;
+ color: #faf8f5;
+}
+
+.dash-page .dashboard-quickstart-card {
+ order: 5;
+ min-height: 572px;
+ margin-bottom: 36px !important;
+}
+
+.dash-page .dashboard-quickstart-card .card-header {
+ margin-bottom: 25px;
+}
+
+.dash-page .dashboard-install-card {
+ order: 6;
+ min-height: 222px;
+}
+
+.dash-page .dashboard-credentials-card {
+ order: 3;
+}
+
+.dash-page .card-header {
+ align-items: flex-start;
+ margin-bottom: 30px;
+}
+
+.dash-page .card-title {
+ color: #faf8f5;
+ font-size: 2.12rem;
+ font-weight: 520;
+ line-height: 0.9;
+ letter-spacing: 0;
+ text-transform: none;
+}
+
+.dash-page .card-subtitle {
+ max-width: 820px;
+ margin-top: 12px;
+ color: #8f9294;
+ font-size: 1.06rem;
+ font-weight: 500;
+ line-height: 1.3;
+}
+
+.dash-page .card-header-actions {
+ align-items: center;
+ gap: 12px;
+}
+
+.dash-page .btn,
+.dash-page .lp-nav-cta {
+ border-radius: 999px;
+ box-shadow: none;
+ font-weight: 600;
+ text-transform: none;
+ transition: background 0.16s ease, color 0.16s ease, transform 0.16s ease, border-color 0.16s ease;
+}
+
+.dash-page .btn:hover:not(:disabled),
+.dash-page .lp-nav-cta:hover:not(:disabled) {
+ transform: translateY(-1px);
+ box-shadow: none;
+}
+
+.dash-page .btn-secondary {
+ border: 1px solid #faf8f5;
+ background: #000000;
+ color: #faf8f5;
+}
+
+.dash-page .btn-secondary:hover:not(:disabled) {
+ background: #faf8f5;
+ color: #000000;
+}
+
+.dash-page .btn-primary,
+.dash-page .lp-nav-cta {
+ min-height: 52px;
+ padding: 0 30px;
+ border: 1px solid #faf8f5;
+ background: #faf8f5;
+ color: #000000;
+}
+
+.dash-page .dashboard-keys-add {
+ gap: 10px;
+ border-radius: 26px;
+ font-size: 1.06rem;
+ font-weight: 500;
+ line-height: 0.84;
+ letter-spacing: 0.72px;
+ white-space: nowrap;
+}
+
+.dash-page .dashboard-keys-add svg {
+ width: 12.15px;
+ height: 12.15px;
+ stroke-width: 1.8;
+}
+
+.dash-page .btn-primary:disabled,
+.dash-page .lp-nav-cta:disabled {
+ border-color: #54575a;
+ background: #262b30;
+ color: #8f9294;
+}
+
+.dash-page .btn-danger {
+ border: 1px solid rgba(248, 113, 113, 0.5);
+ background: rgba(248, 113, 113, 0.1);
+ color: #ff8f8f;
+}
+
+.dash-page .btn-sm {
+ min-height: 40px;
+ padding: 0 18px;
+ font-size: 0.86rem;
+}
+
+.dash-page .warning-box {
+ border: 0;
+ border-radius: 4px;
+ background: #e8ff75;
+ box-shadow: none;
+}
+
+.dash-page .warning-box p {
+ color: #000000;
+}
+
+.dash-page .dashboard-empty-message {
+ min-height: 88px;
+ display: grid;
+ place-items: center;
+ padding: 37px 0 !important;
+ color: #8f9294 !important;
+ font-size: 1.06rem !important;
+ line-height: 1.3;
+}
+
+.dash-page .key-display {
+ border: 1px solid #54575a;
+ border-radius: 16px;
+ background: #050505;
+ box-shadow: none;
+ color: #faf8f5;
+}
+
+.dash-page .key-display--white {
+ background: #050505;
+}
+
+.dash-page .key-display .key-label {
+ color: #8f9294;
+}
+
+.dash-page .key-display .key-value {
+ color: #faf8f5;
+}
+
+.dash-page .demo-code-block {
+ border: 1px solid #54575a;
+ border-radius: 24px;
+ background: #000000 !important;
+ box-shadow: none;
+ color: #faf8f5;
+ font-size: 0.86rem;
+ line-height: 1.48;
+}
+
+.dash-page .demo-code-block span {
+ color: inherit;
+}
+
+.dash-page .dashboard-quickstart-card .demo-code-block {
+ min-height: 385px;
+}
+
+.dash-page .install-tabs {
+ display: flex;
+ gap: 10px;
+ margin-bottom: 18px;
+ overflow: visible;
+}
+
+.dash-page .install-tab,
+.dash-page .install-tab:last-child {
+ width: 72px;
+ min-height: 30px;
+ padding: 0 12px;
+ border: 0;
+ border-radius: 4px;
+ background: #1d2227;
+ color: #8f9294;
+ box-shadow: none;
+ font-size: 0.82rem;
+}
+
+.dash-page .install-tab:hover {
+ background: #262b30;
+ color: #faf8f5;
+}
+
+.dash-page .install-tab--active {
+ background: #faf8f5;
+ color: #000000;
+}
+
+.dash-page .install-command {
+ border: 0;
+ border-radius: 0;
+ padding: 0;
+ background: transparent !important;
+ font-weight: 700;
+}
+
+@media (max-width: 760px) {
+ .dash-nav {
+ min-height: 104px;
+ padding: 24px 18px 0;
+ }
+
+ .dash-nav-inner {
+ align-items: flex-start;
+ flex-direction: column;
+ gap: 18px;
+ }
+
+ .dash-nav-actions {
+ width: 100%;
+ justify-content: space-between;
+ gap: 12px;
+ }
+
+ .dash-address {
+ min-width: 0;
+ max-width: 48vw;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ }
+
+ .dash-outline-button {
+ min-height: 46px;
+ padding: 0 20px;
+ font-size: 0.96rem;
+ }
+
+ .dash-shell {
+ width: calc(100% - 32px);
+ padding: 86px 0 64px;
+ }
+
+ .dash-page .dashboard-header {
+ margin-bottom: 24px;
+ }
+
+ .dash-page .dashboard-header h2 {
+ font-size: 2.45rem;
+ }
+
+ .dash-page .dashboard-header p,
+ .dash-alert p {
+ font-size: 1rem;
+ }
+
+ .dash-alert {
+ margin-bottom: 28px !important;
+ padding: 16px 18px 16px 56px;
+ }
+
+ .dash-alert::before {
+ left: 21px;
+ }
+
+ .dash-page .dashboard-cta-row {
+ grid-template-columns: 1fr;
+ gap: 16px;
+ margin-bottom: 28px;
+ }
+
+ .dash-page .dashboard-cta {
+ min-height: 112px;
+ padding: 22px;
+ border-radius: 20px;
+ }
+
+ .dash-page .dashboard-cta-title {
+ font-size: 1.18rem;
+ }
+
+ .dash-page .dashboard-cta-subtitle {
+ font-size: 0.94rem;
+ }
+
+ .dash-page .dashboard-cta-arrow {
+ display: block;
+ }
+
+ .dash-page .card {
+ padding: 24px;
+ border-radius: 20px;
+ }
+
+ .dash-page .card-header {
+ gap: 18px;
+ }
+
+ .dash-page .card-title {
+ font-size: 1.62rem;
+ }
+
+ .dash-page .card-subtitle {
+ font-size: 0.96rem;
+ }
+
+ .dash-page .card-header-actions {
+ width: 100%;
+ display: grid;
+ grid-template-columns: 1fr;
+ }
+
+ .dash-page .card-header-actions .btn,
+ .dash-page .card-header-actions .lp-nav-cta {
+ width: 100%;
+ }
+
+ .dash-page .dashboard-quickstart-card,
+ .dash-page .dashboard-install-card {
+ min-height: auto;
+ }
+
+ .dash-page .install-tabs {
+ display: grid;
+ grid-template-columns: repeat(2, minmax(0, 1fr));
+ }
+
+ .dash-page .install-tab,
+ .dash-page .install-tab:last-child {
+ width: auto;
+ min-height: 42px;
+ }
+}
+
+/* ========== Walrus Memory Figma marketing rebuild ========== */
+
+.wm-page {
+ --wm-black: #000000;
+ --wm-ink: #050505;
+ --wm-white: #ffffff;
+ --wm-paper: #faf8f5;
+ --wm-blue: #73d7ff;
+ --wm-lime: #e8ff75;
+ --wm-violet: #cab1ff;
+ --wm-muted: rgba(255, 255, 255, 0.68);
+ min-height: 100vh;
+ overflow: hidden;
+ background: var(--wm-black);
+ color: var(--wm-white);
+ font-weight: 400;
+}
+
+.wm-page a {
+ color: inherit;
+ text-decoration: none;
+}
+
+.wm-page button {
+ font: inherit;
+}
+
+.wm-nav {
+ width: min(1344px, calc(100% - 96px));
+ min-height: 52px;
+ margin: 28px auto 0;
+ padding: 0;
+ display: grid;
+ grid-template-columns: 1fr auto 1fr;
+ align-items: center;
+ gap: 18px;
+ position: relative;
+ z-index: 20;
+}
+
+.wm-logo {
+ display: grid;
+ width: fit-content;
+ gap: 0;
+ font-size: 2.08rem;
+ font-weight: 800;
+ line-height: 0.74;
+ text-transform: lowercase;
+ letter-spacing: 0;
+ transform: none;
+}
+
+.wm-logo span:first-child {
+ color: var(--wm-white);
+}
+
+.wm-logo span:last-child {
+ font-weight: 500;
+ background: linear-gradient(100deg, #2368ff 0%, #7248ff 48%, #ee79ff 100%);
+ -webkit-background-clip: text;
+ background-clip: text;
+ color: transparent;
+}
+
+.wm-nav-links {
+ justify-self: center;
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ gap: 0;
+ color: #faf8f5;
+ font-size: 18px;
+ font-weight: 500;
+ line-height: 0.84;
+ letter-spacing: 0.72px;
+}
+
+.wm-nav-links a,
+.wm-nav-link-button {
+ min-height: 52px;
+ color: #faf8f5;
+ background: transparent;
+ border: 0;
+ border-radius: 26px;
+ cursor: pointer;
+ display: inline-flex;
+ align-items: center;
+ gap: 7px;
+ padding: 0 30px;
+}
+
+.wm-nav-links a:hover,
+.wm-nav-link-button:hover {
+ color: var(--wm-white);
+}
+
+.wm-login {
+ justify-self: end;
+ position: relative;
+}
+
+.wm-page .wm-docs-button,
+.wm-page .wm-start-button,
+.wm-page .wm-small-cta {
+ border: 1px solid rgba(250, 248, 245, 0.16);
+ cursor: pointer;
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ gap: 10px;
+ border-radius: 999px;
+ background: rgba(250, 248, 245, 0.04);
+ color: var(--wm-white);
+ font-size: 1rem;
+ font-weight: 500;
+ min-height: 46px;
+ padding: 0 23px;
+ transition: transform 180ms ease, background 180ms ease;
+}
+
+.wm-page .wm-docs-button {
+ position: relative;
+ width: auto;
+ min-width: 200px;
+ min-height: 52px;
+ padding: 0 30px;
+ border: 2px solid #1d2227;
+ border-radius: 26px;
+ background: rgba(0, 0, 0, 0.08);
+ color: #faf8f5;
+ font-size: 18px;
+ font-weight: 500;
+ line-height: 1;
+ letter-spacing: 0.72px;
+ white-space: nowrap;
+ flex-shrink: 0;
+}
+
+.wm-page .wm-docs-button svg {
+ flex: 0 0 auto;
+}
+
+.wm-page .wm-docs-button::before {
+ content: "";
+ position: absolute;
+ top: -2px;
+ left: 32px;
+ width: 75px;
+ height: 2px;
+ background: linear-gradient(90deg, rgba(250, 248, 245, 0) 0%, #faf8f5 50%, rgba(250, 248, 245, 0) 100%);
+ pointer-events: none;
+}
+
+.wm-page .wm-docs-button:hover,
+.wm-page .wm-start-button:hover,
+.wm-page .wm-small-cta:hover {
+ transform: translateY(-2px);
+ background: rgba(250, 248, 245, 0.1);
+}
+
+.wm-menu {
+ position: absolute;
+ top: calc(100% + 10px);
+ right: 0;
+ z-index: 40;
+ min-width: 230px;
+ padding: 8px;
+ border: 1px solid rgba(255, 255, 255, 0.16);
+ border-radius: 8px;
+ background: rgba(10, 10, 10, 0.96);
+ box-shadow: 0 18px 50px rgba(0, 0, 0, 0.45);
+ backdrop-filter: blur(14px);
+}
+
+.wm-demo-dropdown {
+ position: relative;
+}
+
+.wm-demo-dropdown .wm-menu {
+ left: 50%;
+ right: auto;
+ transform: translateX(-50%);
+}
+
+.wm-page .lp-demo-item,
+.wm-page .lp-login-provider-btn,
+.wm-page .lp-login-wallet-btn [class*="ConnectButton"] button,
+.wm-page .lp-login-wallet-btn button[data-dapp-kit] {
+ width: 100%;
+ min-height: 42px;
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ gap: 10px;
+ border: 0;
+ border-radius: 8px;
+ background: transparent;
+ color: var(--wm-white);
+ padding: 0 12px;
+ font-size: 0.76rem;
+ font-weight: 800;
+ cursor: pointer;
+ box-shadow: none;
+}
+
+.wm-page .lp-demo-item:hover,
+.wm-page .lp-login-provider-btn:hover,
+.wm-page .lp-login-wallet-btn [class*="ConnectButton"] button:hover,
+.wm-page .lp-login-wallet-btn button[data-dapp-kit]:hover {
+ background: rgba(255, 255, 255, 0.1);
+}
+
+.wm-hero {
+ width: 100%;
+ min-height: 1074px;
+ margin: 0 auto;
+ padding: 105px 0 0;
+ position: relative;
+ text-align: center;
+ isolation: isolate;
+}
+
+.wm-hero::before {
+ content: none;
+}
+
+.wm-hero::after {
+ content: "";
+ position: absolute;
+ z-index: 1;
+ inset: 0;
+ background: linear-gradient(180deg, rgba(0, 0, 0, 0) 74%, #000000 100%);
+ opacity: 0.38;
+ pointer-events: none;
+}
+
+.wm-hero-bg {
+ position: absolute;
+ z-index: 1;
+ top: -41px;
+ left: calc(50% - 10px);
+ width: 1908px;
+ max-width: none;
+ height: 1406px;
+ transform: translateX(-50%);
+ pointer-events: none;
+ user-select: none;
+}
+
+.wm-hero-bg-layer {
+ position: absolute;
+ inset: 0;
+ width: 100%;
+ height: 100%;
+ max-width: none;
+ object-fit: fill;
+ object-position: bottom center;
+ pointer-events: none;
+ user-select: none;
+}
+
+.wm-hero-bg-layer--r {
+ opacity: 0.6;
+}
+
+.wm-hero-copy {
+ position: relative;
+ z-index: 3;
+ width: min(1240px, calc(100% - 36px));
+ margin: 0 auto;
+}
+
+.wm-hero h1 {
+ margin: 0 auto;
+ color: var(--wm-white);
+ font-size: 96px;
+ line-height: 0.88;
+ font-weight: 500;
+ letter-spacing: 0;
+}
+
+.wm-hero-title-line {
+ display: block;
+ width: 100%;
+}
+
+.wm-hero-title-memory {
+ display: inline-block;
+ color: #faf8f5;
+ letter-spacing: 0.96px;
+ filter: none;
+}
+
+.wm-hero-title-anywhere {
+ display: inline-block;
+ color: transparent;
+ background: linear-gradient(107.00372805169962deg, rgb(47, 92, 255) 33.936%, rgb(146, 73, 255) 49.597%, rgb(237, 160, 255) 65.872%);
+ -webkit-background-clip: text;
+ background-clip: text;
+ letter-spacing: 0.96px;
+ filter: none;
+}
+
+.wm-hero-copy p {
+ width: min(805px, 100%);
+ margin: 28px auto 32px;
+ color: #faf8f5;
+ font-size: 21px;
+ line-height: 1.3;
+ font-weight: 300;
+ letter-spacing: 0.21px;
+}
+
+.wm-hero-copy p strong {
+ color: var(--wm-white);
+ font-weight: 700;
+}
+
+.wm-page .wm-start-button {
+ min-width: 240px;
+ min-height: 64px;
+ background: var(--wm-paper);
+ color: var(--wm-black);
+ border-color: transparent;
+ font-size: 1.13rem;
+}
+
+.wm-code-panel {
+ position: relative;
+ z-index: 3;
+ width: min(940px, calc(100% - 36px));
+ height: 540px;
+ margin: 58px auto 0;
+ overflow: hidden;
+ border-radius: 10px;
+ background: linear-gradient(180deg, rgba(32, 47, 74, 0.28) 0%, rgba(12, 18, 24, 0.34) 100%);
+ box-shadow: 0 40px 140px rgba(0, 0, 0, 0.32);
+ backdrop-filter: blur(18px);
+ text-align: left;
+}
+
+.wm-code-panel::before {
+ content: "";
+ position: absolute;
+ z-index: 1;
+ top: 47px;
+ left: 0;
+ right: 0;
+ height: 1px;
+ background: rgba(250, 248, 245, 0.12);
+}
+
+.wm-code-dots {
+ position: absolute;
+ z-index: 2;
+ top: 16px;
+ left: 16px;
+ display: inline-flex;
+ gap: 10px;
+}
+
+.wm-code-dots span {
+ width: 16px;
+ height: 16px;
+ border-radius: 999px;
+ background: #38445e;
+}
+
+.wm-code-dots span:first-child {
+ background: #faf8f5;
+}
+
+.wm-code-tabs {
+ position: absolute;
+ z-index: 3;
+ top: 10px;
+ right: 12px;
+ display: inline-flex;
+ align-items: center;
+ gap: 5px;
+}
+
+.wm-code-tab {
+ height: 27px;
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ padding: 0 12px;
+ border-radius: 4px;
+ background: rgba(250, 248, 245, 0.1);
+ color: #b1b4b6;
+ font-family: var(--font-mono);
+ font-size: 13px;
+ font-weight: 500;
+ line-height: 0.84;
+ letter-spacing: 0.26px;
+}
+
+.wm-code-tab--active {
+ background: #faf8f5;
+ color: #000000;
+}
+
+.wm-code-copy {
+ position: absolute;
+ z-index: 5;
+ top: 67px;
+ right: 20px;
+ width: 74px;
+ height: 74px;
+ border: 0;
+ border-radius: 999px;
+ display: grid;
+ place-items: center;
+ background: rgba(17, 17, 17, 0.52);
+ color: #faf8f5;
+ cursor: pointer;
+ transition: transform 180ms ease, background 180ms ease, border-color 180ms ease;
+ border: 1px solid rgba(250, 248, 245, 0.04);
+}
+
+.wm-code-copy:hover {
+ transform: translateY(-2px);
+ background: rgba(17, 17, 17, 0.7);
+ border-color: rgba(250, 248, 245, 0.12);
+}
+
+.wm-code-lines {
+ position: absolute;
+ z-index: 2;
+ top: 71px;
+ left: 0;
+ right: 68px;
+ margin: 0;
+ padding: 0;
+ counter-reset: wm-code-line;
+ color: rgba(255, 255, 255, 0.65);
+ font-family: var(--font-mono);
+ font-size: 15px;
+ font-weight: 500;
+ line-height: 1.5;
+ letter-spacing: 0.75px;
+}
+
+.wm-code-lines li {
+ counter-increment: wm-code-line;
+ display: grid;
+ grid-template-columns: 48px minmax(0, 1fr);
+ gap: 20px;
+ min-height: 22.5px;
+}
+
+.wm-code-lines li::before {
+ content: counter(wm-code-line);
+ color: rgba(250, 248, 245, 0.2);
+ text-align: right;
+}
+
+.wm-code-lines code {
+ display: block;
+ min-width: 0;
+ overflow: visible;
+ color: #d1d4d6;
+ font: inherit;
+ white-space: pre-wrap;
+}
+
+.wm-code-comment {
+ color: rgba(255, 255, 255, 0.65);
+}
+
+.wm-code-keyword {
+ color: #cab1ff;
+}
+
+.wm-code-fn {
+ color: #e8ff75;
+}
+
+.wm-code-string {
+ color: #faf8f5;
+}
+
+.wm-code-link {
+ text-decoration: underline;
+ text-decoration-thickness: 1px;
+ text-underline-offset: 2px;
+}
+
+.wm-aurora {
+ position: absolute;
+ pointer-events: none;
+ border-radius: 8px;
+ opacity: 0.72;
+ filter: blur(28px);
+ background:
+ linear-gradient(90deg, rgba(115, 215, 255, 0), rgba(115, 215, 255, 0.66), rgba(202, 177, 255, 0.54), rgba(232, 255, 117, 0));
+}
+
+.wm-aurora--hero {
+ width: 950px;
+ height: 260px;
+ left: 50%;
+ top: 215px;
+ transform: translateX(-50%) rotate(-4deg);
+}
+
+.wm-sdk-bar {
+ position: relative;
+ z-index: 3;
+ width: min(816px, 100%);
+ min-height: 90px;
+ margin: 36px auto 0;
+ padding: 0 26px 0 38px;
+ border: 1px solid rgba(250, 248, 245, 0.08);
+ border-radius: 999px;
+ background: rgba(250, 248, 245, 0.05);
+ color: var(--wm-paper);
+ cursor: pointer;
+ box-shadow: inset 0 0 0 1px rgba(250, 248, 245, 0.05), 0 22px 80px rgba(0, 0, 0, 0.34);
+ backdrop-filter: blur(18px);
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+}
+
+.wm-sdk-bar > span:first-child {
+ display: inline-flex;
+ align-items: center;
+ gap: 18px;
+ font-size: 1.42rem;
+ font-weight: 500;
+ line-height: 1;
+}
+
+.wm-sdk-bar svg {
+ flex: 0 0 auto;
+}
+
+.wm-sdk-actions {
+ display: inline-flex;
+ align-items: center;
+ justify-content: flex-end;
+ gap: 22px;
+ align-self: stretch;
+}
+
+.wm-sdk-toggles {
+ width: 90px;
+ height: 28px;
+ border-radius: 999px;
+ border: 1px solid rgba(250, 248, 245, 0.3);
+ background: transparent;
+ display: grid;
+ grid-template-columns: repeat(2, 1fr);
+ align-items: center;
+ color: var(--wm-paper);
+ font-size: 0.56rem;
+ font-family: var(--font-mono);
+ font-weight: 800;
+ text-transform: uppercase;
+ overflow: hidden;
+}
+
+.wm-sdk-toggles span {
+ height: 100%;
+ display: grid;
+ place-items: center;
+}
+
+.wm-sdk-toggles span:first-child {
+ background: var(--wm-paper);
+ color: var(--wm-black);
+}
+
+.wm-sdk-copy-icon {
+ width: 74px;
+ height: 74px;
+ margin-right: -18px;
+ border-radius: 999px;
+ display: grid;
+ place-items: center;
+ color: var(--wm-paper);
+ background: rgba(22, 116, 213, 0.42);
+}
+
+.wm-mascot-stage {
+ --wm-mascot-scale: 1;
+ position: absolute;
+ z-index: 2;
+ left: 50%;
+ bottom: 0;
+ width: 1440px;
+ height: 596px;
+ transform: translateX(-50%) scale(var(--wm-mascot-scale));
+ transform-origin: bottom center;
+}
+
+.wm-mascot-stage::after {
+ content: "";
+ position: absolute;
+ left: 0;
+ top: 334px;
+ width: 1440px;
+ height: 262px;
+ background: linear-gradient(0.127deg, rgb(0, 0, 0) 12.918%, rgba(0, 0, 0, 0) 99.489%);
+ z-index: 8;
+ pointer-events: none;
+}
+
+.wm-hero-walrus {
+ position: absolute;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ user-select: none;
+}
+
+.wm-hero-walrus-crop {
+ position: relative;
+ display: block;
+ width: 100%;
+ height: 100%;
+ overflow: hidden;
+ pointer-events: none;
+}
+
+.wm-hero-walrus-crop img {
+ position: absolute;
+ display: block;
+ max-width: none;
+}
+
+.wm-hero-walrus--main {
+ left: 565px;
+ top: 0;
+ width: 336px;
+ height: 576px;
+ z-index: 5;
+}
+
+.wm-hero-walrus--main img {
+ width: 196.33%;
+ height: 114.53%;
+ left: -48.19%;
+ top: -0.05%;
+}
+
+.wm-hero-walrus--left-mid,
+.wm-hero-walrus--right-mid {
+ top: 39px;
+ width: 297px;
+ height: 537px;
+ z-index: 4;
+}
+
+.wm-hero-walrus--left-mid img,
+.wm-hero-walrus--right-mid img {
+ width: 195.67%;
+ height: 108.22%;
+ top: 0.01%;
+}
+
+.wm-hero-walrus--left-mid {
+ left: 339px;
+}
+
+.wm-hero-walrus--left-mid img {
+ left: -47.79%;
+}
+
+.wm-hero-walrus--right-mid {
+ left: 830px;
+}
+
+.wm-hero-walrus--right-mid img {
+ left: -47.88%;
+}
+
+.wm-hero-walrus--left {
+ left: 49px;
+ top: 105px;
+ width: 472px;
+ height: 481px;
+ z-index: 3;
+}
+
+.wm-hero-walrus--left .wm-hero-walrus-crop {
+ width: 405.664px;
+ height: 416.53px;
+ transform: rotate(-10deg);
+ filter: drop-shadow(0 4px 4px rgba(0, 0, 0, 0.25));
+}
+
+.wm-hero-walrus--left img {
+ width: 129.72%;
+ height: 126.33%;
+ left: -14.81%;
+ top: 0.02%;
+}
+
+.wm-hero-walrus--right {
+ left: 1029px;
+ top: 104px;
+ width: 440px;
+ height: 479px;
+ z-index: 3;
+}
+
+.wm-hero-walrus--right .wm-hero-walrus-crop {
+ width: 372.161px;
+ height: 421.058px;
+ transform: rotate(10deg);
+}
+
+.wm-hero-walrus--right img {
+ width: 141.4%;
+ height: 124.98%;
+ left: -20.69%;
+ top: 0.01%;
+}
+
+.wm-builders {
+ width: min(1340px, calc(100% - 100px));
+ margin: 0 auto;
+ padding: 0;
+ text-align: center;
+ position: relative;
+ z-index: 5;
+}
+
+/* Lift content sections above the pointer-events:none section-transition
+ gradient overlays (which otherwise dim the top of each heading). */
+.wm-reset,
+.wm-portable,
+.wm-stack,
+.wm-production,
+.wm-bottom-cta,
+.wm-faq {
+ position: relative;
+ z-index: 5;
+}
+
+.wm-reset h2,
+.wm-portable h2,
+.wm-stack h2,
+.wm-production h2,
+.wm-bottom-cta h2 {
+ position: relative;
+ z-index: 2;
+}
+
+.wm-builders h2 {
+ color: #faf8f5;
+ font-size: 72px;
+ line-height: 1.1;
+ font-weight: 500;
+ overflow: visible;
+}
+
+.wm-builders h2 span {
+ display: block;
+ width: 100%;
+ overflow: visible;
+ line-height: 1.1;
+ padding-block: 0.06em;
+}
+
+.wm-builders h2 span:last-child {
+ display: block;
+ width: 100%;
+ filter: none;
+ text-shadow: none;
+}
+
+.wm-builders h2,
+.wm-reset h2,
+.wm-portable h2,
+.wm-stack h2,
+.wm-light-heading h2,
+.wm-production h2,
+.wm-bottom-cta h2,
+.wm-faq h2 {
+ margin: 0;
+ font-size: 4.65rem;
+ line-height: 0.95;
+ font-weight: 500;
+ letter-spacing: 0;
+}
+
+.wm-builders h2 {
+ font-size: 72px;
+ line-height: 1.1;
+ overflow: visible;
+}
+
+.wm-builders h2 span:first-child {
+ filter: none;
+ text-shadow: none;
+}
+
+.wm-logo-row {
+ height: 48px;
+ margin: 33px auto 72px;
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ gap: 24px;
+ color: rgba(255, 255, 255, 0.86);
+}
+
+.wm-logo-row img {
+ display: block;
+ object-fit: contain;
+ position: static;
+ flex: 0 0 auto;
+}
+
+.wm-logo-allium {
+ width: 164px;
+ height: 48px;
+ left: 227px;
+ top: 0;
+}
+
+.wm-logo-inflectiv {
+ width: 186px;
+ height: 40px;
+ left: 437px;
+ top: 4px;
+}
+
+.wm-logo-opengradient {
+ width: 245px;
+ height: 46px;
+ left: 673px;
+ top: 1px;
+}
+
+.wm-logo-talus {
+ width: 144px;
+ height: 25px;
+ left: 968px;
+ top: 11px;
+}
+
+.wm-logo-tatum {
+ width: 163px;
+ height: 33px;
+}
+
+.wm-logo-conso {
+ width: 159px;
+ height: 41px;
+}
+
+.wm-builders-quote-card {
+ width: min(922px, 100%);
+ height: 238px;
+ min-height: 0;
+ margin: 0 auto;
+ padding: 0;
+ border: 0;
+ border-radius: 0;
+ background: transparent;
+ box-shadow: none;
+ position: relative;
+}
+
+.wm-builders p {
+ margin: 0;
+ width: 100%;
+ min-height: 163px;
+ color: #8f9294;
+ font-size: 28px;
+ font-weight: 400;
+ line-height: 1.3;
+ letter-spacing: 0;
+}
+
+.wm-builder-person {
+ position: absolute;
+ left: 50%;
+ top: 170px;
+ width: 424px;
+ transform: translateX(-50%);
+ display: grid;
+ gap: 4px;
+ margin: 0;
+}
+
+.wm-builder-person span {
+ color: #faf8f5;
+ font-size: 24px;
+ font-weight: 700;
+ line-height: 1.3;
+}
+
+.wm-builder-person small {
+ color: #cab1ff;
+ font-family: var(--font-sans);
+ font-size: 0.82rem;
+ font-weight: 500;
+ line-height: 1.5;
+ letter-spacing: 0.7px;
+}
+
+.wm-builder-lines {
+ width: 252px;
+ height: 1px;
+ margin: 28px auto 0;
+ display: flex;
+ justify-content: center;
+ gap: 12px;
+ transform: translateX(-1px);
+}
+
+.wm-builder-lines span {
+ width: 76px;
+ height: 1px;
+ background: #54575a;
+}
+
+.wm-builder-lines span:first-child {
+ background: #faf8f5;
+}
+
+.wm-builders a,
+.wm-stack a,
+.wm-cta-links a {
+ display: inline-flex;
+ align-items: center;
+ gap: 8px;
+ color: var(--wm-white);
+ font-size: 1rem;
+ font-weight: 500;
+}
+
+.wm-spine {
+ width: 87px;
+ height: 188px;
+ margin: 90px auto 110px;
+ position: relative;
+ z-index: 5;
+ display: block;
+}
+
+.wm-spine::before {
+ content: "";
+ position: absolute;
+ left: 50%;
+ top: 0;
+ width: 1px;
+ height: 100%;
+ transform: translateX(-50%);
+ background: repeating-linear-gradient(
+ to bottom,
+ rgba(250, 248, 245, 0.58) 0,
+ rgba(250, 248, 245, 0.58) 2px,
+ transparent 2px,
+ transparent 10px
+ );
+}
+
+.wm-spine span {
+ display: none;
+}
+
+.wm-spine-gem {
+ position: absolute;
+ left: 50%;
+ bottom: -58.5px;
+ width: 55px;
+ height: 55px;
+ border: 1px solid #8f9294;
+ transform: translateX(-50%) rotate(45deg);
+}
+
+.wm-spine-gem::after {
+ content: "";
+ position: absolute;
+ inset: 15px;
+ border: 1px solid #8f9294;
+ box-shadow: inset 0 0 0 8px rgba(0, 0, 0, 0.58);
+}
+
+.wm-spine--lead {
+ height: 225px;
+}
+
+.wm-spine--lead::before {
+ background: repeating-linear-gradient(
+ to bottom,
+ #c7c5c1 0,
+ #c7c5c1 1px,
+ transparent 1px,
+ transparent 4px
+ );
+}
+
+.wm-spine--lead .wm-spine-gem {
+ display: block;
+ width: 56px;
+ height: 56px;
+ top: calc(100% + 4px);
+ bottom: auto;
+ border: 0;
+ transform: translateX(-50%);
+ background: none;
+}
+
+.wm-spine--lead .wm-spine-gem::after {
+ content: none;
+}
+
+.wm-spine--pre-builders {
+ width: 54px;
+ height: 125px;
+ margin: 12px auto 35.7px;
+}
+
+.wm-spine--pre-builders .wm-spine-gem {
+ display: none;
+}
+
+.wm-spine--reset {
+ width: 54px;
+ height: 125px;
+ margin: 0 auto;
+ gap: 0;
+}
+
+.wm-spine--reset::before {
+ height: 100%;
+}
+
+.wm-spine--reset span {
+ background: rgba(255, 255, 255, 0.22);
+}
+
+.wm-spine--reset .wm-spine-gem {
+ display: none;
+}
+
+.wm-reset {
+ width: min(1218px, calc(100% - 40px));
+ margin: 0 auto;
+ padding: 0 0 72px;
+ text-align: center;
+ position: relative;
+}
+
+.wm-reset h2 {
+ width: min(824px, 100%);
+ margin-inline: auto;
+ position: relative;
+ z-index: 2;
+ color: var(--wm-paper);
+ font-size: 72px;
+ line-height: 0.95;
+}
+
+.wm-reset h2 span,
+.wm-portable h2 span,
+.wm-bottom-cta h2 span:last-of-type {
+ color: transparent;
+ background: linear-gradient(100deg, #2368ff 0%, #7248ff 48%, #ee79ff 100%);
+ -webkit-background-clip: text;
+ background-clip: text;
+}
+
+.wm-reset-visual {
+ position: relative;
+ width: 100%;
+ height: 169px;
+ margin: 60px auto 0;
+ overflow: visible;
+}
+
+.wm-reset-visual::before {
+ content: none;
+ position: absolute;
+ left: calc(50% - 780px);
+ top: -278px;
+ width: 1660px;
+ height: 2px;
+ z-index: 1;
+ transform: rotate(-2.6deg);
+ transform-origin: center;
+ background: linear-gradient(90deg, transparent 0%, rgba(3, 158, 255, 0.38) 22%, rgba(3, 158, 255, 0.3) 78%, transparent 100%);
+ opacity: 0.42;
+ pointer-events: none;
+}
+
+.wm-reset-aurora {
+ position: absolute;
+ left: calc(50% - 498px);
+ top: -305px;
+ width: 904px;
+ height: 679px;
+ max-width: none;
+ object-fit: cover;
+ object-position: bottom center;
+ opacity: 1;
+ filter: saturate(1.32) brightness(1.5);
+ mix-blend-mode: screen;
+ z-index: 0;
+ pointer-events: none;
+}
+
+.wm-reset-mascot {
+ position: absolute;
+ left: 50%;
+ top: 0;
+ width: 293.475px;
+ height: 169px;
+ transform: translateX(-50%);
+ max-width: none;
+ object-fit: fill;
+ display: block;
+ z-index: 3;
+ pointer-events: none;
+}
+
+.wm-reset-mascot-crop {
+ position: absolute;
+ left: 0;
+ overflow: hidden;
+ width: 100%;
+}
+
+.wm-reset-mascot-crop img {
+ position: absolute;
+ left: 1.27%;
+ width: 97.88%;
+ max-width: none;
+}
+
+.wm-reset-mascot-crop--main {
+ top: 0;
+ height: 135.45px;
+}
+
+.wm-reset-mascot-crop--main img {
+ top: 0;
+ height: 135.96%;
+}
+
+.wm-reset-mascot-crop--base {
+ top: 135px;
+ height: 34px;
+}
+
+.wm-reset-mascot-crop--base img {
+ top: -278.05%;
+ height: 378.05%;
+}
+
+.wm-command-pill {
+ width: min(944px, 100%);
+ height: 90px;
+ margin: -36px auto 0;
+ position: relative;
+ z-index: 2;
+ padding: 0 56px;
+ border-radius: 999px;
+ border: 1px solid rgba(250, 248, 245, 0.08);
+ background: rgba(250, 248, 245, 0.07);
+ color: var(--wm-paper);
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ font-family: var(--font-mono);
+ font-size: 1.24rem;
+ line-height: 1.3;
+ font-weight: 300;
+ letter-spacing: 0;
+ backdrop-filter: blur(12px);
+ box-shadow: 0 47px 95px rgba(0, 0, 0, 0.66);
+ overflow: hidden;
+}
+
+.wm-command-pill > span {
+ width: 100%;
+ display: block;
+ text-align: center;
+ white-space: nowrap;
+}
+
+.wm-command-pill i {
+ position: absolute;
+ top: 31px;
+ right: 129px;
+ width: 1px;
+ height: 25px;
+ background: var(--wm-paper);
+}
+
+.wm-reset p {
+ width: min(768px, 100%);
+ margin: 65px auto 0;
+ position: relative;
+ z-index: 2;
+ color: #acaca8;
+ font-size: 1.24rem;
+ line-height: 1.3;
+}
+
+.wm-reset p strong {
+ color: var(--wm-paper);
+ font-weight: 700;
+}
+
+.wm-portable {
+ width: min(1340px, calc(100% - 40px));
+ margin: 0 auto;
+ padding: 72px 0 6px;
+ text-align: center;
+}
+
+.wm-portable h2 {
+ width: min(1040px, 100%);
+ margin-inline: auto;
+ color: #faf8f5;
+ font-size: 5.647rem;
+ line-height: 0.85;
+ font-weight: 500;
+ letter-spacing: 0;
+}
+
+.wm-portable h2 span {
+ color: transparent;
+ background-image: linear-gradient(94deg, #383bff 14%, #9a57ff 38%, #eda0ff 52%);
+}
+
+.wm-portable h2 em {
+ font-style: normal;
+ filter: blur(3px);
+ text-shadow: 0 4px 4px rgba(0, 0, 0, 0.25);
+}
+
+.wm-card-grid {
+ margin-top: 58px;
+ display: grid;
+ grid-template-columns: repeat(3, minmax(0, 1fr));
+ gap: 30px;
+}
+
+.wm-dark-card {
+ min-height: 494px;
+ border: 0;
+ border-radius: 24px;
+ background: linear-gradient(180deg, rgba(26, 31, 39, 0.5) 0%, #1a1f27 50%, #1a1f27 100%);
+ padding: 48px;
+ text-align: left;
+ display: flex;
+ flex-direction: column;
+ align-items: flex-start;
+ overflow: hidden;
+}
+
+.wm-card-icon {
+ width: 72px;
+ height: 72px;
+ display: block;
+}
+
+.wm-dark-card h3 {
+ width: min(329px, 100%);
+ margin: 58px 0 8px;
+ color: #faf8f5;
+ font-size: 28px;
+ font-weight: 700;
+ line-height: 1.3;
+ letter-spacing: 0;
+}
+
+.wm-dark-card p {
+ width: min(329px, 100%);
+ margin: 0;
+ color: #c7c5c1;
+ font-size: 18px;
+ line-height: 1.4;
+ letter-spacing: 0.18px;
+}
+
+.wm-dark-card code {
+ width: min(327px, 100%);
+ min-height: 41px;
+ margin-top: auto;
+ border-radius: 4px;
+ background: #000000;
+ color: #faf8f5;
+ font-family: var(--font-mono);
+ font-size: 14px;
+ font-weight: 500;
+ line-height: 1.3;
+ display: flex;
+ align-items: center;
+ gap: 12px;
+ padding: 8px 14px;
+ white-space: normal;
+}
+
+.wm-code-mark {
+ width: 19px;
+ height: 19px;
+ flex: 0 0 19px;
+ border: 1px solid #faf8f5;
+ position: relative;
+ transform: rotate(45deg);
+}
+
+.wm-code-mark::after {
+ content: "";
+ position: absolute;
+ inset: 5px;
+ border: 1px solid #faf8f5;
+}
+
+.wm-code-text {
+ min-width: 0;
+ max-width: 264px;
+ overflow-wrap: break-word;
+}
+
+.wm-code-text > span {
+ display: block;
+}
+
+.wm-page .wm-small-cta {
+ min-height: 52px;
+ padding: 0 28px;
+ border-color: transparent;
+ background: linear-gradient(100deg, #245bff 0%, #7449ff 52%, #ef7bff 100%);
+ color: var(--wm-white);
+}
+
+.wm-page .wm-small-cta:hover {
+ background: linear-gradient(100deg, #3a6cff 0%, #855dff 52%, #f18cff 100%);
+}
+
+.wm-portable .wm-small-cta,
+.wm-light-band .wm-small-cta {
+ margin-top: 72px;
+}
+
+.wm-portable .wm-small-cta {
+ width: 200px;
+ min-height: 52px;
+ padding-inline: 30px;
+ position: relative;
+ left: 10px;
+ border-color: transparent;
+ background: linear-gradient(93.36deg, #383bff 0.29%, #9a57ff 48.11%, #eda0ff 97.8%);
+ color: #faf8f5;
+ font-size: 18px;
+ font-weight: 500;
+ line-height: 0.84;
+ letter-spacing: 0.72px;
+}
+
+.wm-light-band .wm-small-cta {
+ width: max-content;
+ min-width: 197.23px;
+ min-height: 52px;
+ margin-top: 72px;
+ padding-inline: 30px;
+ border-color: transparent;
+ background: linear-gradient(93.36deg, #383bff 0.29%, #9a57ff 48.11%, #eda0ff 97.8%);
+ color: #faf8f5;
+ font-size: 18px;
+ font-weight: 500;
+ line-height: 0.84;
+ letter-spacing: 0.72px;
+ white-space: nowrap;
+}
+
+.wm-light-band .wm-small-cta svg {
+ flex: 0 0 auto;
+}
+
+.wm-light-band .wm-light-band-line {
+ display: block;
+ width: 1px;
+ height: 125px;
+ margin: 36px auto 0;
+ position: relative;
+ z-index: 1;
+ background: repeating-linear-gradient(
+ to bottom,
+ #484946 0,
+ #484946 1px,
+ transparent 1px,
+ transparent 4px
+ );
+}
+
+.wm-stack {
+ width: min(1340px, calc(100% - 100px));
+ min-height: 600px;
+ margin: 88px auto 0;
+ padding: 0 50px;
+ scroll-margin-top: 106px;
+ border-radius: 0;
+ position: relative;
+ overflow: hidden;
+ display: grid;
+ grid-template-columns: 499px minmax(0, 1fr);
+ gap: 136px;
+ background: transparent;
+}
+
+.wm-stack > div:not(.wm-aurora--stack) {
+ position: relative;
+ z-index: 2;
+}
+
+.wm-stack h2 {
+ max-width: 499px;
+ color: #faf8f5;
+ font-size: 72px;
+ font-weight: 500;
+ line-height: 0.95;
+ letter-spacing: 0;
+}
+
+.wm-stack p {
+ margin: 18px 0 21px;
+ max-width: 438px;
+ color: #acaca8;
+ font-size: 21px;
+ font-weight: 400;
+ line-height: 1.4;
+ letter-spacing: 0.21px;
+}
+
+.wm-stack > div:first-child > p {
+ margin-left: -4px;
+ margin-bottom: 18.6px;
+}
+
+.wm-stack > div:first-child > a {
+ margin-left: -2px;
+}
+
+.wm-stack-list {
+ display: grid;
+ gap: 26.42px;
+ align-content: start;
+ padding-top: 0;
+ position: relative;
+ z-index: 2;
+}
+
+.wm-stack-item {
+ min-height: 65.58px;
+ display: grid;
+ grid-template-columns: 34px 1fr;
+ gap: 21px;
+ align-items: start;
+}
+
+.wm-stack-item > span {
+ width: 25px;
+ height: 25px;
+ margin-top: 6px;
+ position: relative;
+ display: block;
+ background: none;
+}
+
+.wm-stack-item > span::before {
+ content: none;
+}
+
+.wm-stack-item h3 {
+ margin: 0;
+ color: var(--wm-white);
+ font-size: 24px;
+ font-weight: 700;
+ line-height: 1.3;
+ letter-spacing: 0;
+}
+
+.wm-stack-item p {
+ margin: 5px 0 0;
+ max-width: 530px;
+ color: #acaca8;
+ font-size: 21px;
+ font-weight: 400;
+ line-height: 1.4;
+ letter-spacing: 0.21px;
+}
+
+.wm-aurora--stack {
+ width: 1205px;
+ height: 869px;
+ left: -50px;
+ top: 84px;
+ z-index: 1;
+ overflow: visible;
+ border-radius: 0;
+ opacity: 1;
+ filter: none;
+ transform: none;
+ background: transparent;
+}
+
+.wm-aurora--stack::before {
+ content: "";
+ position: absolute;
+ inset: 0;
+ background: none;
+ filter: none;
+ opacity: 1;
+}
+
+.wm-aurora-streaks {
+ display: none;
+}
+
+.wm-light-band {
+ margin-top: -1px;
+ background: var(--wm-paper);
+ color: var(--wm-black);
+ padding: 144px max(98px, calc((100vw - 1244px) / 2)) 0;
+ text-align: center;
+ border-radius: 48px 48px 0 0;
+ position: relative;
+ overflow: hidden;
+ isolation: isolate;
+}
+
+.wm-light-band-bg {
+ position: absolute;
+ inset: 0 0 auto;
+ height: 266px;
+ z-index: 0;
+ border-radius: 48px;
+ background:
+ radial-gradient(68% 100% at 50% 100%, rgba(250, 248, 245, 0.96) 0%, rgba(250, 248, 245, 0.76) 56%, rgba(196, 195, 191, 0.58) 100%),
+ linear-gradient(180deg, rgba(172, 172, 168, 0.62) 0%, rgba(250, 248, 245, 0) 100%);
+ pointer-events: none;
+}
+
+.wm-light-heading,
+.wm-builder-grid,
+.wm-light-band .wm-small-cta {
+ position: relative;
+ z-index: 1;
+}
+
+.wm-light-heading h2 {
+ font-size: 72px;
+}
+
+.wm-light-heading p {
+ width: min(816px, 100%);
+ margin: 22px auto 0;
+ color: #000000;
+ font-size: 24px;
+ font-weight: 300;
+ line-height: 1.3;
+ letter-spacing: 0;
+}
+
+.wm-light-heading h2 span:first-child {
+ display: block;
+}
+
+.wm-light-heading p strong {
+ font-weight: 700;
+}
+
+.wm-builder-grid {
+ width: min(1242px, 100%);
+ margin-top: 62px;
+ margin-right: auto;
+ margin-left: auto;
+ display: grid;
+ grid-template-columns: repeat(2, minmax(0, 605px));
+ gap: 30px 32px;
+ justify-content: center;
+}
+
+.wm-builder-grid article {
+ position: relative;
+ width: 100%;
+ height: 207px;
+ min-height: 0;
+ padding: 0;
+ border-radius: 48px;
+ background: linear-gradient(180deg, rgba(228, 225, 221, 0.5) 0%, #e4e1dd 50%);
+ text-align: left;
+ overflow: hidden;
+}
+
+.wm-builder-icon {
+ position: absolute;
+ left: 48px;
+ top: 48px;
+ width: 38px;
+ height: 38px;
+ display: block;
+ background: none;
+}
+
+.wm-builder-grid h3 {
+ position: absolute;
+ left: 108px;
+ top: 42px;
+ width: 449px;
+ margin: 0;
+ color: var(--wm-black);
+ font-size: 24px;
+ line-height: 1.3;
+ font-weight: 700;
+ letter-spacing: 0;
+}
+
+.wm-builder-grid p {
+ position: absolute;
+ left: 108px;
+ top: 88px;
+ margin: 0;
+ width: 449px;
+ max-width: calc(100% - 156px);
+ color: #5e5f5b;
+ font-size: 18px;
+ line-height: 1.4;
+ letter-spacing: 0.18px;
+}
+
+.wm-production {
+ width: 100%;
+ margin: 0;
+ padding: 132px max(100px, calc((100vw - 1240px) / 2)) 0;
+ background: var(--wm-paper);
+ color: var(--wm-black);
+ text-align: center;
+ position: relative;
+ z-index: 2;
+ overflow: hidden;
+}
+
+.wm-production::before {
+ content: "";
+ position: absolute;
+ left: 50%;
+ top: -41px;
+ width: 1px;
+ height: 125px;
+ background: repeating-linear-gradient(
+ to bottom,
+ #484946 0,
+ #484946 1px,
+ transparent 1px,
+ transparent 4px
+ );
+ transform: translateX(-50%);
+ pointer-events: none;
+ z-index: 4;
+}
+
+.wm-production > p {
+ width: min(816px, 100%);
+ margin: 12px auto 47px;
+ position: relative;
+ z-index: 3;
+ color: rgba(0, 0, 0, 0.75);
+ font-size: 24px;
+ font-weight: 300;
+ line-height: 1.3;
+}
+
+.wm-production h2 {
+ position: relative;
+ z-index: 3;
+ font-size: 96px;
+ line-height: 0.85;
+}
+
+.wm-production p a,
+.wm-production p strong {
+ color: inherit;
+ font-weight: 700;
+}
+
+.wm-production p a {
+ text-decoration: underline;
+ text-decoration-thickness: 1px;
+ text-underline-offset: 2px;
+}
+
+.wm-production-aurora {
+ position: absolute;
+ left: 0;
+ top: auto;
+ bottom: 0;
+ width: 100%;
+ height: 838px;
+ z-index: 0;
+ pointer-events: none;
+ background: none;
+ opacity: 0.95;
+}
+
+.wm-production-transition {
+ position: absolute;
+ left: 0;
+ bottom: 0;
+ width: 100%;
+ height: 88px;
+ z-index: 1;
+ pointer-events: none;
+ background: linear-gradient(to top, rgba(26, 31, 39, 0.5) 0%, rgba(26, 31, 39, 0.08) 55%, rgba(0, 0, 0, 0) 100%);
+ border-radius: 0;
+}
+
+.wm-production-grid {
+ display: grid;
+ grid-template-columns: 393px 425px 393px;
+ gap: 24px;
+ align-items: start;
+ justify-content: center;
+ position: relative;
+ z-index: 3;
+}
+
+.wm-flow-column {
+ display: grid;
+ gap: 0;
+ text-align: center;
+}
+
+.wm-flow-column > button {
+ width: 274px;
+ max-width: 100%;
+ height: 74px;
+ border: 1px dashed #000000;
+ border-radius: 8px;
+ background: transparent;
+ color: var(--wm-black);
+ font-size: 36px;
+ font-weight: 700;
+ line-height: 0.85;
+ letter-spacing: 0.36px;
+ cursor: default;
+ justify-self: center;
+ position: relative;
+}
+
+.wm-flow-column > div {
+ min-height: 143px;
+ padding: 0;
+ border-left: 0;
+}
+
+.wm-flow-column > button::after {
+ content: "";
+ position: absolute;
+ left: 50%;
+ top: calc(100% + 4px);
+ width: 1px;
+ height: 61px;
+ border-left: 1px dashed rgba(0, 0, 0, 0.5);
+ transform: translateX(-50%);
+}
+
+.wm-flow-column > div:first-of-type {
+ min-height: 119px;
+ margin-top: 93px;
+}
+
+.wm-flow-column svg {
+ display: none;
+ margin-bottom: 10px;
+}
+
+.wm-flow-column h3 {
+ margin: 0;
+ color: var(--wm-black);
+ font-size: 24px;
+ line-height: 0.85;
+ letter-spacing: 0.24px;
+}
+
+.wm-flow-column p {
+ width: min(359px, 100%);
+ margin: 9px 0 0;
+ justify-self: center;
+ color: #5e5f5b;
+ font-size: 18px;
+ font-weight: 400;
+ line-height: 1.4;
+ letter-spacing: 0.18px;
+}
+
+.wm-production-mascot {
+ width: 425px;
+ height: 550px;
+ min-height: 0;
+ margin-top: 77px;
+ display: block;
+ overflow: hidden;
+}
+
+.wm-production-mascot img {
+ position: relative;
+ left: -17.04%;
+ top: 0;
+ width: 129.38%;
+ height: 100%;
+ max-width: none;
+ max-height: none;
+ object-fit: fill;
+}
+
+.wm-bottom-cta {
+ min-height: 954px;
+ margin-top: -34px;
+ margin-right: 0;
+ margin-left: 0;
+ padding: 167px 20px 80px;
+ border-radius: 48px 48px 0 0;
+ background: #000000;
+ text-align: center;
+ position: relative;
+ overflow: hidden;
+ isolation: isolate;
+ z-index: 3;
+}
+
+.wm-bottom-dark-base,
+.wm-bottom-dark-gradient,
+.wm-bottom-rounded-gradient {
+ position: absolute;
+ pointer-events: none;
+}
+
+.wm-bottom-dark-base {
+ inset: 0;
+ z-index: 0;
+ background: #000000;
+}
+
+.wm-bottom-dark-gradient {
+ left: 0;
+ top: 834px;
+ width: 100%;
+ height: 387px;
+ z-index: 0;
+ background: linear-gradient(to top, #1a1f27 0%, #1a1f27 16.667%, rgba(26, 31, 39, 0) 100%);
+}
+
+.wm-bottom-rounded-gradient {
+ right: calc(50% - 1329px);
+ top: 977px;
+ width: min(1340px, calc(100% - 100px));
+ height: 387px;
+ z-index: 0;
+ border-radius: 0 0 48px 48px;
+ overflow: hidden;
+ background: linear-gradient(to top, #1a1f27 0%, #1a1f27 16.667%, rgba(0, 0, 0, 0) 100%);
+}
+
+.wm-bottom-cta h2 {
+ position: relative;
+ z-index: 2;
+ width: min(1112px, 100%);
+ margin: 0 auto;
+ color: #faf8f5;
+ font-size: 5.65rem;
+ line-height: 0.85;
+ font-weight: 500;
+}
+
+.wm-bottom-cta h2 span {
+ display: inline-block;
+}
+
+.wm-bottom-copy {
+ width: min(680px, 100%);
+ margin: 24px auto 32px;
+ position: relative;
+ z-index: 2;
+ display: grid;
+ gap: 2px;
+ color: #faf8f5;
+ letter-spacing: 0.28px;
+}
+
+.wm-bottom-copy strong {
+ font-size: 28px;
+ line-height: 1.3;
+ font-weight: 700;
+}
+
+.wm-bottom-copy span {
+ color: #faf8f5;
+ font-size: 28px;
+ line-height: 1.3;
+ font-weight: 300;
+}
+
+.wm-aurora--cta {
+ width: 780px;
+ height: 260px;
+ left: calc(50% + 425px);
+ top: -170px;
+ transform: translateX(-50%) rotate(-6deg);
+ opacity: 0.44;
+ z-index: 1;
+}
+
+.wm-spine--compact {
+ position: relative;
+ width: 56px;
+ height: 137px;
+ margin: 24px auto 0;
+ display: block;
+}
+
+.wm-spine--compact::before {
+ content: "";
+ display: block;
+ position: absolute;
+ left: 50%;
+ top: 0;
+ width: 1px;
+ height: 81px;
+ transform: translateX(-50%);
+ background: repeating-linear-gradient(
+ to bottom,
+ rgba(250, 248, 245, 0.5) 0,
+ rgba(250, 248, 245, 0.5) 1px,
+ transparent 1px,
+ transparent 4px
+ );
+}
+
+.wm-spine--compact span {
+ display: none;
+}
+
+.wm-spine--compact .wm-spine-gem {
+ display: block;
+ top: 81px;
+ bottom: auto;
+ width: 56px;
+ height: 56px;
+ border: 0;
+ transform: translateX(-50%);
+ background: none;
+}
+
+.wm-spine--compact .wm-spine-gem::after {
+ content: none;
+}
+
+.wm-bottom-cta .wm-start-button {
+ position: relative;
+ z-index: 2;
+ min-width: 166px;
+ min-height: 44px;
+ padding: 0 25px;
+ border: 0;
+ background: linear-gradient(100deg, #3e45ff 0%, #7d52ff 52%, #ec7dff 100%);
+ color: #ffffff;
+ font-size: 0.94rem;
+}
+
+.wm-cta-links {
+ position: relative;
+ z-index: 2;
+ width: min(620px, 100%);
+ margin: 26px auto 0;
+ display: flex;
+ justify-content: center;
+ gap: 28px;
+}
+
+.wm-cta-links a {
+ padding-bottom: 5px;
+ border-bottom: 1px solid rgba(250, 248, 245, 0.16);
+ color: rgba(250, 248, 245, 0.88);
+ font-size: 0.82rem;
+}
+
+.wm-cta-links a::after {
+ content: "\2192";
+ margin-left: 7px;
+}
+
+.wm-faq {
+ background:
+ radial-gradient(circle at 8% 14%, rgba(255, 255, 255, 0.07), transparent 25%),
+ linear-gradient(145deg, #111923 0%, #05080b 56%, #0c1117 100%);
+ color: var(--wm-white);
+ width: min(1340px, calc(100% - 100px));
+ margin: 0 auto;
+ min-height: 494px;
+ padding: 80px 50px 78px;
+ border-radius: 42px 42px 0 0;
+ display: grid;
+ grid-template-columns: 300px 1fr;
+ gap: 52px;
+}
+
+.wm-faq > div {
+ display: grid;
+ gap: 0;
+}
+
+.wm-faq h2 {
+ color: #faf8f5;
+ font-size: 5rem;
+ line-height: 0.85;
+ font-weight: 500;
+}
+
+.wm-faq article {
+ border-bottom: 1px solid rgba(255, 255, 255, 0.14);
+ padding: 0 0 7px;
+}
+
+.wm-faq article + article {
+ padding-top: 7px;
+}
+
+.wm-faq-question {
+ width: 100%;
+ min-height: 28px;
+ padding: 0;
+ border: 0;
+ background: transparent;
+ color: var(--wm-white);
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ gap: 24px;
+ text-align: left;
+ cursor: pointer;
+}
+
+.wm-faq-question span {
+ color: var(--wm-white);
+ font-size: 1.06rem;
+ line-height: 1.25;
+ font-weight: 700;
+ letter-spacing: 0;
+}
+
+.wm-faq-question svg {
+ flex: 0 0 auto;
+ color: #faf8f5;
+ stroke-width: 1.7;
+}
+
+.wm-faq p {
+ max-width: 650px;
+ margin-top: 10px;
+ color: rgba(255, 255, 255, 0.66);
+ font-size: 0.92rem;
+ line-height: 1.42;
+ font-weight: 500;
+}
+
+.wm-footer {
+ width: min(1340px, calc(100% - 40px));
+ margin: 0 auto;
+ padding: 203px 0 0;
+ color: var(--wm-white);
+ position: relative;
+}
+
+.wm-footer-grid {
+ display: grid;
+ grid-template-columns: repeat(4, minmax(0, 1fr));
+ gap: 48px;
+}
+
+.wm-footer-grid div {
+ display: grid;
+ gap: 13px;
+ align-content: start;
+}
+
+.wm-footer-grid span {
+ margin-bottom: 10px;
+ color: rgba(255, 255, 255, 0.48);
+ font-size: 0.78rem;
+ font-weight: 900;
+}
+
+.wm-footer-grid a {
+ color: rgba(255, 255, 255, 0.82);
+ font-size: 0.95rem;
+}
+
+.wm-footer-bottom {
+ min-height: 506px;
+ margin-top: 86px;
+ position: relative;
+ display: grid;
+ align-items: end;
+ overflow: hidden;
+}
+
+.wm-footer-word {
+ position: absolute;
+ left: 50%;
+ bottom: -64px;
+ transform: translateX(-50%);
+ font-size: 21.7rem;
+ line-height: 0.78;
+ font-weight: 900;
+ color: var(--wm-white);
+ letter-spacing: 0;
+ white-space: nowrap;
+}
+
+.wm-footer-bottom img {
+ position: absolute;
+ left: 50%;
+ bottom: 0;
+ width: 488px;
+ height: 213px;
+ max-width: 48vw;
+ transform: translateX(-50%);
+ object-fit: cover;
+ object-position: top center;
+ z-index: 2;
+}
+
+.wm-socials {
+ display: flex;
+ gap: 10px;
+ z-index: 3;
+}
+
+.wm-socials a,
+.wm-socials button {
+ width: 42px;
+ height: 42px;
+ border: 1px solid rgba(255, 255, 255, 0.16);
+ border-radius: 50%;
+ background: rgba(255, 255, 255, 0.08);
+ color: var(--wm-white);
+ display: grid;
+ place-items: center;
+ cursor: pointer;
+ text-decoration: none;
+}
+
+.wm-socials a img {
+ height: 15px;
+ width: auto;
+ display: block;
+}
+
+.wm-footer-top {
+ display: grid;
+ grid-template-columns: 1fr auto;
+ gap: 60px;
+ align-items: start;
+}
+
+.wm-footer-grid a {
+ display: inline-flex;
+ align-items: center;
+ gap: 4px;
+}
+
+.wm-footer-grid a svg {
+ opacity: 0.55;
+}
+
+.wm-footer-side {
+ display: flex;
+ flex-direction: column;
+ align-items: flex-end;
+ gap: 26px;
+}
+
+.wm-footer-cta {
+ min-height: 40px;
+ padding: 0 18px;
+ font-size: 0.74rem;
+ background: var(--wm-white);
+ color: var(--wm-black);
+}
+
+.wm-footer-meta {
+ position: absolute;
+ top: 183px;
+ right: 0;
+ z-index: 4;
+ margin-top: 0;
+ display: flex;
+ justify-content: flex-end;
+ align-items: center;
+ gap: 24px;
+ color: rgba(255, 255, 255, 0.5);
+ font-size: 0.78rem;
+}
+
+.wm-footer-lang {
+ display: inline-flex;
+ align-items: center;
+ gap: 4px;
+ color: rgba(255, 255, 255, 0.78);
+ cursor: pointer;
+}
+
+.wm-footer-copyright {
+ color: rgba(255, 255, 255, 0.48);
+}
+
+@media (max-width: 980px) {
+ .wm-nav {
+ grid-template-columns: 1fr auto;
+ }
+
+ .wm-nav-links {
+ display: none;
+ }
+
+ .wm-hero {
+ min-height: 1180px;
+ padding-top: 100px;
+ }
+
+ .wm-hero-bg {
+ width: 1650px;
+ height: 1216px;
+ top: -24px;
+ }
+
+ .wm-hero h1 {
+ font-size: 4.35rem;
+ }
+
+ .wm-hero-copy p {
+ font-size: 1rem;
+ }
+
+ .wm-sdk-bar {
+ min-height: 76px;
+ }
+
+ .wm-sdk-bar > span:first-child {
+ font-size: 1.35rem;
+ }
+
+ .wm-sdk-copy-icon {
+ width: 60px;
+ height: 60px;
+ }
+
+ .wm-code-panel {
+ height: 540px;
+ margin-top: 64px;
+ }
+
+ .wm-code-copy {
+ width: 60px;
+ height: 60px;
+ top: 63px;
+ right: 16px;
+ }
+
+ .wm-code-lines {
+ right: 36px;
+ font-size: 13px;
+ letter-spacing: 0.35px;
+ }
+
+ .wm-mascot-stage {
+ --wm-mascot-scale: 0.78;
+ }
+
+ .wm-builders h2,
+ .wm-reset h2,
+ .wm-portable h2,
+ .wm-light-heading h2,
+ .wm-production h2,
+ .wm-bottom-cta h2,
+ .wm-faq h2 {
+ font-size: 3.65rem;
+ }
+
+ .wm-logo-row {
+ flex-wrap: wrap;
+ height: auto;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ gap: 18px 32px;
+ margin: 30px auto 60px;
+ }
+
+ .wm-logo-row img {
+ position: static;
+ }
+
+ .wm-card-grid,
+ .wm-stack,
+ .wm-builder-grid,
+ .wm-production-grid,
+ .wm-faq,
+ .wm-footer-grid {
+ grid-template-columns: 1fr;
+ }
+
+ .wm-stack {
+ padding: 70px 36px;
+ gap: 44px;
+ min-height: auto;
+ }
+
+ .wm-stack-list {
+ padding-top: 0;
+ }
+
+ .wm-aurora--stack {
+ left: 50%;
+ top: auto;
+ bottom: -245px;
+ width: 920px;
+ height: 550px;
+ transform: translateX(-50%);
+ }
+
+ .wm-builder-grid {
+ border: 0;
+ gap: 1px;
+ }
+
+ .wm-production-mascot {
+ order: -1;
+ width: min(425px, 100%);
+ height: 550px;
+ min-height: 0;
+ margin: 0 auto 24px;
+ }
+
+ .wm-production-mascot img {
+ left: -17.04%;
+ width: 129.38%;
+ height: 100%;
+ max-width: none;
+ max-height: none;
+ }
+
+ .wm-production-aurora {
+ top: auto;
+ bottom: -150px;
+ height: 560px;
+ background-size: 960px 559px;
+ opacity: 0.48;
+ -webkit-mask-image: linear-gradient(to bottom, transparent 0, transparent 160px, rgba(0, 0, 0, 0.24) 280px, #000 430px);
+ mask-image: linear-gradient(to bottom, transparent 0, transparent 160px, rgba(0, 0, 0, 0.24) 280px, #000 430px);
+ }
+
+ .wm-production-transition {
+ height: 72px;
+ }
+
+ .wm-flow-column {
+ max-width: 560px;
+ margin: 0 auto;
+ }
+
+ .wm-faq {
+ gap: 36px;
+ }
+
+ .wm-footer-top {
+ grid-template-columns: 1fr;
+ gap: 36px;
+ }
+
+ .wm-footer-side {
+ align-items: flex-start;
+ }
+
+ .wm-footer-meta {
+ flex-direction: column;
+ align-items: flex-start;
+ gap: 8px;
+ }
+
+ .wm-bottom-cta {
+ width: 100%;
+ margin-top: 0;
+ margin-right: 0;
+ margin-left: 0;
+ }
+
+ .wm-bottom-copy,
+ .wm-cta-links {
+ max-width: 100%;
+ }
+
+ .wm-cta-links {
+ flex-wrap: wrap;
+ }
+
+ .wm-footer-word {
+ font-size: 7.4rem;
+ }
+}
+
+@media (min-width: 641px) and (max-width: 980px) {
+ .wm-portable {
+ padding-bottom: 61px;
+ }
+
+ .wm-portable .wm-small-cta {
+ min-height: 36px;
+ padding: 0 20px;
+ font-size: 12px;
+ }
+
+ .wm-stack {
+ width: 100%;
+ min-height: 498px;
+ padding: 0 clamp(46px, 6vw, 58px);
+ grid-template-columns: minmax(295px, 360px) minmax(0, 1fr);
+ gap: clamp(32px, 6.45vw, 62px);
+ background: transparent;
+ }
+
+ .wm-stack h2 {
+ max-width: 360px;
+ font-size: clamp(42px, 5vw, 48px);
+ line-height: 0.95;
+ }
+
+ .wm-stack p {
+ max-width: 300px;
+ margin: 17px 0 18px;
+ font-size: 14px;
+ line-height: 1.35;
+ letter-spacing: 0.14px;
+ }
+
+ .wm-stack a {
+ font-size: 12px;
+ }
+
+ .wm-stack-list {
+ padding-top: 72px;
+ gap: 18px;
+ }
+
+ .wm-stack-item {
+ min-height: 44px;
+ grid-template-columns: 24px 1fr;
+ gap: 12px;
+ }
+
+ .wm-stack-item > span {
+ width: 16px;
+ height: 16px;
+ margin-top: 3px;
+ background-size: 16px 16px;
+ }
+
+ .wm-stack-item h3 {
+ font-size: 16px;
+ line-height: 1.25;
+ }
+
+ .wm-stack-item p {
+ max-width: 330px;
+ margin-top: 5px;
+ font-size: 14px;
+ line-height: 1.35;
+ letter-spacing: 0.14px;
+ }
+
+ .wm-aurora--stack {
+ left: clamp(84px, 9.8vw, 118px);
+ top: 196px;
+ bottom: auto;
+ width: 82.8vw;
+ height: 49.45vw;
+ transform: none;
+ }
+}
+
+@media (max-width: 640px) {
+ .wm-nav {
+ width: calc(100% - 28px);
+ padding-top: 12px;
+ }
+
+ .wm-docs-button {
+ min-height: 40px;
+ padding: 0 16px;
+ font-size: 0.68rem;
+ }
+
+ .wm-logo {
+ font-size: 0.64rem;
+ }
+
+ .wm-logo-mark {
+ width: 31px;
+ height: 31px;
+ }
+
+ .wm-logo-mark span {
+ top: 8px;
+ width: 8px;
+ height: 8px;
+ }
+
+ .wm-hero {
+ width: 100%;
+ min-height: 910px;
+ padding-top: 78px;
+ }
+
+ .wm-hero-bg {
+ width: 1180px;
+ height: 870px;
+ top: -28px;
+ left: 50%;
+ }
+
+ .wm-hero h1 {
+ font-size: 3rem;
+ line-height: 0.96;
+ }
+
+ .wm-hero-copy p {
+ margin-top: 20px;
+ font-size: 0.94rem;
+ }
+
+ .wm-start-button {
+ min-height: 48px;
+ min-width: 168px;
+ }
+
+ .wm-sdk-bar {
+ min-height: 64px;
+ margin-top: 36px;
+ padding: 0 12px 0 18px;
+ }
+
+ .wm-sdk-bar > span:first-child {
+ gap: 10px;
+ font-size: 1rem;
+ }
+
+ .wm-sdk-actions {
+ gap: 8px;
+ }
+
+ .wm-sdk-toggles {
+ width: 70px;
+ height: 25px;
+ }
+
+ .wm-sdk-copy-icon {
+ width: 46px;
+ height: 46px;
+ margin-right: -7px;
+ }
+
+ .wm-code-panel {
+ height: 470px;
+ margin-top: 48px;
+ border-radius: 8px;
+ }
+
+ .wm-code-panel::before {
+ top: 44px;
+ }
+
+ .wm-code-dots {
+ top: 15px;
+ left: 14px;
+ gap: 8px;
+ }
+
+ .wm-code-dots span {
+ width: 12px;
+ height: 12px;
+ }
+
+ .wm-code-tabs {
+ top: 9px;
+ right: 8px;
+ gap: 4px;
+ }
+
+ .wm-code-tab {
+ height: 25px;
+ padding: 0 8px;
+ font-size: 10px;
+ letter-spacing: 0.1px;
+ }
+
+ .wm-code-copy {
+ top: 56px;
+ right: 10px;
+ width: 48px;
+ height: 48px;
+ }
+
+ .wm-code-lines {
+ top: 64px;
+ right: 12px;
+ font-size: 10px;
+ line-height: 1.5;
+ letter-spacing: 0.12px;
+ }
+
+ .wm-code-lines li {
+ grid-template-columns: 28px minmax(0, 1fr);
+ gap: 12px;
+ min-height: 15px;
+ }
+
+ .wm-mascot-stage {
+ --wm-mascot-scale: 0.54;
+ }
+
+ .wm-builders,
+ .wm-reset,
+ .wm-portable,
+ .wm-production,
+ .wm-footer {
+ width: calc(100% - 28px);
+ }
+
+ .wm-builders {
+ margin-top: 78px;
+ }
+
+ .wm-logo-row {
+ gap: 18px 22px;
+ margin: 24px auto 44px;
+ }
+
+ .wm-logo-allium {
+ width: 132px;
+ height: 39px;
+ }
+
+ .wm-logo-inflectiv {
+ width: 149px;
+ height: 32px;
+ }
+
+ .wm-logo-opengradient {
+ width: 196px;
+ height: 37px;
+ }
+
+ .wm-logo-talus {
+ width: 116px;
+ height: 20px;
+ }
+
+ .wm-builders h2,
+ .wm-reset h2,
+ .wm-portable h2,
+ .wm-light-heading h2,
+ .wm-production h2,
+ .wm-bottom-cta h2,
+ .wm-faq h2 {
+ font-size: 2.58rem;
+ line-height: 1;
+ }
+
+ .wm-builders p,
+ .wm-reset p,
+ .wm-light-heading p,
+ .wm-production p {
+ font-size: 1.08rem;
+ line-height: 1.35;
+ }
+
+ .wm-builders-quote-card {
+ height: auto;
+ }
+
+ .wm-builders p {
+ min-height: 0;
+ }
+
+ .wm-builder-person {
+ position: static;
+ width: 100%;
+ transform: none;
+ margin-top: 24px;
+ }
+
+ .wm-builder-lines {
+ transform: none;
+ }
+
+ .wm-spine {
+ height: 130px;
+ margin-bottom: 58px;
+ }
+
+ .wm-reset-visual {
+ height: 190px;
+ }
+
+ .wm-reset-aurora {
+ left: calc(50% + 250px);
+ top: -190px;
+ width: 640px;
+ height: 480px;
+ }
+
+ .wm-command-pill {
+ height: 70px;
+ padding: 0 18px;
+ font-size: 1rem;
+ }
+
+ .wm-card-grid {
+ margin-top: 44px;
+ }
+
+ .wm-dark-card {
+ min-height: 400px;
+ padding: 30px;
+ }
+
+ .wm-dark-card h3 {
+ margin-top: 44px;
+ font-size: 1.82rem;
+ }
+
+ .wm-stack {
+ width: calc(100% - 28px);
+ padding: 58px 24px;
+ }
+
+ .wm-stack h2 {
+ font-size: 2.55rem;
+ }
+
+ .wm-light-band {
+ padding: 80px 14px 88px;
+ }
+
+ .wm-builder-grid article {
+ position: relative;
+ display: grid;
+ grid-template-columns: 38px minmax(0, 1fr);
+ gap: 0 18px;
+ min-height: 260px;
+ padding: 28px;
+ }
+
+ .wm-builder-icon,
+ .wm-builder-grid h3,
+ .wm-builder-grid p {
+ position: static;
+ left: auto;
+ top: auto;
+ width: auto;
+ max-width: none;
+ }
+
+ .wm-builder-icon {
+ margin-top: 4px;
+ grid-row: 1 / span 2;
+ }
+
+ .wm-production {
+ width: 100%;
+ padding-top: 88px;
+ padding-right: 14px;
+ padding-left: 14px;
+ }
+
+ .wm-production::before {
+ display: none;
+ }
+
+ .wm-production-grid {
+ gap: 22px;
+ }
+
+ .wm-production-mascot {
+ width: min(330px, 100%);
+ height: 427px;
+ }
+
+ .wm-flow-column > button {
+ min-height: 60px;
+ font-size: 1.22rem;
+ }
+
+ .wm-bottom-cta {
+ min-height: 520px;
+ padding: 82px 14px 64px;
+ }
+
+ .wm-bottom-cta h2 {
+ width: 100%;
+ }
+
+ .wm-bottom-copy {
+ width: min(340px, 100%);
+ }
+
+ .wm-bottom-copy strong {
+ font-size: 1.08rem;
+ }
+
+ .wm-bottom-copy span {
+ font-size: 0.98rem;
+ }
+
+ .wm-cta-links {
+ gap: 18px;
+ }
+
+ .wm-faq {
+ width: calc(100% - 28px);
+ padding: 58px 24px;
+ }
+
+ .wm-faq h3 {
+ font-size: 1.42rem;
+ }
+
+ .wm-footer-bottom {
+ display: block;
+ min-height: 320px;
+ margin-top: 64px;
+ }
+
+ .wm-footer-word {
+ font-size: 4.2rem;
+ bottom: 70px;
+ }
+
+ .wm-footer-meta {
+ position: relative;
+ top: auto;
+ right: auto;
+ width: min(300px, 100%);
+ margin: 0;
+ }
+
+ .wm-footer-bottom img {
+ width: 300px;
+ height: 142px;
+ max-width: 78vw;
+ }
+
+ .wm-socials {
+ bottom: 22px;
+ }
+}
+
+/* ========== Walrus Memory Figma dashboard rebuild (node 2255-167) ========== */
+
+.dash-page {
+ --dash-bg: #000000;
+ --dash-card: #000000;
+ --dash-panel: rgba(255, 255, 255, 0.08);
+ --dash-panel-border: rgba(250, 248, 245, 0.1);
+ --dash-card-border: #54575a;
+ --dash-card-border-hover: rgba(250, 248, 245, 0.28);
+ --dash-text: #faf8f5;
+ --dash-muted: #8f9294;
+ --dash-subtle: #c7c5c1;
+ --dash-yellow: #e8ff75;
+ --dash-yellow-soft: rgba(232, 255, 117, 0.1);
+ --dash-yellow-border: rgba(232, 255, 117, 0.36);
+ --dash-violet: #e8ff75;
+ --dash-paper: #faf8f5;
+ min-height: 100vh;
+ background: var(--dash-bg);
+ color: var(--dash-text);
+ font-family: var(--font-sans);
+ overflow-x: clip;
+}
+
+.dash-page a {
+ color: inherit;
+}
+
+.dash-page button {
+ font-family: inherit;
+}
+
+.dash-nav {
+ width: min(1240px, calc(100% - 40px));
+ margin: 0 auto;
+ padding: 24px 0 14px;
+}
+
+.dash-nav-inner {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ gap: 16px;
+}
+
+.dash-logo {
+ display: inline-flex;
+ flex-direction: column;
+ line-height: 0.86;
+ color: var(--dash-text);
+ font-weight: 900;
+ font-size: 1.35rem;
+ text-transform: lowercase;
+ text-decoration: none;
+ letter-spacing: 0;
+}
+
+.dash-logo span:nth-child(2) {
+ color: transparent;
+ background: var(--wordmark-memory-gradient);
+ -webkit-background-clip: text;
+ background-clip: text;
+}
+
+.dash-nav-actions {
+ display: inline-flex;
+ align-items: center;
+ gap: 14px;
+ min-width: 0;
+}
+
+.dash-page .dash-address {
+ width: 125px;
+ height: 28px;
+ min-height: 28px;
+ padding: 0 12px;
+ border-radius: 4px;
+ background: #262b30;
+ color: var(--dash-text);
+ font-family: var(--font-mono);
+ font-size: 12px;
+ font-weight: 500;
+ line-height: 0.84;
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ border: 0;
+ text-align: center;
+ white-space: nowrap;
+}
+
+.dash-outline-button {
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ gap: 8px;
+ min-height: 52px;
+ padding: 0 28px;
+ border-radius: 26px;
+ background: #000000;
+ color: var(--dash-text);
+ font-size: 1rem;
+ font-weight: 600;
+ border: 1px solid var(--dash-paper);
+ cursor: pointer;
+ transition: background 180ms ease, border-color 180ms ease;
+}
+
+.dash-outline-button:hover {
+ background: rgba(250, 248, 245, 0.08);
+ border-color: var(--dash-paper);
+}
+
+.dash-shell {
+ width: min(1240px, calc(100% - 40px));
+ margin: 0 auto;
+ padding: 60px 0 80px;
+}
+
+.dash-page .dashboard-header {
+ margin-bottom: 36px;
+}
+
+.dash-page .dashboard-header h2 {
+ font-size: 56px;
+ font-weight: 500;
+ color: var(--dash-text);
+ letter-spacing: 0;
+ line-height: 0.88;
+}
+
+.dash-page .dashboard-header p {
+ margin-top: 14px;
+ color: var(--dash-muted);
+ font-size: 21px;
+ font-weight: 500;
+ line-height: 1.3;
+ overflow-wrap: anywhere;
+}
+
+.dash-page .dashboard-header--compact {
+ margin-bottom: 28px;
+}
+
+.dash-page .dash-alert {
+ min-height: 65px;
+ position: relative;
+ display: flex;
+ align-items: center;
+ border: 0;
+ background: var(--dash-yellow);
+ border-radius: 4px;
+ padding: 16px 24px 16px 68px;
+ color: #000000;
+}
+
+.dash-page .dash-alert::before {
+ content: none;
+}
+
+.dash-alert-icon {
+ position: absolute;
+ left: 20px;
+ top: 50%;
+ width: 29px;
+ height: 26px;
+ transform: translateY(-50%);
+ color: #000000;
+ display: block;
+ clip-path: polygon(50% 0, 100% 100%, 0 100%);
+ background: currentColor;
+}
+
+.dash-alert-icon::before {
+ content: "";
+ position: absolute;
+ left: 13px;
+ top: 7px;
+ width: 3px;
+ height: 11px;
+ border-radius: 999px;
+ background: var(--dash-yellow);
+}
+
+.dash-alert-icon::after {
+ content: "";
+ position: absolute;
+ left: 13px;
+ top: 20px;
+ width: 3px;
+ height: 3px;
+ border-radius: 999px;
+ background: var(--dash-yellow);
+}
+
+.dash-page .dash-alert p {
+ color: #000000;
+ font-size: 21px;
+ font-weight: 500;
+ line-height: 1.3;
+ margin: 0;
+ min-width: 0;
+ overflow-wrap: anywhere;
+}
+
+.dash-page .dashboard-cta-row {
+ display: grid;
+ grid-template-columns: repeat(2, minmax(0, 1fr));
+ gap: 20px;
+ margin-bottom: 28px;
+}
+
+.dash-page .dashboard-cta-row > :only-child {
+ grid-column: 1 / -1;
+}
+
+.dash-page .dashboard-cta {
+ display: grid;
+ grid-template-columns: auto 1fr auto;
+ align-items: center;
+ gap: 24px;
+ height: 114px;
+ min-height: 114px;
+ padding: 25px 29px;
+ border-radius: 24px;
+ background: rgba(255, 255, 255, 0.08);
+ border: 1px solid rgba(250, 248, 245, 0.1);
+ color: var(--dash-text);
+ text-decoration: none;
+ cursor: pointer;
+ box-shadow: none;
+ overflow: hidden;
+ transform: none;
+ transition: border-color 180ms ease, transform 180ms ease, background 180ms ease;
+ margin-bottom: 0;
+}
+
+.dash-page .dashboard-cta:hover {
+ border-color: var(--dash-card-border-hover);
+ background: rgba(255, 255, 255, 0.12);
+ transform: translateY(-2px);
+ box-shadow: none;
+}
+
+.dash-page .dashboard-cta:active {
+ transform: translateY(0);
+ box-shadow: none;
+}
+
+.dash-page .dashboard-cta--disabled {
+ cursor: default;
+ opacity: 0.6;
+}
+
+.dash-page .dashboard-cta--disabled:hover {
+ border-color: var(--dash-panel-border);
+ background: var(--dash-panel);
+ transform: none;
+}
+
+.dash-page .dashboard-cta-icon-wrap {
+ width: 35px;
+ height: 40px;
+ margin-top: 0;
+ border-radius: 0;
+ border: 0;
+ display: grid;
+ place-items: center;
+ color: #8f9294;
+ flex-shrink: 0;
+}
+
+.dash-page .dashboard-cta-icon {
+ width: 35px;
+ height: 40px;
+ color: #8f9294;
+ display: block;
+}
+
+.dash-page .dashboard-cta-text {
+ min-width: 0;
+}
+
+.dash-page .dashboard-cta-title {
+ color: var(--dash-text);
+ font-size: 24px;
+ font-weight: 700;
+ line-height: 1.3;
+ overflow-wrap: anywhere;
+}
+
+.dash-page .dashboard-cta-subtitle {
+ margin-top: 5px;
+ color: #c7c5c1;
+ font-size: 18px;
+ font-weight: 400;
+ line-height: 1.4;
+ letter-spacing: 0.18px;
+ overflow-wrap: anywhere;
+}
+
+.dash-page .dashboard-cta-arrow {
+ color: var(--dash-text);
+ width: 20.36px;
+ height: 20.36px;
+ margin-top: 4px;
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ flex-shrink: 0;
+}
+
+.dash-page .card {
+ background: var(--dash-card);
+ border: 1px solid var(--dash-card-border);
+ border-radius: 24px;
+ padding: 40px;
+ box-shadow: none;
+ color: var(--dash-text);
+}
+
+.dash-page .card:hover {
+ box-shadow: none;
+}
+
+.dash-page .dashboard-keys-card {
+ border-color: var(--dash-card-border);
+ box-shadow: none;
+}
+
+.dash-page .card-header {
+ align-items: flex-start;
+ margin-bottom: 22px;
+ gap: 18px;
+}
+
+.dash-page .card-title {
+ font-size: 36px;
+ font-weight: 500;
+ color: var(--dash-text);
+ letter-spacing: 0;
+ line-height: 0.88;
+ overflow-wrap: anywhere;
+}
+
+.dash-page .card-subtitle {
+ margin-top: 8px;
+ color: var(--dash-muted);
+ font-size: 18px;
+ font-weight: 500;
+ line-height: 1.35;
+ overflow-wrap: anywhere;
+}
+
+.dash-page .card-header-actions {
+ flex-shrink: 0;
+ align-self: center;
+}
+
+.dash-page .card-header-actions .btn-secondary,
+.dash-page .dashboard-keys-refresh {
+ background: transparent;
+ color: var(--dash-text);
+ border: 1px solid var(--dash-paper);
+ border-radius: 26px;
+ padding: 0 24px;
+ min-height: 52px;
+ font-size: 1rem;
+ font-weight: 600;
+ box-shadow: none;
+ display: inline-flex;
+ align-items: center;
+ gap: 8px;
+ transition: background 180ms ease, border-color 180ms ease;
+}
+
+.dash-page .dashboard-keys-refresh:hover:not(:disabled) {
+ background: rgba(250, 248, 245, 0.08);
+ border-color: var(--dash-paper);
+ transform: none;
+ box-shadow: none;
+}
+
+.dash-page .dashboard-keys-add,
+.dash-page .lp-nav-cta {
+ background: var(--dash-paper);
+ color: var(--dash-bg);
+ border: 1px solid var(--dash-paper);
+ border-radius: 26px;
+ padding: 0 28px;
+ min-height: 52px;
+ font-size: 1rem;
+ font-weight: 600;
+ box-shadow: none;
+ display: inline-flex;
+ align-items: center;
+ gap: 8px;
+ cursor: pointer;
+ transition: background 160ms ease, transform 160ms ease;
+}
+
+.dash-page .dashboard-keys-add:hover:not(:disabled),
+.dash-page .lp-nav-cta:hover:not(:disabled) {
+ background: var(--dash-yellow);
+ border-color: var(--dash-yellow);
+ transform: translateY(-1px);
+ box-shadow: none;
+}
+
+.dash-page .dashboard-keys-add:disabled,
+.dash-page .lp-nav-cta:disabled {
+ opacity: 0.45;
+ cursor: not-allowed;
+}
+
+.dash-page .dashboard-empty-message {
+ color: var(--dash-muted) !important;
+ font-size: 0.96rem !important;
+ padding: 56px 0 !important;
+}
+
+.dash-page .key-display,
+.dash-page .key-display--white {
+ background: rgba(255, 255, 255, 0.08);
+ border: 1px solid var(--dash-card-border);
+ border-radius: 16px;
+ padding: 20px;
+ box-shadow: none;
+ color: var(--dash-text);
+}
+
+.dash-page .key-display .key-label {
+ color: var(--dash-yellow);
+ letter-spacing: 0.1em;
+ font-weight: 700;
+ text-transform: uppercase;
+ font-size: 0.7rem;
+}
+
+.dash-page .key-display .key-value {
+ color: var(--dash-text);
+}
+
+.dash-page .key-display .btn-secondary,
+.dash-page .key-display .btn-danger {
+ border: 0;
+ border-radius: 999px;
+ padding: 6px 14px;
+ font-size: 0.74rem;
+ box-shadow: none;
+ display: inline-flex;
+ align-items: center;
+ gap: 6px;
+}
+
+.dash-page .key-display .btn-secondary {
+ background: rgba(255, 255, 255, 0.12);
+ border: 1px solid rgba(255, 255, 255, 0.16);
+ color: var(--dash-text);
+ transition: background 0.12s ease, border-color 0.12s ease;
+}
+
+.dash-page .key-display .btn-secondary:hover:not(:disabled) {
+ background: #faf8f5;
+ border-color: #faf8f5;
+ color: #000000;
+ transform: none;
+ box-shadow: none;
+}
+
+.dash-page .key-display .btn-danger {
+ background: rgba(248, 113, 113, 0.12);
+ color: #fda4af;
+}
+
+.dash-page .key-display .btn-danger:hover:not(:disabled) {
+ background: rgba(248, 113, 113, 0.22);
+ transform: none;
+ box-shadow: none;
+}
+
+.dash-page .warning-box {
+ background: #e8ff75;
+ border: 0;
+ border-radius: 4px;
+ box-shadow: none;
+ padding: 16px 24px;
+ color: #000000;
+}
+
+.dash-page .warning-box p {
+ color: #000000;
+ font-size: 0.86rem;
+ margin: 0;
+ line-height: 1.5;
+}
+
+.dash-page .warning-box strong {
+ color: #000000;
+}
+
+.dash-page .warning-box code {
+ background: rgba(0, 0, 0, 0.08);
+ color: #000000;
+ padding: 1px 6px;
+ border-radius: 4px;
+ font-size: 0.82em;
+}
+
+.dash-connect-shell {
+ min-height: calc(100vh - 108px);
+ display: grid;
+ place-items: center;
+ padding-top: 28px;
+}
+
+.dash-connect-card {
+ width: min(760px, 100%);
+ display: grid;
+ grid-template-columns: auto 1fr;
+ gap: 26px;
+ align-items: start;
+ padding: 38px;
+ border-radius: 22px;
+ border: 1px solid var(--dash-card-border);
+ background: var(--dash-card);
+}
+
+.dash-connect-kicker {
+ margin: 0 0 12px;
+ color: var(--dash-violet);
+ font-size: 0.72rem;
+ font-weight: 900;
+ letter-spacing: 0.12em;
+ text-transform: uppercase;
+}
+
+.dash-connect-card h1 {
+ margin: 0;
+ color: var(--dash-text);
+ font-size: clamp(2rem, 5vw, 4.6rem);
+ font-weight: 900;
+ letter-spacing: 0;
+ line-height: 0.98;
+}
+
+.dash-connect-card p:not(.dash-connect-kicker) {
+ max-width: 520px;
+ margin: 18px 0 0;
+ color: var(--dash-muted);
+ font-size: 1rem;
+ line-height: 1.55;
+}
+
+.dash-connect-actions {
+ grid-column: 2;
+ display: flex;
+ margin-top: 8px;
+}
+
+.dash-connect-actions [class*="ConnectButton"] button,
+.dash-connect-actions button[data-dapp-kit] {
+ min-height: 48px !important;
+ padding: 0 26px !important;
+ border: 0 !important;
+ border-radius: 999px !important;
+ background: var(--dash-paper) !important;
+ color: var(--dash-bg) !important;
+ font-family: var(--font-sans) !important;
+ font-size: 0.9rem !important;
+ font-weight: 900 !important;
+ box-shadow: none !important;
+ transition: background 160ms ease, transform 160ms ease !important;
+}
+
+.dash-connect-actions [class*="ConnectButton"] button:hover,
+.dash-connect-actions button[data-dapp-kit]:hover {
+ background: var(--dash-yellow) !important;
+ transform: translateY(-1px);
+}
+
+.setup-page {
+ min-height: 100vh;
+}
+
+.setup-shell {
+ width: min(1160px, calc(100% - 48px));
+ min-height: calc(100vh - 128px);
+ margin: 0 auto;
+ padding: 64px 0 84px;
+ display: grid;
+ grid-template-columns: minmax(280px, 0.86fr) minmax(520px, 1.14fr);
+ gap: 42px;
+ align-items: start;
+}
+
+.setup-hero {
+ position: sticky;
+ top: 32px;
+ padding-top: 6px;
+}
+
+.setup-back-link {
+ display: inline-flex;
+ align-items: center;
+ gap: 8px;
+ min-height: 40px;
+ margin-bottom: 42px;
+ color: var(--dash-muted);
+ font-size: 0.86rem;
+ font-weight: 800;
+ text-decoration: none;
+ transition: color 160ms ease;
+}
+
+.setup-back-link:hover {
+ color: var(--dash-text);
+}
+
+.setup-kicker {
+ margin: 0 0 18px;
+ color: var(--dash-violet);
+ font-size: 0.76rem;
+ font-weight: 900;
+ letter-spacing: 0.12em;
+ text-transform: uppercase;
+}
+
+.setup-hero h1 {
+ max-width: 520px;
+ margin: 0;
+ color: var(--dash-text);
+ font-size: clamp(3rem, 4.8vw, 5.2rem);
+ font-weight: 900;
+ letter-spacing: 0;
+ line-height: 0.92;
+}
+
+.setup-hero p:not(.setup-kicker) {
+ max-width: 440px;
+ margin: 24px 0 0;
+ color: var(--dash-muted);
+ font-size: 1rem;
+ line-height: 1.58;
+}
+
+.setup-card {
+ width: 100%;
+ min-height: 610px;
+ padding: 28px;
+ border: 1px solid var(--dash-card-border);
+ border-radius: 22px;
+ background: var(--dash-card);
+}
+
+.setup-progress {
+ display: grid;
+ grid-template-columns: repeat(3, minmax(0, 1fr));
+ gap: 10px;
+ margin-bottom: 28px;
+}
+
+.setup-progress-step {
+ min-height: 38px;
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ gap: 7px;
+ border: 1px solid rgba(255, 255, 255, 0.11);
+ border-radius: 999px;
+ color: var(--dash-muted);
+ font-size: 0.78rem;
+ font-weight: 800;
+}
+
+.setup-progress-step--active {
+ border-color: var(--dash-yellow-border);
+ background: var(--dash-yellow-soft);
+ color: var(--dash-text);
+}
+
+.setup-progress-step--done {
+ border-color: rgba(232, 255, 117, 0.32);
+ color: #e8ff75;
+}
+
+.setup-panel,
+.setup-state-panel {
+ display: flex;
+ flex-direction: column;
+}
+
+.setup-panel-header {
+ margin-bottom: 24px;
+}
+
+.setup-panel-header h2,
+.setup-state-panel h2 {
+ margin: 0;
+ color: var(--dash-text);
+ font-size: clamp(2rem, 4vw, 3rem);
+ font-weight: 900;
+ letter-spacing: 0;
+ line-height: 1;
+}
+
+.setup-panel-header p,
+.setup-state-panel p {
+ margin: 12px 0 0;
+ color: var(--dash-muted);
+ font-size: 0.96rem;
+ line-height: 1.55;
+}
+
+.setup-feature-grid {
+ display: grid;
+ grid-template-columns: repeat(3, minmax(0, 1fr));
+ gap: 12px;
+ margin-bottom: 24px;
+}
+
+.setup-feature-grid > div {
+ min-height: 128px;
+ padding: 18px;
+ border: 1px solid rgba(255, 255, 255, 0.08);
+ border-radius: 16px;
+ background: rgba(255, 255, 255, 0.04);
+}
+
+.setup-feature-grid strong {
+ display: block;
+ margin-bottom: 8px;
+ color: var(--dash-text);
+ font-size: 0.94rem;
+ font-weight: 900;
+}
+
+.setup-feature-grid p {
+ margin: 0;
+ color: var(--dash-muted);
+ font-size: 0.84rem;
+ line-height: 1.42;
+}
+
+.setup-primary-button,
+.setup-secondary-button,
+.setup-mini-button {
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ gap: 9px;
+ border-radius: 999px;
+ font-family: var(--font-sans);
+ font-weight: 900;
+ letter-spacing: 0;
+ cursor: pointer;
+ transition: background 160ms ease, color 160ms ease, border-color 160ms ease, transform 160ms ease;
+}
+
+.setup-primary-button {
+ width: fit-content;
+ min-height: 48px;
+ padding: 0 26px;
+ border: 0;
+ background: var(--dash-paper);
+ color: var(--dash-bg);
+}
+
+.setup-primary-button--wide {
+ width: 100%;
+}
+
+.setup-primary-button:hover:not(:disabled),
+.setup-secondary-button:hover:not(:disabled),
+.setup-mini-button:hover:not(:disabled) {
+ transform: translateY(-1px);
+}
+
+.setup-primary-button:hover:not(:disabled) {
+ background: var(--dash-yellow);
+}
+
+.setup-primary-button:disabled,
+.setup-secondary-button:disabled {
+ opacity: 0.45;
+ cursor: not-allowed;
+}
+
+.setup-divider {
+ display: flex;
+ align-items: center;
+ gap: 14px;
+ margin: 26px 0 18px;
+ color: var(--dash-muted);
+ font-size: 0.76rem;
+ font-weight: 800;
+ text-transform: uppercase;
+}
+
+.setup-divider::before,
+.setup-divider::after {
+ content: "";
+ height: 1px;
+ flex: 1;
+ background: rgba(255, 255, 255, 0.09);
+}
+
+.setup-import {
+ display: grid;
+ gap: 12px;
+}
+
+.setup-textarea {
+ width: 100%;
+ min-height: 112px;
+ resize: vertical;
+ padding: 18px;
+ border: 1px solid rgba(255, 255, 255, 0.14);
+ border-radius: 16px;
+ outline: none;
+ background: #050505;
+ color: var(--dash-text);
+ font-family: var(--font-mono);
+ font-size: 0.92rem;
+ line-height: 1.5;
+}
+
+.setup-textarea:focus {
+ border-color: var(--dash-yellow);
+}
+
+.setup-secondary-button {
+ min-height: 46px;
+ padding: 0 22px;
+ border: 1px solid var(--dash-yellow-border);
+ background: var(--dash-yellow-soft);
+ color: var(--dash-text);
+}
+
+.setup-secondary-button:hover:not(:disabled) {
+ background: rgba(232, 255, 117, 0.16);
+}
+
+.setup-warning,
+.setup-error {
+ margin-bottom: 16px;
+ padding: 14px 16px;
+ border-radius: 14px;
+ font-size: 0.88rem;
+ line-height: 1.5;
+}
+
+.setup-warning {
+ border: 1px solid rgba(232, 255, 117, 0.24);
+ background: rgba(232, 255, 117, 0.08);
+ color: var(--dash-text);
+}
+
+.setup-warning strong {
+ color: #e8ff75;
+}
+
+.setup-warning code {
+ padding: 1px 6px;
+ border-radius: 6px;
+ background: rgba(0, 0, 0, 0.35);
+ color: #e8ff75;
+}
+
+.setup-error {
+ border: 1px solid rgba(248, 113, 113, 0.28);
+ background: rgba(248, 113, 113, 0.09);
+ color: #fca5a5;
+}
+
+.setup-error-action {
+ margin-top: 12px;
+}
+
+.setup-key-box {
+ position: relative;
+ margin-bottom: 14px;
+ padding: 18px 92px 18px 18px;
+ border: 1px solid rgba(255, 255, 255, 0.1);
+ border-radius: 16px;
+ background: #050505;
+}
+
+.setup-key-box--muted {
+ padding-right: 18px;
+}
+
+.setup-key-label {
+ margin-bottom: 8px;
+ color: var(--dash-muted);
+ font-size: 0.68rem;
+ font-weight: 900;
+ letter-spacing: 0.1em;
+ text-transform: uppercase;
+}
+
+.setup-key-value {
+ color: var(--dash-text);
+ font-family: var(--font-mono);
+ font-size: 0.8rem;
+ line-height: 1.6;
+ overflow-wrap: anywhere;
+}
+
+.setup-mini-button {
+ min-height: 34px;
+ padding: 0 13px;
+ border: 1px solid rgba(255, 255, 255, 0.14);
+ background: rgba(255, 255, 255, 0.08);
+ color: var(--dash-text);
+ font-size: 0.78rem;
+ text-decoration: none;
+}
+
+.setup-key-box .setup-mini-button {
+ position: absolute;
+ top: 18px;
+ right: 18px;
+}
+
+.setup-mini-button:hover:not(:disabled) {
+ background: rgba(255, 255, 255, 0.14);
+}
+
+.setup-confirm {
+ display: flex;
+ gap: 10px;
+ align-items: flex-start;
+ margin: 20px 0 18px;
+ color: var(--dash-muted);
+ font-size: 0.88rem;
+ line-height: 1.45;
+ cursor: pointer;
+}
+
+.setup-confirm input {
+ margin-top: 3px;
+ accent-color: var(--dash-yellow);
+}
+
+.setup-state-panel {
+ min-height: 430px;
+ align-items: center;
+ justify-content: center;
+ text-align: center;
+ color: var(--dash-text);
+}
+
+.setup-state-panel .spinner {
+ width: 34px;
+ height: 34px;
+ margin-bottom: 22px;
+}
+
+.setup-state-panel > svg {
+ margin-bottom: 18px;
+ color: var(--dash-yellow);
+}
+
+.dashboard-quickstart-toggle {
+ display: inline-flex;
+ align-items: center;
+ gap: 4px;
+ height: 32px;
+ padding: 4px;
+ border-radius: 999px;
+ background: rgba(255, 255, 255, 0.08);
+ color: var(--dash-muted);
+ font-family: var(--font-mono);
+ font-size: 0.7rem;
+ font-weight: 800;
+ text-transform: uppercase;
+ letter-spacing: 0.05em;
+}
+
+.dashboard-quickstart-toggle > button,
+.dashboard-quickstart-toggle > span {
+ display: inline-grid;
+ place-items: center;
+ height: 100%;
+ padding: 0 14px;
+ border: 0;
+ border-radius: 999px;
+ background: transparent;
+ color: inherit;
+ font: inherit;
+ text-transform: uppercase;
+ letter-spacing: inherit;
+ cursor: pointer;
+}
+
+.dashboard-quickstart-toggle > button:hover {
+ color: var(--dash-text);
+}
+
+.dashboard-quickstart-toggle-active {
+ background: var(--dash-paper);
+ color: var(--dash-bg) !important;
+}
+
+.dashboard-quickstart-toggle > button.dashboard-quickstart-toggle-active {
+ background: var(--dash-paper);
+ color: var(--dash-bg) !important;
+}
+
+.dash-page .dashboard-quickstart-codewrap {
+ position: relative;
+}
+
+.dash-page .dashboard-quickstart-card pre,
+.dash-page .dashboard-quickstart-card .demo-code-block {
+ background: #050505 !important;
+ border-radius: 18px;
+ border: 1px solid rgba(255, 255, 255, 0.08);
+ margin: 0;
+ padding: 28px 32px !important;
+ font-size: 15px;
+ line-height: 1.4;
+ font-weight: 300;
+ overflow-x: auto;
+}
+
+.dash-page .dashboard-quickstart-card pre code,
+.dash-page .dashboard-quickstart-card .demo-code-block code {
+ color: var(--dash-paper) !important;
+ background: transparent !important;
+}
+
+.dash-page .dashboard-quickstart-copy {
+ position: absolute;
+ top: 18px;
+ right: 18px;
+ z-index: 2;
+ width: 44px;
+ height: 44px;
+ padding: 0;
+ border-radius: 50%;
+ background: rgba(255, 255, 255, 0.08);
+ color: var(--dash-text);
+ border: 0;
+ display: grid;
+ place-items: center;
+ box-shadow: none;
+ cursor: pointer;
+ transition: background 160ms ease;
+}
+
+.dash-page .dashboard-quickstart-copy:hover:not(:disabled) {
+ background: rgba(255, 255, 255, 0.16);
+ transform: none;
+ box-shadow: none;
+}
+
+.dash-page .dashboard-quickstart-copy-label {
+ display: none;
+}
+
+.dash-page .install-tabs {
+ display: inline-flex;
+ gap: 10px;
+ background: transparent;
+ border: 0;
+ overflow: visible;
+ margin-bottom: 22px;
+}
+
+.dash-page .install-tab,
+.dash-page .install-tab:last-child {
+ width: 72px;
+ height: 28px;
+ min-height: 28px;
+ border: 0;
+ border-radius: 4px;
+ background: #1d2227;
+ color: var(--dash-muted);
+ padding: 0;
+ font-size: 14px;
+ font-weight: 500;
+ font-family: var(--font-sans);
+ text-transform: lowercase;
+ line-height: 0.84;
+ transition: background 160ms ease, color 160ms ease;
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+}
+
+.dash-page .install-tab:hover {
+ background: rgba(255, 255, 255, 0.12);
+ color: var(--dash-text);
+}
+
+.dash-page .install-tab--active {
+ background: var(--dash-paper);
+ color: var(--dash-bg) !important;
+}
+
+.dash-page .install-command,
+.dash-page .install-tabs + .demo-code-block {
+ background: transparent !important;
+ border: 0 !important;
+ border-radius: 0 !important;
+ padding: 14px 0 !important;
+ font-size: 0.98rem;
+ color: var(--dash-paper) !important;
+}
+
+.dash-page .install-command code {
+ color: var(--dash-paper) !important;
+}
+
+@media (max-width: 860px) {
+ .dash-shell {
+ padding: 40px 0 60px;
+ }
+
+ .dash-page .dashboard-header h2 {
+ font-size: 3.4rem;
+ }
+
+ .dash-page .dashboard-cta-row {
+ grid-template-columns: 1fr;
+ }
+
+ .dash-page .dashboard-cta {
+ min-height: 108px;
+ padding: 22px 24px;
+ }
+
+ .dash-page .dashboard-cta-icon-wrap {
+ width: 40px;
+ height: 40px;
+ }
+
+ .dash-page .dashboard-cta-icon {
+ width: 22px;
+ height: 22px;
+ }
+
+ .dash-page .dashboard-cta-title {
+ font-size: 1.2rem;
+ }
+
+ .dash-page .card {
+ padding: 24px 22px;
+ }
+
+ .dash-page .card-header {
+ flex-direction: column;
+ align-items: flex-start;
+ }
+
+ .dash-page .card-title {
+ font-size: 1.45rem;
+ }
+
+ .dash-page .card-header-actions {
+ width: 100%;
+ display: grid;
+ grid-template-columns: 1fr 1fr;
+ gap: 10px;
+ align-self: stretch;
+ }
+
+ .dash-page .dashboard-keys-refresh,
+ .dash-page .dashboard-keys-add {
+ width: 100%;
+ justify-content: center;
+ }
+
+ .dash-page .dashboard-quickstart-card pre,
+ .dash-page .dashboard-quickstart-card .demo-code-block {
+ padding: 22px 18px !important;
+ font-size: 0.78rem;
+ }
+
+ .dash-connect-card {
+ grid-template-columns: 1fr;
+ padding: 28px 24px;
+ }
+
+ .dash-connect-actions {
+ grid-column: 1;
+ }
+
+ .setup-shell {
+ width: calc(100% - 32px);
+ min-height: auto;
+ grid-template-columns: 1fr;
+ gap: 26px;
+ padding: 40px 0 64px;
+ }
+
+ .setup-hero {
+ position: static;
+ }
+
+ .setup-back-link {
+ margin-bottom: 28px;
+ }
+
+ .setup-card {
+ min-height: auto;
+ padding: 22px;
+ }
+
+ .setup-feature-grid,
+ .setup-progress {
+ grid-template-columns: 1fr;
+ }
+
+ .setup-primary-button {
+ width: 100%;
+ }
+}
+
+@media (max-width: 640px) {
+ .dash-nav {
+ width: calc(100% - 40px);
+ padding-top: 18px;
+ }
+
+ .dash-nav-inner {
+ display: grid;
+ grid-template-columns: 1fr;
+ justify-items: center;
+ gap: 18px;
+ }
+
+ .dash-nav-actions {
+ width: 100%;
+ justify-content: space-between;
+ gap: 10px;
+ }
+
+ .dash-page .dash-address {
+ max-width: 145px;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ }
+
+ .dash-outline-button {
+ min-height: 44px;
+ padding: 0 18px;
+ font-size: 0.9rem;
+ }
+
+ .dash-page .dash-alert {
+ padding: 16px 18px 16px 56px;
+ }
+
+ .dash-alert::before {
+ left: 20px;
+ }
+
+ .dash-page .dashboard-header h2 {
+ font-size: 2.6rem;
+ }
+}
+
+/* ========== Playground dark theme ========== */
+
+.app:has(.playground-dashboard) {
+ --bg-primary: #000000;
+ --bg-secondary: #050505;
+ --bg-card: #0a0a0a;
+ --bg-card-hover: rgba(255, 255, 255, 0.08);
+ --bg-input: #050505;
+ --text-primary: #faf8f5;
+ --text-secondary: #c7c5c1;
+ --text-muted: #8f9294;
+ --playground-accent: #e8ff75;
+ --playground-accent-strong: #e8ff75;
+ --playground-accent-soft: rgba(232, 255, 117, 0.1);
+ --playground-accent-border: rgba(232, 255, 117, 0.36);
+ --accent-subtle: var(--playground-accent-soft);
+ --success: #86efac;
+ --success-border: rgba(34, 197, 94, 0.35);
+ --warning: #fde68a;
+ --warning-border: rgba(245, 158, 11, 0.35);
+ --danger: #fca5a5;
+ --danger-border: rgba(248, 113, 113, 0.35);
+ --border: 1px solid #54575a;
+ --border-light: 1px solid rgba(250, 248, 245, 0.12);
+ --neo-shadow: none;
+ --neo-shadow-sm: none;
+ --neo-shadow-xs: none;
+ background: #000000;
+ color: #faf8f5;
+}
+
+.playground-nav {
+ background: #000000;
+ border-bottom: 1px solid rgba(250, 248, 245, 0.1);
+}
+
+.playground-nav .demo-nav-back {
+ color: #8f9294;
+}
+
+.playground-nav .demo-nav-back:hover {
+ color: #faf8f5;
+}
+
+.playground-nav .nav-address {
+ border: 0;
+ background: #262b30;
+ color: #faf8f5;
+}
+
+.playground-nav .lp-nav-cta {
+ border: 1px solid #faf8f5;
+ background: #faf8f5;
+ color: #000000;
+ box-shadow: none;
+}
+
+.playground-nav .lp-nav-cta:hover:not(:disabled) {
+ background: var(--playground-accent);
+ border-color: var(--playground-accent);
+ transform: translateY(-1px);
+ box-shadow: none;
+}
+
+.playground-dashboard .dashboard-header h2,
+.playground-dashboard .dashboard-header p,
+.playground-dashboard .input-group label,
+.playground-dashboard .card-title,
+.playground-dashboard .demo-step-title {
+ color: #faf8f5;
+}
+
+.playground-dashboard .dashboard-header p,
+.playground-dashboard .card-subtitle {
+ color: #c7c5c1;
+}
+
+.playground-dashboard .dashboard-header strong,
+.playground-dashboard .dashboard-header code {
+ color: var(--playground-accent);
+}
+
+.playground-dashboard .card,
+.playground-dashboard .demo-step {
+ border: 1px solid #54575a;
+ background: #0a0a0a;
+ color: #faf8f5;
+ box-shadow: none;
+}
+
+.playground-dashboard .card:hover {
+ border-color: rgba(250, 248, 245, 0.28);
+ box-shadow: none;
+}
+
+.playground-dashboard .demo-step-badge {
+ border: 1px solid #54575a;
+ background: rgba(255, 255, 255, 0.08);
+ color: #faf8f5;
+ box-shadow: none;
+}
+
+.playground-dashboard .demo-step-badge--highlight {
+ border-color: var(--playground-accent);
+ background: var(--playground-accent);
+ color: #000000;
+}
+
+.playground-dashboard .btn-primary {
+ border: 1px solid var(--playground-accent);
+ background: var(--playground-accent);
+ color: #000000;
+ box-shadow: none;
+}
+
+.playground-dashboard .btn-primary:hover:not(:disabled) {
+ background: #faf8f5;
+ border-color: #faf8f5;
+ transform: translateY(-1px);
+ box-shadow: none;
+}
+
+.playground-dashboard .btn-primary:disabled {
+ border-color: #54575a;
+ background: #262b30;
+ color: #8f9294;
+ box-shadow: none;
+}
+
+.playground-dashboard .demo-server-tag {
+ border: 1px solid #54575a;
+ background: rgba(255, 255, 255, 0.08);
+ color: #faf8f5;
+ box-shadow: none;
+}
+
+.playground-dashboard .demo-tag-value--server,
+.playground-dashboard .demo-tag-value--sdk {
+ color: var(--playground-accent);
+}
+
+.playground-dashboard .demo-tag-value--key {
+ color: var(--playground-accent);
+}
+
+.playground-dashboard .input {
+ border: 1px solid #54575a;
+ background: #050505;
+ color: #faf8f5;
+ box-shadow: none;
+}
+
+.playground-dashboard .input:focus {
+ border-color: var(--playground-accent);
+ box-shadow: 0 0 0 3px rgba(232, 255, 117, 0.12);
+}
+
+.playground-dashboard .input::placeholder {
+ color: #8f9294;
+}
+
+.playground-dashboard select.input option {
+ background: #050505;
+ color: #faf8f5;
+}
+
+.playground-dashboard .demo-code-block {
+ border: 1px solid #54575a;
+ background: #050505 !important;
+ color: #faf8f5 !important;
+ box-shadow: none;
+}
+
+/* NOTE: removed `.playground-dashboard .demo-code-block span { color: inherit !important }`.
+ That rule forced every syntax token to the base off-white via !important,
+ overriding react-syntax-highlighter's inline token colors and making the
+ playground snippets fully monochrome. Without it, walrusCodeTheme's token
+ colors (purple keywords, lime strings/keys, gray comments) render. */
+
+.playground-dashboard .demo-info-panel,
+.playground-dashboard .demo-phase-indicator {
+ border: 1px solid var(--playground-accent-border);
+ background: var(--playground-accent-soft);
+ color: #c7c5c1;
+}
+
+.playground-dashboard .demo-info-label,
+.playground-dashboard summary {
+ color: #8f9294;
+}
+
+.playground-dashboard .demo-ai-panel {
+ border: 1px solid #54575a;
+ background: #050505;
+ box-shadow: none;
+}
+
+.playground-dashboard .demo-result-panel {
+ border: 1px solid rgba(34, 197, 94, 0.35);
+ background: rgba(34, 197, 94, 0.08);
+ box-shadow: none;
+}
+
+.playground-dashboard .demo-error-panel {
+ border: 1px solid rgba(248, 113, 113, 0.35);
+ background: rgba(248, 113, 113, 0.08);
+ box-shadow: none;
+}
+
+.playground-dashboard .demo-memory-item span:last-child,
+.playground-dashboard .demo-result-pre {
+ color: #c7c5c1;
+}
+
+@media (max-width: 640px) {
+ .playground-nav .walrus-memory-wordmark {
+ font-size: 1.2rem;
+ }
+}
+
+/* ========== Dashboard density alignment ========== */
+
+.dashboard-nav {
+ position: sticky;
+ top: 0;
+ z-index: 80;
+ border-bottom: 1px solid rgba(250, 248, 245, 0.1);
+}
+
+.dashboard-nav .nav-inner {
+ max-width: 1280px;
+}
+
+.dashboard-nav .lp-nav-cta {
+ min-height: 0;
+ padding: 10px 22px;
+ border: 1px solid #faf8f5;
+ border-radius: 999px;
+ background: #faf8f5;
+ color: #000000;
+ box-shadow: none;
+ font-size: 0.92rem;
+ font-weight: 700;
+ text-transform: lowercase;
+}
+
+.dashboard-nav .lp-nav-cta:hover:not(:disabled) {
+ background: var(--playground-accent, #e8ff75);
+ border-color: var(--playground-accent, #e8ff75);
+ transform: translateY(-1px);
+ box-shadow: none;
+}
+
+.dash-page .dash-shell {
+ width: min(1100px, calc(100% - 64px));
+ max-width: 1100px;
+ padding: 34px 0 68px;
+}
+
+.dash-page .dashboard-header {
+ margin-bottom: 20px;
+}
+
+.dash-page .dashboard-header--compact {
+ margin-bottom: 18px;
+}
+
+.dash-page .dashboard-header h2 {
+ margin: 0 0 8px;
+ font-size: 1.54rem;
+ font-weight: 800;
+ line-height: 1.05;
+}
+
+.dash-page .dashboard-header p {
+ max-width: 680px;
+ margin-top: 0;
+ font-size: 0.92rem;
+ line-height: 1.45;
+}
+
+.dash-page .dash-alert {
+ min-height: 48px;
+ margin-bottom: 18px !important;
+ padding: 11px 16px 11px 48px;
+}
+
+.dash-alert-icon {
+ left: 18px;
+ width: 22px;
+ height: 20px;
+}
+
+.dash-alert-icon::before {
+ left: 10px;
+ top: 5px;
+ width: 2px;
+ height: 8px;
+}
+
+.dash-alert-icon::after {
+ left: 10px;
+ top: 15px;
+ width: 2px;
+ height: 2px;
+}
+
+.dash-page .dash-alert p {
+ font-size: 0.88rem;
+ line-height: 1.28;
+}
+
+.dash-page .dashboard-cta-row {
+ gap: 14px;
+ margin-bottom: 20px;
+}
+
+.dash-page .dashboard-cta {
+ min-height: 76px;
+ height: auto;
+ gap: 14px;
+ padding: 15px 18px;
+ border-radius: 12px;
+}
+
+.dash-page .dashboard-cta-icon-wrap {
+ width: 24px;
+ height: 28px;
+ margin-top: 1px;
+}
+
+.dash-page .dashboard-cta-icon {
+ width: 24px;
+ height: 28px;
+}
+
+.dash-page .dashboard-cta-title {
+ font-size: 1.02rem;
+ font-weight: 800;
+ line-height: 1.18;
+}
+
+.dash-page .dashboard-cta-subtitle {
+ margin-top: 4px;
+ font-size: 0.82rem;
+ line-height: 1.35;
+}
+
+.dash-page .dashboard-cta-arrow {
+ width: 16px;
+ height: 16px;
+}
+
+.dash-page .card {
+ margin-bottom: 20px !important;
+ padding: 20px;
+ border-radius: 12px;
+}
+
+.dash-page .dashboard-keys-card,
+.dash-page .dashboard-quickstart-card,
+.dash-page .dashboard-install-card {
+ min-height: 0;
+ margin-bottom: 20px !important;
+}
+
+.dash-page .card-header {
+ margin-bottom: 14px;
+ gap: 16px;
+}
+
+.dash-page .card-title,
+.dash-page .dashboard-keys-card .card-title {
+ font-size: 1.08rem;
+ font-weight: 800;
+ line-height: 1.15;
+}
+
+.dash-page .card-subtitle {
+ margin-top: 4px;
+ font-size: 0.82rem;
+ line-height: 1.35;
+}
+
+.dash-page .card-header-actions {
+ gap: 10px;
+}
+
+.dash-page .card-header-actions .btn-secondary,
+.dash-page .dashboard-keys-refresh,
+.dash-page .dashboard-keys-add {
+ /* Figma node 2325-6980: 52px pills, radius 26, px-30, 18px label,
+ tracking 0.72px. Both buttons equal. */
+ min-height: 52px;
+ height: 52px;
+ padding: 10px 30px;
+ border-radius: 26px;
+ font-size: 1.125rem;
+ letter-spacing: 0.72px;
+}
+
+.dash-page .key-display,
+.dash-page .key-display--white {
+ padding: 13px 15px;
+ border-radius: 10px;
+}
+
+.dash-page .key-display .key-label {
+ font-size: 0.68rem;
+}
+
+.dash-page .key-display .key-value {
+ font-size: 0.78rem;
+ line-height: 1.5;
+}
+
+.dash-page .warning-box {
+ padding: 13px 15px;
+ border-radius: 10px;
+}
+
+.dash-page .dashboard-quickstart-card .card-header {
+ margin-bottom: 16px;
+}
+
+.dash-page .dashboard-quickstart-card pre,
+.dash-page .dashboard-quickstart-card .demo-code-block {
+ min-height: 0;
+ padding: 18px 20px !important;
+ border-radius: 12px;
+ font-size: 12.5px;
+ line-height: 1.42;
+}
+
+.dash-page .dashboard-quickstart-copy {
+ top: 12px;
+ right: 12px;
+ width: 34px;
+ height: 34px;
+}
+
+.dash-page .install-tabs {
+ gap: 8px;
+ margin-bottom: 14px;
+}
+
+.dash-page .install-tab,
+.dash-page .install-tab:last-child {
+ width: 64px;
+ height: 28px;
+ font-size: 0.78rem;
+}
+
+.dash-page .install-command,
+.dash-page .install-tabs + .demo-code-block {
+ padding: 10px 0 !important;
+ font-size: 0.82rem;
+}
+
+.dash-page .dashboard-install-codewrap {
+ position: relative;
+ display: inline-flex;
+ align-items: center;
+ gap: 24px;
+ width: 100%;
+ max-width: 100%;
+}
+
+.dash-page .dashboard-install-codewrap .install-command {
+ display: inline-block;
+ width: auto;
+ max-width: calc(100% - 40px);
+ padding: 10px 0 !important;
+ white-space: pre;
+ overflow-x: auto;
+}
+
+.dash-page .dashboard-install-copy {
+ position: static;
+ z-index: 2;
+ width: 24px;
+ height: 24px;
+ padding: 0;
+ border: 0;
+ border-radius: 0;
+ background: transparent;
+ color: #54575a;
+ display: grid;
+ place-items: center;
+ box-shadow: none;
+ cursor: pointer;
+ transform: none;
+ flex: 0 0 24px;
+}
+
+.dash-page .dashboard-install-copy:hover:not(:disabled) {
+ background: transparent;
+ color: #8f9294;
+ box-shadow: none;
+}
+
+.dash-page .dashboard-install-copy svg {
+ width: 18px;
+ height: 18px;
+ display: block;
+}
+
+.dash-page .install-command-text {
+ font-family: var(--font-mono);
+ color: #faf8f5;
+ background: transparent;
+ border: 0;
+ box-shadow: none;
+ font-weight: 700;
+}
+
+.dash-page .dashboard-keys-add {
+ height: 52px;
+ min-height: 52px;
+ padding: 10px 30px;
+ gap: 10px;
+ justify-content: center;
+ border: 1px solid #faf8f5;
+ border-radius: 26px;
+ background: #faf8f5;
+ color: #000000;
+ font-size: 18px;
+ font-weight: 500;
+ line-height: 0.84;
+ letter-spacing: 0.72px;
+ white-space: nowrap;
+ box-shadow: none;
+}
+
+.dash-page .dashboard-keys-add svg {
+ width: 12.15px;
+ height: 12.15px;
+ stroke-width: 1.8;
+}
+
+/* ── Refresh: transparent + white outline; hover LIGHTENS the fill ── */
+.dash-page .dashboard-keys-refresh,
+.dash-page .dashboard-keys-refresh:focus,
+.dash-page .dashboard-keys-refresh:focus-visible,
+.dash-page .dashboard-keys-refresh:disabled {
+ background: transparent;
+ border-color: #faf8f5;
+ color: #faf8f5 !important;
+ -webkit-text-fill-color: #faf8f5;
+ opacity: 1;
+ transform: none;
+ box-shadow: none;
+ transition: background 0.14s ease;
+}
+
+.dash-page .dashboard-keys-refresh:hover:not(:disabled),
+.dash-page .dashboard-keys-refresh:active:not(:disabled) {
+ background: rgba(250, 248, 245, 0.16);
+ border-color: #faf8f5;
+ color: #faf8f5 !important;
+ -webkit-text-fill-color: #faf8f5;
+ transform: none;
+ box-shadow: none;
+}
+
+/* ── Add key: white fill; hover BRIGHTENS to the lime accent ── */
+.dash-page .dashboard-keys-add,
+.dash-page .dashboard-keys-add:focus,
+.dash-page .dashboard-keys-add:focus-visible,
+.dash-page .dashboard-keys-add:disabled {
+ background: #faf8f5;
+ border-color: #faf8f5;
+ color: #000000 !important;
+ -webkit-text-fill-color: #000000;
+ opacity: 1;
+ transform: none;
+ box-shadow: none;
+ transition: background 0.14s ease, border-color 0.14s ease;
+}
+
+.dash-page .dashboard-keys-add:hover:not(:disabled),
+.dash-page .dashboard-keys-add:active:not(:disabled) {
+ background: #e8ff75;
+ border-color: #e8ff75;
+ color: #000000 !important;
+ -webkit-text-fill-color: #000000;
+ transform: none;
+ box-shadow: none;
+}
+
+.dash-page .dashboard-keys-add svg {
+ width: 12.15px;
+ height: 12.15px;
+ stroke-width: 1.8;
+}
+
+.dash-page .install-tabs {
+ gap: 10px;
+ margin-bottom: 22px;
+}
+
+.dash-page .install-tab,
+.dash-page .install-tab:last-child {
+ width: 72px;
+ height: 28px;
+ min-height: 28px;
+ padding: 8px 12px;
+ border: 0;
+ outline: 0;
+ border-radius: 4px;
+ background: #1d2227;
+ color: #8f9294;
+ box-shadow: none;
+ font-size: 14px;
+ font-weight: 500;
+ line-height: 0.84;
+ letter-spacing: 0.14px;
+ text-transform: lowercase;
+ transition: background 0.12s ease, color 0.12s ease;
+}
+
+/* Inactive tab: hover BRIGHTENS the text (matches the TS/PY toggle behavior) */
+.dash-page .install-tab:hover:not(.install-tab--active),
+.dash-page .install-tab:focus-visible:not(.install-tab--active) {
+ outline: 0;
+ background: #262b30;
+ color: #faf8f5;
+ box-shadow: none;
+}
+
+.dash-page .install-tab--active,
+.dash-page .install-tab--active:hover,
+.dash-page .install-tab--active:focus,
+.dash-page .install-tab--active:focus-visible,
+.dash-page .install-tab--active:active {
+ outline: 0;
+ background: #faf8f5;
+ color: #000000 !important;
+ box-shadow: none;
+}
+
+.dash-page .dashboard-empty-message--account {
+ width: 100%;
+ min-height: 86px;
+ padding: 29px 0 !important;
+ color: #54575a !important;
+ font-size: 21px !important;
+ font-weight: 400;
+ line-height: 1.3;
+ text-align: center;
+}
+
+.dash-page .dashboard-empty-message--account .dashboard-empty-message-link {
+ display: inline;
+ padding: 0;
+ border: none;
+ background: none;
+ font: inherit;
+ color: #faf8f5;
+ cursor: pointer;
+ text-decoration-line: underline;
+ text-decoration-thickness: from-font;
+ text-underline-position: from-font;
+}
+
+.dash-page .dashboard-empty-message--account .dashboard-empty-message-link:hover {
+ opacity: 0.8;
+}
+
+@media (max-width: 860px) {
+ .dashboard-nav .nav-inner {
+ max-width: none;
+ }
+
+ .dash-page .dash-shell {
+ width: calc(100% - 32px);
+ padding: 32px 0 56px;
+ }
+
+ .dash-page .dashboard-header h2 {
+ font-size: 1.55rem;
+ }
+
+ .dash-page .dashboard-cta {
+ min-height: 82px;
+ padding: 16px 18px;
+ }
+
+ .dash-page .card {
+ padding: 20px;
+ }
+}
+
+/* ========== Walrus Memory app flow system pass ========== */
+
+.setup-classic-nav,
+.playground-nav,
+.dashboard-nav {
+ height: 128px;
+ padding: 0 50px 0 49px;
+ background: #000000;
+ border-bottom: 0;
+ align-items: flex-start;
+}
+
+.setup-classic-nav .nav-inner,
+.playground-nav .nav-inner,
+.dashboard-nav .nav-inner {
+ position: relative;
+ max-width: 1280px;
+ margin: 0 auto;
+ height: 128px;
+}
+
+.setup-classic-nav .nav-brand,
+.playground-nav .nav-brand,
+.dashboard-nav .nav-brand {
+ position: absolute;
+ left: 0;
+ top: 34px;
+}
+
+.setup-classic-nav .walrus-memory-wordmark,
+.playground-nav .walrus-memory-wordmark,
+.dashboard-nav .walrus-memory-wordmark {
+ color: #faf8f5;
+ font-size: 2.23rem;
+ line-height: 0.85;
+ font-weight: 900;
+}
+
+.setup-classic-nav .nav-brand-logo,
+.dashboard-nav .nav-brand-logo {
+ display: block;
+ height: 56px;
+ width: auto;
+}
+
+.setup-classic-nav .nav-user,
+.playground-nav .nav-user,
+.dashboard-nav .nav-user {
+ position: absolute;
+ right: 0;
+ top: 27px;
+ height: 52px;
+ gap: 24px;
+}
+
+.setup-classic-nav .nav-address,
+.playground-nav .nav-address,
+.dashboard-nav .nav-address {
+ width: 125px;
+ height: 28px;
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ border: 0;
+ border-radius: 4px;
+ background: #262b30;
+ color: #faf8f5;
+ padding: 0 12px;
+ font-size: 12px;
+ font-weight: 500;
+ letter-spacing: 0.6px;
+ line-height: 0.84;
+ box-shadow: none;
+}
+
+.setup-classic-nav .lp-nav-cta,
+.playground-nav .lp-nav-cta,
+.dashboard-nav .lp-nav-cta {
+ box-sizing: border-box;
+ width: 153.04px;
+ height: 52px;
+ min-height: 52px;
+ padding: 10px 30px;
+ border: 1px solid #faf8f5;
+ border-radius: 26px;
+ background: #000000;
+ color: #faf8f5;
+ box-shadow: none;
+ gap: 10px;
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ font-size: 18px;
+ font-weight: 500;
+ letter-spacing: 0.72px;
+ line-height: 0.84;
+ text-transform: none;
+ white-space: nowrap;
+}
+
+.setup-classic-nav .lp-nav-cta svg,
+.playground-nav .lp-nav-cta svg,
+.dashboard-nav .lp-nav-cta svg {
+ width: 13.04px;
+ height: 12.14px;
+ flex: 0 0 auto;
+ stroke-width: 1.7;
+}
+
+.setup-classic-nav .lp-nav-cta:hover:not(:disabled),
+.playground-nav .lp-nav-cta:hover:not(:disabled),
+.dashboard-nav .lp-nav-cta:hover:not(:disabled) {
+ background: #000000;
+ border-color: #faf8f5;
+ color: #faf8f5;
+ transform: none;
+ box-shadow: none;
+}
+
+.setup-classic-nav .demo-nav-back,
+.playground-nav .demo-nav-back,
+.dashboard-nav .demo-nav-back {
+ color: #8f9294;
+ font-size: 0.82rem;
+}
+
+.setup-classic-nav .demo-nav-back:hover,
+.playground-nav .demo-nav-back:hover,
+.dashboard-nav .demo-nav-back:hover {
+ color: #faf8f5;
+}
+
+.playground-dashboard {
+ width: min(900px, calc(100% - 48px));
+ max-width: 900px;
+ padding: 34px 0 68px;
+}
+
+.playground-dashboard {
+ width: min(960px, calc(100% - 48px));
+ max-width: 960px;
+}
+
+.setup-classic-container {
+ width: min(900px, calc(100% - 48px));
+ max-width: 900px;
+ min-height: calc(100vh - 128px);
+ padding: 34px 0 68px;
+}
+
+.setup-classic-panel {
+ width: min(520px, 100%);
+}
+
+.playground-dashboard .dashboard-header,
+.dash-page .dashboard-header,
+.setup-classic-intro {
+ margin-bottom: 20px;
+}
+
+.playground-dashboard .dashboard-header h2,
+.dash-page .dashboard-header h2,
+.setup-classic-title {
+ margin: 0 0 8px;
+ font-size: 1.54rem;
+ font-weight: 800;
+ line-height: 1.05;
+ letter-spacing: 0;
+ color: #faf8f5;
+}
+
+.playground-dashboard .dashboard-header p,
+.dash-page .dashboard-header p,
+.setup-classic-description {
+ max-width: 680px;
+ margin-top: 0;
+ color: #c7c5c1;
+ font-size: 0.92rem;
+ line-height: 1.45;
+}
+
+.setup-classic-description {
+ margin: 0 auto 22px;
+}
+
+.playground-dashboard .card,
+.playground-dashboard .demo-step,
+.dash-page .card,
+.setup-classic-feature-card {
+ padding: 20px;
+ border: 1px solid #54575a;
+ border-radius: 12px;
+ background: #0a0a0a;
+ color: #faf8f5;
+ box-shadow: none;
+}
+
+.playground-dashboard .card,
+.playground-dashboard .demo-step,
+.dash-page .card {
+ margin-bottom: 56px !important;
+}
+
+.playground-dashboard .card-header,
+.dash-page .card-header {
+ margin-bottom: 14px;
+ gap: 16px;
+}
+
+.playground-dashboard .card-title,
+.playground-dashboard .demo-step-title,
+.dash-page .card-title,
+.setup-classic-feature strong {
+ color: #faf8f5;
+ font-size: 1.08rem;
+ font-weight: 800;
+ line-height: 1.15;
+}
+
+.playground-dashboard .card-subtitle,
+.dash-page .card-subtitle,
+.setup-classic-feature p {
+ color: #b8bbbe;
+ font-size: 0.82rem;
+ line-height: 1.35;
+}
+
+.setup-classic-feature {
+ gap: 10px;
+ margin-bottom: 14px;
+}
+
+.setup-classic-generate,
+.setup-classic .setup-import-button,
+.playground-dashboard .btn,
+.dash-page .btn,
+.dash-page .dash-shell .lp-nav-cta {
+ min-height: 36px;
+ padding: 0 14px;
+ border-radius: 10px;
+ font-size: 0.82rem;
+}
+
+.setup-classic-generate,
+.setup-classic .setup-import-button {
+ min-height: 42px;
+ padding: 0 18px;
+ border-radius: 999px;
+}
+
+.playground-dashboard .demo-server-info {
+ display: grid;
+ grid-template-columns: repeat(2, max-content);
+ gap: 10px;
+ margin-bottom: 20px;
+}
+
+@media (max-width: 640px) {
+ .playground-dashboard .demo-server-info {
+ grid-template-columns: 1fr;
+ }
+}
+
+.playground-dashboard .demo-server-tag {
+ border: 1px solid #54575a;
+ border-radius: 10px;
+ background: rgba(255, 255, 255, 0.08);
+ padding: 8px 12px;
+ color: #faf8f5;
+ box-shadow: none;
+ font-size: 0.78rem;
+}
+
+.playground-dashboard .demo-step-badge {
+ width: 34px;
+ height: 34px;
+ border-radius: 9px;
+ font-size: 0.92rem;
+}
+
+.playground-dashboard .demo-code-block,
+.dash-page .dashboard-quickstart-card .demo-code-block,
+.dash-page .install-command {
+ border-radius: 12px;
+ font-size: 12.5px;
+ line-height: 1.42;
+ box-shadow: none;
+}
+
+.dash-page .dashboard-quickstart-card {
+ min-height: 572px;
+ padding: 39px;
+ border-color: #54575a;
+ border-radius: 24px;
+ background: #000000;
+ overflow: clip;
+}
+
+.dash-page .dashboard-quickstart-card .card-header {
+ margin-bottom: 34px;
+}
+
+.dash-page .dashboard-quickstart-card .card-title {
+ color: #faf8f5;
+ font-size: 36px;
+ font-weight: 500;
+ line-height: 0.88;
+ letter-spacing: 0;
+}
+
+.dash-page .dashboard-quickstart-card .card-subtitle {
+ margin-top: 14px;
+ font-size: 18px;
+ font-weight: 400;
+ line-height: 1.3;
+}
+
+.dash-page .dashboard-header h2 {
+ color: #faf8f5;
+ font-family: var(--font-sans);
+ font-size: 56px;
+ font-weight: 500;
+ line-height: 0.88;
+ letter-spacing: 0;
+}
+
+.dash-page .dashboard-cta-title {
+ color: #faf8f5;
+ font-family: var(--font-sans);
+ font-size: 24px;
+ font-weight: 650;
+ line-height: 1.3;
+ letter-spacing: 0;
+}
+
+.dash-page .dashboard-cta-subtitle {
+ margin-top: 0;
+ color: #c7c5c1;
+ font-family: var(--font-sans);
+ font-size: 18px;
+ font-weight: 400;
+ line-height: 1.3;
+ letter-spacing: 0;
+}
+
+.dash-page .dashboard-keys-card {
+ min-height: 277px;
+ padding: 39px 40px;
+ border-color: #54575a;
+ border-radius: 24px;
+ background: #000000;
+ overflow: clip;
+}
+
+.dash-page .dashboard-keys-card .card-header {
+ align-items: flex-start;
+ gap: 24px;
+ margin-bottom: 52px;
+}
+
+.dash-page .dashboard-keys-card .card-title {
+ color: #faf8f5;
+ font-family: var(--font-sans);
+ font-size: 36px;
+ font-weight: 500;
+ line-height: 0.88;
+ letter-spacing: 0;
+}
+
+.dash-page .dashboard-keys-card .card-subtitle {
+ margin-top: 14px;
+ color: #b8bbbe;
+ font-family: var(--font-sans);
+ font-size: 18px;
+ font-weight: 400;
+ line-height: 1.3;
+}
+
+.dash-page .dashboard-keys-card .card-header-actions {
+ align-self: flex-start;
+ gap: 20px;
+}
+
+.dash-page .dashboard-keys-card .dashboard-keys-refresh,
+.dash-page .dashboard-keys-card .dashboard-keys-add {
+ height: 52px;
+ min-height: 52px;
+ border-radius: 26px;
+ padding: 10px 30px;
+ font-family: var(--font-sans);
+ font-size: 18px;
+ font-weight: 500;
+ line-height: 0.84;
+ letter-spacing: 0.72px;
+}
+
+.dash-page .dashboard-keys-card .dashboard-keys-refresh {
+ width: 128px;
+ justify-content: center;
+}
+
+.dash-page .dashboard-keys-card .dashboard-keys-refresh svg {
+ display: none;
+}
+
+.dash-page .dashboard-keys-card .dashboard-keys-add {
+ width: 152px;
+ gap: 14px;
+ justify-content: center;
+}
+
+.dash-page .dashboard-keys-card .dashboard-keys-add svg {
+ width: 12.15px;
+ height: 12.15px;
+ stroke-width: 1.8;
+}
+
+.dash-page .dashboard-keys-card .dashboard-empty-message--account {
+ display: block;
+ min-height: 90px;
+ padding: 24px 0 0 !important;
+ color: #54575a !important;
+ font-family: var(--font-sans);
+ font-size: 21px !important;
+ font-weight: 400;
+ line-height: 1.3;
+ text-align: center;
+}
+
+.dash-page .dashboard-install-card .card-title {
+ color: #faf8f5;
+ font-family: var(--font-sans);
+ font-size: 36px;
+ font-weight: 500;
+ line-height: 0.88;
+ letter-spacing: 0;
+}
+
+.dash-page .dashboard-install-card .install-command-text {
+ font-family: var(--font-mono);
+ color: #faf8f5;
+ font-size: 15px;
+ font-weight: 300;
+ line-height: 1.4;
+ letter-spacing: 0.15px;
+}
+
+.dash-page .dashboard-quickstart-card pre,
+.dash-page .dashboard-quickstart-card .demo-code-block {
+ min-height: 395px;
+ padding: 31px 39px !important;
+ border: 1px solid #54575a;
+ border-radius: 24px;
+ background: #000000 !important;
+ font-size: 15px;
+ line-height: 1.45;
+}
+
+.playground-dashboard .demo-code-block {
+ padding: 16px 18px !important;
+}
+
+.setup-classic-divider {
+ margin: 22px 0 16px;
+}
+
+.setup-classic .setup-import-textarea {
+ min-height: 78px;
+ border-radius: 10px;
+ font-size: 0.82rem;
+}
+
+@media (max-width: 860px) {
+ .setup-classic-nav,
+ .playground-nav,
+ .dashboard-nav {
+ height: 92px;
+ padding: 0 16px;
+ }
+
+ .setup-classic-nav .nav-inner,
+ .playground-nav .nav-inner,
+ .dashboard-nav .nav-inner {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ height: 92px;
+ min-height: 92px;
+ padding: 0;
+ }
+
+ .setup-classic-nav .nav-brand,
+ .playground-nav .nav-brand,
+ .dashboard-nav .nav-brand {
+ top: 22px;
+ }
+
+ .setup-classic-nav .walrus-memory-wordmark,
+ .playground-nav .walrus-memory-wordmark,
+ .dashboard-nav .walrus-memory-wordmark {
+ font-size: 1.45rem;
+ }
+
+ .setup-classic-nav .nav-user,
+ .playground-nav .nav-user,
+ .dashboard-nav .nav-user {
+ display: flex;
+ align-items: center;
+ top: 18px;
+ gap: 10px;
+ }
+
+ .setup-classic-nav .nav-address,
+ .playground-nav .nav-address,
+ .dashboard-nav .nav-address {
+ width: auto;
+ min-width: 112px;
+ }
+
+ .setup-classic-nav .lp-nav-cta,
+ .playground-nav .lp-nav-cta,
+ .dashboard-nav .lp-nav-cta {
+ width: auto;
+ min-height: 44px;
+ height: 44px;
+ padding: 0 18px;
+ font-size: 0.95rem;
+ }
+
+ .dash-page .dash-shell,
+ .playground-dashboard,
+ .setup-classic-container {
+ width: calc(100% - 32px);
+ padding: 32px 0 56px;
+ }
+
+ .playground-dashboard .dashboard-header h2,
+ .dash-page .dashboard-header h2,
+ .setup-classic-title {
+ font-size: 1.38rem;
+ }
+}
+
+/* ── Figma 2325-6980: authoritative Delegate-keys header buttons + "+" icon.
+ Appended last (equal-or-higher specificity than the earlier duplicated
+ .dash-page rules) so these values win regardless of source-order conflicts. ── */
+.dash-page .dashboard-keys-card .card-header-actions .dashboard-keys-refresh,
+.dash-page .dashboard-keys-card .card-header-actions .dashboard-keys-add {
+ min-height: 52px;
+ height: 52px;
+ padding: 10px 30px;
+ border-radius: 26px;
+ font-family: var(--font-sans);
+ font-size: 18px;
+ font-weight: 500;
+ line-height: 1;
+ letter-spacing: 0.72px;
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+}
+
+.dash-page .dashboard-keys-card .card-header-actions .dashboard-keys-refresh {
+ width: 127px;
+ gap: 0;
+ border: 1px solid #faf8f5;
+ background: transparent;
+ color: #faf8f5;
+}
+
+.dash-page .dashboard-keys-card .card-header-actions .dashboard-keys-refresh svg {
+ display: none;
+}
+
+.dash-page .dashboard-keys-card .card-header-actions .dashboard-keys-add {
+ width: auto;
+ gap: 10px;
+ border: 1px solid #faf8f5;
+ background: #faf8f5;
+ color: #000000;
+}
+
+.dash-page .dashboard-keys-card .card-header-actions .dashboard-keys-add svg {
+ width: 16px;
+ height: 16px;
+ stroke-width: 2.5;
+ flex-shrink: 0;
+ display: block;
+}
+
+.dash-page .dashboard-keys-card .card-header-actions .dashboard-keys-refresh:hover {
+ background: rgba(250, 248, 245, 0.16);
+ border-color: #faf8f5;
+ color: #faf8f5;
+}
+
+.dash-page .dashboard-keys-card .card-header-actions .dashboard-keys-add:hover {
+ background: #e8ff75;
+ border-color: #e8ff75;
+ color: #000000;
+}
+
+.dash-page .dashboard-add-key-form {
+ display: flex;
+ flex-direction: column;
+ gap: 16px;
+ margin-bottom: 20px;
+ padding: 24px 28px;
+ border: 1px solid #54575a;
+ border-radius: 24px;
+ background: rgba(255, 255, 255, 0.08);
+ transform-origin: top center;
+ animation: dashboardInlineReveal 360ms cubic-bezier(0.16, 1, 0.3, 1) both;
+}
+
+.dash-page .dashboard-add-key-form--closing {
+ pointer-events: none;
+ animation: dashboardInlineExit 260ms cubic-bezier(0.32, 0, 0.67, 0) both;
+}
+
+.dash-page .dashboard-add-key-form--closing .dashboard-add-key-field,
+.dash-page .dashboard-add-key-form--closing .dashboard-add-key-note,
+.dash-page .dashboard-add-key-form--closing .dashboard-add-key-actions {
+ animation: dashboardInlineItemExit 180ms cubic-bezier(0.32, 0, 0.67, 0) both;
+}
+
+.dash-page .dashboard-add-key-form--closing .dashboard-add-key-note {
+ animation-delay: 50ms;
+}
+
+.dash-page .dashboard-add-key-form--closing .dashboard-add-key-actions {
+ animation-delay: 70ms;
+}
+
+.dash-page .dashboard-add-key-field {
+ display: flex;
+ flex-direction: column;
+ gap: 8px;
+ animation: dashboardInlineItemReveal 300ms cubic-bezier(0.16, 1, 0.3, 1) 50ms both;
+}
+
+.dash-page .dashboard-add-key-label {
+ color: #faf8f5;
+ font-size: 18px;
+ font-weight: 500;
+ line-height: 1.2;
+}
+
+.dash-page .dashboard-add-key-input {
+ width: 100%;
+ min-height: 50px;
+ padding: 12px 16px;
+ border: 1px solid rgba(250, 248, 245, 0.12);
+ border-radius: 14px;
+ background: #050505;
+ color: #faf8f5;
+ font-family: var(--font-sans);
+ font-size: 18px;
+ line-height: 1.2;
+ outline: none;
+ box-shadow: none;
+}
+
+.dash-page .dashboard-add-key-input:focus {
+ border-color: rgba(232, 255, 117, 0.7);
+ box-shadow: 0 0 0 3px rgba(232, 255, 117, 0.12);
+}
+
+.dash-page .dashboard-add-key-note {
+ margin: 0;
+ color: #b8bbbe;
+ font-size: 18px;
+ line-height: 1.35;
+ animation: dashboardInlineItemReveal 300ms cubic-bezier(0.16, 1, 0.3, 1) 90ms both;
+}
+
+.dash-page .dashboard-add-key-actions {
+ display: flex;
+ justify-content: flex-end;
+ gap: 12px;
+ margin-top: 2px;
+ animation: dashboardInlineItemReveal 300ms cubic-bezier(0.16, 1, 0.3, 1) 130ms both;
+}
+
+@keyframes dashboardInlineReveal {
+ from {
+ opacity: 0;
+ filter: blur(10px);
+ transform: translate3d(0, -8px, 0) scaleY(0.94);
+ }
+
+ to {
+ opacity: 1;
+ filter: blur(0);
+ transform: translate3d(0, 0, 0) scaleY(1);
+ }
+}
+
+@keyframes dashboardInlineItemReveal {
+ from {
+ opacity: 0;
+ filter: blur(6px);
+ transform: translate3d(0, 10px, 0);
+ }
+
+ to {
+ opacity: 1;
+ filter: blur(0);
+ transform: translate3d(0, 0, 0);
+ }
+}
+
+@keyframes dashboardInlineExit {
+ from {
+ opacity: 1;
+ filter: blur(0);
+ transform: translate3d(0, 0, 0) scaleY(1);
+ }
+
+ to {
+ opacity: 0;
+ filter: blur(8px);
+ transform: translate3d(0, -10px, 0) scaleY(0.92);
+ }
+}
+
+@keyframes dashboardInlineItemExit {
+ from {
+ opacity: 1;
+ filter: blur(0);
+ transform: translate3d(0, 0, 0);
+ }
+
+ to {
+ opacity: 0;
+ filter: blur(5px);
+ transform: translate3d(0, -8px, 0);
+ }
+}
+
+.dash-page .dashboard-add-key-cancel,
+.dash-page .dashboard-add-key-create {
+ min-height: 44px;
+ padding: 10px 22px;
+ border-radius: 22px;
+ font-family: var(--font-sans);
+ font-size: 16px;
+ font-weight: 500;
+ line-height: 1;
+ letter-spacing: 0;
+ box-shadow: none;
+}
+
+.dash-page .dashboard-add-key-create {
+ min-width: 112px;
+}
+
+.dash-page .dashboard-add-key-cancel {
+ border: 1px solid #faf8f5;
+ background: transparent;
+ color: #faf8f5;
+}
+
+.dash-page .dashboard-add-key-cancel:hover:not(:disabled) {
+ background: rgba(250, 248, 245, 0.14);
+ color: #faf8f5;
+}
+
+.dash-page .dashboard-add-key-create {
+ border: 1px solid #faf8f5;
+ background: #faf8f5;
+ color: #000000;
+}
+
+.dash-page .dashboard-add-key-create:hover:not(:disabled) {
+ border-color: #e8ff75;
+ background: #e8ff75;
+ color: #000000;
+}
+
+.dash-page .dashboard-key-ready-block {
+ margin-bottom: 26px;
+}
+
+.dash-page .dashboard-key-ready-warning {
+ margin-bottom: 16px;
+ min-height: 56px;
+ display: flex;
+ align-items: center;
+ gap: 14px;
+ padding: 16px 22px;
+ border-radius: 4px;
+}
+
+.dash-page .dashboard-key-ready-warning-icon {
+ flex: 0 0 auto;
+ color: #000000;
+}
+
+.dash-page .dashboard-key-ready-warning p {
+ margin: 0;
+ color: #000000;
+ font-size: 16px;
+ font-weight: 500;
+ line-height: 1.4;
+}
+
+.dash-page .dashboard-key-ready-warning strong {
+ color: #000000;
+ font-weight: 700;
+}
+
+.dash-page .dashboard-key-ready-display {
+ padding: 28px;
+}
+
+.dash-page .dashboard-key-ready-display .key-label {
+ margin-bottom: 18px;
+}
+
+.dash-page .dashboard-key-ready-display .key-value {
+ margin-bottom: 18px;
+}
+
+.dash-page .dashboard-key-ready-display .key-actions {
+ margin-top: 0;
+ gap: 12px;
+}
+
+.dash-page .dashboard-key-list {
+ display: flex;
+ flex-direction: column;
+ gap: 20px;
+}
+
+.dash-page .dashboard-key-list--busy {
+ opacity: 0.68;
+ transition: opacity 160ms ease;
+}
+
+.dash-page .dashboard-key-table-wrap {
+ width: 100%;
+ overflow: hidden;
+ border: 1px solid #54575a;
+ border-radius: 18px;
+ background: rgba(255, 255, 255, 0.06);
+}
+
+.dash-page .dashboard-key-table {
+ width: 100%;
+ border-collapse: collapse;
+ table-layout: fixed;
+}
+
+.dash-page .dashboard-key-table th,
+.dash-page .dashboard-key-table td {
+ padding: 14px 18px;
+ text-align: left;
+ vertical-align: middle;
+}
+
+.dash-page .dashboard-key-table th {
+ border-bottom: 1px solid rgba(250, 248, 245, 0.12);
+ color: #b8bbbe;
+ font-size: 14px;
+ font-weight: 500;
+ line-height: 1.2;
+}
+
+.dash-page .dashboard-key-table td {
+ border-bottom: 1px solid rgba(250, 248, 245, 0.08);
+ color: #faf8f5;
+ font-size: 14px;
+ line-height: 1.35;
+}
+
+.dash-page .dashboard-key-table tbody tr:last-child td {
+ border-bottom: 0;
+}
+
+.dash-page .dashboard-key-table-select {
+ width: 62px;
+}
+
+.dash-page .dashboard-key-table th:nth-child(2) {
+ width: 24%;
+}
+
+.dash-page .dashboard-key-table th:nth-child(4) {
+ width: 120px;
+}
+
+.dash-page .dashboard-key-table-actions {
+ width: 108px;
+ text-align: right !important;
+}
+
+.dash-page .dashboard-key-row {
+ transition: background 0.14s ease, box-shadow 0.14s ease;
+}
+
+.dash-page .dashboard-key-row--selected {
+ background: rgba(232, 255, 117, 0.08);
+ box-shadow: inset 0 0 0 1px rgba(232, 255, 117, 0.26);
+}
+
+.dash-page .dashboard-key-cell-select {
+ width: 62px;
+}
+
+.dash-page .dashboard-key-name {
+ min-width: 0;
+ display: flex;
+ align-items: center;
+ flex-wrap: nowrap;
+ gap: 8px;
+ color: #e8ff75;
+ font-size: 15px;
+ font-weight: 600;
+ line-height: 1.25;
+}
+
+.dash-page .dashboard-key-name > span:first-child {
+ min-width: 0;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+}
+
+.dash-page .dashboard-key-current-badge {
+ display: inline-flex;
+ align-items: center;
+ flex: 0 0 auto;
+ min-height: 22px;
+ padding: 3px 8px;
+ border: 1px solid rgba(232, 255, 117, 0.38);
+ border-radius: 999px;
+ color: #e8ff75;
+ font-size: 12px;
+ font-weight: 500;
+ line-height: 1;
+}
+
+.dash-page .dashboard-key-public {
+ display: inline-block;
+ max-width: 100%;
+ color: #faf8f5;
+ font-family: var(--font-mono);
+ font-size: 13px;
+ line-height: 1.45;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ vertical-align: middle;
+ white-space: nowrap;
+}
+
+.dash-page .dashboard-key-created {
+ color: #b8bbbe !important;
+ white-space: nowrap;
+}
+
+.dash-page .dashboard-key-row-actions {
+ text-align: right;
+}
+
+.dash-page .dashboard-key-actions {
+ display: flex;
+ align-items: center;
+ justify-content: flex-end;
+ gap: 8px;
+}
+
+.dash-page .dashboard-key-row-actions .btn-secondary,
+.dash-page .dashboard-key-row-actions .btn-danger {
+ width: 34px;
+ min-width: 34px;
+ height: 34px;
+ min-height: 34px;
+ padding: 0;
+ border-radius: 10px;
+ font-size: 13px;
+ line-height: 1;
+ letter-spacing: 0;
+ text-transform: none;
+ box-shadow: none;
+}
+
+.dash-page .dashboard-key-row-actions .dashboard-key-icon-action {
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+}
+
+.dash-page .dashboard-key-row-actions .btn-secondary.dashboard-key-icon-action {
+ border-color: #faf8f5;
+ background: #faf8f5;
+ color: #000000;
+}
+
+.dash-page .dashboard-key-row-actions .btn-secondary.dashboard-key-icon-action:hover:not(:disabled) {
+ border-color: #e8ff75;
+ background: #e8ff75;
+ color: #000000;
+}
+
+.dash-page .dashboard-key-row-actions .btn-danger.dashboard-key-icon-action {
+ border-color: #ff6b6b;
+ background: #ff6b6b;
+ color: #ffffff;
+}
+
+.dash-page .dashboard-key-row-actions .btn-danger.dashboard-key-icon-action:hover:not(:disabled) {
+ border-color: #ff8f8f;
+ background: #ff8f8f;
+ color: #ffffff;
+}
+
+.dash-page .dashboard-key-row-actions .dashboard-key-icon-action--copied {
+ border-color: #e8ff75;
+ background: #e8ff75;
+ color: #000000;
+}
+
+.dash-page .dashboard-key-row-actions .btn-secondary svg,
+.dash-page .dashboard-key-row-actions .btn-danger svg {
+ display: block;
+}
+
+.dash-page .dashboard-key-selection-bar {
+ display: flex;
+ align-items: center;
+ justify-content: flex-end;
+ flex-wrap: wrap;
+ gap: 12px 14px;
+ min-height: 38px;
+ margin-bottom: 18px;
+ padding: 0;
+ border: 0;
+ border-radius: 0;
+ background: transparent;
+}
+
+.dash-page .dashboard-key-checkbox {
+ position: relative;
+ display: inline-flex;
+ align-items: center;
+ gap: 10px;
+ color: #faf8f5;
+ font-family: var(--font-sans);
+ font-size: 14px;
+ font-weight: 500;
+ line-height: 1;
+ cursor: pointer;
+ user-select: none;
+}
+
+.dash-page .dashboard-key-checkbox {
+ width: 24px;
+ height: 24px;
+ gap: 0;
+ align-self: center;
+}
+
+.dash-page .dashboard-key-checkbox input {
+ position: absolute;
+ width: 1px;
+ height: 1px;
+ opacity: 0;
+ pointer-events: none;
+}
+
+.dash-page .dashboard-key-checkbox-box {
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ width: 22px;
+ height: 22px;
+ flex: 0 0 22px;
+ border: 1px solid rgba(250, 248, 245, 0.72);
+ border-radius: 6px;
+ background: rgba(5, 5, 5, 0.5);
+ transition: background 0.14s ease, border-color 0.14s ease, box-shadow 0.14s ease;
+}
+
+.dash-page .dashboard-key-checkbox input:checked + .dashboard-key-checkbox-box {
+ border-color: #e8ff75;
+ background: #e8ff75;
+}
+
+.dash-page .dashboard-key-checkbox input:checked + .dashboard-key-checkbox-box::after {
+ content: "";
+ width: 7px;
+ height: 11px;
+ margin-top: -2px;
+ border: solid #000000;
+ border-width: 0 2px 2px 0;
+ transform: rotate(45deg);
+}
+
+.dash-page .dashboard-key-checkbox input:focus-visible + .dashboard-key-checkbox-box {
+ box-shadow: 0 0 0 3px rgba(232, 255, 117, 0.18);
+}
+
+.dash-page .dashboard-key-checkbox input:disabled + .dashboard-key-checkbox-box {
+ opacity: 0.48;
+ cursor: not-allowed;
+}
+
+.dash-page .dashboard-key-selection-status {
+ display: inline-flex;
+ align-items: center;
+ min-height: 36px;
+ margin-left: 0;
+ color: #b8bbbe;
+ font-size: 14px;
+ line-height: 1;
+}
+
+.dash-page .dashboard-key-bulk-actions {
+ display: flex;
+ align-items: center;
+ flex-wrap: wrap;
+ gap: 10px;
+}
+
+.dash-page .dashboard-key-clear-selection,
+.dash-page .dashboard-key-remove-selected {
+ height: 36px;
+ min-height: 36px;
+ padding: 0 14px;
+ border-radius: 18px;
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ font-size: 13px;
+ line-height: 1;
+ letter-spacing: 0;
+ text-transform: none;
+ box-shadow: none;
+}
+
+.dash-page .dashboard-key-clear-selection {
+ min-width: 64px;
+}
+
+.dash-page .dashboard-key-remove-selected {
+ min-width: 142px;
+}
+
+.dash-page .dashboard-key-remove-selected svg {
+ display: block;
+}
+
+.dash-page .dashboard-keys-card .key-display {
+ display: flex;
+ flex-direction: column;
+ gap: 14px;
+ padding: 24px 28px;
+ border-radius: 24px;
+ border-color: #54575a;
+ background: rgba(255, 255, 255, 0.08);
+}
+
+.dash-page .dashboard-keys-card .dashboard-key-skeleton {
+ pointer-events: none;
+}
+
+.dash-page .dashboard-key-skeleton-line {
+ display: inline-block;
+ border-radius: 999px;
+ background: rgba(250, 248, 245, 0.14);
+ animation: dashboardSkeletonPulse 1.2s ease-in-out infinite;
+}
+
+.dash-page .dashboard-key-skeleton-line--check {
+ width: 22px;
+ height: 22px;
+ border-radius: 6px;
+}
+
+.dash-page .dashboard-key-skeleton-line--label {
+ width: min(170px, 80%);
+ height: 18px;
+}
+
+.dash-page .dashboard-key-skeleton-line--value {
+ width: min(210px, 90%);
+ height: 16px;
+}
+
+.dash-page .dashboard-key-skeleton-line--date {
+ width: 76px;
+ height: 16px;
+}
+
+.dash-page .dashboard-key-skeleton-line--actions {
+ width: 76px;
+ height: 34px;
+ margin-top: 2px;
+}
+
+.dash-page .dashboard-credentials-card {
+ padding: 39px 40px;
+}
+
+.dash-page .dashboard-credentials-card .card-header {
+ margin-bottom: 34px;
+}
+
+.dash-page .dashboard-credentials-card .card-title {
+ color: #faf8f5;
+ font-family: var(--font-sans);
+ font-size: 36px;
+ font-weight: 500;
+ line-height: 0.88;
+ letter-spacing: 0;
+}
+
+.dash-page .dashboard-credentials-card .card-subtitle {
+ margin-top: 14px;
+ color: #b8bbbe;
+ font-family: var(--font-sans);
+ font-size: 18px;
+ font-weight: 400;
+ line-height: 1.3;
+}
+
+.dash-page .dashboard-credentials-alert {
+ margin-bottom: 18px;
+ min-height: 56px;
+ display: flex;
+ align-items: center;
+ gap: 14px;
+ padding: 16px 22px;
+ border: 0;
+ border-radius: 4px;
+ background: #e8ff75;
+ color: #000000;
+}
+
+.dash-page .dashboard-credentials-alert-icon {
+ flex: 0 0 auto;
+ color: #000000;
+}
+
+.dash-page .dashboard-credentials-alert p {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 6px 14px;
+ margin: 0;
+ color: #000000;
+ font-size: 16px;
+ font-weight: 500;
+ line-height: 1.4;
+}
+
+.dash-page .dashboard-credentials-alert p + p {
+ margin-top: 8px;
+ color: #000000;
+}
+
+.dash-page .dashboard-credentials-alert strong {
+ color: #000000;
+ font-weight: 700;
+}
+
+.dash-page .dashboard-credentials-alert code {
+ padding: 2px 6px;
+ border-radius: 6px;
+ background: rgba(0, 0, 0, 0.08);
+ color: #000000;
+ font-family: var(--font-mono);
+ font-size: 0.95em;
+}
+
+.dash-page .dashboard-credentials-panel {
+ overflow: hidden;
+ border: 1px solid #54575a;
+ border-radius: 24px;
+ background: #000000;
+}
+
+.dash-page .dashboard-credential-row {
+ display: grid;
+ grid-template-columns: minmax(0, 1fr) auto;
+ gap: 18px;
+ align-items: center;
+ padding: 18px 22px;
+ border-bottom: 1px solid rgba(250, 248, 245, 0.1);
+}
+
+.dash-page .dashboard-credential-row:last-child {
+ border-bottom: 0;
+}
+
+.dash-page .dashboard-credential-label {
+ display: flex;
+ align-items: center;
+ flex-wrap: wrap;
+ gap: 8px;
+ color: #b8bbbe;
+ font-size: 14px;
+ font-weight: 500;
+ line-height: 1.25;
+ letter-spacing: 0;
+ text-transform: none;
+}
+
+.dash-page .dashboard-credential-label span {
+ color: #8f9294;
+ font-family: var(--font-mono);
+ font-size: 13px;
+ font-weight: 400;
+}
+
+.dash-page .dashboard-credential-value {
+ display: block;
+ margin-top: 10px;
+ color: #faf8f5;
+ font-family: var(--font-mono);
+ font-size: 14px;
+ line-height: 1.45;
+ overflow-wrap: anywhere;
+}
+
+.dash-page .dashboard-credential-actions {
+ display: flex;
+ align-items: center;
+ justify-content: flex-end;
+ gap: 8px;
+}
+
+.dash-page .dashboard-credential-icon-button {
+ width: 34px;
+ height: 34px;
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ border: 1px solid rgba(250, 248, 245, 0.12);
+ border-radius: 12px;
+ background: rgba(255, 255, 255, 0.08);
+ color: #faf8f5;
+ cursor: pointer;
+ transition: background 0.14s ease, border-color 0.14s ease, color 0.14s ease;
+}
+
+.dash-page .dashboard-credential-icon-button:hover:not(:disabled) {
+ border-color: rgba(250, 248, 245, 0.24);
+ background: rgba(255, 255, 255, 0.14);
+}
+
+.dash-page .dashboard-credential-icon-button--copied {
+ border-color: #e8ff75;
+ background: #e8ff75;
+ color: #000000;
+}
+
+@keyframes dashboardSkeletonPulse {
+ 0%,
+ 100% {
+ opacity: 0.5;
+ }
+
+ 50% {
+ opacity: 1;
+ }
+}
+
+@media (prefers-reduced-motion: reduce) {
+ .dash-page .dashboard-key-skeleton-line {
+ animation: none;
+ }
+}
+
+.dash-page .dashboard-keys-card .dashboard-key-item {
+ transition: border-color 0.14s ease, background 0.14s ease, box-shadow 0.14s ease;
+}
+
+.dash-page .dashboard-keys-card .dashboard-key-item--selected {
+ border-color: #e8ff75;
+ background: rgba(232, 255, 117, 0.08);
+ box-shadow: inset 0 0 0 1px rgba(232, 255, 117, 0.32);
+}
+
+.dash-page .dashboard-key-item-header {
+ display: grid;
+ grid-template-columns: 24px minmax(0, 1fr);
+ align-items: center;
+ gap: 12px;
+}
+
+.dash-page .dashboard-key-item-header .key-label {
+ min-width: 0;
+ margin-bottom: 0;
+ overflow-wrap: anywhere;
+}
+
+.dash-page .dashboard-key-item-header .key-label span {
+ margin-left: 8px;
+ font-weight: 400;
+}
+
+.dash-page .dashboard-keys-card .key-display .key-label {
+ color: #e8ff75;
+ font-size: 15px;
+ font-weight: 600;
+ line-height: 1.2;
+ letter-spacing: 0;
+ text-transform: none;
+}
+
+.dash-page .dashboard-keys-card .key-display .key-label span {
+ color: #e8ff75;
+ opacity: 0.9;
+}
+
+.dash-page .dashboard-keys-card .key-display .key-value {
+ color: #faf8f5;
+ font-size: 14px;
+ line-height: 1.45;
+ letter-spacing: 0;
+}
+
+.dash-page .dashboard-keys-card .key-display .key-actions {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 10px;
+ margin-top: 2px;
+}
+
+.dash-page .dashboard-keys-card .key-display .btn-secondary,
+.dash-page .dashboard-keys-card .key-display .btn-danger {
+ min-height: 36px;
+ padding: 8px 14px;
+ border-radius: 18px;
+ font-size: 13px;
+ line-height: 1;
+ letter-spacing: 0;
+ text-transform: none;
+}
+
+.dash-page .dashboard-keys-card .key-display .btn-danger {
+ min-width: 88px;
+}
+
+.dash-page .dashboard-keys-card .key-display .btn-secondary svg,
+.dash-page .dashboard-keys-card .key-display .btn-danger svg {
+ display: block;
+}
+
+@media (max-width: 860px) {
+ .dash-page .dashboard-credentials-card {
+ padding: 28px 24px;
+ }
+
+ .dash-page .dashboard-credentials-card .card-header {
+ margin-bottom: 22px;
+ }
+
+ .dash-page .dashboard-credentials-alert p {
+ display: block;
+ }
+
+ .dash-page .dashboard-credentials-alert p span {
+ display: block;
+ margin-top: 6px;
+ }
+
+ .dash-page .dashboard-credential-row {
+ grid-template-columns: 1fr;
+ gap: 14px;
+ padding: 16px;
+ }
+
+ .dash-page .dashboard-credential-actions {
+ justify-content: flex-start;
+ }
+
+ .dash-page .dashboard-key-table-wrap {
+ overflow: visible;
+ border: 0;
+ border-radius: 0;
+ background: transparent;
+ }
+
+ .dash-page .dashboard-key-table,
+ .dash-page .dashboard-key-table thead,
+ .dash-page .dashboard-key-table tbody,
+ .dash-page .dashboard-key-table tr,
+ .dash-page .dashboard-key-table td {
+ display: block;
+ width: 100%;
+ }
+
+ .dash-page .dashboard-key-table thead {
+ display: none;
+ }
+
+ .dash-page .dashboard-key-table tr {
+ margin-bottom: 14px;
+ padding: 16px;
+ border: 1px solid #54575a;
+ border-radius: 18px;
+ background: rgba(255, 255, 255, 0.08);
+ }
+
+ .dash-page .dashboard-key-table tbody tr:last-child {
+ margin-bottom: 0;
+ }
+
+ .dash-page .dashboard-key-table td {
+ display: grid;
+ grid-template-columns: 92px minmax(0, 1fr);
+ gap: 12px;
+ align-items: start;
+ padding: 8px 0;
+ border-bottom: 0;
+ }
+
+ .dash-page .dashboard-key-table td::before {
+ content: attr(data-label);
+ color: #8f9294;
+ font-size: 13px;
+ line-height: 1.35;
+ }
+
+ .dash-page .dashboard-key-list--skeleton .dashboard-key-table td {
+ grid-template-columns: 1fr;
+ }
+
+ .dash-page .dashboard-key-list--skeleton .dashboard-key-table td::before {
+ display: none;
+ }
+
+ .dash-page .dashboard-key-cell-select {
+ align-items: center !important;
+ }
+
+ .dash-page .dashboard-key-row-actions {
+ text-align: left;
+ }
+
+ .dash-page .dashboard-key-actions {
+ justify-content: flex-start;
+ }
+
+ .dash-page .dashboard-key-row-actions .btn-secondary,
+ .dash-page .dashboard-key-row-actions .btn-danger {
+ flex: 0 0 34px;
+ }
+
+ .dash-page .dashboard-key-selection-bar {
+ align-items: stretch;
+ flex-direction: column;
+ }
+
+ .dash-page .dashboard-key-selection-status {
+ margin-left: 0;
+ }
+
+ .dash-page .dashboard-key-bulk-actions {
+ width: 100%;
+ }
+
+ .dash-page .dashboard-key-clear-selection,
+ .dash-page .dashboard-key-remove-selected {
+ flex: 1 1 0;
+ }
+}
+
+.dash-page .dashboard-quickstart-card pre,
+.dash-page .dashboard-quickstart-card .demo-code-block {
+ overflow-x: clip;
+ white-space: pre-wrap;
+ word-break: break-word;
+}
+
+.dash-page .dashboard-quickstart-card pre code,
+.dash-page .dashboard-quickstart-card .demo-code-block code,
+.dash-page .dashboard-quickstart-card .demo-code-block span {
+ white-space: pre-wrap !important;
+ word-break: break-word;
+}
+
+.dash-page .dashboard-install-card {
+ padding: 39px 40px;
+}
+
+.dash-page .dashboard-install-card .card-header {
+ margin-bottom: 34px;
+}
+
+.dash-page .dashboard-install-card .card-subtitle {
+ margin-top: 14px;
+ color: #b8bbbe;
+ font-size: 18px;
+ font-weight: 400;
+ line-height: 1.3;
+}
+
+.dash-page .dashboard-install-card .install-tabs {
+ margin-bottom: 28px;
+}
+
+.dash-page .dashboard-install-card .install-tab,
+.dash-page .dashboard-install-card .install-tab:last-child {
+ line-height: 1;
+}
+
+.dash-page .dashboard-install-card .dashboard-install-codewrap {
+ gap: 10px;
+}
+
+.dash-page .dashboard-install-card .dashboard-install-codewrap .install-command {
+ padding: 0 !important;
+ overflow-x: clip;
+ white-space: normal;
+ overflow-wrap: anywhere;
+}
+
+.dash-page .dashboard-install-card .dashboard-install-copy {
+ width: 24px;
+ height: 24px;
+ flex: 0 0 24px;
+ border-radius: 8px;
+ background: rgba(255, 255, 255, 0.08);
+ color: #faf8f5;
+}
+
+.dash-page .dashboard-install-card .dashboard-install-copy svg {
+ width: 12px;
+ height: 12px;
+}
+
+.dash-page .dashboard-install-card .dashboard-install-copy:hover:not(:disabled) {
+ background: rgba(255, 255, 255, 0.14);
+ color: #faf8f5;
+}
+
+/* ── Figma 2325-6980: even, generous block spacing. The CTA row was only ~20px
+ below; align it with the 56px card gaps so the whole stack breathes like the
+ design (Figma's literal 36px sits between much taller cards). ── */
+.dash-page .dashboard-cta-row {
+ gap: 30px;
+ margin-bottom: 56px;
+}
+
+.dash-page .dashboard-cta-row--primary {
+ margin-bottom: 30px;
+}
+
+.dash-page .dashboard-section-head {
+ order: 2;
+ margin-bottom: 16px;
+}
+
+.dash-page .dashboard-section-head h3 {
+ margin: 0 0 4px;
+ font-size: 1.15rem;
+ font-weight: 600;
+ color: #faf8f5;
+ letter-spacing: 0;
+}
+
+.dash-page .dashboard-section-head p {
+ margin: 0;
+ font-size: 0.9rem;
+ color: #8f9294;
+}
+
+.dash-page .dashboard-cta-row--resources {
+ grid-template-columns: repeat(3, minmax(0, 1fr));
+}
+
+/* One consistent card style across Dashboard + Playground: match the CTA cards
+ (12px radius, subtle border + translucent bg) so content/step cards stop
+ looking like a different component. */
+.dash-page .card,
+.playground-dashboard .card {
+ border-radius: 12px !important;
+ border: 1px solid rgba(250, 248, 245, 0.1) !important;
+ background: rgba(255, 255, 255, 0.08) !important;
+}
+
+/* Mobile: stack the Resources cards instead of cramming 3 columns. Placed after
+ the --resources rule so it wins inside the breakpoint. */
+@media (max-width: 860px) {
+ .dash-page .dashboard-cta-row--resources {
+ grid-template-columns: 1fr;
+ }
+}
+
+/* Dashboard CTA cards: final pass against the two-card design comp. This lives
+ after the duplicated dashboard rules so the CTA spacing stays deterministic. */
+.dash-page .dashboard-cta-row {
+ gap: 28px;
+ margin-bottom: 56px;
+}
+
+.dash-page .dashboard-cta-row--primary {
+ grid-template-columns: 1fr;
+ margin-top: 24px;
+ margin-bottom: 30px;
+}
+
+.dash-page .dashboard-cta-row--resources {
+ grid-template-columns: repeat(3, minmax(0, 1fr));
+}
+
+.dash-page .dashboard-cta-row > :only-child {
+ grid-column: 1 / -1;
+}
+
+.dash-page .dashboard-cta {
+ grid-template-columns: 36px minmax(0, 1fr) 21px;
+ min-height: 104px;
+ height: auto;
+ gap: 22px;
+ padding: 26px 27px;
+ border-radius: 22px;
+}
+
+.dash-page .dashboard-cta-icon-wrap {
+ width: 36px;
+ height: 40px;
+}
+
+.dash-page .dashboard-cta-icon {
+ width: 36px;
+ height: 40px;
+}
+
+.dash-page .dashboard-cta-title {
+ line-height: 1.18;
+}
+
+.dash-page .dashboard-cta-subtitle {
+ margin-top: 8px;
+ line-height: 1.2;
+}
+
+.dash-page .dashboard-cta-arrow {
+ width: 21px;
+ height: 21px;
+ margin-top: 0;
+}
+
+@media (max-width: 860px) {
+ .dash-page .dashboard-cta-row,
+ .dash-page .dashboard-cta-row--primary,
+ .dash-page .dashboard-cta-row--resources {
+ grid-template-columns: 1fr;
+ gap: 14px;
+ }
+
+ .dash-page .dashboard-cta-row {
+ margin-bottom: 24px;
+ }
+
+ .dash-page .dashboard-cta-row--primary {
+ margin-top: 18px;
+ margin-bottom: 24px;
+ }
+
+ .dash-page .dashboard-cta {
+ grid-template-columns: 30px minmax(0, 1fr) 18px;
+ min-height: 92px;
+ gap: 16px;
+ padding: 21px 22px;
+ border-radius: 18px;
+ }
+
+ .dash-page .dashboard-cta-icon-wrap,
+ .dash-page .dashboard-cta-icon {
+ width: 30px;
+ height: 34px;
+ }
+
+ .dash-page .dashboard-cta-subtitle {
+ margin-top: 5px;
+ }
+}
+
+/* Dashboard major-section rhythm. Keep large cards on one shared vertical gap
+ instead of mixing JSX inline margins with older dashboard density rules. */
+.dash-page {
+ --dashboard-major-gap: 56px;
+ --dashboard-related-gap: 30px;
+ --dashboard-mobile-major-gap: 24px;
+}
+
+.dash-page .dashboard-cta-row--primary {
+ margin-bottom: var(--dashboard-related-gap);
+}
+
+.dash-page .dashboard-section-head {
+ margin-bottom: 16px;
+}
+
+.dash-page .dashboard-cta-row--resources,
+.dash-page .dashboard-credentials-card,
+.dash-page .dashboard-keys-card,
+.dash-page .dashboard-quickstart-card {
+ margin-bottom: var(--dashboard-major-gap) !important;
+}
+
+.dash-page .dashboard-install-card {
+ margin-bottom: 0 !important;
+}
+
+@media (max-width: 860px) {
+ .dash-page .dashboard-cta-row--primary,
+ .dash-page .dashboard-cta-row--resources,
+ .dash-page .dashboard-credentials-card,
+ .dash-page .dashboard-keys-card,
+ .dash-page .dashboard-quickstart-card {
+ margin-bottom: var(--dashboard-mobile-major-gap) !important;
+ }
+}
+
+/* ── Alert: icon + text as one centered flex row (replaces the
+ absolutely-positioned icon, which left an 8px gap and felt off-center). ── */
+.dash-page .dash-alert {
+ display: flex;
+ align-items: center;
+ gap: 14px;
+ padding: 16px 22px;
+ min-height: 56px;
+}
+
+.dash-page .dash-alert .dash-alert-icon {
+ position: relative;
+ left: auto;
+ top: auto;
+ transform: none;
+ flex: 0 0 auto;
+ width: 24px;
+ height: 24px;
+ color: #000000;
+ background: transparent;
+ clip-path: none;
+ display: block;
+}
+
+.dash-page .dash-alert .dash-alert-icon::before,
+.dash-page .dash-alert .dash-alert-icon::after {
+ content: none;
+}
+
+.dash-page .dash-alert p {
+ font-size: 16px;
+ line-height: 1.4;
+}
+
+/* Dashboard heading subtitles: keep these at the same scale as card subtitles. */
+.dash-page .dashboard-header p,
+.dash-page .dashboard-section-head p {
+ color: #b8bbbe;
+ font-size: 18px;
+ font-weight: 400;
+ line-height: 1.3;
+}
+
+.dash-page .dashboard-header,
+.dash-page .dash-alert,
+.dash-page .dashboard-cta-row--primary,
+.dash-page .dashboard-section-head,
+.dash-page .dashboard-cta-row--resources,
+.dash-page .dashboard-credentials-card,
+.dash-page .dashboard-keys-card,
+.dash-page .dashboard-quickstart-card,
+.dash-page .dashboard-install-card {
+ animation: dashboardReveal 420ms cubic-bezier(0.16, 1, 0.3, 1) both;
+}
+
+.dash-page .dashboard-header {
+ animation-delay: 20ms;
+}
+
+.dash-page .dash-alert {
+ animation-delay: 55ms;
+}
+
+.dash-page .dashboard-cta-row--primary {
+ animation-delay: 90ms;
+}
+
+.dash-page .dashboard-section-head {
+ animation-delay: 125ms;
+}
+
+.dash-page .dashboard-cta-row--resources {
+ animation-delay: 160ms;
+}
+
+.dash-page .dashboard-credentials-card {
+ animation-delay: 195ms;
+}
+
+.dash-page .dashboard-keys-card {
+ animation-delay: 230ms;
+}
+
+.dash-page .dashboard-quickstart-card {
+ animation-delay: 265ms;
+}
+
+.dash-page .dashboard-install-card {
+ animation-delay: 300ms;
+}
+
+.dash-page .dashboard-cta-row--primary {
+ animation: none !important;
+ opacity: 1;
+ filter: none;
+ transform: none;
+}
+
+@keyframes dashboardReveal {
+ from {
+ opacity: 0;
+ filter: blur(5px);
+ transform: translate3d(0, 10px, 0) scale(0.992);
+ }
+
+ to {
+ opacity: 1;
+ filter: blur(0);
+ transform: translate3d(0, 0, 0) scale(1);
+ }
+}
+
+.dashboard-nav .lp-nav-cta {
+ line-height: 1;
+}
+
+.dashboard-nav .lp-nav-cta svg {
+ display: block;
+ margin-top: 1px;
+}
+
+.dash-page .dashboard-confirm-backdrop {
+ position: fixed;
+ inset: 0;
+ z-index: 2000;
+ display: grid;
+ place-items: center;
+ padding: 24px;
+ background: rgba(0, 0, 0, 0.68);
+ backdrop-filter: blur(14px);
+ animation: dashboardConfirmBackdropIn 140ms ease both;
+}
+
+.dash-page .dashboard-confirm-dialog {
+ width: min(440px, 100%);
+ padding: 28px;
+ display: grid;
+ grid-template-columns: minmax(0, 1fr);
+ gap: 24px;
+ border: 1px solid rgba(250, 248, 245, 0.1);
+ border-radius: 12px;
+ background: rgba(255, 255, 255, 0.08);
+ color: #faf8f5;
+ box-shadow: 0 28px 90px rgba(0, 0, 0, 0.55);
+ animation: dashboardConfirmDialogIn 280ms cubic-bezier(0.16, 1, 0.3, 1) both;
+}
+
+.dash-page .dashboard-confirm-copy h3 {
+ margin: 0;
+ color: #faf8f5;
+ font-size: 24px;
+ font-weight: 600;
+ line-height: 1.12;
+ letter-spacing: 0;
+}
+
+.dash-page .dashboard-confirm-copy p {
+ margin: 10px 0 0;
+ color: #b8bbbe;
+ font-size: 18px;
+ font-weight: 400;
+ line-height: 1.35;
+}
+
+.dash-page .dashboard-confirm-actions {
+ display: flex;
+ justify-content: flex-end;
+ gap: 12px;
+}
+
+.dash-page .dashboard-confirm-cancel,
+.dash-page .dashboard-confirm-remove {
+ min-height: 48px;
+ padding: 0 22px;
+ border-radius: 24px;
+ font-size: 16px;
+ font-weight: 500;
+ line-height: 1;
+ letter-spacing: 0;
+}
+
+.dash-page .dashboard-confirm-cancel {
+ min-width: 104px;
+}
+
+.dash-page .dashboard-confirm-remove {
+ min-width: 112px;
+ border-color: #ff6b6b;
+ background: #ff6b6b;
+ color: #fff;
+}
+
+.dash-page .dashboard-confirm-remove:hover:not(:disabled) {
+ border-color: #ff8f8f;
+ background: #ff8f8f;
+ color: #fff;
+}
+
+.dash-page .dashboard-confirm-remove:disabled {
+ color: rgba(255, 255, 255, 0.72);
+}
+
+@keyframes dashboardConfirmBackdropIn {
+ from {
+ opacity: 0;
+ }
+
+ to {
+ opacity: 1;
+ }
+}
+
+@keyframes dashboardConfirmDialogIn {
+ from {
+ opacity: 0;
+ filter: blur(6px);
+ transform: translate3d(0, 10px, 0) scale(0.98);
+ }
+
+ to {
+ opacity: 1;
+ filter: blur(0);
+ transform: translate3d(0, 0, 0) scale(1);
+ }
+}
+
+@media (max-width: 860px) {
+ .dash-page .dashboard-header p,
+ .dash-page .dashboard-section-head p {
+ font-size: 16px;
+ }
+
+ .dash-page .dashboard-confirm-dialog {
+ gap: 20px;
+ padding: 22px;
+ }
+
+ .dash-page .dashboard-confirm-copy h3 {
+ font-size: 24px;
+ }
+
+ .dash-page .dashboard-confirm-copy p {
+ font-size: 16px;
+ }
+
+ .dash-page .dashboard-confirm-actions {
+ flex-direction: column-reverse;
+ margin-top: 4px;
+ }
+
+ .dash-page .dashboard-confirm-cancel,
+ .dash-page .dashboard-confirm-remove {
+ width: 100%;
+ }
+}
+
+@media (prefers-reduced-motion: reduce) {
+ .wm-route-pending img,
+ .dash-page .dashboard-header,
+ .dash-page .dash-alert,
+ .dash-page .dashboard-cta-row--primary,
+ .dash-page .dashboard-section-head,
+ .dash-page .dashboard-cta-row--resources,
+ .dash-page .dashboard-credentials-card,
+ .dash-page .dashboard-keys-card,
+ .dash-page .dashboard-quickstart-card,
+ .dash-page .dashboard-install-card,
+ .dash-page .dashboard-add-key-form,
+ .dash-page .dashboard-add-key-field,
+ .dash-page .dashboard-add-key-note,
+ .dash-page .dashboard-add-key-actions,
+ .dash-page .dashboard-confirm-backdrop,
+ .dash-page .dashboard-confirm-dialog {
+ animation: none;
+ }
+}
+
+/* ── Sign-in screen (Figma 2556:112) ───────────────────────── */
+.wm-signin {
+ position: fixed;
+ inset: 0;
+ z-index: 1000;
+ background: #050608;
+ overflow: hidden;
+ display: grid;
+ place-items: center;
+ font-family: var(--font-sans);
+}
+
+.wm-signin--page {
+ position: relative;
+ inset: auto;
+ z-index: 0;
+ min-height: 100vh;
+ min-height: 100dvh;
+ overflow: clip;
+}
+
+.wm-signin-backdrop {
+ position: absolute;
+ inset: 0;
+ z-index: 0;
+}
+
+.wm-signin-aurora {
+ position: absolute;
+ inset: 0;
+ width: 100%;
+ height: 100%;
+ object-fit: cover;
+ object-position: center;
+ opacity: 1;
+ z-index: 0;
+ pointer-events: none;
+}
+
+.wm-signin::after {
+ content: "";
+ position: absolute;
+ inset: 0;
+ z-index: 1;
+ pointer-events: none;
+ background: linear-gradient(
+ 90deg,
+ rgba(5, 6, 8, 0) 0%,
+ rgba(5, 6, 8, 0) 42%,
+ rgba(5, 6, 8, 0.5) 62%,
+ rgba(5, 6, 8, 0.74) 82%,
+ rgba(5, 6, 8, 0.74) 100%
+ );
+}
+
+.wm-signin-close {
+ position: absolute;
+ top: 28px;
+ right: 28px;
+ z-index: 3;
+ width: 42px;
+ height: 42px;
+ display: grid;
+ place-items: center;
+ border: 1px solid rgba(250, 248, 245, 0.18);
+ border-radius: 50%;
+ background: rgba(255, 255, 255, 0.06);
+ color: #faf8f5;
+ cursor: pointer;
+}
+
+.wm-signin-close svg {
+ transform: rotate(45deg);
+}
+
+.wm-signin-inner {
+ position: relative;
+ z-index: 2;
+ width: min(1480px, calc(100% - 112px));
+ display: grid;
+ grid-template-columns: minmax(520px, 640px) minmax(560px, 1fr);
+ align-items: center;
+ gap: clamp(64px, 5.2vw, 96px);
+}
+
+.wm-signin-card {
+ width: clamp(520px, 33vw, 640px);
+ max-width: 100%;
+ aspect-ratio: 900 / 1010;
+ padding: clamp(52px, 5.3vh, 76px) 0 clamp(42px, 4.8vh, 62px);
+ border-radius: 18px;
+ border: 0;
+ background:
+ radial-gradient(82% 48% at 87% 2%, rgba(0, 91, 153, 0.78) 0%, rgba(0, 60, 112, 0.5) 35%, rgba(0, 17, 31, 0) 72%),
+ radial-gradient(78% 45% at 1% 16%, rgba(129, 120, 178, 0.44) 0%, rgba(43, 55, 90, 0.28) 44%, rgba(0, 12, 22, 0) 78%),
+ linear-gradient(180deg, rgba(12, 34, 61, 0.96) 0%, rgba(0, 64, 96, 0.8) 46%, rgba(0, 14, 22, 0.95) 74%, #01060a 100%);
+ backdrop-filter: blur(30px);
+ -webkit-backdrop-filter: blur(30px);
+ text-align: center;
+ box-shadow: none;
+}
+
+.wm-signin-logo {
+ display: block;
+ width: min(330px, 46%);
+ max-width: none;
+ height: auto;
+ margin: 0 auto;
+}
+
+.wm-signin-sub {
+ width: min(610px, 78%);
+ margin: clamp(28px, 3.7vh, 42px) auto clamp(42px, 5.4vh, 58px);
+ color: #faf8f5;
+ font-size: clamp(23px, 1.55vw, 34px);
+ font-weight: 400;
+ line-height: 1.34;
+}
+
+.wm-page .wm-signin-google,
+.wm-page .wm-signin-wallet button {
+ width: 100%;
+ min-height: clamp(62px, 6vh, 86px);
+ padding: 0 clamp(30px, 3.2vw, 48px);
+ border-radius: 999px;
+ border: 2px solid rgba(250, 248, 245, 0.94);
+ background: transparent;
+ color: #faf8f5;
+ font-family: var(--font-sans);
+ font-size: clamp(20px, 1.18vw, 26px);
+ font-weight: 500;
+ letter-spacing: 0;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ gap: 12px;
+ cursor: pointer;
+ box-sizing: border-box;
+}
+
+.wm-signin-google {
+ position: relative;
+ width: min(552px, 62%);
+ margin: 0 auto clamp(22px, 2.3vh, 28px);
+ border-color: #faf8f5;
+}
+
+.wm-page .wm-signin-google {
+ width: min(552px, 62%);
+}
+
+.wm-signin-google svg {
+ position: absolute;
+ left: clamp(30px, 10%, 48px);
+ flex: 0 0 auto;
+ width: clamp(27px, 1.65vw, 34px);
+ height: clamp(27px, 1.65vw, 34px);
+}
+
+.wm-signin-google:hover {
+ background: rgba(255, 255, 255, 0.08);
+}
+
+.wm-signin-wallet {
+ display: block;
+ width: min(552px, 62%);
+ margin: 0 auto;
+}
+
+.wm-signin-wallet button {
+ background: transparent !important;
+ border: 2px solid rgba(250, 248, 245, 0.94) !important;
+ border-radius: 999px !important;
+ box-shadow: none !important;
+}
+
+.wm-signin-wallet button,
+.wm-signin-wallet button * {
+ color: #faf8f5 !important;
+}
+
+.wm-signin-wallet button:hover {
+ background: rgba(255, 255, 255, 0.08) !important;
+}
+
+.wm-signin-tos {
+ width: min(360px, 64%);
+ margin: clamp(38px, 5vh, 54px) auto 0;
+ color: #8f9294;
+ font-size: clamp(13px, 0.9vw, 18px);
+ font-weight: 400;
+ line-height: 1.34;
+}
+
+.wm-signin-tos a {
+ color: #faf8f5;
+ text-decoration: none;
+}
+
+.wm-signin-trusted {
+ text-align: center;
+}
+
+.wm-signin-trusted h2 {
+ margin: 0 0 44px;
+ color: #faf8f5;
+ font-size: 72px;
+ line-height: 0.9;
+ font-weight: 500;
+ letter-spacing: 0;
+ text-align: center;
+}
+
+.wm-signin-trusted h2 span {
+ color: transparent;
+ background: linear-gradient(93deg, #383bff 0%, #9a57ff 48%, #eda0ff 98%);
+ -webkit-background-clip: text;
+ background-clip: text;
+}
+
+.wm-signin-logos {
+ display: grid;
+ grid-template-columns: repeat(3, auto);
+ justify-content: center;
+ justify-items: center;
+ align-items: center;
+ gap: 36px 52px;
+}
+
+.wm-signin-logos img {
+ height: auto;
+ max-width: 100%;
+ object-fit: contain;
+ opacity: 0.92;
+}
+
+@media (max-width: 900px) {
+ .wm-signin-inner {
+ grid-template-columns: 1fr;
+ gap: 40px;
+ justify-items: center;
+ width: calc(100% - 40px);
+ }
+
+ .wm-signin-card {
+ width: min(100%, 640px);
+ aspect-ratio: auto;
+ min-height: min(760px, calc(100vh - 72px));
+ padding: 64px 0 50px;
+ }
+
+ .wm-signin-logo {
+ width: min(330px, 58%);
+ }
+
+ .wm-signin-sub {
+ width: min(520px, 82%);
+ font-size: clamp(25px, 6.2vw, 34px);
+ margin: 36px auto 58px;
+ }
+
+ .wm-page .wm-signin-google,
+ .wm-page .wm-signin-wallet {
+ width: min(440px, 82%);
+ }
+
+ .wm-signin-google,
+ .wm-signin-wallet button {
+ min-height: 72px;
+ font-size: clamp(22px, 5.4vw, 30px);
+ }
+
+ .wm-signin-google svg {
+ position: static;
+ left: auto;
+ }
+
+ .wm-signin-tos {
+ width: min(360px, 72%);
+ margin-top: 54px;
+ font-size: clamp(14px, 3.4vw, 20px);
+ }
+
+ .wm-signin-trusted {
+ display: none;
+ }
+}
+
+/* Setup flow: align the create-key screen with the dashboard visual system. */
+.setup-classic {
+ background: #000000;
+}
+
+.setup-classic-container {
+ width: min(1100px, calc(100% - 64px));
+ max-width: 1100px;
+ min-height: calc(100vh - 128px);
+ padding: 34px 0 68px;
+}
+
+.setup-classic-panel {
+ width: min(560px, 100%);
+ margin: 0 auto;
+}
+
+.setup-classic-title {
+ margin: 0 0 14px;
+ color: #faf8f5;
+ font-size: 36px;
+ font-weight: 500;
+ line-height: 0.98;
+ letter-spacing: 0;
+}
+
+.setup-classic-description {
+ max-width: 560px;
+ margin: 0 auto 38px;
+ color: #b8bbbe;
+ font-size: 18px;
+ font-weight: 400;
+ line-height: 1.35;
+}
+
+.setup-classic-feature-card {
+ margin-bottom: 34px !important;
+ padding: 30px;
+ border: 1px solid #54575a !important;
+ border-radius: 24px !important;
+ background: #000000 !important;
+ box-shadow: none !important;
+}
+
+.setup-classic-feature {
+ margin-bottom: 26px;
+}
+
+.setup-classic-feature strong {
+ color: #faf8f5;
+ font-size: 24px;
+ font-weight: 650;
+ line-height: 1.18;
+ letter-spacing: 0;
+}
+
+.setup-classic-feature p {
+ margin: 8px 0 0;
+ color: #b8bbbe;
+ font-size: 18px;
+ font-weight: 400;
+ line-height: 1.3;
+ letter-spacing: 0;
+}
+
+.setup-classic-generate {
+ width: 236px;
+ height: 52px;
+ min-height: 52px;
+ padding: 0 30px;
+ border-radius: 26px;
+ background: #faf8f5;
+ border-color: #faf8f5;
+ color: #000000;
+ font-size: 18px;
+ font-weight: 650;
+ line-height: 0.84;
+ letter-spacing: 0;
+}
+
+.setup-classic-generate:hover:not(:disabled) {
+ background: #e8ff75;
+ border-color: #e8ff75;
+ color: #000000;
+ transform: none;
+}
+
+.setup-classic-actions {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ gap: 26px;
+}
+
+.setup-classic-import-trigger {
+ padding: 0;
+ border: 0;
+ background: transparent;
+ color: #8f9294;
+ font: inherit;
+ font-size: 18px;
+ font-weight: 400;
+ line-height: 1.3;
+ letter-spacing: 0;
+ text-decoration: none;
+ cursor: pointer;
+ box-shadow: none;
+}
+
+.setup-classic-import-trigger:hover:not(:disabled) {
+ color: #faf8f5;
+ background: transparent;
+ transform: none;
+ box-shadow: none;
+}
+
+.setup-classic-import-screen {
+ text-align: center;
+}
+
+.setup-classic-divider {
+ margin: 30px 0 22px;
+ color: #8f9294;
+ font-size: 18px;
+ font-weight: 400;
+ line-height: 1.3;
+}
+
+.setup-classic .setup-import-textarea {
+ min-height: 112px;
+ padding: 20px;
+ border: 1px solid #54575a;
+ border-radius: 16px;
+ background: #000000;
+ color: #faf8f5;
+ font-size: 18px;
+ line-height: 1.4;
+}
+
+.setup-classic .setup-import-textarea:focus {
+ border-color: #8f9294;
+ box-shadow: none;
+}
+
+.setup-classic-import-actions {
+ display: block;
+ margin-top: 22px;
+}
+
+.setup-classic .setup-import-button {
+ width: 100%;
+ height: 62px;
+ min-height: 62px;
+ margin-top: 22px;
+ padding: 0 30px;
+ border-radius: 31px;
+ background: #e8ff75;
+ border-color: #e8ff75;
+ color: #000000;
+ font-size: 18px;
+ font-weight: 650;
+ line-height: 0.84;
+ letter-spacing: 0;
+}
+
+.setup-classic-import-actions .setup-import-button {
+ margin-top: 0;
+}
+
+.setup-classic-back-button {
+ width: 132px;
+ height: 62px;
+ min-height: 62px;
+ border-radius: 31px;
+ border: 1px solid #faf8f5;
+ background: transparent;
+ color: #faf8f5;
+ font-size: 18px;
+ font-weight: 650;
+ line-height: 0.84;
+ box-shadow: none;
+}
+
+.setup-classic-back-button:hover:not(:disabled) {
+ background: rgba(255, 255, 255, 0.08);
+ color: #faf8f5;
+ transform: none;
+ box-shadow: none;
+}
+
+.setup-classic-error {
+ margin-top: 14px;
+ padding: 14px 16px;
+ border: 1px solid rgba(255, 107, 107, 0.35);
+ border-radius: 16px;
+ background: rgba(255, 107, 107, 0.1);
+ color: #ff8f8f;
+ font-size: 16px;
+ line-height: 1.35;
+}
+
+.setup-classic-state {
+ min-height: 320px;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+ padding: 72px 0;
+ text-align: center;
+}
+
+.setup-classic-spinner {
+ width: 44px;
+ height: 44px;
+ margin-bottom: 26px;
+ color: #faf8f5;
+ border-width: 4px;
+ opacity: 1;
+}
+
+.setup-classic-state-title {
+ margin: 0 0 10px;
+ color: #faf8f5;
+ font-size: 24px;
+ font-weight: 500;
+ line-height: 1.25;
+}
+
+.setup-classic-state-subtitle {
+ margin: 0;
+ color: #b8bbbe;
+ font-size: 18px;
+ font-weight: 400;
+ line-height: 1.35;
+}
+
+.setup-classic-state-heading {
+ margin: 0 0 12px;
+ color: #faf8f5;
+ font-size: 36px;
+ font-weight: 500;
+ line-height: 0.98;
+}
+
+.setup-classic-ready-screen {
+ text-align: left;
+}
+
+.setup-classic-ready-screen .setup-classic-title {
+ margin-bottom: 34px;
+ text-align: center;
+}
+
+.setup-classic-ready-warning {
+ min-height: 56px;
+ display: flex;
+ align-items: center;
+ gap: 14px;
+ margin-bottom: 24px;
+ padding: 16px 22px;
+ border: 0;
+ border-radius: 4px;
+ background: #e8ff75;
+}
+
+.setup-classic .setup-classic-ready-warning {
+ border-radius: 4px;
+}
+
+.setup-classic-ready-warning-icon {
+ flex: 0 0 auto;
+ color: #000000;
+}
+
+.setup-classic-ready-warning p {
+ margin: 0;
+ color: #000000;
+ font-size: 16px;
+ font-weight: 500;
+ line-height: 1.4;
+}
+
+.setup-classic-ready-warning strong {
+ color: #000000;
+ font-weight: 700;
+}
+
+.setup-key-panel {
+ overflow: hidden;
+ margin-bottom: 24px;
+ border: 1px solid #54575a;
+ border-radius: 24px;
+ background: #000000;
+}
+
+.setup-key-row {
+ display: grid;
+ grid-template-columns: minmax(0, 1fr) auto;
+ gap: 18px;
+ align-items: center;
+ padding: 22px 28px;
+ border-bottom: 1px solid rgba(250, 248, 245, 0.1);
+}
+
+.setup-key-row:last-child {
+ border-bottom: 0;
+}
+
+.setup-key-main {
+ min-width: 0;
+}
+
+.setup-key-label {
+ display: flex;
+ align-items: center;
+ flex-wrap: wrap;
+ gap: 8px;
+ color: #b8bbbe;
+ font-size: 16px;
+ font-weight: 500;
+ line-height: 1.25;
+}
+
+.setup-key-label span {
+ color: #8f9294;
+ font-size: 14px;
+ font-weight: 400;
+}
+
+.setup-key-value {
+ display: block;
+ margin-top: 12px;
+ color: #faf8f5;
+ font-family: var(--font-mono);
+ font-size: 15px;
+ font-weight: 400;
+ line-height: 1.45;
+ overflow-wrap: anywhere;
+}
+
+.setup-key-actions {
+ display: flex;
+ justify-content: flex-end;
+}
+
+.setup-key-copy-button {
+ width: 40px;
+ height: 40px;
+ min-height: 40px;
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ padding: 0;
+ border: 1px solid rgba(250, 248, 245, 0.12);
+ border-radius: 14px;
+ background: rgba(255, 255, 255, 0.08);
+ color: #faf8f5;
+ cursor: pointer;
+ box-shadow: none;
+}
+
+.setup-key-copy-button:hover:not(:disabled) {
+ border-color: rgba(250, 248, 245, 0.24);
+ background: rgba(255, 255, 255, 0.14);
+ color: #faf8f5;
+}
+
+.setup-key-copy-button--copied {
+ border-color: #e8ff75;
+ background: #e8ff75;
+ color: #000000;
+}
+
+.setup-classic-ready-error {
+ margin-bottom: 20px;
+}
+
+.setup-classic-error-action {
+ display: inline-flex;
+ margin-top: 12px;
+ color: #faf8f5;
+ text-decoration: none;
+}
+
+.setup-classic-confirm {
+ position: relative;
+ display: flex;
+ align-items: center;
+ gap: 12px;
+ margin-bottom: 26px;
+ color: #faf8f5;
+ font-size: 16px;
+ font-weight: 400;
+ line-height: 1.3;
+ cursor: pointer;
+}
+
+.setup-classic-confirm input {
+ position: absolute;
+ opacity: 0;
+ pointer-events: none;
+}
+
+.setup-classic-confirm-box {
+ width: 22px;
+ height: 22px;
+ flex: 0 0 auto;
+ margin-top: 0;
+ transform: translateY(-1px);
+ border: 1px solid #54575a;
+ border-radius: 6px;
+ background: #000000;
+ transition: background 0.14s ease, border-color 0.14s ease;
+}
+
+.setup-classic-confirm-box::after {
+ content: "";
+ display: block;
+ width: 7px;
+ height: 11px;
+ margin: 3px auto 0;
+ border: solid #000000;
+ border-width: 0 2px 2px 0;
+ opacity: 0;
+ transform: rotate(45deg);
+}
+
+.setup-classic-confirm input:checked + .setup-classic-confirm-box {
+ border-color: #e8ff75;
+ background: #e8ff75;
+}
+
+.setup-classic-confirm input:checked + .setup-classic-confirm-box::after {
+ opacity: 1;
+}
+
+.setup-classic-confirm input:focus-visible + .setup-classic-confirm-box {
+ outline: 2px solid #e8ff75;
+ outline-offset: 3px;
+}
+
+.setup-classic-confirm-text {
+ min-width: 0;
+ display: block;
+}
+
+.setup-classic-register {
+ width: 100%;
+ height: 62px;
+ min-height: 62px;
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ padding: 0 30px;
+ border: 1px solid #e8ff75;
+ border-radius: 31px;
+ background: #e8ff75;
+ color: #000000;
+ font-family: var(--font-sans);
+ font-size: 18px;
+ font-weight: 650;
+ line-height: 0.84;
+ letter-spacing: 0;
+ cursor: pointer;
+ box-shadow: none !important;
+ transform: none !important;
+ transition: none !important;
+ animation: none !important;
+}
+
+.setup-classic-register:hover,
+.setup-classic-register:hover:not(:disabled),
+.setup-classic-register:active,
+.setup-classic-register:active:not(:disabled) {
+ background: #e8ff75;
+ border-color: #e8ff75;
+ color: #000000;
+ transform: none !important;
+ box-shadow: none !important;
+}
+
+.setup-classic-register:focus,
+.setup-classic-register:focus-visible {
+ outline: none;
+ transform: none !important;
+ box-shadow: none !important;
+}
+
+.setup-classic-register:disabled {
+ border-color: rgba(232, 255, 117, 0.18);
+ background: rgba(232, 255, 117, 0.22);
+ color: rgba(0, 0, 0, 0.42);
+ cursor: not-allowed;
+ transform: none;
+ box-shadow: none;
+}
+
+.setup-classic-register:disabled:hover {
+ border-color: rgba(232, 255, 117, 0.18);
+ background: rgba(232, 255, 117, 0.22);
+ color: rgba(0, 0, 0, 0.42);
+ transform: none;
+ box-shadow: none;
+}
+
+.setup-classic .setup-import-button:hover:not(:disabled) {
+ background: #e8ff75;
+ border-color: #e8ff75;
+ color: #000000;
+ transform: none;
+}
+
+@media (max-width: 860px) {
+ .setup-classic-nav .nav-brand-logo,
+ .dashboard-nav .nav-brand-logo {
+ height: 44px;
+ }
+
+ .setup-classic-container {
+ width: calc(100% - 32px);
+ min-height: calc(100vh - 92px);
+ padding: 32px 0 56px;
+ }
+
+ .setup-classic-panel {
+ width: 100%;
+ }
+
+ .setup-classic-title {
+ font-size: 30px;
+ }
+
+ .setup-classic-description,
+ .setup-classic-feature p,
+ .setup-classic-divider {
+ font-size: 16px;
+ }
+
+ .setup-classic-feature-card {
+ padding: 24px;
+ border-radius: 20px !important;
+ }
+
+ .setup-classic-feature strong {
+ font-size: 22px;
+ }
+
+ .setup-key-row {
+ grid-template-columns: 1fr;
+ padding: 20px;
+ }
+
+ .setup-key-actions {
+ justify-content: flex-start;
+ }
+
+ .setup-classic-generate {
+ width: 100%;
+ }
+
+ .setup-classic-import-actions {
+ flex-direction: column-reverse;
+ gap: 12px;
+ }
+
+ .setup-classic-back-button,
+ .setup-classic-import-actions .setup-import-button {
+ width: 100%;
+ }
+}
+
+/* Playground final override. This is intentionally last because the file still
+ contains older duplicated dashboard/playground passes above. */
+.playground-nav .nav-brand-logo {
+ display: block;
+ height: 56px;
+ width: auto;
+}
+
+.playground-nav .demo-nav-back {
+ min-height: 28px;
+ display: inline-flex;
+ align-items: center;
+ gap: 8px;
+ color: #b8bbbe;
+ font-size: 16px;
+ font-weight: 500;
+ letter-spacing: 0.2px;
+ text-decoration: none;
+}
+
+.playground-nav .demo-nav-icon {
+ display: none;
+ flex: 0 0 auto;
+ stroke-width: 1.8;
+}
+
+.playground-nav .demo-nav-back:hover {
+ color: #faf8f5;
+}
+
+.playground-dashboard {
+ width: min(1100px, calc(100% - 64px)) !important;
+ max-width: 1100px !important;
+ padding: 34px 0 68px !important;
+}
+
+.playground-dashboard .dashboard-header {
+ max-width: 880px;
+ margin-bottom: 28px !important;
+ animation: dashboardReveal 360ms cubic-bezier(0.16, 1, 0.3, 1) both;
+}
+
+.playground-dashboard .dashboard-header h2 {
+ margin: 0 0 14px;
+ color: #faf8f5;
+ font-family: var(--font-sans);
+ font-size: 56px !important;
+ font-weight: 500;
+ line-height: 0.88;
+ letter-spacing: 0;
+}
+
+.playground-dashboard .dashboard-header p {
+ max-width: 860px;
+ margin: 0;
+ color: #b8bbbe;
+ font-size: 18px !important;
+ font-weight: 400;
+ line-height: 1.35;
+}
+
+.playground-dashboard .dashboard-header code,
+.playground-dashboard .demo-doc-link {
+ color: #e8ff75;
+ font-weight: 500;
+}
+
+.playground-dashboard .demo-server-info {
+ display: flex !important;
+ flex-wrap: wrap;
+ gap: 12px;
+ margin-bottom: 42px;
+ animation: dashboardReveal 360ms cubic-bezier(0.16, 1, 0.3, 1) 45ms both;
+}
+
+.playground-dashboard .demo-server-tag {
+ min-height: 40px;
+ display: inline-flex;
+ align-items: center;
+ gap: 8px;
+ padding: 0 14px;
+ border: 1px solid #54575a;
+ border-radius: 12px;
+ background: rgba(255, 255, 255, 0.08);
+ color: #b8bbbe;
+ font-family: var(--font-mono);
+ font-size: 13px;
+ font-weight: 400;
+ line-height: 1.2;
+ box-shadow: none;
+}
+
+.playground-dashboard .demo-tag-value,
+.playground-dashboard .demo-tag-value--server,
+.playground-dashboard .demo-tag-value--key,
+.playground-dashboard .demo-tag-value--sdk {
+ color: #e8ff75;
+ font-weight: 500;
+}
+
+.playground-dashboard .demo-server-tag--namespace {
+ padding-right: 10px;
+}
+
+.playground-dashboard .demo-namespace-input {
+ width: auto;
+ min-width: 74px;
+ padding: 0;
+ border: 0;
+ outline: none;
+ background: transparent;
+ color: #faf8f5;
+ font-family: var(--font-mono);
+ font-size: 13px;
+ font-weight: 500;
+}
+
+.playground-dashboard .card.demo-step {
+ margin-bottom: 42px !important;
+ padding: 32px !important;
+ border: 1px solid #54575a !important;
+ border-radius: 24px !important;
+ background: rgba(255, 255, 255, 0.08) !important;
+ color: #faf8f5;
+ box-shadow: none !important;
+ animation: dashboardReveal 360ms cubic-bezier(0.16, 1, 0.3, 1) both;
+}
+
+.playground-dashboard .card.demo-step:hover {
+ border-color: #54575a !important;
+ box-shadow: none !important;
+}
+
+.playground-dashboard .card-header {
+ align-items: flex-start;
+ gap: 24px;
+ margin-bottom: 24px !important;
+}
+
+.playground-dashboard .card-header > :last-child {
+ flex: 0 0 auto;
+}
+
+.playground-dashboard .demo-step-header-row {
+ min-width: 0;
+ align-items: flex-start;
+ gap: 18px;
+}
+
+.playground-dashboard .demo-step-badge {
+ width: 40px !important;
+ height: 40px !important;
+ border: 1px solid #54575a;
+ border-radius: 12px !important;
+ background: #000000;
+ color: #faf8f5;
+ font-family: var(--font-mono);
+ font-size: 15px;
+ font-weight: 500;
+ line-height: 1;
+ box-shadow: none;
+}
+
+.playground-dashboard .demo-step-badge--highlight {
+ border-color: #e8ff75;
+ background: #e8ff75;
+ color: #000000;
+}
+
+.playground-dashboard .card-title,
+.playground-dashboard .demo-step-title {
+ color: #faf8f5;
+ font-family: var(--font-sans);
+ font-size: 28px !important;
+ font-weight: 650;
+ line-height: 1.05;
+ letter-spacing: 0;
+}
+
+.playground-dashboard .card-subtitle {
+ margin-top: 8px;
+ color: #b8bbbe;
+ font-family: var(--font-sans);
+ font-size: 17px !important;
+ font-weight: 400;
+ line-height: 1.3;
+}
+
+.playground-dashboard .btn {
+ min-width: 84px;
+ min-height: 44px !important;
+ height: 44px;
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ padding: 2px 22px 0;
+ border-radius: 22px;
+ font-family: var(--font-sans);
+ font-size: 16px;
+ font-weight: 550;
+ line-height: 1;
+ letter-spacing: 0;
+ box-shadow: none !important;
+ transform: none !important;
+ transition: background 0.14s ease, border-color 0.14s ease, color 0.14s ease;
+}
+
+.playground-dashboard .btn-primary,
+.playground-dashboard .btn-primary:hover:not(:disabled),
+.playground-dashboard .btn-primary:active:not(:disabled) {
+ border: 1px solid #e8ff75;
+ background: #e8ff75;
+ color: #000000;
+ transform: none !important;
+ box-shadow: none !important;
+}
+
+.playground-dashboard .btn-primary:disabled {
+ border-color: rgba(232, 255, 117, 0.18);
+ background: rgba(232, 255, 117, 0.22);
+ color: rgba(0, 0, 0, 0.42);
+}
+
+.playground-dashboard .btn-primary.demo-run-button--loading:disabled {
+ border-color: #e8ff75;
+ background: #e8ff75;
+ color: #000000;
+ opacity: 1;
+}
+
+.playground-dashboard .demo-button-spinner {
+ width: 14px;
+ height: 14px;
+ border-color: rgba(0, 0, 0, 0.28);
+ border-top-color: #000000;
+}
+
+.playground-dashboard .input-group {
+ margin-bottom: 18px !important;
+}
+
+.playground-dashboard .input-group label,
+.playground-dashboard .demo-info-label,
+.playground-dashboard .demo-result-label,
+.playground-dashboard .demo-error-label {
+ display: block;
+ margin-bottom: 12px;
+ color: #b8bbbe;
+ font-family: var(--font-sans);
+ font-size: 17px !important;
+ font-weight: 400;
+ line-height: 1.3;
+ letter-spacing: 0;
+}
+
+.playground-dashboard .input {
+ min-height: 52px;
+ padding: 13px 16px;
+ border: 1px solid #54575a;
+ border-radius: 14px;
+ background: #000000;
+ color: #faf8f5;
+ font-family: var(--font-sans);
+ font-size: 16px;
+ font-weight: 400;
+ line-height: 1.4;
+ box-shadow: none;
+}
+
+.playground-dashboard textarea.input {
+ min-height: 108px;
+ resize: vertical;
+}
+
+.playground-dashboard .input:focus {
+ border-color: #e8ff75;
+ outline: none;
+ box-shadow: 0 0 0 3px rgba(232, 255, 117, 0.12);
+}
+
+.playground-dashboard .input::placeholder {
+ color: #8f9294;
+}
+
+.playground-dashboard select.input {
+ width: 152px;
+ flex: 0 0 152px;
+}
+
+.playground-dashboard select.input option {
+ background: #000000;
+ color: #faf8f5;
+}
+
+.playground-dashboard .demo-code-block {
+ margin: 0;
+ padding: 24px 28px !important;
+ border: 1px solid #54575a;
+ border-radius: 24px !important;
+ background: #000000 !important;
+ color: #faf8f5 !important;
+ font-family: var(--font-mono);
+ font-size: 14px !important;
+ font-weight: 400;
+ line-height: 1.5 !important;
+ white-space: pre-wrap !important;
+ word-break: break-word;
+ overflow-x: hidden;
+ box-shadow: none !important;
+}
+
+.playground-dashboard .demo-code-block code {
+ white-space: inherit !important;
+}
+
+.playground-dashboard .demo-code-block--spaced {
+ margin-bottom: 18px;
+}
+
+.playground-dashboard .demo-info-panel,
+.playground-dashboard .demo-ai-panel,
+.playground-dashboard .demo-result-panel,
+.playground-dashboard .demo-error-panel,
+.playground-dashboard .demo-phase-indicator {
+ margin-bottom: 18px;
+ padding: 20px;
+ border-radius: 20px;
+ background: #000000;
+ color: #b8bbbe;
+ box-shadow: none;
+}
+
+.playground-dashboard .demo-info-panel:last-child,
+.playground-dashboard .demo-ai-panel:last-child,
+.playground-dashboard .demo-result-panel:last-child,
+.playground-dashboard .demo-error-panel:last-child,
+.playground-dashboard .demo-phase-indicator:last-child {
+ margin-bottom: 0;
+}
+
+.playground-dashboard .demo-info-panel,
+.playground-dashboard .demo-ai-panel,
+.playground-dashboard .demo-phase-indicator {
+ border: 1px solid #54575a;
+}
+
+.playground-dashboard .demo-result-panel {
+ border: 1px solid rgba(232, 255, 117, 0.44);
+}
+
+.playground-dashboard .demo-error-panel {
+ border: 1px solid rgba(255, 110, 116, 0.55);
+}
+
+.playground-dashboard .demo-result-label {
+ color: #e8ff75;
+}
+
+.playground-dashboard .demo-error-label,
+.playground-dashboard .demo-error-pre {
+ color: #ff878d;
+}
+
+.playground-dashboard .demo-result-pre,
+.playground-dashboard .demo-error-pre {
+ margin: 0;
+ color: #faf8f5;
+ font-family: var(--font-mono);
+ font-size: 14px;
+ line-height: 1.55;
+ white-space: pre-wrap;
+ word-break: break-word;
+}
+
+.playground-dashboard .demo-ai-answer {
+ color: #faf8f5;
+ font-size: 16px;
+ line-height: 1.55;
+}
+
+.playground-dashboard .demo-phase-indicator {
+ display: flex;
+ align-items: center;
+ gap: 12px;
+ color: #faf8f5;
+}
+
+.playground-dashboard .demo-llm-controls {
+ display: flex;
+ gap: 12px;
+ margin-bottom: 10px;
+}
+
+.playground-dashboard .demo-llm-controls input {
+ flex: 1;
+}
+
+.playground-dashboard .demo-field-note {
+ color: #b8bbbe;
+ font-family: var(--font-sans);
+ font-size: 17px !important;
+ font-weight: 400;
+ line-height: 1.3;
+}
+
+.playground-dashboard .demo-ready-pill {
+ min-height: 28px;
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ padding: 0 12px;
+ border-radius: 14px;
+ background: #e8ff75;
+ color: #000000;
+ font-size: 13px;
+ font-weight: 600;
+}
+
+.playground-dashboard .demo-memory-item {
+ display: grid;
+ grid-template-columns: 48px minmax(0, 1fr);
+ gap: 12px;
+ align-items: baseline;
+ margin-bottom: 10px;
+ color: #b8bbbe;
+ font-family: var(--font-mono);
+ font-size: 13px;
+ line-height: 1.45;
+}
+
+.playground-dashboard .demo-memory-item:last-child {
+ margin-bottom: 0;
+}
+
+.playground-dashboard .demo-memory-score {
+ color: #e8ff75;
+}
+
+.playground-dashboard .demo-details-summary {
+ margin-bottom: 10px;
+ color: #b8bbbe;
+ cursor: pointer;
+ font-size: 14px;
+ line-height: 1.3;
+}
+
+.playground-dashboard .demo-system-prompt {
+ color: #b8bbbe !important;
+ font-size: 13px !important;
+}
+
+.playground-dashboard .demo-mode-divider {
+ margin: 56px 0 30px;
+ color: #b8bbbe;
+ font-family: var(--font-sans);
+ font-size: 17px !important;
+ font-weight: 400;
+ line-height: 1.3;
+ text-align: center;
+}
+
+@media (max-width: 860px) {
+ .setup-classic-nav,
+ .playground-nav,
+ .dashboard-nav {
+ height: 80px;
+ padding: 0 14px;
+ }
+
+ .setup-classic-nav .nav-inner,
+ .playground-nav .nav-inner,
+ .dashboard-nav .nav-inner {
+ height: 80px;
+ min-height: 80px;
+ }
+
+ .setup-classic-nav .nav-brand,
+ .playground-nav .nav-brand,
+ .dashboard-nav .nav-brand {
+ top: 22px;
+ }
+
+ .setup-classic-nav .nav-brand-logo,
+ .playground-nav .nav-brand-logo,
+ .dashboard-nav .nav-brand-logo {
+ height: 36px;
+ }
+
+ .setup-classic-nav .nav-user,
+ .playground-nav .nav-user,
+ .dashboard-nav .nav-user {
+ top: 21px;
+ height: 38px;
+ gap: 8px;
+ }
+
+ .setup-classic-nav .nav-address,
+ .playground-nav .nav-address,
+ .dashboard-nav .nav-address {
+ min-width: 96px;
+ height: 34px;
+ padding: 0 10px;
+ font-size: 11px;
+ letter-spacing: 0.45px;
+ }
+
+ .setup-classic-nav .lp-nav-cta,
+ .playground-nav .lp-nav-cta,
+ .dashboard-nav .lp-nav-cta {
+ height: 38px;
+ min-height: 38px;
+ padding: 0 14px;
+ border-radius: 19px;
+ font-size: 14px;
+ letter-spacing: 0.3px;
+ gap: 8px;
+ }
+
+ .setup-classic-nav .lp-nav-cta svg,
+ .playground-nav .lp-nav-cta svg,
+ .dashboard-nav .lp-nav-cta svg {
+ width: 12px;
+ height: 12px;
+ }
+
+ .playground-nav .demo-nav-label {
+ display: none;
+ }
+
+ .playground-nav .demo-nav-icon {
+ display: block;
+ }
+
+ .playground-nav .demo-nav-back {
+ width: 38px !important;
+ min-width: 38px !important;
+ height: 38px !important;
+ min-height: 38px !important;
+ padding: 0 !important;
+ border: 1px solid #54575a;
+ border-radius: 19px;
+ background: #000000;
+ color: #faf8f5;
+ justify-content: center;
+ }
+
+ .dash-page .dash-shell,
+ .playground-dashboard,
+ .setup-classic-container {
+ width: calc(100% - 28px) !important;
+ padding: 28px 0 48px !important;
+ }
+
+ .dash-page .card,
+ .playground-dashboard .card.demo-step {
+ padding: 24px !important;
+ border-radius: 20px !important;
+ }
+
+ .dash-page .card-header,
+ .playground-dashboard .card-header {
+ gap: 18px;
+ margin-bottom: 28px !important;
+ }
+
+ .dash-page .card-title,
+ .playground-dashboard .card-title,
+ .playground-dashboard .demo-step-title {
+ font-size: 28px !important;
+ line-height: 1;
+ }
+
+ .dash-page .card-subtitle,
+ .playground-dashboard .card-subtitle {
+ font-size: 16px !important;
+ line-height: 1.32;
+ }
+
+ .playground-dashboard .dashboard-header h2 {
+ font-size: 38px !important;
+ line-height: 0.96;
+ }
+
+ .playground-dashboard .dashboard-header p {
+ font-size: 16px !important;
+ }
+
+ .dash-page .card-header-actions .btn-secondary,
+ .dash-page .card-header-actions .lp-nav-cta,
+ .playground-dashboard .btn {
+ min-height: 44px !important;
+ height: 44px;
+ padding: 0 16px;
+ border-radius: 22px;
+ font-size: 15px;
+ letter-spacing: 0.25px;
+ }
+
+ .playground-dashboard .btn {
+ width: 100%;
+ }
+
+ .playground-dashboard .demo-llm-controls {
+ flex-direction: column;
+ }
+
+ .playground-dashboard select.input {
+ width: 100%;
+ flex-basis: auto;
+ }
+
+ .dash-page .dashboard-keys-card {
+ padding: 24px !important;
+ }
+
+ .dash-page .dashboard-keys-card .card-header {
+ flex-direction: column;
+ align-items: stretch;
+ }
+
+ .dash-page .dashboard-keys-card .card-header-actions {
+ width: 100%;
+ max-width: 100%;
+ display: grid;
+ grid-template-columns: repeat(2, minmax(0, 1fr));
+ gap: 12px;
+ align-self: stretch;
+ }
+
+ .dash-page .dashboard-keys-card .card-header-actions .dashboard-keys-refresh,
+ .dash-page .dashboard-keys-card .card-header-actions .dashboard-keys-add {
+ width: 100%;
+ min-width: 0;
+ }
+}
+
+@media (max-width: 820px) {
+ .setup-classic-nav,
+ .playground-nav,
+ .dashboard-nav {
+ height: 72px;
+ padding: 0 10px;
+ }
+
+ .setup-classic-nav .nav-inner,
+ .playground-nav .nav-inner,
+ .dashboard-nav .nav-inner {
+ height: 72px;
+ min-height: 72px;
+ }
+
+ .setup-classic-nav .nav-brand,
+ .playground-nav .nav-brand,
+ .dashboard-nav .nav-brand {
+ top: 20px;
+ }
+
+ .setup-classic-nav .nav-brand-logo,
+ .playground-nav .nav-brand-logo,
+ .dashboard-nav .nav-brand-logo {
+ height: 32px;
+ }
+
+ .setup-classic-nav .nav-user,
+ .playground-nav .nav-user,
+ .dashboard-nav .nav-user {
+ top: 18px;
+ height: 36px;
+ gap: 6px;
+ }
+
+ .setup-classic-nav .nav-address,
+ .playground-nav .nav-address,
+ .dashboard-nav .nav-address {
+ min-width: 86px;
+ height: 32px;
+ padding: 0 8px;
+ font-size: 10.5px;
+ letter-spacing: 0.35px;
+ }
+
+ .setup-classic-nav .lp-nav-cta,
+ .playground-nav .lp-nav-cta,
+ .dashboard-nav .lp-nav-cta {
+ height: 36px;
+ min-height: 36px;
+ padding: 0 12px;
+ border-radius: 18px;
+ font-size: 13px;
+ gap: 7px;
+ }
+
+ .setup-classic-nav .lp-nav-cta svg,
+ .playground-nav .lp-nav-cta svg,
+ .dashboard-nav .lp-nav-cta svg {
+ width: 11px;
+ height: 11px;
+ }
+
+ .playground-nav .demo-nav-back {
+ width: 36px !important;
+ min-width: 36px !important;
+ height: 36px !important;
+ min-height: 36px !important;
+ border-radius: 18px;
+ }
+
+ .playground-nav .demo-nav-icon {
+ width: 16px;
+ height: 16px;
+ }
+}
diff --git a/apps/app/src/pages/Dashboard.tsx b/apps/app/src/pages/Dashboard.tsx
index 5b5588e6..a48cd0ed 100644
--- a/apps/app/src/pages/Dashboard.tsx
+++ b/apps/app/src/pages/Dashboard.tsx
@@ -2,26 +2,27 @@
* Dashboard — Account info, delegate keys management, SDK integration guide
*/
-import { useState, useCallback, useEffect, useMemo } from 'react'
+import { useState, useCallback, useEffect, useMemo, useRef, type SVGProps } from 'react'
import {
useCurrentAccount,
useDisconnectWallet,
useSignPersonalMessage,
useSuiClient,
} from '@mysten/dapp-kit'
+import { Transaction } from '@mysten/sui/transactions'
import { useSponsoredTransaction } from '../hooks/useSponsoredTransaction'
-import { generateDelegateKey, addDelegateKey, removeDelegateKey } from '@mysten-incubation/memwal/account'
+import { generateDelegateKey, addDelegateKey } from '@mysten-incubation/memwal/account'
import type { WalletSigner } from '@mysten-incubation/memwal/manual'
-import { Link } from 'react-router-dom'
-import { Copy, Eye, EyeOff, Trash2, RefreshCw, Plus, LogOut } from 'lucide-react'
+import { Link, useNavigate } from 'react-router-dom'
+import { TriangleAlert, Copy, Eye, EyeOff, Trash2, RefreshCw, Plus, LogOut, Github, MessageCircle } from 'lucide-react'
import { Light as SyntaxHighlighter } from 'react-syntax-highlighter'
import js from 'react-syntax-highlighter/dist/esm/languages/hljs/javascript'
-import bash from 'react-syntax-highlighter/dist/esm/languages/hljs/bash'
-import { githubGist } from 'react-syntax-highlighter/dist/esm/styles/hljs'
+import python from 'react-syntax-highlighter/dist/esm/languages/hljs/python'
SyntaxHighlighter.registerLanguage('javascript', js)
-SyntaxHighlighter.registerLanguage('bash', bash)
+SyntaxHighlighter.registerLanguage('python', python)
import { useDelegateKey } from '../App'
+import { Card } from '../components/Card'
import { config } from '../config'
import { getAnalyticsErrorType, trackEvent } from '../utils/analytics'
import {
@@ -31,7 +32,82 @@ import {
type DynamicFieldObjectFields,
type RegistryObjectFields,
} from '../utils/suiFields'
-import memwalLogo from '../assets/memwal-logo.svg'
+
+function DelegateKeyCtaIcon(props: SVGProps
) {
+ return (
+
+ )
+}
+
+function DocumentationCtaIcon(props: SVGProps) {
+ return (
+
+ )
+}
+
+function CtaArrowIcon(props: SVGProps) {
+ return (
+
+ )
+}
+
+const walrusCodeTheme = {
+ hljs: {
+ color: '#faf8f5',
+ background: '#050505',
+ },
+ 'hljs-keyword': {
+ color: '#cab1ff',
+ },
+ 'hljs-built_in': {
+ color: '#faf8f5',
+ },
+ 'hljs-title': {
+ color: '#faf8f5',
+ },
+ 'hljs-attr': {
+ color: '#e8ff75',
+ },
+ 'hljs-property': {
+ color: '#e8ff75',
+ },
+ 'hljs-variable': {
+ color: '#faf8f5',
+ },
+ 'hljs-string': {
+ color: '#e8ff75',
+ },
+ 'hljs-comment': {
+ color: '#8f9294',
+ },
+ 'hljs-number': {
+ color: '#e8ff75',
+ },
+ 'hljs-literal': {
+ color: '#e8ff75',
+ },
+ 'hljs-params': {
+ color: '#faf8f5',
+ },
+}
// ============================================================
// Types
@@ -45,37 +121,120 @@ interface OnChainDelegateKey {
}
const MAX_DELEGATE_KEYS = 20
-const MAX_DELEGATE_KEYS_MESSAGE = 'this wallet already has 20 delegate keys. remove an old key before creating a new delegate key.'
+const MAX_DELEGATE_KEYS_MESSAGE = 'This wallet already has 20 delegate keys. Remove an old key before creating a new delegate key.'
+const SDK_DEFAULT_SERVER_URL = 'https://relayer.memwal.ai'
+const PRIVATE_KEY_ENV = 'MEMWAL_PRIVATE_KEY'
+const ACCOUNT_ID_ENV = 'MEMWAL_ACCOUNT_ID'
+const SERVER_URL_ENV = 'MEMWAL_SERVER_URL'
+type QuickstartLanguage = 'ts' | 'py'
+type RemoveKeysConfirmState = {
+ publicKeys: string[]
+ source: 'single' | 'selection'
+}
+
+function bytesToHex(bytes: Uint8Array | number[]): string {
+ return Array.from(bytes).map((b) => b.toString(16).padStart(2, '0')).join('')
+}
+
+function hexToByteArray(hex: string): number[] {
+ const normalized = hex.startsWith('0x') ? hex.slice(2) : hex
+ if (!/^[0-9a-fA-F]{64}$/.test(normalized)) {
+ throw new Error('invalid delegate public key')
+ }
+
+ return Array.from({ length: normalized.length / 2 }, (_, i) =>
+ parseInt(normalized.slice(i * 2, i * 2 + 2), 16)
+ )
+}
+
+function compactPublicKey(publicKey: string): string {
+ const normalized = publicKey.startsWith('0x') ? publicKey.slice(2) : publicKey
+ if (normalized.length <= 24) return publicKey
+ return `${normalized.slice(0, 12)}...${normalized.slice(-8)}`
+}
+
+function DelegateKeySkeletonList() {
+ return (
+
+
+
+
+ | Select |
+ Key name |
+ Public key |
+ Created |
+ Actions |
+
+
+
+ {[0, 1].map((index) => (
+
+ |
+ |
+ |
+ |
+ |
+
+ ))}
+
+
+
+ )
+}
// ============================================================
// Dashboard Component
// ============================================================
-export default function Dashboard() {
+export default function Dashboard({
+ previewMode = false,
+ previewState = 'empty',
+}: {
+ previewMode?: boolean
+ previewState?: 'empty' | 'ready'
+}) {
const currentAccount = useCurrentAccount()
+ const navigate = useNavigate()
const { mutateAsync: disconnect } = useDisconnectWallet()
const { mutateAsync: signAndExecuteTx } = useSponsoredTransaction()
const { mutateAsync: signPersonalMsg } = useSignPersonalMessage()
const suiClient = useSuiClient()
- const { delegateKey, delegatePublicKey, accountObjectId, clearDelegateKeys } = useDelegateKey()
+ const { delegateKey, delegatePublicKey, accountObjectId, setDelegateKeys, clearDelegateKeys } = useDelegateKey()
- const address = currentAccount?.address || ''
+ const address = currentAccount?.address || (
+ previewMode
+ ? '0x7f33c06e6d144bc3c24aaef7c8f7421c1287df6ce9c5ab74ac729b13f4194'
+ : ''
+ )
+ const previewReady = previewMode && previewState === 'ready'
+ const previewAccountObjectId = previewReady
+ ? '0x7bc62cf958c4b27b16ad2f1a3f33d1f0e811e08d4fc079edc3525a7d2e2dc551'
+ : null
const [resolvedAccountObjectId, setResolvedAccountObjectId] = useState(accountObjectId)
+ const shouldResolveAccount = Boolean(address && !previewMode && !accountObjectId)
+ const [accountLookupAddress, setAccountLookupAddress] = useState(address)
+ const [accountLookupComplete, setAccountLookupComplete] = useState(!shouldResolveAccount)
const [loadingAccount, setLoadingAccount] = useState(false)
- const effectiveAccountObjectId = accountObjectId ?? resolvedAccountObjectId
+ const effectiveAccountObjectId = accountObjectId ?? previewAccountObjectId ?? resolvedAccountObjectId
const [showKey, setShowKey] = useState(false)
const [copied, setCopied] = useState(null)
const [pkgManager, setPkgManager] = useState<'npm' | 'pnpm' | 'yarn' | 'bun'>('npm')
+ const [quickstartLanguage, setQuickstartLanguage] = useState('ts')
// Delegate key management state
const [onChainKeys, setOnChainKeys] = useState([])
const [loadingKeys, setLoadingKeys] = useState(false)
const [addingKey, setAddingKey] = useState(false)
const [removingKey, setRemovingKey] = useState(null)
+ const [removingSelectedKeys, setRemovingSelectedKeys] = useState(false)
+ const [removeKeysConfirm, setRemoveKeysConfirm] = useState(null)
+ const [selectedKeyPublicKeys, setSelectedKeyPublicKeys] = useState([])
const [showAddForm, setShowAddForm] = useState(false)
- const [newKeyLabel, setNewKeyLabel] = useState('New Key')
+ const [addKeyFormClosing, setAddKeyFormClosing] = useState(false)
+ const [newKeyLabel, setNewKeyLabel] = useState('New key')
const [keyError, setKeyError] = useState('')
const [newPrivateKey, setNewPrivateKey] = useState(null)
+ const addKeyFormCloseTimerRef = useRef(null)
// WalletSigner adapter — wraps dapp-kit hooks into SDK's WalletSigner interface
const walletSigner = useMemo(() => {
@@ -103,15 +262,56 @@ export default function Dashboard() {
trackEvent('sign_out', { location: 'dashboard' })
clearDelegateKeys()
await disconnect()
- }, [clearDelegateKeys, disconnect])
+ navigate('/')
+ }, [clearDelegateKeys, disconnect, navigate])
+
+ const openAddKeyForm = useCallback(() => {
+ if (addKeyFormCloseTimerRef.current !== null) {
+ window.clearTimeout(addKeyFormCloseTimerRef.current)
+ addKeyFormCloseTimerRef.current = null
+ }
+ setAddKeyFormClosing(false)
+ setShowAddForm(true)
+ }, [])
+
+ const closeAddKeyForm = useCallback(() => {
+ setKeyError('')
+ setAddKeyFormClosing(true)
+ if (addKeyFormCloseTimerRef.current !== null) {
+ window.clearTimeout(addKeyFormCloseTimerRef.current)
+ }
+ addKeyFormCloseTimerRef.current = window.setTimeout(() => {
+ setShowAddForm(false)
+ setAddKeyFormClosing(false)
+ addKeyFormCloseTimerRef.current = null
+ }, 260)
+ }, [])
+
+ useEffect(() => {
+ return () => {
+ if (addKeyFormCloseTimerRef.current !== null) {
+ window.clearTimeout(addKeyFormCloseTimerRef.current)
+ }
+ }
+ }, [])
const fetchAccountObjectId = useCallback(async () => {
- if (!address) {
+ if (!address || previewMode) {
setResolvedAccountObjectId(null)
+ setAccountLookupAddress(address)
+ setAccountLookupComplete(true)
+ setLoadingAccount(false)
+ return
+ }
+ if (accountObjectId) {
+ setResolvedAccountObjectId(accountObjectId)
+ setAccountLookupAddress(address)
+ setAccountLookupComplete(true)
+ setLoadingAccount(false)
return
}
- if (accountObjectId) return
setResolvedAccountObjectId(null)
+ setAccountLookupComplete(false)
setLoadingAccount(true)
try {
const registryObj = await suiClient.getObject({
@@ -134,29 +334,38 @@ export default function Dashboard() {
console.error('Failed to fetch account object ID:', err)
setResolvedAccountObjectId(null)
} finally {
+ setAccountLookupAddress(address)
+ setAccountLookupComplete(true)
setLoadingAccount(false)
}
- }, [address, accountObjectId, suiClient])
+ }, [address, accountObjectId, previewMode, suiClient])
useEffect(() => {
setResolvedAccountObjectId(accountObjectId)
- }, [accountObjectId])
+ if (accountObjectId) {
+ setAccountLookupAddress(address)
+ setAccountLookupComplete(true)
+ }
+ }, [accountObjectId, address])
useEffect(() => {
fetchAccountObjectId()
}, [fetchAccountObjectId])
const hasResolvedAccount = Boolean(effectiveAccountObjectId)
- const isRecoveringExistingAccount = !delegateKey && hasResolvedAccount
- const isNewAccount = !delegateKey && !loadingAccount && !hasResolvedAccount
+ const accountLookupPending = loadingAccount || (shouldResolveAccount && (!accountLookupComplete || accountLookupAddress !== address))
+ const isRecoveringExistingAccount = !delegateKey && hasResolvedAccount && !previewReady
+ const isNewAccount = !delegateKey && accountLookupComplete && !hasResolvedAccount
const activeEnvironmentLabel = config.suiNetwork === 'mainnet'
? 'production / mainnet'
: 'staging / testnet'
const expectedRelayerUrl = config.suiNetwork === 'mainnet'
? 'https://relayer.memwal.ai'
- : 'https://relayer.staging.memwal.ai'
+ : 'https://relayer.memwal.ai'
const normalizedRelayerUrl = config.memwalServerUrl.toLowerCase()
- const relayerEnvironmentLabel = normalizedRelayerUrl.includes('localhost') || normalizedRelayerUrl.includes('127.0.0.1')
+ const relayerEnvironmentLabel = normalizedRelayerUrl.startsWith('/')
+ ? 'local dev proxy / testnet'
+ : normalizedRelayerUrl.includes('localhost') || normalizedRelayerUrl.includes('127.0.0.1')
? 'local development'
: normalizedRelayerUrl.includes('staging')
? 'staging / testnet'
@@ -169,14 +378,29 @@ export default function Dashboard() {
normalizedRelayerUrl.includes('relayer.memwal.ai') &&
!normalizedRelayerUrl.includes('staging') &&
!normalizedRelayerUrl.includes('dev'))
- const dashboardSubtitle = delegateKey
- ? 'manage your Walrus Memory account and delegate keys'
- : loadingAccount
- ? 'checking your Walrus Memory account...'
+ const dashboardSubtitle = delegateKey || previewReady
+ ? 'Manage your Walrus Memory account and delegate keys'
+ : accountLookupPending
+ ? 'Checking your Walrus Memory account...'
: hasResolvedAccount
- ? 'remove an old delegate key, then create a new one'
- : 'no Walrus Memory account found for this wallet'
+ ? 'Manage your Walrus Memory account and delegate keys in one place'
+ : 'Manage your Walrus Memory account and delegate keys'
+ const showDashboardSubtitle = Boolean(dashboardSubtitle)
const hasMaxDelegateKeys = onChainKeys.length >= MAX_DELEGATE_KEYS
+ const isKeyListLoading = accountLookupPending || (loadingKeys && onChainKeys.length === 0)
+ const isKeyListRefreshing = loadingKeys && onChainKeys.length > 0
+ const selectableKeyPublicKeys = useMemo(() => onChainKeys.map((key) => key.publicKey), [onChainKeys])
+ const selectedKeySet = useMemo(() => new Set(selectedKeyPublicKeys), [selectedKeyPublicKeys])
+ const selectedKeyCount = selectedKeyPublicKeys.length
+ const keyRemovalBusy = removingSelectedKeys || Boolean(removingKey)
+ const showKeySelectionControls = Boolean(effectiveAccountObjectId) && selectedKeyCount > 0 && !accountLookupPending
+
+ useEffect(() => {
+ setSelectedKeyPublicKeys((prev) => {
+ const next = prev.filter((publicKey) => selectableKeyPublicKeys.includes(publicKey))
+ return next.length === prev.length ? prev : next
+ })
+ }, [selectableKeyPublicKeys])
// ============================================================
// Fetch on-chain delegate keys
@@ -280,16 +504,15 @@ export default function Dashboard() {
suiNetwork: config.suiNetwork,
})
+ const delegatePublicKeyHex = bytesToHex(delegate.publicKey)
setNewPrivateKey(delegate.privateKey)
- setShowAddForm(false)
- setNewKeyLabel('New Key')
-
- // Copy private key to clipboard automatically
- await navigator.clipboard.writeText(delegate.privateKey)
+ setDelegateKeys(delegate.privateKey, delegatePublicKeyHex, effectiveAccountObjectId!)
+ closeAddKeyForm()
+ setNewKeyLabel('New key')
- // Refresh key list
- await fetchOnChainKeys()
trackEvent('delegate_key_add_complete', { location: 'dashboard' })
+ void navigator.clipboard.writeText(delegate.privateKey).catch(() => undefined)
+ void fetchOnChainKeys()
} catch (err: unknown) {
const msg = err instanceof Error ? err.message : 'failed to add key'
setKeyError(msg)
@@ -297,48 +520,163 @@ export default function Dashboard() {
} finally {
setAddingKey(false)
}
- }, [walletSigner, hasMaxDelegateKeys, effectiveAccountObjectId, newKeyLabel, suiClient, fetchOnChainKeys])
+ }, [
+ walletSigner,
+ hasMaxDelegateKeys,
+ effectiveAccountObjectId,
+ newKeyLabel,
+ suiClient,
+ fetchOnChainKeys,
+ setDelegateKeys,
+ closeAddKeyForm,
+ ])
// ============================================================
- // Remove a delegate key (via SDK)
+ // Remove delegate keys
// ============================================================
- const handleRemoveKey = useCallback(async (publicKeyHex: string) => {
- if (!walletSigner) return
- if (!confirm('remove this delegate key? this cannot be undone.')) return
- setRemovingKey(publicKeyHex)
+ const removeDelegateKeysInTransaction = useCallback(async (publicKeyHexes: string[]) => {
+ if (!walletSigner || !effectiveAccountObjectId) return
+
+ const tx = new Transaction()
+ for (const publicKeyHex of publicKeyHexes) {
+ tx.moveCall({
+ target: `${config.memwalPackageId}::account::remove_delegate_key`,
+ arguments: [
+ tx.object(effectiveAccountObjectId),
+ tx.pure('vector', hexToByteArray(publicKeyHex)),
+ ],
+ })
+ }
+
+ const result = await signAndExecuteTx({ transaction: tx })
+ await suiClient.waitForTransaction({
+ digest: result.digest,
+ options: { showEffects: true, showObjectChanges: true },
+ })
+ }, [walletSigner, effectiveAccountObjectId, signAndExecuteTx, suiClient])
+
+ const executeRemoveKeys = useCallback(async (publicKeyHexes: string[], source: RemoveKeysConfirmState['source']) => {
+ if (!walletSigner || !effectiveAccountObjectId || publicKeyHexes.length === 0) return
+
+ const isSelectionRemoval = source === 'selection'
+ if (isSelectionRemoval) {
+ setRemovingSelectedKeys(true)
+ } else {
+ setRemovingKey(publicKeyHexes[0])
+ }
setKeyError('')
setNewPrivateKey(null)
- trackEvent('delegate_key_remove_start', { location: 'dashboard' })
- try {
- await removeDelegateKey({
- packageId: config.memwalPackageId,
- accountId: effectiveAccountObjectId!,
- publicKey: publicKeyHex,
- walletSigner,
- suiClient,
- suiNetwork: config.suiNetwork,
- })
- // key removed successfully
+ const removeEventPayload = isSelectionRemoval
+ ? { location: 'dashboard', selected_count: publicKeyHexes.length }
+ : { location: 'dashboard' }
- // If we removed our own key, clear local state
- if (publicKeyHex === delegatePublicKey) {
+ trackEvent('delegate_key_remove_start', removeEventPayload)
+ try {
+ await removeDelegateKeysInTransaction(publicKeyHexes)
+
+ if (delegatePublicKey && publicKeyHexes.includes(delegatePublicKey)) {
clearDelegateKeys()
}
- // Refresh key list
+ setSelectedKeyPublicKeys((prev) =>
+ isSelectionRemoval
+ ? []
+ : prev.filter((key) => key !== publicKeyHexes[0])
+ )
await fetchOnChainKeys()
- trackEvent('delegate_key_remove_complete', { location: 'dashboard' })
+ trackEvent('delegate_key_remove_complete', removeEventPayload)
} catch (err: unknown) {
- const msg = err instanceof Error ? err.message : 'failed to remove key'
+ const msg = err instanceof Error
+ ? err.message
+ : isSelectionRemoval
+ ? 'failed to remove selected keys'
+ : 'failed to remove key'
setKeyError(msg)
trackEvent('delegate_key_remove_failed', { error_type: getAnalyticsErrorType(err) })
} finally {
+ if (isSelectionRemoval) {
+ setRemovingSelectedKeys(false)
+ } else {
+ setRemovingKey(null)
+ }
+ }
+ }, [
+ walletSigner,
+ effectiveAccountObjectId,
+ removeDelegateKeysInTransaction,
+ delegatePublicKey,
+ clearDelegateKeys,
+ fetchOnChainKeys,
+ ])
+
+ const handleRemoveKey = useCallback((publicKeyHex: string) => {
+ if (!walletSigner || !effectiveAccountObjectId) return
+ setRemoveKeysConfirm({ publicKeys: [publicKeyHex], source: 'single' })
+ }, [walletSigner, effectiveAccountObjectId])
+
+ const toggleKeySelection = useCallback((publicKeyHex: string) => {
+ setSelectedKeyPublicKeys((prev) =>
+ prev.includes(publicKeyHex)
+ ? prev.filter((key) => key !== publicKeyHex)
+ : [...prev, publicKeyHex]
+ )
+ }, [])
+
+ const clearSelectedKeys = useCallback(() => {
+ setSelectedKeyPublicKeys([])
+ }, [])
+
+ const handleRemoveSelectedKeys = useCallback(() => {
+ if (!walletSigner || !effectiveAccountObjectId || selectedKeyPublicKeys.length === 0) return
+
+ const keysToRemove = selectedKeyPublicKeys.filter((publicKey) => selectableKeyPublicKeys.includes(publicKey))
+ if (keysToRemove.length === 0) {
+ setSelectedKeyPublicKeys([])
+ return
+ }
+
+ setRemoveKeysConfirm({ publicKeys: keysToRemove, source: 'selection' })
+ }, [
+ walletSigner,
+ effectiveAccountObjectId,
+ selectedKeyPublicKeys,
+ selectableKeyPublicKeys,
+ ])
+
+ const confirmRemoveKeys = useCallback(async () => {
+ if (!removeKeysConfirm) return
+
+ await executeRemoveKeys(removeKeysConfirm.publicKeys, removeKeysConfirm.source)
+ setRemoveKeysConfirm(null)
+ }, [executeRemoveKeys, removeKeysConfirm])
+
+ useEffect(() => {
+ if (!removeKeysConfirm || keyRemovalBusy) return undefined
- setRemovingKey(null)
+ const closeOnEscape = (event: KeyboardEvent) => {
+ if (event.key === 'Escape') {
+ setRemoveKeysConfirm(null)
+ }
}
- }, [walletSigner, effectiveAccountObjectId, delegatePublicKey, suiClient, fetchOnChainKeys, clearDelegateKeys])
+
+ window.addEventListener('keydown', closeOnEscape)
+ return () => window.removeEventListener('keydown', closeOnEscape)
+ }, [keyRemovalBusy, removeKeysConfirm])
+
+ const removeConfirmCount = removeKeysConfirm?.publicKeys.length ?? 0
+ const removeConfirmBusy = removeKeysConfirm
+ ? removeKeysConfirm.source === 'selection'
+ ? removingSelectedKeys
+ : removingKey === removeKeysConfirm.publicKeys[0]
+ : false
+ const removeConfirmTitle = removeConfirmCount === 1
+ ? 'Remove delegate key?'
+ : `Remove ${removeConfirmCount} delegate keys?`
+ const removeConfirmDescription = removeConfirmCount === 1
+ ? 'This key will be removed from your Walrus Memory account. This cannot be undone.'
+ : `${removeConfirmCount} selected keys will be removed from your Walrus Memory account. This cannot be undone.`
// ============================================================
// SDK code snippets
@@ -349,12 +687,12 @@ export default function Dashboard() {
const PRIVATE_KEY_PLACEHOLDER = ''
const ACCOUNT_ID_PLACEHOLDER = ''
- const sdkSnippet = `import { MemWal } from "@mysten-incubation/memwal"
+ const sdkTypeScriptSnippet = `import { MemWal } from "@mysten-incubation/memwal"
const memwal = MemWal.create({
- key: process.env.MEMWAL_PRIVATE_KEY ?? "${PRIVATE_KEY_PLACEHOLDER}",
- accountId: process.env.MEMWAL_ACCOUNT_ID ?? "${effectiveAccountObjectId ?? ACCOUNT_ID_PLACEHOLDER}",
- serverUrl: process.env.MEMWAL_SERVER_URL ?? "${config.memwalServerUrl}",
+ key: process.env.${PRIVATE_KEY_ENV} ?? "${PRIVATE_KEY_PLACEHOLDER}",
+ accountId: process.env.${ACCOUNT_ID_ENV} ?? "${effectiveAccountObjectId ?? ACCOUNT_ID_PLACEHOLDER}",
+ serverUrl: process.env.${SERVER_URL_ENV} ?? "${SDK_DEFAULT_SERVER_URL}",
})
// Remember something
@@ -365,14 +703,38 @@ await memwal.waitForRememberJob(job.job_id)
const result = await memwal.recall("food allergies")
console.log(result.results[0].text)`
+ const sdkPythonSnippet = `import asyncio
+import os
+from memwal import MemWal
+
+async def main():
+ memwal = MemWal.create(
+ key=os.environ["${PRIVATE_KEY_ENV}"],
+ account_id=os.environ["${ACCOUNT_ID_ENV}"],
+ server_url=os.environ.get("${SERVER_URL_ENV}", "${SDK_DEFAULT_SERVER_URL}"),
+ )
+
+ await memwal.remember_and_wait("I'm allergic to peanuts")
+
+ result = await memwal.recall("food allergies")
+ print(result.results[0].text)
+
+ await memwal.close()
+
+asyncio.run(main())`
+
+ const sdkSnippet = quickstartLanguage === 'py' ? sdkPythonSnippet : sdkTypeScriptSnippet
+ const sdkSnippetLanguage = quickstartLanguage === 'py' ? 'python' : 'javascript'
+ const sdkCopyLabel = `sdk-${quickstartLanguage}`
+
const aiSnippet = `import { generateText } from "ai"
import { withMemWal } from "@mysten-incubation/memwal/ai"
import { openai } from "@ai-sdk/openai"
const model = withMemWal(openai("gpt-4o"), {
- key: process.env.MEMWAL_PRIVATE_KEY ?? "${PRIVATE_KEY_PLACEHOLDER}",
- accountId: process.env.MEMWAL_ACCOUNT_ID ?? "${effectiveAccountObjectId ?? ACCOUNT_ID_PLACEHOLDER}",
- serverUrl: process.env.MEMWAL_SERVER_URL ?? "${config.memwalServerUrl}",
+ key: process.env.${PRIVATE_KEY_ENV} ?? "${PRIVATE_KEY_PLACEHOLDER}",
+ accountId: process.env.${ACCOUNT_ID_ENV} ?? "${effectiveAccountObjectId ?? ACCOUNT_ID_PLACEHOLDER}",
+ serverUrl: process.env.${SERVER_URL_ENV} ?? "${SDK_DEFAULT_SERVER_URL}",
})
const result = await generateText({
@@ -382,85 +744,92 @@ const result = await generateText({
]
})
// → LLM knows: "User is allergic to peanuts"`
+ const docsHref = config.docsUrl || 'https://docs.memwal.ai'
+ const githubHref = 'https://github.com/MystenLabs/memwal'
+ const discordHref = 'https://discord.gg/walrusprotocol'
+ const installCommand = pkgManager === 'npm' ? 'npm install @mysten-incubation/memwal' :
+ pkgManager === 'pnpm' ? 'pnpm add @mysten-incubation/memwal' :
+ pkgManager === 'yarn' ? 'yarn add @mysten-incubation/memwal' :
+ 'bun add @mysten-incubation/memwal'
+ const installCopyLabel = `install-${pkgManager}`
return (
- <>
-