From cc4112363258224d6040bb1f6fba68f7cdb5bef6 Mon Sep 17 00:00:00 2001 From: YeonGyu-Kim Date: Thu, 2 Jul 2026 20:44:29 +0900 Subject: [PATCH 01/35] feat(design-system): flip tokens to the light sage palette Co-Authored-By: Claude Fable 5 --- packages/web/app/styles/design-system.css | 166 ++++++++++++++++------ 1 file changed, 123 insertions(+), 43 deletions(-) diff --git a/packages/web/app/styles/design-system.css b/packages/web/app/styles/design-system.css index 7b554c9..b56eafd 100644 --- a/packages/web/app/styles/design-system.css +++ b/packages/web/app/styles/design-system.css @@ -6,56 +6,60 @@ --font-sans: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; --font-mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; + /* Editorial serif for section display headings ONLY (DESIGN.md §3). + System ui-serif stack — still zero webfonts. */ + --font-serif: ui-serif, Georgia, Cambria, "Times New Roman", serif; } @layer base { :root { - /* Surfaces — near-black canvas with a faint cool-green undertone. */ - --surface-base: #0a0c0b; - --surface-0: #0a0c0b; - --surface-1: rgba(255, 255, 255, 0.018); - --surface-2: rgba(255, 255, 255, 0.035); - --surface-3: rgba(255, 255, 255, 0.055); - --card-base: #0E1411; - --surface-night: #0a0c0b; - --surface-panel: #0E1411; - --surface-panel-alt: #0C1310; - --surface-panel-deep: #0D1310; + /* Surfaces — light sage paper with a faint green undertone. */ + --surface-base: #f4f6ee; + --surface-0: #f4f6ee; + --surface-1: rgba(16, 25, 20, 0.03); + --surface-2: rgba(16, 25, 20, 0.05); + --surface-3: rgba(16, 25, 20, 0.08); + --card-base: #ffffff; + --surface-night: #e9ede0; + --surface-panel: #fbfcf7; + --surface-panel-alt: #f7faf2; + --surface-panel-deep: #f3f7ec; /* Brand — green core (green-500 family), clearly green not teal. */ --brand-core: #22c55e; --brand-mid: #16a34a; --brand-outer: #15803d; - /* Text. */ - --text-primary: #ffffff; - --text-secondary: #b8c2bc; - --text-tertiary: #8b9690; - --text-muted: rgba(255, 255, 255, 0.74); - --text-soft: #dcfce7; - - /* Accent — the live-wire green (green-400/300, unambiguously green). */ - --accent-primary: #4ade80; - --accent-primary-soft: rgba(74, 222, 128, 0.1); - --accent-primary-border: rgba(74, 222, 128, 0.24); - --accent-cyan: #4ade80; + /* Text — deep green-tinted inks, AA on the sage canvas. */ + --text-primary: #101914; + --text-secondary: #3f4b43; + --text-tertiary: #55645b; + --text-muted: rgba(16, 25, 20, 0.75); + --text-soft: #14532d; + + /* Accent — AA-legible forest green on light ground. --accent-mint is for + fills/decoration ONLY, never text on light surfaces. */ + --accent-primary: #15803d; + --accent-primary-soft: rgba(21, 128, 61, 0.08); + --accent-primary-border: rgba(21, 128, 61, 0.28); + --accent-cyan: #15803d; --accent-teal: #22c55e; --accent-mint: #86efac; - --accent-glow: #86efac; + --accent-glow: #14532d; /* Borders. */ - --border-subtle: rgba(255, 255, 255, 0.06); - --border-default: rgba(255, 255, 255, 0.1); + --border-subtle: rgba(16, 25, 20, 0.10); + --border-default: rgba(16, 25, 20, 0.16); - /* Status. */ - --status-success: #22c55e; - --status-warning: #f59e0b; - --status-error: #ef4444; + /* Status — AA on light. */ + --status-success: #15803d; + --status-warning: #a16207; + --status-error: #b91c1c; } html { background-color: var(--surface-base); - color-scheme: dark; + color-scheme: light; } body { @@ -68,8 +72,8 @@ } ::selection { - background-color: var(--brand-outer); - color: var(--text-primary); + background-color: #bbf7d0; + color: #14532d; } a { @@ -81,30 +85,106 @@ outline: 2px solid var(--accent-primary); outline-offset: 3px; } + + /* Codex window adapter — the surface tokens the ulw-demo / team-mode + window mocks consume (see DESIGN.md § Codex window adapter tokens). + Default theme: LIGHT, faithful to the Codex desktop app. */ + .ulw-window { + --codex-window-bg: #ffffff; + --codex-window-chrome: #f6f7f6; + --codex-window-border: rgba(10, 12, 11, 0.12); + --codex-window-text: #17211b; + --codex-window-text-soft: #5b675f; + --codex-window-chip: rgba(10, 12, 11, 0.06); + --codex-window-active: rgba(34, 197, 94, 0.12); + --codex-window-active-border: rgba(22, 101, 52, 0.28); + --codex-window-accent: #166534; + --codex-window-glyph-text: #ffffff; + --codex-window-traffic-red: #f87171; + --codex-window-traffic-amber: #fbbf24; + --codex-window-traffic-green: #34d399; + + /* Subagent lane-glyph identity colors — tuned for the white window + (each holds >= 3:1 against --codex-window-bg; the white glyph + letter stays >= 4.5:1 on every lane). */ + --lane-root: #115e59; + --lane-explore: #1d4ed8; + --lane-library: #92400e; + --lane-plan: #6d28d9; + --lane-todo: #334155; + --lane-execute: #166534; + --lane-test: #b91c1c; + --lane-qa: #be185d; + --lane-review: #4338ca; + --lane-continuation: #475569; + } + + /* Dark window variant — toggled via the role=group window-theme switch + (sets data-window-theme on .ulw-window). Values derive from the + retired dark site palette (#0E1411 family). */ + [data-window-theme="dark"] { + --codex-window-bg: #101613; + --codex-window-chrome: #0e1411; + --codex-window-border: rgba(232, 240, 234, 0.14); + --codex-window-text: #e8f0ea; + --codex-window-text-soft: #b8c2bc; + --codex-window-chip: rgba(232, 240, 234, 0.07); + --codex-window-active: rgba(74, 222, 128, 0.16); + --codex-window-active-border: rgba(74, 222, 128, 0.32); + --codex-window-accent: #4ade80; + --codex-window-glyph-text: #0a0c0b; + --codex-window-traffic-red: #f87171; + --codex-window-traffic-amber: #fbbf24; + --codex-window-traffic-green: #34d399; + + /* Lane glyphs re-tuned >= 3:1 against the dark window ground + (same hue identity per lane, lifted two Tailwind stops). */ + --lane-root: #2dd4bf; + --lane-explore: #60a5fa; + --lane-library: #f59e0b; + --lane-plan: #a78bfa; + --lane-todo: #94a3b8; + --lane-execute: #4ade80; + --lane-test: #f87171; + --lane-qa: #f472b6; + --lane-review: #818cf8; + --lane-continuation: #cbd5e1; + } } @layer utilities { + /* Hero-card washes — soft mint/sage radials composited on the white card + base. Light identity: alpha washes over var(--card-base); no near-black + stops, no screen blending (which needs a dark ground). */ .card-gradient-base { - background: radial-gradient(120% 100% at 60% 65%, #22c55e 0%, #16a34a 35%, #15803d 70%, #0a0c0b 100%); + background: + radial-gradient(120% 100% at 60% 65%, rgba(34, 197, 94, 0.10) 0%, rgba(34, 197, 94, 0.07) 35%, rgba(34, 197, 94, 0.04) 70%, rgba(134, 239, 172, 0.03) 100%), + var(--card-base); } .card-gradient-beam { - background: radial-gradient(55% 55% at 38% -8%, rgba(134,239,172,0.55) 0%, rgba(74,222,128,0.22) 35%, rgba(255,255,255,0) 65%), - radial-gradient(32% 28% at 55% -5%, rgba(134,239,172,0.38) 0%, rgba(255,255,255,0) 70%); - mix-blend-mode: screen; + background: + radial-gradient(55% 55% at 38% -8%, rgba(134, 239, 172, 0.30) 0%, rgba(134, 239, 172, 0.12) 35%, rgba(134, 239, 172, 0) 65%), + radial-gradient(32% 28% at 55% -5%, rgba(134, 239, 172, 0.16) 0%, rgba(134, 239, 172, 0) 70%); } .card-gradient-sheen { - background: linear-gradient(118deg, transparent 18%, rgba(134,239,172,0.16) 26%, rgba(134,239,172,0.30) 30%, rgba(134,239,172,0.12) 35%, transparent 45%), - linear-gradient(112deg, transparent 8%, rgba(74,222,128,0.12) 15%, transparent 28%); + background: + linear-gradient(118deg, transparent 18%, rgba(134, 239, 172, 0.10) 26%, rgba(134, 239, 172, 0.16) 30%, rgba(134, 239, 172, 0.08) 35%, transparent 45%), + linear-gradient(112deg, transparent 8%, rgba(34, 197, 94, 0.06) 15%, transparent 28%); filter: blur(20px); - mix-blend-mode: screen; opacity: 0.85; } .card-gradient-pools { - background: radial-gradient(55% 50% at 8% 95%, rgba(34,197,94,0.26), transparent 70%), - radial-gradient(45% 45% at 95% 40%, rgba(134,239,172,0.20), transparent 70%); - mix-blend-mode: screen; + background: + radial-gradient(55% 50% at 8% 95%, rgba(34, 197, 94, 0.12), transparent 70%), + radial-gradient(45% 45% at 95% 40%, rgba(134, 239, 172, 0.16), transparent 70%); + } + + /* ampcode-style dotted vertical column rules: every column after the + first gets a dotted left rule (MarketingRuleGrid ruleStyle="dotted"). */ + .rule-grid-dotted > * + * { + border-left: 1px dotted var(--border-subtle); } } From 18e3bb3da842a40e601c39eaa440da8c53557490 Mon Sep 17 00:00:00 2001 From: YeonGyu-Kim Date: Thu, 2 Jul 2026 20:44:29 +0900 Subject: [PATCH 02/35] feat(demo): port source-grounded ulw demo scene data Co-Authored-By: Claude Fable 5 --- packages/web/lib/site-config.ts | 39 +++++ packages/web/lib/ulw-demo-scenes.ts | 214 ++++++++++++++++++++++++++++ 2 files changed, 253 insertions(+) create mode 100644 packages/web/lib/ulw-demo-scenes.ts diff --git a/packages/web/lib/site-config.ts b/packages/web/lib/site-config.ts index 449ea68..5b851de 100644 --- a/packages/web/lib/site-config.ts +++ b/packages/web/lib/site-config.ts @@ -79,6 +79,45 @@ export const SITE_CONFIG = { "Skills auto-activate when a task matches their domain, so you do not need to study every one first. Add a skill name to your prompt when you want to call it explicitly; ulw-research is the maximum-saturation mode for deep codebase, web, official-docs, and OSS-repo research.", skills: ["ulw-research", "review-work", "remove-ai-slops", "frontend", "programming", "visual-qa", "LSP", "AST-grep"], }, + // Copy grounded in content/docs/ultrawork.md and ulw-loop.md — see .omo/evidence/copy-ledger.md. + ulwDemo: { + kicker: "Ultrawork, live", + title: "Watch an ultrawork run close the loop", + intro: + "Include ultrawork (or the short alias ulw) anywhere in your prompt and the harness switches to maximum-precision, outcome-first, evidence-driven orchestration. An agent saying it is done does not mean the work is done — the work is done when observable evidence verifies it.", + quote: "Plan, execute, verify, and keep the evidence attached.", + }, + // Copy grounded in plugins/omo/skills/teammode/SKILL.md — see .omo/evidence/copy-ledger.md. + teamMode: { + kicker: "Team Mode", + title: "Run a named team of cooperating Codex threads", + body: "One leader, durable state on disk. The main session is always the team leader: it splits the work and assigns each slice, holds live situational awareness of every member, verifies and QAs what they deliver, relays findings between members, and synthesizes the result.", + compositionRule: + "Members are defined by a concrete part, ownership area, or perspective — never a vague job role.", + whenTitle: "When a team beats plain subagents", + whenPoints: [ + "The work does not split into perfectly isolated pieces, but doing it in parallel is clearly more convenient — members need to see and react to each other's findings.", + "One task still needs exploration, yet its goal is already clear — parallel investigation under a fixed objective.", + ], + stateNote: + "A bundled cross-platform script writes the .omo/teams state plus an auto-generated member field manual.", + threadNote: "Sent by Codex from another thread", + memberThreads: [ + { name: "Triage feature and question issues", status: "running" }, + { name: "Review PR readiness", status: "running" }, + { name: "Triage LazyCodex issues", status: "reported" }, + { name: "Triage runtime bug reports", status: "reported" }, + ], + }, + // Copy grounded in plugins/omo/skills/ulw-research/SKILL.md — see .omo/evidence/copy-ledger.md. + ulwResearch: { + kicker: "$ulw-research", + title: "Maximum-saturation research orchestration", + body: "Parallel explore and librarian swarms across the codebase, web, official docs, and OSS repos; a recursive expand loop driven by the leads workers return; empirical verification by running code; cited synthesis and optional reports.", + activation: + "Activates only on an explicit demand for research — say ulw-research or any ulw research wording in your prompt. While active, exhaustive coverage is the goal.", + lanes: ["codebase", "web", "official docs", "OSS repos"], + }, } as const; export type SiteConfig = typeof SITE_CONFIG; diff --git a/packages/web/lib/ulw-demo-scenes.ts b/packages/web/lib/ulw-demo-scenes.ts new file mode 100644 index 0000000..367f31e --- /dev/null +++ b/packages/web/lib/ulw-demo-scenes.ts @@ -0,0 +1,214 @@ +/** + * Source-grounded scene data for the interactive Ultrawork demo. + * + * Every visible string traces to OMO/LazyCodex source truth via + * `.omo/reference/source-ledger.md` (workflow beats → omo source lines) and + * `content/docs/{ultrawork,ulw-loop,manual-qa}.md`. Do not invent beats, + * metrics, or command flags here — extend the ledger first. + */ + +export type UlwLane = + | "root" + | "explore" + | "library" + | "plan" + | "todo" + | "execute" + | "test" + | "qa" + | "review" + | "continuation"; + +export type UlwScene = { + readonly key: string; + readonly tab: string; + readonly command: string; + readonly status: string; + readonly title: string; + readonly body: string; + readonly composer: string; + readonly sideTitle: string; + readonly sideBody: string; + readonly ledger: string; + readonly json: string; + readonly lanes: readonly UlwLane[]; + readonly proof: number; +}; + +export type UlwStep = { readonly heading: string; readonly detail: string }; + +export type UlwWorker = { + readonly name: string; + readonly role: string; + readonly lane: UlwLane; + readonly glyph: string; +}; + +export const ULW_DEMO_STEPS = [ + { heading: "Explorer + Librarian swarm", detail: "Call parallel subagents to find repo truth, docs, commands, and inaccurate claims to avoid." }, + { heading: "Plan agent / Prometheus", detail: "Combine research into a decision-complete plan before implementation begins." }, + { heading: "TodoWrite + task system", detail: "Register atomic tasks and blockedBy edges; `.omo/ulw-loop/goals.json` stores criteria." }, + { heading: "$start-work assigns lanes", detail: "Executor, QA Executor, reviewer, and gate workers receive bounded deliverables." }, + { heading: "TDD red", detail: "Capture the failing-first proof before production code changes." }, + { heading: "GREEN + record-evidence", detail: "Make the smallest fix, pass the test, and record criterion-scoped evidence." }, + { heading: "QA fail -> goal_retried", detail: "Manual QA can fail the run; ULW records the failure and retries the same criterion." }, + { heading: "Quality gate + checkpoint", detail: "Only code review, manualQa, gateReview, iteration, and coverage evidence close the story." }, +] as const satisfies readonly UlwStep[]; + +export const ULW_DEMO_PROOFS = [ + "research facts", + "plan artifact", + "TodoWrite", + "worker lanes", + "TDD red", + "record-evidence", + "QA fail retry", + "checkpoint complete", +] as const satisfies readonly string[]; + +export const ULW_DEMO_WORKERS = [ + { name: "Root Orchestrator", role: "holding goal", lane: "root", glyph: "R" }, + { name: "Explorer the 53rd", role: "repo scan", lane: "explore", glyph: "X" }, + { name: "Explorer the 54th", role: "tests", lane: "explore", glyph: "X" }, + { name: "Librarian the 24th", role: "docs", lane: "library", glyph: "L" }, + { name: "Librarian the 25th", role: "contracts", lane: "library", glyph: "L" }, + { name: "Plan agent / Prometheus", role: "waiting", lane: "plan", glyph: "P" }, + { name: "TodoWrite adapter", role: "tasks", lane: "todo", glyph: "T" }, + { name: "Executor the 23rd", role: "implementation", lane: "execute", glyph: "E" }, + { name: "TDD Executor the 12th", role: "red/green", lane: "test", glyph: "T" }, + { name: "QA Executor the 23rd", role: "Manual QA", lane: "qa", glyph: "Q" }, + { name: "lazycodex-code-reviewer", role: "codeReview", lane: "review", glyph: "C" }, + { name: "lazycodex-gate-reviewer", role: "gateReview", lane: "review", glyph: "G" }, + { name: "Stop/SubagentStop hook", role: "continue", lane: "continuation", glyph: "S" }, +] as const satisfies readonly UlwWorker[]; + +export const ULW_DEMO_SCENES = [ + { + key: "research", + tab: "01 Research", + command: 'task(subagent_type="explorer") + task(subagent_type="librarian")', + status: "Research wave · Explorer and Librarian gather source truth", + title: "Ultrawork starts by fanning out research.", + body: "Root does not guess. Explorer reads the local implementation, Librarian checks docs and contracts, and their findings become the input to the Plan agent.", + composer: "Root is waiting for Explorer and Librarian findings before the Plan agent writes anything.", + sideTitle: "Research lanes are live.", + sideBody: "Explorer reads the local implementation while Librarian checks docs and skill contracts. Root waits for both before planning.", + ledger: "plan_created pending research facts", + json: '{ "activeGoalId": null, "criteria": "pending" }', + lanes: ["root", "explore", "library"], + proof: 0, + }, + { + key: "plan", + tab: "02 Plan", + command: "$ulw-plan .omo/plans/ultrawork-demo.md", + status: "Planning · Plan agent / Prometheus synthesizes the lanes", + title: "Plan first, then execute with evidence.", + body: "The Plan agent merges Explorer and Librarian findings into a decision-complete plan: references, acceptance criteria, QA channel, evidence path, and workers.", + composer: "Plan agent is writing the handoff surface; no product code is touched here.", + sideTitle: "Plan agent is planner-only.", + sideBody: "The safe claim is planning, not execution. Implementation begins only after start-work or ulw-loop picks up the plan.", + ledger: "plan_created .omo/plans/ultrawork-demo.md\nsteering_accepted research findings", + json: '{ "briefPath": ".omo/ulw-loop/brief.md", "goalsPath": ".omo/ulw-loop/goals.json" }', + lanes: ["root", "explore", "library", "plan"], + proof: 1, + }, + { + key: "todo", + tab: "03 Todo", + command: "TodoWrite -> task_create + omo ulw-loop create-goals", + status: "Todo registration · file-backed tasks and success criteria", + title: "The todo list becomes durable state.", + body: "TodoWrite commits atomic work before generation. In OMO, ulw-loop persists goals, criteria, and the append-only ledger under `.omo/ulw-loop/`.", + composer: "Registering G001 with C001 happy, C002 edge, and C003 regression criteria.", + sideTitle: "TodoWrite is not decoration.", + sideBody: "Tasks are marked complete only after their matching artifact lands; multi-agent work uses dependencies instead of loose memory.", + ledger: "plan_created 1 goal(s) created\nG001 status=pending\nC001/C002/C003 status=pending", + json: '{ "activeGoalId": null, "goals": [{ "id": "G001-ultrawork-demo", "status": "pending" }] }', + lanes: ["root", "plan", "todo"], + proof: 2, + }, + { + key: "assign", + tab: "04 Assign", + command: "$start-work .omo/plans/ultrawork-demo.md", + status: "Assignment · subagents receive bounded tasks", + title: "Root assigns work instead of doing it all directly.", + body: "Executor owns implementation, TDD Executor owns the failing-first proof, QA Executor owns the real browser scenario, and reviewers own the final gate.", + composer: "Executor, TDD, QA, and review lanes are active; root watches dependencies and drift.", + sideTitle: "Subagents are visible work lanes.", + sideBody: "The roster makes delegation observable: each worker owns a narrow deliverable and returns artifact-backed evidence.", + ledger: "goal_started G001-ultrawork-demo Attempt 1\nactiveGoalId=G001-ultrawork-demo", + json: '{ "activeGoalId": "G001-ultrawork-demo", "attempt": 1, "status": "in_progress" }', + lanes: ["root", "todo", "execute", "test", "qa", "review", "continuation"], + proof: 3, + }, + { + key: "red", + tab: "05 TDD RED", + command: "bun test ultrawork-demo.test.ts # TDD red", + status: "TDD red · failing-first proof captured", + title: "The first proof is allowed to fail.", + body: "A behavior change gets a RED proof before the fix. ULW treats a hollow test as non-evidence, so the failure has to match the user-facing contract.", + composer: "TDD Executor captured RED for the right reason; Executor can now make the smallest GREEN change.", + sideTitle: "TDD red is a gate, not theater.", + sideBody: "The run records the failing proof before production changes, then routes the fix to the right worker.", + ledger: "criterion_failed G001 C001\nmessage=TDD red captured before fix", + json: '{ "C001": { "status": "fail", "capturedEvidence": "TDD red" } }', + lanes: ["root", "execute", "test"], + proof: 4, + }, + { + key: "green", + tab: "06 GREEN", + command: 'omo ulw-loop record-evidence --goal-id G001 --criterion-id C001 --status pass --evidence "GREEN unit proof + cleanup receipt"', + status: "GREEN · criterion-scoped evidence is recorded", + title: "GREEN lands only with recorded evidence.", + body: "After the smallest fix, ULW records non-empty evidence against the exact criterion. The ledger entry is `evidence_captured`, not a vague done message.", + composer: "Executor returned GREEN; root is recording C001 evidence before moving to real-surface QA.", + sideTitle: "record-evidence is append-only proof.", + sideBody: "The criterion now has status pass, capturedEvidence, capturedAt, and a ledger entry.", + ledger: "evidence_captured G001 C001 status=pass\ncapturedEvidence=GREEN unit proof", + json: '{ "C001": { "status": "pass", "capturedEvidence": "GREEN unit proof" } }', + lanes: ["root", "execute", "test", "todo"], + proof: 5, + }, + { + key: "qa-retry", + tab: "07 QA retry", + command: "browser QA -> QA fail -> omo ulw-loop complete-goals --retry-failed", + status: "QA fail · retry the same criterion until the surface passes", + title: "Manual QA can send the work back.", + body: "Tests prove the unit contract; browser/manual QA proves the real surface. If QA fails, ULW records failure evidence, retries the goal, and keeps the loop moving.", + composer: "QA Executor found a real-surface mismatch; root records goal_failed and resumes with --retry-failed.", + sideTitle: "QA fail is part of the loop.", + sideBody: "The demo should show retry, not pretend the first pass is final.", + ledger: "goal_failed G001 evidence=QA fail\ncriterion_failed C002 real surface mismatch\ngoal_retried G001 Attempt 2", + json: '{ "status": "in_progress", "attempt": 2, "failureReason": "QA fail" }', + lanes: ["root", "execute", "test", "qa", "continuation"], + proof: 6, + }, + { + key: "checkpoint", + tab: "08 Checkpoint", + command: 'omo ulw-loop checkpoint --goal-id G001 --status complete --evidence "manual QA + review + criteria evidence" --codex-goal-json .omo/evidence/get-goal-complete.json --quality-gate-json .omo/evidence/quality-gate.json', + status: "Checkpoint · quality gate closes the story", + title: "Done means the quality gate passes.", + body: "The final story needs codeReview, manualQa, gateReview, iteration, criteriaCoverage, and artifact-backed evidence before checkpointing complete.", + composer: "Root has code review, Manual QA screenshots, gate review, iteration proof, and criteria coverage.", + sideTitle: "checkpoint --status complete is the close.", + sideBody: "Only after the quality gate is clean does the run checkpoint the story and write aggregate completion evidence.", + ledger: "evidence_captured C002/C003 status=pass\naggregate_completed G001\ncheckpoint --status complete", + json: '{ "aggregateCompletion": { "status": "complete" }, "qualityGate": "clean" }', + lanes: ["root", "qa", "review", "todo"], + proof: 7, + }, +] as const satisfies readonly UlwScene[]; + +export const ULW_DEMO_ENVIRONMENT: readonly (readonly [string, string])[] = [ + ["Changes", "scoped"], + [".omo/ulw-loop", "ledger"], + ["Mode", "ulw ulw ulw"], +] as const; + +export const ULW_DEMO_AUTOPLAY_MS = 7000; From 6ee563b77e3aefa53cce9c6ad8694404152bc2b6 Mon Sep 17 00:00:00 2001 From: YeonGyu-Kim Date: Thu, 2 Jul 2026 20:44:29 +0900 Subject: [PATCH 03/35] docs(design): rewrite DESIGN.md for the light system Co-Authored-By: Claude Fable 5 --- packages/web/DESIGN.md | 234 +++++++++++++++++++++++++++++++++-------- 1 file changed, 191 insertions(+), 43 deletions(-) diff --git a/packages/web/DESIGN.md b/packages/web/DESIGN.md index c8f9920..6fbd04f 100644 --- a/packages/web/DESIGN.md +++ b/packages/web/DESIGN.md @@ -4,11 +4,17 @@ Implementation sources: - Browser CSS tokens and shared utility layers live in `app/styles/design-system.css`, imported before page-specific styles by `app/globals.css`. - Reusable React primitives live in `components/design-system/`; landing and docs components compose from those primitives. - Social preview tokens live in `app/og-image-theme.ts` and intentionally mirror the browser palette. -- Page-specific composition styles live in `app/styles/landing.css` and `app/styles/docs.css`. +- Page-specific composition styles live in `app/styles/landing.css`, `app/styles/ulw-demo.css`, and `app/styles/docs.css`. ## 1. Atmosphere & Identity -LazyCodex feels like a serious command surface for complex codebases: near-black, quiet, technical, and lit by an emerald signal. The signature is a glowing green card-in-canvas composition with a geometric rounded-square `L` mark. The brand color is green, not teal, cyan, purple, or blue. +LazyCodex feels like a calm, precise productivity tool for complex codebases: a light sage-paper +canvas, editorial structure with dotted column rules, and green as the single brand signal. The +signature composition is a white card sitting on the pale sage ground with the geometric +rounded-square `L` mark. Dark surfaces still exist, but only as deliberate accents — code blocks, +command surfaces, the Hephaestus showcase band, and the demo window's dark theme — small dark +windows on light ground, never the page itself. The brand color is green, not teal, cyan, purple, +or blue. ## 2. Color @@ -16,36 +22,103 @@ LazyCodex feels like a serious command surface for complex codebases: near-black | Role | Token | Value | Usage | | --- | --- | --- | --- | -| Surface/base | `--surface-base`, `--surface-night`, `--surface-0` | `#0a0c0b` | Page canvas and footer | -| Surface/subtle | `--surface-1` | `rgba(255,255,255,0.018)` | Hover and quiet fills | -| Surface/raised | `--surface-2` | `rgba(255,255,255,0.035)` | Secondary tonal layer | -| Surface/strong | `--surface-3` | `rgba(255,255,255,0.055)` | Stronger tonal layer | -| Surface/card | `--card-base`, `--surface-panel` | `#0E1411` | Hero card, command surfaces | -| Surface/alt | `--surface-panel-alt` | `#0C1310` | Alternate panel | -| Surface/deep | `--surface-panel-deep` | `#0D1310` | Deep panel | -| Brand/core | `--brand-core` | `#22c55e` | Green brand center | +| Surface/base | `--surface-base`, `--surface-0` | `#f4f6ee` | Page canvas | +| Surface/night | `--surface-night` | `#e9ede0` | Footer and deeper page bands | +| Surface/subtle | `--surface-1` | `rgba(16,25,20,0.03)` | Hover and quiet fills | +| Surface/raised | `--surface-2` | `rgba(16,25,20,0.05)` | Secondary tonal layer | +| Surface/strong | `--surface-3` | `rgba(16,25,20,0.08)` | Stronger tonal layer | +| Surface/card | `--card-base` | `#ffffff` | Hero card, white content cards | +| Surface/panel | `--surface-panel` | `#fbfcf7` | Panels, install bar | +| Surface/alt | `--surface-panel-alt` | `#f7faf2` | Alternate panel | +| Surface/deep | `--surface-panel-deep` | `#f3f7ec` | Deep panel | +| Brand/core | `--brand-core` | `#22c55e` | Green brand center (fills, gradients) | | Brand/mid | `--brand-mid` | `#16a34a` | Green gradient middle | -| Brand/outer | `--brand-outer` | `#15803d` | Selection and gradient edge | -| Accent/primary | `--accent-primary` | `#4ade80` | CTAs, focus, active docs links | -| Accent/soft | `--accent-primary-soft` | `rgba(74,222,128,0.1)` | Soft green fills | -| Accent/border | `--accent-primary-border` | `rgba(74,222,128,0.24)` | Soft green outlines | -| Accent/mint | `--accent-mint`, `--accent-glow` | `#86efac` | Highlights, glow text | -| Text/primary | `--text-primary` | `#ffffff` | Main text and headings | -| Text/secondary | `--text-secondary` | `#b8c2bc` | Supporting text | -| Text/tertiary | `--text-tertiary` | `#8b9690` | Labels, metadata | -| Text/muted | `--text-muted` | `rgba(255,255,255,0.74)` | Body copy on dark surfaces | -| Text/soft | `--text-soft` | `#dcfce7` | Mint-tinted text | -| Border/subtle | `--border-subtle` | `rgba(255,255,255,0.06)` | Dividers and quiet controls | -| Border/default | `--border-default` | `rgba(255,255,255,0.1)` | Panels and cards | -| Status/success | `--status-success` | `#22c55e` | Positive status | -| Status/warning | `--status-warning` | `#f59e0b` | Warnings | -| Status/error | `--status-error` | `#ef4444` | Errors | +| Brand/outer | `--brand-outer` | `#15803d` | Gradient edge | +| Accent/primary | `--accent-primary` | `#15803d` | CTAs, focus, active docs links (AA on light) | +| Accent/soft | `--accent-primary-soft` | `rgba(21,128,61,0.08)` | Soft green fills | +| Accent/border | `--accent-primary-border` | `rgba(21,128,61,0.28)` | Soft green outlines | +| Accent/mint | `--accent-mint` | `#86efac` | Fills and decoration ONLY — never text on light | +| Accent/glow | `--accent-glow` | `#14532d` | Deep green emphasis | +| Text/primary | `--text-primary` | `#101914` | Main text and headings | +| Text/secondary | `--text-secondary` | `#3f4b43` | Supporting text | +| Text/tertiary | `--text-tertiary` | `#55645b` | Labels, metadata | +| Text/muted | `--text-muted` | `rgba(16,25,20,0.75)` | Body copy | +| Text/soft | `--text-soft` | `#14532d` | Deep-green tinted text | +| Border/subtle | `--border-subtle` | `rgba(16,25,20,0.10)` | Dividers, dotted rules, quiet controls | +| Border/default | `--border-default` | `rgba(16,25,20,0.16)` | Panels and cards | +| Status/success | `--status-success` | `#15803d` | Positive status | +| Status/warning | `--status-warning` | `#a16207` | Warnings | +| Status/error | `--status-error` | `#b91c1c` | Errors | + +`::selection` uses a `#bbf7d0` background with `#14532d` text. `:focus-visible` outlines use +`--accent-primary`. The `html` element declares `color-scheme: light`; the site identity is a +FIXED light canvas — there is no site-wide `prefers-color-scheme` flip. Dark appears only inside +the sanctioned dark surfaces below. + +### Codex window adapter tokens (ulw-demo / team-mode mocks only) + +The interactive Ultrawork demo and the Team Mode thread mock reproduce the Codex Desktop surface +on the light canvas. The window carries its own isolated adapter palette with two themes selected +by `data-window-theme="light|dark"` on `.ulw-window` — light is the default and the +server-rendered state; a `role="group"` toggle switches it (see § CodexWindow). Adapter tokens +never leak into ordinary landing/docs UI, and ordinary tokens never restyle the window interior. + +Light theme (default block on `.ulw-window`): + +| Role | Token | Value | Usage | +| --- | --- | --- | --- | +| Window/canvas | `--codex-window-bg` | `#ffffff` | Codex window body | +| Window/chrome | `--codex-window-chrome` | `#f6f7f6` | Title bar, sidebar, composer field | +| Window/border | `--codex-window-border` | `rgba(10,12,11,0.12)` | Window ring, pane dividers | +| Window/text | `--codex-window-text` | `#17211b` | Primary transcript text | +| Window/text-soft | `--codex-window-text-soft` | `#5b675f` | Tool rows, metadata, timestamps | +| Window/chip | `--codex-window-chip` | `rgba(10,12,11,0.06)` | Inline code chips, path chips | +| Window/active | `--codex-window-active` | `rgba(34,197,94,0.12)` | Active step, active roster row | +| Window/active-border | `--codex-window-active-border` | `rgba(22,101,52,0.28)` | Active step/proof outlines | +| Window/accent | `--codex-window-accent` | `#166534` | Active-state text on light surface (AA on white) | +| Window/glyph-text | `--codex-window-glyph-text` | `#ffffff` | Letters inside roster glyph squares | +| Window/traffic | `--codex-window-traffic-red/-amber/-green` | `#f87171` / `#fbbf24` / `#34d399` | macOS traffic-light ornaments | + +Dark theme (override block scoped `[data-window-theme="dark"]`, same 13 token names): + +| Role | Token | Value | +| --- | --- | --- | +| Window/canvas | `--codex-window-bg` | `#101613` | +| Window/text | `--codex-window-text` | `#e8f0ea` | +| Window/chrome, border, chip, text-soft, active(+border), accent, glyph-text, traffic | same names | tuned values derived from the retired `#0E1411` dark-panel family — `app/styles/design-system.css` is authoritative | + +Every (text, background) pair in BOTH window themes must pass `.omo/scripts/contrast-check.mjs` +at ≥ 4.5:1 (≥ 3:1 only for display-size text). + +### Subagent lane glyph tokens + +The roster glyph squares use per-agent identity hues faithful to the Codex Desktop reference. +They are exposed as per-theme custom props (`--lane-`) so the dark window block can re-tune +any glyph that fails contrast against `--codex-window-bg`: + +| Lane | Token | Light value | +| --- | --- | --- | +| Root | `--lane-root` | `#115e59` | +| Explore | `--lane-explore` | `#1d4ed8` | +| Library | `--lane-library` | `#92400e` | +| Plan | `--lane-plan` | `#6d28d9` | +| Todo | `--lane-todo` | `#334155` | +| Execute | `--lane-execute` | `#166534` | +| Test | `--lane-test` | `#b91c1c` | +| QA | `--lane-qa` | `#be185d` | +| Review | `--lane-review` | `#4338ca` | +| Continuation | `--lane-continuation` | `#475569` | + +These are identity badges scoped to the window adapter, not brand accents — the green-only brand +rule applies everywhere outside the window. ### Rules -- New UI uses `--accent-primary` and `--accent-mint`; `--accent-cyan` and `--accent-teal` remain green aliases only for compatibility. +- New UI uses `--accent-primary`; `--accent-cyan` and `--accent-teal` remain green aliases only for compatibility. +- `--accent-mint` (`#86efac`) is a fill/decoration color only. It fails AA as text on the light canvas and must never be used for copy. - Accent is reserved for interactivity, code emphasis, focus, and brand signal. -- Raw colors belong in this file, `design-system.css`, or OG theme tokens. Component code should reference tokens or shared primitives. +- Dark surfaces are allowed ONLY in four places: docs/code blocks (`pre`), command surfaces (`CommandCodeSurface`), the Hephaestus showcase band (`ShowcaseSurface`), and the demo window's dark theme. Everything else sits on the light canvas. +- Raw colors belong in this file, `design-system.css`, or OG theme tokens. Component code references tokens or shared primitives. The sanctioned raw values in components are: `#101613` (dark accent surface), `#dcfce7` (text on dark code chips), gradient stops `#15803d`/`#16a34a`/`#22c55e`, brand glow `rgba(21,128,61,0.25)`, and card shadow `rgba(16,25,20,0.04)`. ## 3. Typography @@ -67,7 +140,12 @@ LazyCodex feels like a serious command surface for complex codebases: near-black - Primary: `ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif` - Mono: `ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace` -- The landing wordmark intentionally uses the native primary stack so the LCP text has no webfont dependency. +- Display serif: `--font-serif: ui-serif, Georgia, Cambria, "Times New Roman", serif` — declared in the `@theme` block; a SYSTEM stack, never a webfont (Lighthouse perf 100 depends on zero webfonts). + +### Rules + +- The serif stack is for section display headings only (via the `serif` option on `SectionHeading`), giving marketing bands the editorial voice. Body copy, UI chrome, cards, and docs prose stay on the sans stack. +- The landing wordmark/`h1` and hero lead intentionally stay on the native sans stack so the LCP text has no font-substitution or reflow risk. ## 4. Spacing & Layout @@ -83,49 +161,98 @@ All spacing resolves to a 4px rhythm. Existing Tailwind values map to the same r - Docs collapse: hide the ToC below `1100px`; single column and mobile menu below `768px`. - Full-height surfaces use `min-h-[100dvh]`, never `h-screen`. +### Dotted rule grid + +- The `.rule-grid-dotted` utility applies `border-left: 1px dotted var(--border-subtle)` to child columns — the editorial vertical column rule of the light identity. +- Apply it through `MarketingRuleGrid` with `ruleStyle="dotted"` on multi-column marketing bands that need column separation without card chrome. Solid rules remain the default (`ruleStyle="solid"`). +- Dotted rules never appear inside the demo window or the docs layout. + ### Rules - `MarketingContainer`, `MarketingSection`, and `MarketingRuleGrid` in `components/design-system/layout.tsx` own the repeated page width and split-section geometry. - Use CSS Grid for multi-column layouts. Avoid percentage flex math. -- Preserve the existing information architecture: landing first, docs as a single richly-sectioned page. +- Landing IA, top to bottom: header → compact hero → `#ulw-demo` (interactive demo directly under the hero) → install → command cards → feature workflows (+ built-in skills band) → team mode → ulw-research → Hephaestus (+ OmO intro) → docs CTA → footer. Docs remain a single richly-sectioned page. +- Marketing sections must never wrap an `h2` in `
` — `e2e/landing.spec.ts` asserts `article h2` equals exactly the command-card names. ## 5. Components ### BrandMark - **Source**: `components/design-system/brand-mark.tsx`. -- **Structure**: inline SVG rounded square, `L` stroke, mint/green dot. -- **Variants**: `nav` 24px geometry, `hero` 160px geometry with `HeroBrandMark` glow wrapper. +- **Structure**: inline SVG rounded square, `L` stroke, mint/green dot; tile fill `var(--card-base)`, stroke `var(--accent-primary)`. +- **Variants**: `nav` 24px geometry, `hero` 160px geometry with `HeroBrandMark` glow wrapper (soft `rgba(21,128,61,0.25)` glow tuned for the light canvas). - **States**: inherited from the containing link or surface. - **Accessibility**: decorative mark uses `aria-hidden`; header link owns the accessible label. ### Layout Primitives - **Source**: `components/design-system/layout.tsx`. -- **Components**: `PageShell`, `SkipLink`, `MarketingMain`, `MarketingContainer`, `MarketingSection`, `MarketingRuleGrid`. +- **Components**: `PageShell`, `SkipLink`, `MarketingMain`, `MarketingContainer`, `MarketingSection`, `MarketingRuleGrid` (with the `ruleStyle: "solid" | "dotted"` variant). - **Usage**: pages and repeated landing bands. They preserve the current DOM semantics while centralizing width, `dvh`, and split-grid rules. ### Typography Primitives - **Source**: `components/design-system/typography.tsx`. -- **Components**: `Kicker`, `SectionHeading`, `BodyText`, `GradientTitle`, `AccentBadge`, `InlineCode`. -- **Usage**: marketing sections, showcase titles, badges, and command/code snippets. +- **Components**: `Kicker`, `SectionHeading` (with the serif display option), `BodyText`, `GradientTitle`, `AccentBadge`, `InlineCode`. +- **Usage**: marketing sections, showcase titles, badges, and command/code snippets. `GradientTitle` uses the light-legible green gradient (`#15803d → #16a34a → #22c55e`). - **Motion**: typography itself does not animate; reveal behavior remains in CSS utilities. ### Surface Primitives - **Source**: `components/design-system/surfaces.tsx`. - **Components**: `SurfaceCard`, `AccentSurface`, `ShowcaseSurface`, `CommandCodeSurface`, `IconWell`, `FactList`, `CompactDotList`, `NumberedPoint`. -- **Usage**: command cards, OmO/Lazy comparison cards, Hephaestus and Ultrawork black showcases, numbered workflow rows. +- **Usage**: white cards (`--card-base` + `--border-subtle` + soft shadow) for command cards, comparison cards, and numbered workflow rows. `ShowcaseSurface` stays an intentional dark accent band (`#101613`) for the Hephaestus showcase; `CommandCodeSurface` stays a dark code chip (`#101613` with `#dcfce7` text) — code surfaces are deliberately dark on the light canvas. - **Depth**: border plus tonal shift, with showcase shadows only where already present. ### Action Primitives - **Source**: `components/design-system/actions.tsx`. - **Components**: `LinkAction`, `GlowActionFrame`. -- **Variants**: primary filled text button, secondary outlined button. +- **Variants**: primary is the token-inverted ink button (`--text-primary` fill, `--surface-base` text); secondary is outlined (`--border-default`, hover `--surface-1`). - **States**: hover scale or tonal shift, visible focus ring, no layout-property animation. +### CodexWindow (ulw-demo) + +- **Source**: `components/site/ulw-demo/codex-window.tsx` (client leaf), scene data in `lib/ulw-demo-scenes.ts`. +- **Structure**: Codex Desktop window (adapter tokens above) on the light canvas: title bar with traffic lights and + `ULTRAWORK MODE ENABLED!` badge, transcript pane (command chip → status line → scene headline → + scene body → 8 numbered workflow steps), right rail (Environment card, Subagents roster, + narrative card, `goals.json / ledger.jsonl` card), composer bar, scene tab strip with play/pause. +- **Variants**: 8 scenes (`research → plan → todo → assign → red → green → qa-retry → checkpoint`), + each atomically updating command, status, headline, body, active step, roster lanes, proof chips, + ledger, and JSON card. +- **Window themes**: light (default) and dark, driven by `data-window-theme="light|dark"` on + `.ulw-window`. Light is the server-rendered default (faithful to the real Codex app and the state + Lighthouse audits); dark re-themes only the window interior through the + `[data-window-theme="dark"]` token block — the page canvas never changes. +- **Window theme toggle**: a `role="group"` container labeled `aria-label="Demo window theme"` + holding two ` + {/* display:contents keeps the shared flex-wrap layout while giving the + tablist only tab children (aria-required-children). */} +
+ {ULW_DEMO_SCENES.map((entry, index) => ( + + ))} +
+
+ + +
+ + + ) +} diff --git a/packages/web/components/site/ulw-demo/ulw-demo-section.tsx b/packages/web/components/site/ulw-demo/ulw-demo-section.tsx new file mode 100644 index 0000000..ed6093e --- /dev/null +++ b/packages/web/components/site/ulw-demo/ulw-demo-section.tsx @@ -0,0 +1,42 @@ +import type { JSX } from "react" +import { MarketingSection } from "../../design-system/layout" +import { InlineCode, Kicker } from "../../design-system/typography" +import { SITE_CONFIG } from "../../../lib/site-config" +import { CodexWindow } from "./codex-window" + +/** + * Interactive Ultrawork demo — the landing's product anchor. Intro copy is + * grounded in content/docs/ultrawork.md (see .omo/evidence/copy-ledger.md); + * the window itself replays a real ulw run as a live-DOM scene machine. + */ +export function UlwDemoSection(): JSX.Element { + return ( + /* This worktree's MarketingSection exposes no id prop, so the #ulw-demo + anchor lives on a wrapper div (landing-sections.spec locates it). */ +
+ + {SITE_CONFIG.ulwDemo.kicker} +

+ {SITE_CONFIG.ulwDemo.title} +

+

+ {SITE_CONFIG.ulwDemo.intro} +

+ +
+ + {SITE_CONFIG.ultraworkExample} + +
+ +
+ “{SITE_CONFIG.ulwDemo.quote}” +
+ +
+ +
+
+
+ ) +} diff --git a/packages/web/components/site/ulw-demo/window-panes.tsx b/packages/web/components/site/ulw-demo/window-panes.tsx new file mode 100644 index 0000000..d4e376c --- /dev/null +++ b/packages/web/components/site/ulw-demo/window-panes.tsx @@ -0,0 +1,157 @@ +import type { JSX } from "react" +import { + ULW_DEMO_ENVIRONMENT, + ULW_DEMO_PROOFS, + ULW_DEMO_STEPS, + ULW_DEMO_WORKERS, + type UlwScene, +} from "../../../lib/ulw-demo-scenes" + +/** + * Presentational panes for the Codex window. Pure functions of the active + * scene — every visible string comes from `lib/ulw-demo-scenes.ts` + * (source-grounded, see .omo/evidence/copy-ledger.md). + */ + +export function WindowChrome(): JSX.Element { + return ( + <> + +
+
+ + ) +} + +export function TranscriptPane({ + scene, + sceneIndex, +}: { + readonly scene: UlwScene + readonly sceneIndex: number +}): JSX.Element { + return ( +
+
+ + + {scene.command} + +
+ + {/* The live region stays OUTSIDE the keyed swap subtree: React must + mutate its text in place for screen readers to announce scenes. */} + + {scene.status} + +
+

{scene.title}

+

{scene.body}

+
+ +
+ {ULW_DEMO_STEPS.map((step, index) => ( +
+ {String(index + 1).padStart(2, "0")} +
+ {step.heading} +

{step.detail}

+
+
+ ))} +
+ +
+ {ULW_DEMO_PROOFS.map((proof, index) => ( + + {proof} + + ))} +
+
+ ) +} + +export function ComposerBar({ scene }: { readonly scene: UlwScene }): JSX.Element { + return ( +
+ + {scene.composer} + Full access + 5.5 High +
+ ) +} + +export function SideRail({ scene }: { readonly scene: UlwScene }): JSX.Element { + return ( + + ) +} From b37db7020d6774164c8d263fadfcc358578ff4a6 Mon Sep 17 00:00:00 2001 From: YeonGyu-Kim Date: Thu, 2 Jul 2026 21:34:55 +0900 Subject: [PATCH 12/35] feat(landing): port team mode and ulw-research sections to light Co-Authored-By: Claude Fable 5 --- .../web/components/site/team-mode-section.tsx | 96 +++++++++++++++++++ .../components/site/ulw-research-section.tsx | 44 +++++++++ 2 files changed, 140 insertions(+) create mode 100644 packages/web/components/site/team-mode-section.tsx create mode 100644 packages/web/components/site/ulw-research-section.tsx diff --git a/packages/web/components/site/team-mode-section.tsx b/packages/web/components/site/team-mode-section.tsx new file mode 100644 index 0000000..91b3fe6 --- /dev/null +++ b/packages/web/components/site/team-mode-section.tsx @@ -0,0 +1,96 @@ +import type { JSX } from "react" +import { MarketingRuleGrid, MarketingSection } from "../design-system/layout" +import { SurfaceCard } from "../design-system/surfaces" +import { BodyText, Kicker, SectionHeading } from "../design-system/typography" +import { SITE_CONFIG } from "../../lib/site-config" + +/** + * Team Mode — copy grounded in plugins/omo/skills/teammode/SKILL.md and the + * recorded Codex Desktop team session (see .omo/evidence/copy-ledger.md). + * The thread mock reuses the Codex window adapter tokens; rows are not + * interactive, so they carry no hover states. + */ +export function TeamModeSection(): JSX.Element { + const { teamMode } = SITE_CONFIG + + return ( + + +
+ {teamMode.kicker} + + {teamMode.title} + + {teamMode.body} +

+ {teamMode.compositionRule} +

+

+ {teamMode.stateNote} +

+
+ +
+
+
+
+
+ {teamMode.memberThreads.map((member) => ( +
+ + {member.name} + + + {member.status} + +
+ ))} +
+

+ {teamMode.threadNote} +

+

+ Member A COMPLETE verification note: report exists, pinned-link + check passed, and no GitHub mutations/repo edits. +

+
+
+
+ + +

+ {teamMode.whenTitle} +

+
    + {teamMode.whenPoints.map((point) => ( +
  • +
  • + ))} +
+
+
+
+
+ ) +} diff --git a/packages/web/components/site/ulw-research-section.tsx b/packages/web/components/site/ulw-research-section.tsx new file mode 100644 index 0000000..4fdd34c --- /dev/null +++ b/packages/web/components/site/ulw-research-section.tsx @@ -0,0 +1,44 @@ +import type { JSX } from "react" +import { MarketingSection } from "../design-system/layout" +import { AccentSurface } from "../design-system/surfaces" +import { BodyText, Kicker, SectionHeading } from "../design-system/typography" +import { SITE_CONFIG } from "../../lib/site-config" + +/** + * ulw-research — copy grounded in plugins/omo/skills/ulw-research/SKILL.md + * (see .omo/evidence/copy-ledger.md). Lane chips are informational, not + * interactive, so they carry no hover states. + */ +export function UlwResearchSection(): JSX.Element { + const { ulwResearch } = SITE_CONFIG + + return ( + + +
+ {ulwResearch.kicker} + + {ulwResearch.title} + + {ulwResearch.body} +
+ +
+
    + {ulwResearch.lanes.map((lane) => ( +
  • + {lane} +
  • + ))} +
+

+ {ulwResearch.activation} +

+
+
+
+ ) +} From 8ff67f65ef883e31ecabcafbbeebe5ede3e516be Mon Sep 17 00:00:00 2001 From: YeonGyu-Kim Date: Thu, 2 Jul 2026 21:34:55 +0900 Subject: [PATCH 13/35] fix(docs): light-theme coherence for the docs surface Co-Authored-By: Claude Fable 5 --- packages/web/app/styles/docs.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/web/app/styles/docs.css b/packages/web/app/styles/docs.css index 31c8380..66d446d 100644 --- a/packages/web/app/styles/docs.css +++ b/packages/web/app/styles/docs.css @@ -303,7 +303,7 @@ .docs-content code { font-family: var(--font-mono); background: var(--surface-2); - color: var(--accent-mint); + color: var(--text-soft); padding: 0.15em 0.4em; border-radius: 4px; font-size: 0.85em; From 23ad8c685f94214af00fc03aad30fadc28716e6c Mon Sep 17 00:00:00 2001 From: YeonGyu-Kim Date: Thu, 2 Jul 2026 21:52:54 +0900 Subject: [PATCH 14/35] feat(landing): compose the light IA and retire the raster badge Two e2e selector-drift touch-ups (plan-sanctioned): the commands anchor re-scoped to the command-card-unique '$ulw-loop "task"' because the demo window header now sits above install, and the window-theme locator scoped to '#ulw-demo .ulw-window' because team-mode reuses the window class. Both strengthen selectors; no assertion changed. Hero padding tightened (md:pt 52->40, md:pb 44->24) to keep the demo window above the 900px fold. Co-Authored-By: Claude Fable 5 --- packages/web/app/page.tsx | 6 ++- packages/web/components/site/brand-image.tsx | 39 ------------------ packages/web/components/site/hero.tsx | 2 +- .../web/components/site/ultrawork-section.tsx | 38 ----------------- packages/web/e2e/landing-sections.spec.ts | 2 +- packages/web/e2e/ulw-demo.spec.ts | 8 ++-- packages/web/public/img/badge-ultrawork.avif | Bin 42604 -> 0 bytes packages/web/public/img/badge-ultrawork.png | Bin 58761 -> 0 bytes packages/web/public/img/badge-ultrawork.webp | Bin 96964 -> 0 bytes 9 files changed, 10 insertions(+), 85 deletions(-) delete mode 100644 packages/web/components/site/brand-image.tsx delete mode 100644 packages/web/components/site/ultrawork-section.tsx delete mode 100644 packages/web/public/img/badge-ultrawork.avif delete mode 100644 packages/web/public/img/badge-ultrawork.png delete mode 100644 packages/web/public/img/badge-ultrawork.webp diff --git a/packages/web/app/page.tsx b/packages/web/app/page.tsx index 5ce94d9..29194d2 100644 --- a/packages/web/app/page.tsx +++ b/packages/web/app/page.tsx @@ -13,8 +13,9 @@ import { Hero } from "../components/site/hero" import { InstallBlock } from "../components/site/install-block" import { SiteFooter } from "../components/site/site-footer" import { SiteHeader } from "../components/site/site-header" -import { UltraworkSection } from "../components/site/ultrawork-section" +import { TeamModeSection } from "../components/site/team-mode-section" import { UlwDemoSection } from "../components/site/ulw-demo/ulw-demo-section" +import { UlwResearchSection } from "../components/site/ulw-research-section" export default function LandingPage(): JSX.Element { return ( @@ -31,8 +32,9 @@ export default function LandingPage(): JSX.Element { + + - diff --git a/packages/web/components/site/brand-image.tsx b/packages/web/components/site/brand-image.tsx deleted file mode 100644 index 0cd49a3..0000000 --- a/packages/web/components/site/brand-image.tsx +++ /dev/null @@ -1,39 +0,0 @@ -import type { JSX } from "react" - -interface BrandImageProps { - readonly src: string - readonly alt: string - readonly width: number - readonly height: number - readonly className?: string - readonly priority?: boolean -} - -export function BrandImage({ - src, - alt, - width, - height, - className = "", - priority = false, -}: BrandImageProps): JSX.Element { - // Strip extension to get base path - const basePath = src.replace(/\.[^/.]+$/, "") - - return ( - - - - {alt} - - ) -} diff --git a/packages/web/components/site/hero.tsx b/packages/web/components/site/hero.tsx index 826ba61..20b8fad 100644 --- a/packages/web/components/site/hero.tsx +++ b/packages/web/components/site/hero.tsx @@ -4,7 +4,7 @@ import { SITE_CONFIG } from "../../lib/site-config" export function Hero(): JSX.Element { return ( -
+
{/* Open light canvas — no card, no gradient washes. The declarative hero text sits directly on the sage ground so it stays the LCP element and paints at FCP; the demo window below carries the diff --git a/packages/web/components/site/ultrawork-section.tsx b/packages/web/components/site/ultrawork-section.tsx deleted file mode 100644 index 97475a8..0000000 --- a/packages/web/components/site/ultrawork-section.tsx +++ /dev/null @@ -1,38 +0,0 @@ -import type { JSX } from "react" -import { MarketingSection } from "../design-system/layout" -import { ShowcaseSurface } from "../design-system/surfaces" -import { GradientTitle, InlineCode } from "../design-system/typography" -import { SITE_CONFIG } from "../../lib/site-config" -import { BrandImage } from "./brand-image" - -export function UltraworkSection(): JSX.Element { - return ( - -

- {SITE_CONFIG.ultraworkTagline} -

- -
- - {SITE_CONFIG.ultraworkExample} - -
- - - - Ultrawork - - - - -
- ) -} diff --git a/packages/web/e2e/landing-sections.spec.ts b/packages/web/e2e/landing-sections.spec.ts index d2ab473..9147e2f 100644 --- a/packages/web/e2e/landing-sections.spec.ts +++ b/packages/web/e2e/landing-sections.spec.ts @@ -63,7 +63,7 @@ test.describe("information architecture", () => { const demo = await page .locator("#ulw-demo") .evaluate((node) => node.getBoundingClientRect().top + window.scrollY) - const commands = await topOf(page, "$ulw-loop") + const commands = await topOf(page, '$ulw-loop "task"') const workflows = await topOf(page, SITE_CONFIG.featureWorkflows.title) const teamMode = await topOf(page, SITE_CONFIG.teamMode.title) const research = await topOf(page, SITE_CONFIG.ulwResearch.title) diff --git a/packages/web/e2e/ulw-demo.spec.ts b/packages/web/e2e/ulw-demo.spec.ts index 326b744..86bf35a 100644 --- a/packages/web/e2e/ulw-demo.spec.ts +++ b/packages/web/e2e/ulw-demo.spec.ts @@ -95,7 +95,7 @@ test.describe("ulw demo — window theme toggle", () => { page, }) => { await page.goto("/") - const ulwWindow = page.locator(".ulw-window") + const ulwWindow = page.locator("#ulw-demo .ulw-window") // Light is the default (faithful to the real Codex app; Lighthouse audits it). await expect(ulwWindow).toHaveAttribute("data-window-theme", "light") @@ -115,7 +115,7 @@ test.describe("ulw demo — window theme toggle", () => { page, }) => { await page.goto("/") - const ulwWindow = page.locator(".ulw-window") + const ulwWindow = page.locator("#ulw-demo .ulw-window") const group = page.getByRole("group", { name: "Demo window theme" }) const lightButton = group.getByRole("button", { name: "Light" }) const darkButton = group.getByRole("button", { name: "Dark" }) @@ -132,7 +132,7 @@ test.describe("ulw demo — window theme toggle", () => { page, }) => { await page.goto("/") - const ulwWindow = page.locator(".ulw-window") + const ulwWindow = page.locator("#ulw-demo .ulw-window") const group = page.getByRole("group", { name: "Demo window theme" }) const lightButton = group.getByRole("button", { name: "Light" }) const darkButton = group.getByRole("button", { name: "Dark" }) @@ -154,7 +154,7 @@ test.describe("ulw demo — window theme toggle", () => { // Reduced motion pins the demo on scene 0 so the visibility check is stable. await page.emulateMedia({ reducedMotion: "reduce" }) await page.goto("/") - const ulwWindow = page.locator(".ulw-window") + const ulwWindow = page.locator("#ulw-demo .ulw-window") const darkButton = page .getByRole("group", { name: "Demo window theme" }) .getByRole("button", { name: "Dark" }) diff --git a/packages/web/public/img/badge-ultrawork.avif b/packages/web/public/img/badge-ultrawork.avif deleted file mode 100644 index 2c8fa564a8be94d538693083f44ec1d173632468..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 42604 zcmYJaV|Zpwur(apb~3Rwv2EMd9ox2T+qOBeor!JRdFMIjJJ(k~x>l{K+TFc>Rrgg5 z1O$X<=Imi_=n60c`X@F3Gp7Hr4Z!f94Qyaz>TLKQ|4)8dm{>dhF9ZUz2N*m5AO1hh z0>cg@VNZa)vE4rnXXwf#902y;1VCs2CwtTX z01yyp0MP#~;$OBq;6DZ!>fiAHMdSTPa2UF{3;zdP9BsL5>`l%8XAt5t1{m9OIe9oa zo7y;W{fhxu0}LHKxD2iBE&k{K-~;S!{s;U^{kM0}01!|h5U^kn(2#!w4#3g$e>VvP zgzzuf`oEC>7G8X7V`Aux0t5qtP0oS%Ap*vNgTy@10wR;`?rwzB>{1kxUp$MH#zfVp z2Ig5Y`Je#X((|G{^qkA?fI_YIP6zR{ysR)0k##VeT8WjPnga0 zKI_las)>-xUxO%1$cDzfKd3(EGZ_EuTQMpp_x9ySgow&GlHhq8q32TiuqF7;UHcP- zpt-#X8~B^oQ1i4}=n7VEt6{5dy3>mUhe4AxF~{KEI6g^w2-GLK z#qKFwybcLYA;V+3y|mvPxe_@%3#n;TjH2#5U4&#$LXzWKPuZMZoU$(SWoIB= zpBM0Hl?@O<4CnM}5@AIqaQbRc6F7EFWq=qNVTb2|#@uGVqz8lc z*_rg-k$u2V*0rR*s|pz6{a=dCaPnui+98^vk zqKBS&qh-?Fz$Jx)O3={?uwSM{N1o^7=!wPF@}s`0G-<}99pw47wr~DqiT!DosIf;_k9{C^fi`S$ zPnjRuu#CMr8(XKh9ww7Zsy?Ze|6f>ZrPEoUJxASIn=y|JG=AQwc^!(8hYPm?Z3&;i z_3seeBPY{rrKZlv8Lffm+ryhrN6A0Te)ho^$tHY1;9>R92CwygQ!XkL#I@?~VZF2+SU%s%fX95G1OPNTY%WYv}+m ztnswho6-Kg;N@uC4VW+@lnnhyi`+#igx7IT(yexk<9B^*>>6M5fPL?wm32sO-&UbE zI&jHNl)+m+33aXrw7L=(X7|MhI5g23EUL@zZTv|ZpZ*|ES*%VG?1fQvS{#U#G&;)a zRsUWTSXjepN~gJR0MAtu_J* zqzNtgtzWd?RX$ge!7gJ{f41WtEXOK2>elp*vju$5N}rlR@Aq^04ZEbbn<=xA==6?R zb7dWm$LlC#ST}xlb$FhHA*@P!tk?VuqoLC4_&%vWKdR_tp#jqF8h}znZ;vFhGHE-XTdpl9m2fe{6g~n7t3yUQi@k?-cioh4gQ6B)@Lq=m zvi>0NrPKuQp_X^zoZT6@oWFdTr9J3WrCWg`ECpyqJ$Q_~% zi)+z{E7f-jkf=bLO7bEG!L{hEbYvvP?OH*O6Ku1lXWwpYy24i+aP{C8IvkN;et{S||dn8v4X#$N{x?3lXlBR#>-cykozwHqGV&={X5m{hp)CGNewpR6XT z!r3E{%qt4Wxyh4g6w;9|GIV;j+%B0n47{I4B%EwBI(;&xdi2&-XY#N^j^A0Mvollb?$dMHM3)J$Df2kaFaFIj89NA{WRFrO_jdQ@A&(y`u5pY4WZLx0>5V3r&;Q z%o(eM8D0kPKuvrfFQk7dr%ylsd&m!W5{}HVUSOGac>u*;Z>%PMTRjB$T`;=+E$H}~ ziA~q4=?eVTiO34%BUzjz5eCpoGHHQC!AdG#y@#Aa1V8=&_4;&aKac^Qw5 z%xtgT;6)V*%JJ$EHN7njcYEJDzw_dFlwJDG({6Y9lkXD}#^qKPtQ6QlV(r@JOXUIx zZ5tGUrxDxh9uMEz5w31qirqQ&IkIb`FxC6kRHh-SLv9<1TW4pc6J3xm^~TcBkMkO% zF}dp>%kEqkhE#M4+bmyA@2rM~ND_HceMgv*I+ZjP%7|*DAjj}!eg%e}h-cDb3OzEr z<|2{213Rv68)}W`n0i$0KN{k;QP^!_qR`X$A47pFi!-+ba~^5)LtlsbSB6Id(k+gW z+T-EIqAIX^R7{*B^;&iu4(ob79qBwU3a0mQ`!M1bQMYls_m9kfx&u9|;0jFkwKkXz zsJ_Cwx3A!3;FTt=^@OwFx4DM%HmSD7Q&;C0j{QbXg`VhB-##lblufbTprcp)BYaV4 zR+2h6o@8srs8I_-ImTz+Ta7Wts9?MAoejwK$qXd#_LU&aQ%H8Q9|-4EMV27w2GV$J z{6Cs6qy7w4a{r>Q%z`_LenkapqCy?~%^0;;gYmQnMqI?^dc`*(4bvM2mtrsrF=V9o z_0*OBxjuQ6X&$QMQcGyiIi!@Z>vQ)6qDa*hUsCM5tcTb7>?ObIJ80cPSlr7TmH;T* z7wW2A@0DJ*uf>O+a^Cpq0=C%;PqcWyqLWM^Z>Q8B^xy(5lo%J5O+RhBm75kY>?IA} zEZQvs>s&X9-V@v2P4zz~-OA6=$4;Jrp`)5RHT$B7Qidv7ncmVI^7fGX+=m1`NxYrE zPQ->%dsW)u^lG>^OKJe)6(n;MP09~{Sx^a|egc3(2v;h}QOhP~Dqify-;J8r9O%LH zBoX;7;F5tGYq=XuztWF#sSM?+6~X1Ml+f2X3^!e$3Yp*2ym~+$3>Fa>SvB-R3>;9` zBLh(tD2kx09n3tY{ZwXMm>+%K!C@L>XVHUF^F9U z6Hf{3c|IF)l8YmZ{H5P=)Q?l{Av+eM*1Ujx(yMg&Gm*BEmX{aK(3J%}UG@_!nO;Qt zqZ^kghB(HOUlk#7W(=l6VOatoA};S9I_{#v)msfj*5jx(5yGr*vQ?>E!xnV@b>_Wh zJLGD`k{t)KBcQ0`Hk@%blV^n>(5+h3+JU|Hy&KeFiS_yr@mKoJHF6*@?pD3ugfo5s zhrM${EUrj?9{%e-NkZhW9z+~0g+VyNSb%G)rN@r&!`oR3kxm9Mdvlo}G2otH-HC?D zQN~-1L1o!BDmCN$%pOpMNY2 zK@JQSZe~5TFbLUtO1!P;hcex;hm~feURO>;_VC;}oVSI8bzrnRPPZF9-RYAOo+|E} z5pxsIX30pxj%Zn=U%d}r)1ZS?#{hKBXcFX1-lvf0cu^(HOQ1;M{@t7C76MAJ93#0Z z%ub@8y|`+{oN502eV+vNV>=iE2)wJT$^t>}&`|PR3G}vfD*LRz&&f zNDIL_wZ$eY@p9p;*dl_+=2$Y4&|isu;Z$6WyLN~_avdkrSseaHyo7YP(Qee7$sehK zV!t0KI_aFhuFR2?FSZn~5n&5yde|Do*DA+$%S%PmthdYA{V@j(dZ`#}|}@O@4jkPE2~@kIE+ z?Fst;*d>b_rLI@ss21m-FwZdzt?+IKYJHytPR;*Lv`Gk)xtGaE=Z6rogMPT18AAfz zRBG~scS-sgZ#-9vD#1lK*-@P7=uM=XGHYt)ja51 z7I?`&AqP+O!v=lNjAlJ~pF9=8j6C!0-AgWTdoybC0=c;^pIMf%J{@rJ=0K3Hyh(W0Aushf48 zK3&lVS_#S;VDw<*&d9<_3{0JD@*yBD&e|dsiU*TLIrF7~TCC*#J~2a4*COTCg8z0K zqR3fXYd`yPQE>{4cgUQnp7!l&YKgnrXrG%$#R}#QRZm`|G)#G9?eHCj<+&K=M!**{ z#Mj>H2?}G|96Q|k8#X~mywJ_KXL{3^9QERPxblUPpZW=04UI2cwJi8f!wkd}I>0WZgazYEr75dlWm?2B>XduIBpuoZu zN)Y@X6PF~h(ONfJgXPjYJ{<&Kx|033nzV&RHTOxqN{#S{@Mg;zvyz>N-}SDAW%i?( zF7=&>>a5sshll5u>){BedTa}fPxu5UWw{EGTgzqPGDX7JRof4d?b*HJaO?!2-MK}K z4;?B8k}ciVO4>;LP-^A7#{l$}`}m#daM*ToF#%-pz4FUb#nGn^sa@3*TTnXiA z=*cZTs{LI_elzE1d1q)uV`ke+1E+va96S*CwuntFRV?*vIA#h}&j5YPpcZb@ntM=4 z)IOK3lwf{wE5;rleo|r?CrQ$vN?Cub=kd-=&-UEnOvbxtn5Rd1qxQ^Cm>ejExwt;R zi{DoDN>JVF9OmAxbi#_RM8f5mjkFaumdxO*ybMghia%*YWV@1ZqTejW+ZH{bK_Es? zjvCQ^2U_S2>#!83;)c2Pq}~Xph6@>O^nF99tcP)`(O(#XbP2l};W{eH?hB9U;K+o3I%mtPuTRi= zFIoXJP$gMF-jn?RR>{~75}GtBU&?w2C#HG-HdDGOiY{`o`UbyrV@ik2lLTSWXZ4zk zYM+6|GOOh*wBjC7+^)d(HTNM7{eu087B>xGLR?CHqgYpd z;I?bR8b_^SLKIj#9xZ(#`BYvd^t7uaax)sKrj+Kto2;<`wzl}`VBJ4ROpTJAMDg0- zreZO**3zLr#)?PKH*d>|QwcX_^lNz_zF_9D(-9^}KtM~!HOaq!j;j&=7O`cA2o67kfT8Qw(YEE}<@9cu&M_`hbzle6)yu{g- zL&&GQn#qSBl3Neli`^mQ|1J|A{Dg*yM@HxCI{XuFIam0?mi9jl42535eHj)>K& zrY0GK%@I+jZ5XB|<)85^WM@Bxhu`HXPKxbAE+EA<53iRg_sM6c@geD{N^c_M{39Wu zZ8xHUfB=Ex^zkD{ggv|{G}3Urn=A@e;9d88S%Sz<%Xj_RNj_y4LFZ15uvWJN=XALk z42B7*QVk532F|Igj?F6Fp!Tz(b~)?8!lwg6eBoe4Ochcp8yS zJ30?%0-K12Y9k-Vek9_e?$CKtwh&rC{w7%0%VOhTxi?$!tl)ahneW_?3VH{p9eb!m zp?%0B)|)i{R57w(odEiX5+~Iv7pYmPV*aFOD&yx0Mw!GdiI@T zL%pkmCIN?hP)^8Ro4o`J)KrGE>p+~5S2Fq9%50s#oXVEOQ5ZNI>doI_L=Q;M8j0P| z2bYO#DB`5)<{$_V5aP1E-oLTpzs*T1oQ#372W}6Ru&}t39Fuf#F0N{0Ofaw%wOz5#6}e3{s7*ze3Qna~e#yquwH6Wq z!cu)&Acy|QG}KEbi$akhd!`x%0ru7my{2xv_Df8moIw#stAY}MGu$uFL2S#Bfe_MgDjwr(O9FX z&QZla_NuJLFr5swNZNwDu^qZ=&?C39fXghuu9`;BYPeG~(YCP9A%n++0+xNigVsm! z<2ZsQelX4N=goT*elQ$Mp04s6nhrY#DXC_(&PhfYaEg>w*OY6y6|CYI7z5TCR}};u z2_Rlyp1aNOc6Ld{TJo}1M~F!^|IM^L*LsEUx}?QALHXqR+}(b*cSply^<iB?k}Ptrm0j)*Zizvk$uV)mgLtJwh5EzO?#A^0<5$W`ZtEBkq6c z56^7*qQ;DurloSMmU!vQlM%4i1n#lLYDCOw&fd>%dssE$`khflco?c$WQVV8TE}O_Vn&AnNoSEFtBzkBEM0GDM z`>T7vD4W2^3t8efb~_t>c#ns9Cb(4}{=LegLZ&ToK^tw8vSGl2X??75b zrCNiJTe^HNhT3x3fC`s>?vXHGnLe*ks|p;k?DA|6E8pYHynh_UHZn6mq zn*$xBA$g9>WcUpN2UE=xtD%)UEa4Uo82I4je3A=vHa+T2W_}is3pW;QJ{}7~uRrp% z+YEj8Hw^e)LfJ$6y?jPW>}L)EKd}CwpdFoR|qD`L7k7 zGFahS-$BnlqQs&|8w>|B%1?FP^HSi&NYJABx3{kVJXwNeaH%9j0uqj;D^jSi$sxMJ z!)^%zTsP)oo^oayf$nA2kR=Kzrb3Dw7vL>k=`RiCDsts`X@9e937|x5`siV`wg$K7 zMTf zJBMFo9xc;9*z8>jIkk))zl-KnMgeXloc*ABKH_-g}O(@HVzfFy{k|%fJ4n?>^wX@X?lL_% zhszTNKSehBJ3XP{YRHe;YK>G)(g|DPdSWnMrdZu8-DZD|S=gm+gIxch_zN}FIa}@5 zKyu@3TQt0Hrsj1wF@D~!P}(EW=yKrhb+E~x5i48kx^Iy|6Y$Xi5o0 z$`mPM=dkNAPxb&pp&(8j;2!mTZt(F-H}dXiJ{4D2IuYudbj*{8kJctrbl4v1S*(*<;0op_dAB%jD)K1e`E> z7$a}J-PjjsiB0exU8=ncVWWzd!$TZy9up!}o$x&FXdQgiH%}Wp?jy!(&PKNIKutqv z9-MPS9;WNmuR-UcUG1txA|vzSEywwrN-g#Ea?8|0ui=5U$RsK2Ho;ANS;HMK)kl=9 zVI&~e(VMJfX`O=-gXh^*^WCxKp?LByTrSbbC%{b`Ft>1oeLWsZ*iS?Ty3qzRFcO&| zyf0h09VmU*gTA684z^P|bg>JUsdSH2+9^b_n@|JoF+EyqAWq2gh4TPpdh4buHoM9$ zFz3gIB>O&r$JBC14wFFR zksaZKj!4jC+r>m*hEk^oC@*6`^+Q1OXv6+H8NTIBVhXAfp1sMiot|?G@(LPbgc2Ow(X4`upP#lm;T{JEKl-H3qp#l z^Mls?A}O;vDY+bLrpzMO^rW3&$r*D}_tk{IB7t)I$e*>AMIQ_AOATqeYY7(JvrL3A zjt#3G*9eV~rqK5FFS%6AildVhnkgBdnf*`+I6idn(H2cR`=OxzfimZ@rN~3()!Ly< z)WvY(fhZ&f@*Eoo5~g|r*!s;cKyo(%t|f;R5Syi#4RtzwzlJK}#W5z}((Z)}Laf z(52)1rwzbqK3Mj4(?K#`v49|mu19@7I%&$!MKNn8?HWkA7>|E~{CI%TrcubluhZZq1X70URENKP z6??lbKP&ggPTnK9!{QxNg)<^CRwC{lU!#ILKTU^rlLZ7+FzlB5+|p&@^;<8y%bum` z-@Y^1G~;j<$+d^eKfo^z=J{q*QX$wUkuM1qBWA?zjMT>{;4%`fU{*Kz8oY|)Xvl*;~z`)q069c$N9vy zAc()6kuHevUwS#!#Bg)>KZ@E#b{ZKx2PxwCTb+J=v*Qc;OD&x_hb7G_)OfI;&RUKg zDh@@q@dB5f8ro77^t)v-G&uD&m@llW+{9|ynSRP&3;oJ2oeP4g%@q=ew*a>FlOuu>vs-Xe;3=M`vSe zUdoWLXJPRg1#H0G1Yxp+0Kg-`?_gk@NJ(qgfK5j=$hzNDcd7!Y+CIOIKl@lif3C!A zSW`Er;_v+)DIYy^k0tVtFIWn#DeLEOER=(b= zhfG9ac)!w^2M(B|v>+k-T<7)0&Zl(&wqCkERv>js?UWUH_%Dh^9W#vK4|Q1VIiZya z;uf+DDH`cyTGv^Jn8~wb%5!b?(2vT8Xq>s0jC8odV$F}~J%G5>91AK8uQAwdrt(2P z0|`W3hGCMO5S^-4g3{*jboAR}LX?u}MWl3$Y^lH1obvqK_g6N%GXszIGY|LG%^4F7 zvcNeV-}`8ROMrY;ow1txsjyI7a#@HI zw1?q-Pe+)I!DM@?Me+&ax-D4Bm&h_0)RMbe&@S74Ao-u4uN#6Fua7~#yTr*bArU@< zR8S3?JMocavYy8!%^tFv6ThuP4+O;-&w=V3+^c)e5r7d^NwxPTF8h)T61(i$_6T_# zf_5L#-;|7Jq1-hTrYL;*gR3aJdI&Q+$lk|~%(EK5h`DX+{I$-_R#<5K;tZ`;%eyEw zvrQd#97I&g>n;L6S%{JTkMFR;3YQ6$xkb`Sg?WNa+Kq@tj$U7Q^Nr7lXdk3UeX9v8 z5edV++!@CY!OR*f3Ls?d^41WyE+c5(qUVs3O{v(V7^5vBlhBrqPNSR6>{lcTl7y&3 zhKXgfL}s+cD*7JtCa&bOi95w$K(bD+cRMdMH)A0E*B_LoQn1mY?J0sxUdTE`f;pvx z-}r&DidqN%evzl( z_-X!xf(bl3?Z`@CD8-bvjjFRRXF9lVVH9F3hV^m!ak_WWx*cE_&(v=M(-eFuq+59p zDl-6O)sPPfYZwiruXA96#hy_^053}4eW8jo90D)`Jrei?L>s@@NAaDQLW->v25&Y( zVfFrcb!vy1xIfa5)M^1DuVQ<;@5R0(j%t1jMz@NAPN$?rdBk&-pw>lB^bViICdn*% zEw%lk>e4IN%#}|tewz_0e?MqcX%%EY=qY%T^TbKvV%`(bB|?E<3LJdi=<8>Oprfp92Tj9H_bd?Xhhy5e=p&TLLnF6fV=ygkbcR*xH&VWn}W|!p?)EZVmn!7Xo7$s{y5ad{}kJc&Y<$~U&gS-=X zSZo4-xCWkKE)^e7a;;&5 zRN%`~ThO%p|FuR!ko*<>RBZJeY3iSDGi-~D6f-DvNDqlA{weM9hgqr?IwFfjr(Uww z1od9JI

t&rSs@(9jgaupAvODUd5BMzwB-&m40oL_^h0u89wm!k)SCi=+Fz5OvgT zir(AkL7=ZF)$fu;lHoS(|_7w@7B8H{K_L^ES1Qqj%J6#zJ%ob2lxiVLG2!8YX%DX^2ndJ&5O zZ~b+Kux(v^5%VASWo2XJSh#31b+>b(7^tF}0*l)Lw6LL3&JNuM_X6Ewo$yH@c*?jXaGbJXFZ-EeknHaVbjF*&f`)n z)9)#wqjWICoJf5b+Pt`3%ut)t-`P4^&~BbUPplo@^k=WzO6Zzgi#YBBr>NY=q2EXgSo!53Qyx`@yk^omrP|uzj zuJ!I(9QP+_Y8YU9>M)HQg2MdZQP|DhGW84mNyUIj}^mqm<(*wsxi#sddqav)>Nw17?f^oilm*3X^(4G2Jw(o$!gE3VCb1-nyX@>xkY1GMn!d?zp6x4S+n zI?TjB4tM?%E^Rt!0Nq$FeUP4rfV%KNmRm~KiHZUGn4_!WYTY=he{H8a{ zf=iUn!J&3to8vg`8@J~CjIx2*rP*sWi>_$>=kj%xmR)=-z%kSa~?kfdP+S`R?+^ct+?2= z`Pw;%r#l0?g(0GUm9s0^!4f3$!5&C z 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 diff --git a/packages/web/public/img/badge-ultrawork.png b/packages/web/public/img/badge-ultrawork.png deleted file mode 100644 index 50cb940d1dcd7ea96c7b7602b253738db1d432c7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 58761 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 z

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 AjsO4v From 6793424129aa43601f749f8ae1bcf73edf406e3d Mon Sep 17 00:00:00 2001 From: YeonGyu-Kim Date: Thu, 2 Jul 2026 22:19:56 +0900 Subject: [PATCH 15/35] fix(design-system): deepen accent green for AA on tinted chip fills Lighthouse mobile a11y caught --accent-primary #15803d at ~4.2:1 on the tinted pill/chip fills (#e2ede0/#e9ebe3/#e9f0e5) and the ported demo intro chip using mint as text on light. accent-primary is now #166534 (5.9-7.1:1 on every observed fill) and the chip text uses --accent-glow, honoring the 'mint is never text on light' rule. Contrast script gains the four tinted pairs so this class of regression fails locally before CI. Co-Authored-By: Claude Fable 5 --- packages/web/DESIGN.md | 2 +- packages/web/app/styles/design-system.css | 7 ++++--- packages/web/components/site/ulw-demo/ulw-demo-section.tsx | 2 +- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/packages/web/DESIGN.md b/packages/web/DESIGN.md index 6fbd04f..0b977d3 100644 --- a/packages/web/DESIGN.md +++ b/packages/web/DESIGN.md @@ -34,7 +34,7 @@ or blue. | Brand/core | `--brand-core` | `#22c55e` | Green brand center (fills, gradients) | | Brand/mid | `--brand-mid` | `#16a34a` | Green gradient middle | | Brand/outer | `--brand-outer` | `#15803d` | Gradient edge | -| Accent/primary | `--accent-primary` | `#15803d` | CTAs, focus, active docs links (AA on light) | +| Accent/primary | `--accent-primary` | `#166534` | CTAs, focus, active docs links (AA on light) | | Accent/soft | `--accent-primary-soft` | `rgba(21,128,61,0.08)` | Soft green fills | | Accent/border | `--accent-primary-border` | `rgba(21,128,61,0.28)` | Soft green outlines | | Accent/mint | `--accent-mint` | `#86efac` | Fills and decoration ONLY — never text on light | diff --git a/packages/web/app/styles/design-system.css b/packages/web/app/styles/design-system.css index b56eafd..7edbd26 100644 --- a/packages/web/app/styles/design-system.css +++ b/packages/web/app/styles/design-system.css @@ -37,9 +37,10 @@ --text-muted: rgba(16, 25, 20, 0.75); --text-soft: #14532d; - /* Accent — AA-legible forest green on light ground. --accent-mint is for - fills/decoration ONLY, never text on light surfaces. */ - --accent-primary: #15803d; + /* Accent — AA-legible forest green on light ground, including the tinted + chip fills (#e2ede0/#e9f0e5 family) where #15803d only reached ~4.2:1. + --accent-mint is for fills/decoration ONLY, never text on light surfaces. */ + --accent-primary: #166534; --accent-primary-soft: rgba(21, 128, 61, 0.08); --accent-primary-border: rgba(21, 128, 61, 0.28); --accent-cyan: #15803d; diff --git a/packages/web/components/site/ulw-demo/ulw-demo-section.tsx b/packages/web/components/site/ulw-demo/ulw-demo-section.tsx index ed6093e..632b0ae 100644 --- a/packages/web/components/site/ulw-demo/ulw-demo-section.tsx +++ b/packages/web/components/site/ulw-demo/ulw-demo-section.tsx @@ -24,7 +24,7 @@ export function UlwDemoSection(): JSX.Element {

- + {SITE_CONFIG.ultraworkExample}
From b4bacf70d186adcccf2f8c46c8726b6042567ced Mon Sep 17 00:00:00 2001 From: YeonGyu-Kim Date: Fri, 3 Jul 2026 09:34:54 +0900 Subject: [PATCH 16/35] feat(design-system): rebuild the identity as a Linear-class dark system User-directed v2: graphite canvas (#0e1012), near-white inks, hairline borders, restrained green accent (#4ade80, AA on every observed surface), dark OG/manifest/favicon/docs. The light Codex window becomes the page's hero contrast layer; the dark window variant reads as an elevated panel. Contrast script re-derived to 50 pairs on the new palette. Co-Authored-By: Claude Fable 5 --- packages/web/DESIGN.md | 137 ++++++++++-------- packages/web/app/icon.svg | 8 +- packages/web/app/layout.tsx | 4 +- packages/web/app/manifest.ts | 4 +- packages/web/app/og-image-theme.ts | 32 ++-- packages/web/app/styles/design-system.css | 120 +++++++-------- packages/web/app/styles/docs.css | 4 +- .../web/components/design-system/actions.tsx | 2 +- .../components/design-system/brand-mark.tsx | 2 +- .../web/components/design-system/surfaces.tsx | 8 +- .../components/design-system/typography.tsx | 2 +- .../components/site/hephaestus-section.tsx | 13 +- packages/web/components/site/hero.tsx | 4 +- 13 files changed, 178 insertions(+), 162 deletions(-) diff --git a/packages/web/DESIGN.md b/packages/web/DESIGN.md index 0b977d3..dcb8fb9 100644 --- a/packages/web/DESIGN.md +++ b/packages/web/DESIGN.md @@ -8,13 +8,15 @@ Implementation sources: ## 1. Atmosphere & Identity -LazyCodex feels like a calm, precise productivity tool for complex codebases: a light sage-paper -canvas, editorial structure with dotted column rules, and green as the single brand signal. The -signature composition is a white card sitting on the pale sage ground with the geometric -rounded-square `L` mark. Dark surfaces still exist, but only as deliberate accents — code blocks, -command surfaces, the Hephaestus showcase band, and the demo window's dark theme — small dark -windows on light ground, never the page itself. The brand color is green, not teal, cyan, purple, -or blue. +LazyCodex feels like a calm, precise productivity tool for complex codebases: a deep graphite +canvas, editorial structure with dotted column rules, hairline white borders, restrained accents, +and green as the single brand signal — crisp and quiet, in the spirit of a modern dark +productivity tool. The signature composition is the faithful LIGHT Codex window sitting on the +dark ground with the geometric rounded-square `L` mark: the light window is the page's hero +contrast, mirroring the real app frames. Elevated panels separate from the canvas through small +tonal lifts plus hairline borders, never heavy chrome. Light surfaces exist only as deliberate +accents — chiefly the demo window's light theme — small light windows on dark ground, never the +page itself. The brand color is green, not teal, cyan, purple, or blue. ## 2. Color @@ -22,46 +24,48 @@ or blue. | Role | Token | Value | Usage | | --- | --- | --- | --- | -| Surface/base | `--surface-base`, `--surface-0` | `#f4f6ee` | Page canvas | -| Surface/night | `--surface-night` | `#e9ede0` | Footer and deeper page bands | -| Surface/subtle | `--surface-1` | `rgba(16,25,20,0.03)` | Hover and quiet fills | -| Surface/raised | `--surface-2` | `rgba(16,25,20,0.05)` | Secondary tonal layer | -| Surface/strong | `--surface-3` | `rgba(16,25,20,0.08)` | Stronger tonal layer | -| Surface/card | `--card-base` | `#ffffff` | Hero card, white content cards | -| Surface/panel | `--surface-panel` | `#fbfcf7` | Panels, install bar | -| Surface/alt | `--surface-panel-alt` | `#f7faf2` | Alternate panel | -| Surface/deep | `--surface-panel-deep` | `#f3f7ec` | Deep panel | +| Surface/base | `--surface-base`, `--surface-0` | `#0e1012` | Page canvas | +| Surface/night | `--surface-night` | `#0a0c0e` | Footer and deeper page bands | +| Surface/subtle | `--surface-1` | `rgba(255,255,255,0.04)` | Hover and quiet fills | +| Surface/raised | `--surface-2` | `rgba(255,255,255,0.06)` | Secondary tonal layer | +| Surface/strong | `--surface-3` | `rgba(255,255,255,0.09)` | Stronger tonal layer | +| Surface/card | `--card-base` | `#16181c` | Elevated dark panels, content cards | +| Surface/panel | `--surface-panel` | `#121417` | Panels, install bar | +| Surface/alt | `--surface-panel-alt` | `#131519` | Alternate panel | +| Surface/deep | `--surface-panel-deep` | `#101215` | Deep panel | | Brand/core | `--brand-core` | `#22c55e` | Green brand center (fills, gradients) | | Brand/mid | `--brand-mid` | `#16a34a` | Green gradient middle | | Brand/outer | `--brand-outer` | `#15803d` | Gradient edge | -| Accent/primary | `--accent-primary` | `#166534` | CTAs, focus, active docs links (AA on light) | -| Accent/soft | `--accent-primary-soft` | `rgba(21,128,61,0.08)` | Soft green fills | -| Accent/border | `--accent-primary-border` | `rgba(21,128,61,0.28)` | Soft green outlines | -| Accent/mint | `--accent-mint` | `#86efac` | Fills and decoration ONLY — never text on light | -| Accent/glow | `--accent-glow` | `#14532d` | Deep green emphasis | -| Text/primary | `--text-primary` | `#101914` | Main text and headings | -| Text/secondary | `--text-secondary` | `#3f4b43` | Supporting text | -| Text/tertiary | `--text-tertiary` | `#55645b` | Labels, metadata | -| Text/muted | `--text-muted` | `rgba(16,25,20,0.75)` | Body copy | -| Text/soft | `--text-soft` | `#14532d` | Deep-green tinted text | -| Border/subtle | `--border-subtle` | `rgba(16,25,20,0.10)` | Dividers, dotted rules, quiet controls | -| Border/default | `--border-default` | `rgba(16,25,20,0.16)` | Panels and cards | -| Status/success | `--status-success` | `#15803d` | Positive status | -| Status/warning | `--status-warning` | `#a16207` | Warnings | -| Status/error | `--status-error` | `#b91c1c` | Errors | - -`::selection` uses a `#bbf7d0` background with `#14532d` text. `:focus-visible` outlines use -`--accent-primary`. The `html` element declares `color-scheme: light`; the site identity is a -FIXED light canvas — there is no site-wide `prefers-color-scheme` flip. Dark appears only inside -the sanctioned dark surfaces below. +| Accent/primary | `--accent-primary` | `#4ade80` | CTAs, focus, active docs links (AA on canvas AND elevated panels) | +| Accent/soft | `--accent-primary-soft` | `rgba(74,222,128,0.10)` | Soft green fills | +| Accent/border | `--accent-primary-border` | `rgba(74,222,128,0.32)` | Soft green outlines | +| Accent/mint | `--accent-mint` | `#86efac` | Fills and decoration first; interactive text stays on `--accent-primary` | +| Accent/glow | `--accent-glow` | `#bbf7d0` | Bright green emphasis | +| Text/primary | `--text-primary` | `#f7f8f8` | Main text and headings | +| Text/secondary | `--text-secondary` | `#b4bcc8` | Supporting text | +| Text/tertiary | `--text-tertiary` | `#98a1ab` | Labels, metadata | +| Text/muted | `--text-muted` | `rgba(247,248,248,0.78)` | Body copy | +| Text/soft | `--text-soft` | `#86efac` | Green-tinted text | +| Border/subtle | `--border-subtle` | `rgba(255,255,255,0.08)` | Hairline dividers, dotted rules, quiet controls | +| Border/default | `--border-default` | `rgba(255,255,255,0.12)` | Panels and cards | +| Status/success | `--status-success` | `#4ade80` | Positive status | +| Status/warning | `--status-warning` | `#fbbf24` | Warnings | +| Status/error | `--status-error` | `#f87171` | Errors | + +`::selection` uses a `#14532d` dark-green background with `#dcfce7` text. `:focus-visible` +outlines use `--accent-primary`. The `html` element declares `color-scheme: dark`; the site +identity is a FIXED dark canvas — there is no site-wide `prefers-color-scheme` flip. Light +appears only inside the sanctioned light surface below (the demo window's light theme). ### Codex window adapter tokens (ulw-demo / team-mode mocks only) The interactive Ultrawork demo and the Team Mode thread mock reproduce the Codex Desktop surface -on the light canvas. The window carries its own isolated adapter palette with two themes selected +on the dark canvas. The window carries its own isolated adapter palette with two themes selected by `data-window-theme="light|dark"` on `.ulw-window` — light is the default and the -server-rendered state; a `role="group"` toggle switches it (see § CodexWindow). Adapter tokens -never leak into ordinary landing/docs UI, and ordinary tokens never restyle the window interior. +server-rendered state: the faithful-app light window on the dark page is the hero contrast, +mirroring the real Codex app frames. A `role="group"` toggle switches it (see § CodexWindow). +Adapter tokens never leak into ordinary landing/docs UI, and ordinary tokens never restyle the +window interior. Light theme (default block on `.ulw-window`): @@ -79,13 +83,19 @@ Light theme (default block on `.ulw-window`): | Window/glyph-text | `--codex-window-glyph-text` | `#ffffff` | Letters inside roster glyph squares | | Window/traffic | `--codex-window-traffic-red/-amber/-green` | `#f87171` / `#fbbf24` / `#34d399` | macOS traffic-light ornaments | -Dark theme (override block scoped `[data-window-theme="dark"]`, same 13 token names): +Dark theme (override block scoped `[data-window-theme="dark"]`, same 13 token names). It is +deliberately a touch LIGHTER than the page canvas (`#0e1012`) with a stronger hairline ring +(`rgba(255,255,255,0.18)`), so the dark window still reads as a distinct elevated layer instead +of dissolving into the page: | Role | Token | Value | | --- | --- | --- | -| Window/canvas | `--codex-window-bg` | `#101613` | -| Window/text | `--codex-window-text` | `#e8f0ea` | -| Window/chrome, border, chip, text-soft, active(+border), accent, glyph-text, traffic | same names | tuned values derived from the retired `#0E1411` dark-panel family — `app/styles/design-system.css` is authoritative | +| Window/canvas | `--codex-window-bg` | `#1a1d22` | +| Window/chrome | `--codex-window-chrome` | `#15181c` | +| Window/text | `--codex-window-text` | `#eef1f4` | +| Window/text-soft | `--codex-window-text-soft` | `#a9b2bd` | +| Window/accent | `--codex-window-accent` | `#4ade80` | +| Window/border, chip, active(+border), glyph-text, traffic | same names | tuned dark-elevated values — `app/styles/design-system.css` is authoritative | Every (text, background) pair in BOTH window themes must pass `.omo/scripts/contrast-check.mjs` at ≥ 4.5:1 (≥ 3:1 only for display-size text). @@ -115,10 +125,10 @@ rule applies everywhere outside the window. ### Rules - New UI uses `--accent-primary`; `--accent-cyan` and `--accent-teal` remain green aliases only for compatibility. -- `--accent-mint` (`#86efac`) is a fill/decoration color only. It fails AA as text on the light canvas and must never be used for copy. +- `--accent-mint` (`#86efac`) is a fill/decoration color first (glows, dots, code prompt glyphs). Interactive text and links stay on `--accent-primary` so the accent voice remains single and restrained. - Accent is reserved for interactivity, code emphasis, focus, and brand signal. -- Dark surfaces are allowed ONLY in four places: docs/code blocks (`pre`), command surfaces (`CommandCodeSurface`), the Hephaestus showcase band (`ShowcaseSurface`), and the demo window's dark theme. Everything else sits on the light canvas. -- Raw colors belong in this file, `design-system.css`, or OG theme tokens. Component code references tokens or shared primitives. The sanctioned raw values in components are: `#101613` (dark accent surface), `#dcfce7` (text on dark code chips), gradient stops `#15803d`/`#16a34a`/`#22c55e`, brand glow `rgba(21,128,61,0.25)`, and card shadow `rgba(16,25,20,0.04)`. +- Light surfaces are allowed ONLY inside the demo window's faithful light theme (`.ulw-window` default adapter block, also used by the Team Mode mock). Everything else sits on the dark canvas. Code blocks (`pre`), command surfaces (`CommandCodeSurface`), and the Hephaestus band (`ShowcaseSurface`) are slightly ELEVATED dark layers — a tonal lift plus a hairline ring, so they never vanish into the page. +- Raw colors belong in this file, `design-system.css`, or OG theme tokens. Component code references tokens or shared primitives. The sanctioned raw values in components are: `#16191e` (showcase band), `#1b1f24` (command code chip), `#15181d` (docs `pre`), `#dcfce7` (text on dark code chips), gradient stops `#86efac`/`#4ade80`/`#22c55e`, brand glow `rgba(74,222,128,0.16)`, card shadow `rgba(0,0,0,0.4)`, and the `white/10` hairline rings on elevated dark chips. ## 3. Typography @@ -163,7 +173,7 @@ All spacing resolves to a 4px rhythm. Existing Tailwind values map to the same r ### Dotted rule grid -- The `.rule-grid-dotted` utility applies `border-left: 1px dotted var(--border-subtle)` to child columns — the editorial vertical column rule of the light identity. +- The `.rule-grid-dotted` utility applies `border-left: 1px dotted var(--border-subtle)` to child columns — the editorial vertical column rule of the LazyCodex identity (the rule color flips with the token: hairline white on the dark canvas). - Apply it through `MarketingRuleGrid` with `ruleStyle="dotted"` on multi-column marketing bands that need column separation without card chrome. Solid rules remain the default (`ruleStyle="solid"`). - Dotted rules never appear inside the demo window or the docs layout. @@ -179,8 +189,8 @@ All spacing resolves to a 4px rhythm. Existing Tailwind values map to the same r ### BrandMark - **Source**: `components/design-system/brand-mark.tsx`. -- **Structure**: inline SVG rounded square, `L` stroke, mint/green dot; tile fill `var(--card-base)`, stroke `var(--accent-primary)`. -- **Variants**: `nav` 24px geometry, `hero` 160px geometry with `HeroBrandMark` glow wrapper (soft `rgba(21,128,61,0.25)` glow tuned for the light canvas). +- **Structure**: inline SVG rounded square, `L` stroke, mint/green dot; dark tile fill `var(--card-base)`, stroke `var(--accent-primary)`. +- **Variants**: `nav` 24px geometry, `hero` 160px geometry with `HeroBrandMark` glow wrapper (soft `rgba(74,222,128,0.16)` glow tuned for the dark canvas). - **States**: inherited from the containing link or surface. - **Accessibility**: decorative mark uses `aria-hidden`; header link owns the accessible label. @@ -194,15 +204,15 @@ All spacing resolves to a 4px rhythm. Existing Tailwind values map to the same r - **Source**: `components/design-system/typography.tsx`. - **Components**: `Kicker`, `SectionHeading` (with the serif display option), `BodyText`, `GradientTitle`, `AccentBadge`, `InlineCode`. -- **Usage**: marketing sections, showcase titles, badges, and command/code snippets. `GradientTitle` uses the light-legible green gradient (`#15803d → #16a34a → #22c55e`). +- **Usage**: marketing sections, showcase titles, badges, and command/code snippets. `GradientTitle` uses the dark-legible green gradient (`#86efac → #4ade80 → #22c55e`). - **Motion**: typography itself does not animate; reveal behavior remains in CSS utilities. ### Surface Primitives - **Source**: `components/design-system/surfaces.tsx`. - **Components**: `SurfaceCard`, `AccentSurface`, `ShowcaseSurface`, `CommandCodeSurface`, `IconWell`, `FactList`, `CompactDotList`, `NumberedPoint`. -- **Usage**: white cards (`--card-base` + `--border-subtle` + soft shadow) for command cards, comparison cards, and numbered workflow rows. `ShowcaseSurface` stays an intentional dark accent band (`#101613`) for the Hephaestus showcase; `CommandCodeSurface` stays a dark code chip (`#101613` with `#dcfce7` text) — code surfaces are deliberately dark on the light canvas. -- **Depth**: border plus tonal shift, with showcase shadows only where already present. +- **Usage**: elevated dark cards (`--card-base` + `--border-subtle` + soft black shadow) for command cards, comparison cards, and numbered workflow rows. `ShowcaseSurface` is a slightly elevated showcase band (`#16191e` + `white/10` ring) for the Hephaestus showcase; `CommandCodeSurface` is an elevated code chip (`#1b1f24` with `#dcfce7` text + `white/10` ring) — code surfaces read as distinct raised layers on the dark canvas, never dissolving into it. +- **Depth**: hairline border plus tonal lift, with showcase shadows only where already present. ### Action Primitives @@ -214,7 +224,7 @@ All spacing resolves to a 4px rhythm. Existing Tailwind values map to the same r ### CodexWindow (ulw-demo) - **Source**: `components/site/ulw-demo/codex-window.tsx` (client leaf), scene data in `lib/ulw-demo-scenes.ts`. -- **Structure**: Codex Desktop window (adapter tokens above) on the light canvas: title bar with traffic lights and +- **Structure**: Codex Desktop window (adapter tokens above) on the dark canvas: title bar with traffic lights and `ULTRAWORK MODE ENABLED!` badge, transcript pane (command chip → status line → scene headline → scene body → 8 numbered workflow steps), right rail (Environment card, Subagents roster, narrative card, `goals.json / ledger.jsonl` card), composer bar, scene tab strip with play/pause. @@ -247,7 +257,7 @@ All spacing resolves to a 4px rhythm. Existing Tailwind values map to the same r - **Source**: `components/site/team-mode-section.tsx`, `components/site/ulw-research-section.tsx`; copy constants in `lib/site-config.ts`. - **Structure**: TeamMode shows a leader thread plus member thread cards (window chrome via the same - adapter tokens, on the light canvas) with a `Sent by Codex from another thread` note bubble; + adapter tokens, on the dark canvas) with a `Sent by Codex from another thread` note bubble; UlwResearch is a compact feature band composed from existing surface primitives. - **Copy rule**: every visible string traces to `plugins/omo/skills/teammode/SKILL.md`, `plugins/omo/skills/ulw-research/SKILL.md`, or `content/docs/*.md` via the copy ledger — no @@ -297,22 +307,23 @@ All spacing resolves to a 4px rhythm. Existing Tailwind values map to the same r ### Strategy -LazyCodex uses a mixed but constrained depth strategy: white cards with subtle borders and soft -shadows for everyday surfaces on the sage canvas, plus deliberate dark accent surfaces where code -or product chrome is shown. +LazyCodex uses a mixed but constrained depth strategy: elevated dark panels with hairline borders +and soft black shadows for everyday surfaces on the graphite canvas, plus the deliberate LIGHT +Codex window where real product chrome is shown. | Level | Treatment | Usage | | --- | --- | --- | -| Canvas | `--surface-base` (`#f4f6ee`) | Whole site background | -| Panel | `--card-base` / `--surface-panel` with `--border-subtle` and `rgba(16,25,20,0.04)` shadow | Cards, install bar, docs input | +| Canvas | `--surface-base` (`#0e1012`) | Whole site background | +| Panel | `--card-base` / `--surface-panel` with `--border-subtle` and `rgba(0,0,0,0.4)` shadow | Cards, install bar, docs input | | Accent panel | `--accent-primary` soft fill and border | Built-in skills, Lazy comparison, workflow code | -| Dark accent | `#101613` surface, ring, light-on-dark text | Code blocks, command surfaces, Hephaestus showcase, demo window dark theme | -| Hero | `--card-base`, layered `.card-gradient-*` mint/sage washes, large soft shadow | Landing hero card | +| Elevated dark chip | `#16191e` / `#1b1f24` / `#15181d` surface + `white/10` ring, light-on-dark text | Code blocks, command surfaces, Hephaestus showcase, demo window dark theme | +| Light accent | `.ulw-window` light adapter theme (`#ffffff` window on the dark ground) | Demo window default, Team Mode mock | +| Hero | `--card-base`, layered `.card-gradient-*` low-alpha green glows, large soft shadow | Landing hero card | ### Rules -- Hero card gradients are soft mint/sage radial washes on white (`rgba(34,197,94,0.10 → 0.04)`, `rgba(134,239,172,0.16)` on `--card-base`) — no dark stops anywhere. -- Dark surfaces appear only in the four sanctioned places above; the page canvas is always light. +- Hero card gradients are subtle radial green glows on the dark panel (`rgba(74,222,128,0.08 → 0.03)` families on `--card-base`) — low alpha only, no light stops anywhere. +- Light surfaces appear only inside the demo window's light adapter theme; the page canvas is always dark. Every other raised layer is an elevated dark surface: tonal lift + hairline ring. - Do not add purple-blue gradients; green is the only brand hue. - Do not replace the hero, the brand mark, or the demo window content with raster screenshots. - If a component pattern appears twice, it belongs in `components/design-system/` and this section. diff --git a/packages/web/app/icon.svg b/packages/web/app/icon.svg index 0781f15..388ab07 100644 --- a/packages/web/app/icon.svg +++ b/packages/web/app/icon.svg @@ -2,11 +2,11 @@ LazyCodex mark - - + + - + - + diff --git a/packages/web/app/layout.tsx b/packages/web/app/layout.tsx index 3e0870e..39121e2 100644 --- a/packages/web/app/layout.tsx +++ b/packages/web/app/layout.tsx @@ -12,8 +12,8 @@ const DESCRIPTION = export const viewport: Viewport = { width: "device-width", initialScale: 1, - themeColor: "#f4f6ee", - colorScheme: "light", + themeColor: "#0e1012", + colorScheme: "dark", } export const metadata: Metadata = { diff --git a/packages/web/app/manifest.ts b/packages/web/app/manifest.ts index 104d096..b410bda 100644 --- a/packages/web/app/manifest.ts +++ b/packages/web/app/manifest.ts @@ -7,8 +7,8 @@ export default function manifest(): MetadataRoute.Manifest { description: "Agent harness for complex codebases inside Codex.", start_url: "/", display: "standalone", - background_color: "#f4f6ee", - theme_color: "#15803d", + background_color: "#0e1012", + theme_color: "#0e1012", // No icons array: the browser favicon comes from the app/icon.svg file // convention; duplicating it here triggers a second eager favicon fetch // that lands on the Lantern LCP critical path. PWA installability isn't a diff --git a/packages/web/app/og-image-theme.ts b/packages/web/app/og-image-theme.ts index 38811a2..e3a8ed8 100644 --- a/packages/web/app/og-image-theme.ts +++ b/packages/web/app/og-image-theme.ts @@ -1,29 +1,29 @@ export const OG_SIZE = { width: 1200, height: 630 } as const export const OG_PALETTE = { - surfaceBase: "#f4f6ee", - cardBase: "#ffffff", + surfaceBase: "#0e1012", + cardBase: "#16181c", brandCore: "#22c55e", brandMid: "#16a34a", brandOuter: "#15803d", - textPrimary: "#101914", - textSecondary: "#3f4b43", - textSoft: "#14532d", - textMuted: "rgba(16, 25, 20, 0.75)", - accentCyan: "#15803d", - accentGlow: "#bbf7d0", - border: "rgba(16, 25, 20, 0.12)", + textPrimary: "#f7f8f8", + textSecondary: "#b4bcc8", + textSoft: "#86efac", + textMuted: "rgba(247, 248, 248, 0.78)", + accentCyan: "#4ade80", + accentGlow: "#166534", + border: "rgba(255, 255, 255, 0.12)", } as const export const OG_GRADIENTS = { - base: `radial-gradient(120% 100% at 60% 65%, rgba(134, 239, 172, 0.18) 0%, rgba(34, 197, 94, 0.10) 35%, rgba(22, 163, 74, 0.05) 70%, rgba(244, 246, 238, 0) 100%)`, + base: `radial-gradient(120% 100% at 60% 65%, rgba(74, 222, 128, 0.10) 0%, rgba(34, 197, 94, 0.06) 35%, rgba(34, 197, 94, 0.03) 70%, rgba(14, 16, 18, 0) 100%)`, beam: - "radial-gradient(55% 55% at 38% -8%, rgba(134,239,172,0.30) 0%, rgba(74,222,128,0.12) 35%, rgba(255,255,255,0) 65%), " + - "radial-gradient(32% 28% at 55% -5%, rgba(134,239,172,0.20) 0%, rgba(255,255,255,0) 70%)", + "radial-gradient(55% 55% at 38% -8%, rgba(74,222,128,0.16) 0%, rgba(74,222,128,0.06) 35%, rgba(14,16,18,0) 65%), " + + "radial-gradient(32% 28% at 55% -5%, rgba(74,222,128,0.10) 0%, rgba(14,16,18,0) 70%)", sheen: - "linear-gradient(118deg, transparent 18%, rgba(134,239,172,0.10) 26%, rgba(134,239,172,0.18) 30%, rgba(134,239,172,0.08) 35%, transparent 45%), " + - "linear-gradient(112deg, transparent 8%, rgba(74,222,128,0.08) 15%, transparent 28%)", + "linear-gradient(118deg, transparent 18%, rgba(74,222,128,0.06) 26%, rgba(74,222,128,0.10) 30%, rgba(74,222,128,0.05) 35%, transparent 45%), " + + "linear-gradient(112deg, transparent 8%, rgba(34,197,94,0.05) 15%, transparent 28%)", pools: - "radial-gradient(55% 50% at 8% 95%, rgba(34,197,94,0.14), transparent 70%), " + - "radial-gradient(45% 45% at 95% 40%, rgba(134,239,172,0.12), transparent 70%)", + "radial-gradient(55% 50% at 8% 95%, rgba(34,197,94,0.10), transparent 70%), " + + "radial-gradient(45% 45% at 95% 40%, rgba(74,222,128,0.08), transparent 70%)", } as const diff --git a/packages/web/app/styles/design-system.css b/packages/web/app/styles/design-system.css index 7edbd26..96feb2e 100644 --- a/packages/web/app/styles/design-system.css +++ b/packages/web/app/styles/design-system.css @@ -13,54 +13,55 @@ @layer base { :root { - /* Surfaces — light sage paper with a faint green undertone. */ - --surface-base: #f4f6ee; - --surface-0: #f4f6ee; - --surface-1: rgba(16, 25, 20, 0.03); - --surface-2: rgba(16, 25, 20, 0.05); - --surface-3: rgba(16, 25, 20, 0.08); - --card-base: #ffffff; - --surface-night: #e9ede0; - --surface-panel: #fbfcf7; - --surface-panel-alt: #f7faf2; - --surface-panel-deep: #f3f7ec; + /* Surfaces — deep graphite canvas, quiet and neutral (Linear-class dark). */ + --surface-base: #0e1012; + --surface-0: #0e1012; + --surface-1: rgba(255, 255, 255, 0.04); + --surface-2: rgba(255, 255, 255, 0.06); + --surface-3: rgba(255, 255, 255, 0.09); + --card-base: #16181c; + --surface-night: #0a0c0e; + --surface-panel: #121417; + --surface-panel-alt: #131519; + --surface-panel-deep: #101215; /* Brand — green core (green-500 family), clearly green not teal. */ --brand-core: #22c55e; --brand-mid: #16a34a; --brand-outer: #15803d; - /* Text — deep green-tinted inks, AA on the sage canvas. */ - --text-primary: #101914; - --text-secondary: #3f4b43; - --text-tertiary: #55645b; - --text-muted: rgba(16, 25, 20, 0.75); - --text-soft: #14532d; - - /* Accent — AA-legible forest green on light ground, including the tinted - chip fills (#e2ede0/#e9f0e5 family) where #15803d only reached ~4.2:1. - --accent-mint is for fills/decoration ONLY, never text on light surfaces. */ - --accent-primary: #166534; - --accent-primary-soft: rgba(21, 128, 61, 0.08); - --accent-primary-border: rgba(21, 128, 61, 0.28); - --accent-cyan: #15803d; + /* Text — near-white inks, AA on the graphite canvas AND on --card-base. */ + --text-primary: #f7f8f8; + --text-secondary: #b4bcc8; + --text-tertiary: #98a1ab; + --text-muted: rgba(247, 248, 248, 0.78); + --text-soft: #86efac; + + /* Accent — green-400 on dark ground: AA (>= 4.5:1) on the canvas, on + --card-base, and on the elevated code chips (#1b1f24 family). + --accent-mint stays a fill/decoration hue by rule, though it is also + AA-legible on every dark surface here. */ + --accent-primary: #4ade80; + --accent-primary-soft: rgba(74, 222, 128, 0.1); + --accent-primary-border: rgba(74, 222, 128, 0.32); + --accent-cyan: #4ade80; --accent-teal: #22c55e; --accent-mint: #86efac; - --accent-glow: #14532d; + --accent-glow: #bbf7d0; - /* Borders. */ - --border-subtle: rgba(16, 25, 20, 0.10); - --border-default: rgba(16, 25, 20, 0.16); + /* Borders — hairline white washes. */ + --border-subtle: rgba(255, 255, 255, 0.08); + --border-default: rgba(255, 255, 255, 0.12); - /* Status — AA on light. */ - --status-success: #15803d; - --status-warning: #a16207; - --status-error: #b91c1c; + /* Status — AA on dark. */ + --status-success: #4ade80; + --status-warning: #fbbf24; + --status-error: #f87171; } html { background-color: var(--surface-base); - color-scheme: light; + color-scheme: dark; } body { @@ -73,8 +74,8 @@ } ::selection { - background-color: #bbf7d0; - color: #14532d; + background-color: #14532d; + color: #dcfce7; } a { @@ -89,7 +90,8 @@ /* Codex window adapter — the surface tokens the ulw-demo / team-mode window mocks consume (see DESIGN.md § Codex window adapter tokens). - Default theme: LIGHT, faithful to the Codex desktop app. */ + Default theme: LIGHT, faithful to the Codex desktop app frames — the + light window on the dark canvas is the page's hero contrast. */ .ulw-window { --codex-window-bg: #ffffff; --codex-window-chrome: #f6f7f6; @@ -121,24 +123,25 @@ } /* Dark window variant — toggled via the role=group window-theme switch - (sets data-window-theme on .ulw-window). Values derive from the - retired dark site palette (#0E1411 family). */ + (sets data-window-theme on .ulw-window). Slightly LIGHTER than the page + canvas (#0e1012) with a stronger hairline ring so the window still reads + as a distinct elevated layer instead of dissolving into the page. */ [data-window-theme="dark"] { - --codex-window-bg: #101613; - --codex-window-chrome: #0e1411; - --codex-window-border: rgba(232, 240, 234, 0.14); - --codex-window-text: #e8f0ea; - --codex-window-text-soft: #b8c2bc; - --codex-window-chip: rgba(232, 240, 234, 0.07); + --codex-window-bg: #1a1d22; + --codex-window-chrome: #15181c; + --codex-window-border: rgba(255, 255, 255, 0.18); + --codex-window-text: #eef1f4; + --codex-window-text-soft: #a9b2bd; + --codex-window-chip: rgba(255, 255, 255, 0.07); --codex-window-active: rgba(74, 222, 128, 0.16); - --codex-window-active-border: rgba(74, 222, 128, 0.32); + --codex-window-active-border: rgba(74, 222, 128, 0.38); --codex-window-accent: #4ade80; --codex-window-glyph-text: #0a0c0b; --codex-window-traffic-red: #f87171; --codex-window-traffic-amber: #fbbf24; --codex-window-traffic-green: #34d399; - /* Lane glyphs re-tuned >= 3:1 against the dark window ground + /* Lane glyphs re-tuned >= 3:1 against the elevated dark window ground (same hue identity per lane, lifted two Tailwind stops). */ --lane-root: #2dd4bf; --lane-explore: #60a5fa; @@ -154,37 +157,38 @@ } @layer utilities { - /* Hero-card washes — soft mint/sage radials composited on the white card - base. Light identity: alpha washes over var(--card-base); no near-black - stops, no screen blending (which needs a dark ground). */ + /* Hero-card washes — subtle radial green glows composited on the elevated + dark panel base. Dark identity: low-alpha green over var(--card-base); + no light stops, no white washes — the glow stays quiet. */ .card-gradient-base { background: - radial-gradient(120% 100% at 60% 65%, rgba(34, 197, 94, 0.10) 0%, rgba(34, 197, 94, 0.07) 35%, rgba(34, 197, 94, 0.04) 70%, rgba(134, 239, 172, 0.03) 100%), + radial-gradient(120% 100% at 60% 65%, rgba(74, 222, 128, 0.08) 0%, rgba(74, 222, 128, 0.05) 35%, rgba(34, 197, 94, 0.03) 70%, rgba(34, 197, 94, 0) 100%), var(--card-base); } .card-gradient-beam { background: - radial-gradient(55% 55% at 38% -8%, rgba(134, 239, 172, 0.30) 0%, rgba(134, 239, 172, 0.12) 35%, rgba(134, 239, 172, 0) 65%), - radial-gradient(32% 28% at 55% -5%, rgba(134, 239, 172, 0.16) 0%, rgba(134, 239, 172, 0) 70%); + radial-gradient(55% 55% at 38% -8%, rgba(74, 222, 128, 0.14) 0%, rgba(74, 222, 128, 0.06) 35%, rgba(74, 222, 128, 0) 65%), + radial-gradient(32% 28% at 55% -5%, rgba(74, 222, 128, 0.08) 0%, rgba(74, 222, 128, 0) 70%); } .card-gradient-sheen { background: - linear-gradient(118deg, transparent 18%, rgba(134, 239, 172, 0.10) 26%, rgba(134, 239, 172, 0.16) 30%, rgba(134, 239, 172, 0.08) 35%, transparent 45%), - linear-gradient(112deg, transparent 8%, rgba(34, 197, 94, 0.06) 15%, transparent 28%); + linear-gradient(118deg, transparent 18%, rgba(74, 222, 128, 0.06) 26%, rgba(74, 222, 128, 0.1) 30%, rgba(74, 222, 128, 0.05) 35%, transparent 45%), + linear-gradient(112deg, transparent 8%, rgba(34, 197, 94, 0.04) 15%, transparent 28%); filter: blur(20px); opacity: 0.85; } .card-gradient-pools { background: - radial-gradient(55% 50% at 8% 95%, rgba(34, 197, 94, 0.12), transparent 70%), - radial-gradient(45% 45% at 95% 40%, rgba(134, 239, 172, 0.16), transparent 70%); + radial-gradient(55% 50% at 8% 95%, rgba(34, 197, 94, 0.09), transparent 70%), + radial-gradient(45% 45% at 95% 40%, rgba(74, 222, 128, 0.07), transparent 70%); } /* ampcode-style dotted vertical column rules: every column after the - first gets a dotted left rule (MarketingRuleGrid ruleStyle="dotted"). */ + first gets a dotted left rule (MarketingRuleGrid ruleStyle="dotted"). + The rule color flips with --border-subtle (hairline white on dark). */ .rule-grid-dotted > * + * { border-left: 1px dotted var(--border-subtle); } diff --git a/packages/web/app/styles/docs.css b/packages/web/app/styles/docs.css index 66d446d..a12c8b9 100644 --- a/packages/web/app/styles/docs.css +++ b/packages/web/app/styles/docs.css @@ -309,8 +309,10 @@ font-size: 0.85em; } +/* Code blocks blend with the dark docs surface as slightly elevated + panels — hairline border keeps them a distinct layer. */ .docs-content pre { - background: #0c100e; + background: #15181d; border: 1px solid var(--border-subtle); padding: 1.1rem 1.25rem; border-radius: 10px; diff --git a/packages/web/components/design-system/actions.tsx b/packages/web/components/design-system/actions.tsx index 46c147d..901d0e7 100644 --- a/packages/web/components/design-system/actions.tsx +++ b/packages/web/components/design-system/actions.tsx @@ -38,7 +38,7 @@ export function LinkAction({ export function GlowActionFrame({ children }: { readonly children: ReactNode }): JSX.Element { return (
-
+
{children}
) diff --git a/packages/web/components/design-system/brand-mark.tsx b/packages/web/components/design-system/brand-mark.tsx index 9c5823b..aab2413 100644 --- a/packages/web/components/design-system/brand-mark.tsx +++ b/packages/web/components/design-system/brand-mark.tsx @@ -75,7 +75,7 @@ export function HeroBrandMark(): JSX.Element { className="absolute inset-0 rounded-[28px] opacity-60 blur-2xl" style={{ background: - "radial-gradient(circle at 50% 50%, rgba(21,128,61,0.25) 0%, transparent 70%)", + "radial-gradient(circle at 50% 50%, rgba(74,222,128,0.16) 0%, transparent 70%)", }} aria-hidden="true" /> diff --git a/packages/web/components/design-system/surfaces.tsx b/packages/web/components/design-system/surfaces.tsx index f34f3b2..9e8213d 100644 --- a/packages/web/components/design-system/surfaces.tsx +++ b/packages/web/components/design-system/surfaces.tsx @@ -21,7 +21,7 @@ export function SurfaceCard({ children, className }: ChildrenProps): JSX.Element return (
@@ -47,7 +47,7 @@ export function ShowcaseSurface({ children, className }: ChildrenProps): JSX.Ele return (
@@ -58,7 +58,7 @@ export function ShowcaseSurface({ children, className }: ChildrenProps): JSX.Ele } export function CommandCodeSurface({ children }: ChildrenProps): JSX.Element { - return
{children}
+ return
{children}
} export function IconWell({ children }: ChildrenProps): JSX.Element { @@ -112,7 +112,7 @@ export function CompactDotList({ export function NumberedPoint({ index, label, text }: NumberedPointProps): JSX.Element { return ( -
+
{String(index + 1).padStart(2, "0")} diff --git a/packages/web/components/design-system/typography.tsx b/packages/web/components/design-system/typography.tsx index 692738e..d7f2894 100644 --- a/packages/web/components/design-system/typography.tsx +++ b/packages/web/components/design-system/typography.tsx @@ -2,7 +2,7 @@ import type { CSSProperties, JSX, ReactNode } from "react" import { cx } from "./utils" const gradientTextStyle = { - background: "linear-gradient(180deg, #15803d 0%, #16a34a 50%, #22c55e 100%)", + background: "linear-gradient(180deg, #86efac 0%, #4ade80 50%, #22c55e 100%)", WebkitBackgroundClip: "text", backgroundClip: "text", color: "transparent", diff --git a/packages/web/components/site/hephaestus-section.tsx b/packages/web/components/site/hephaestus-section.tsx index 0baeb73..5c5052e 100644 --- a/packages/web/components/site/hephaestus-section.tsx +++ b/packages/web/components/site/hephaestus-section.tsx @@ -52,13 +52,12 @@ export function HephaestusSection(): JSX.Element {
- {/* Hephaestus — the ported agent. This ShowcaseSurface is the ONE - intentional dark marketing band on the light canvas (DESIGN.md - contrast anchor). The light-canvas ink tokens are re-scoped here to - the dark-window text family (design-system.css dark window block) so - every inner primitive reads light-on-dark at AA: #e8f0ea/#b8c2bc are - ~15.7:1/~10:1 and #4ade80 ~10.4:1 against the #101613 band. */} - + {/* Hephaestus — the ported agent. This ShowcaseSurface is an elevated + showcase band (#16191e + hairline ring) on the dark canvas. The + global dark ink tokens already read AA here: #f7f8f8/#b4bcc8 are + ~16:1/~8.8:1 and #4ade80 ~9.5:1 against the #16191e band, so no + per-band token re-scope is needed. */} +
{hephaestus.badge}
diff --git a/packages/web/components/site/hero.tsx b/packages/web/components/site/hero.tsx index 20b8fad..7e0f8ef 100644 --- a/packages/web/components/site/hero.tsx +++ b/packages/web/components/site/hero.tsx @@ -5,8 +5,8 @@ import { SITE_CONFIG } from "../../lib/site-config" export function Hero(): JSX.Element { return (
- {/* Open light canvas — no card, no gradient washes. The declarative - hero text sits directly on the sage ground so it stays the LCP + {/* Open dark canvas — no card, no gradient washes. The declarative + hero text sits directly on the graphite ground so it stays the LCP element and paints at FCP; the demo window below carries the visual weight. Compact by design: the block stays under ~60vh at 1440x900 so the demo window's top edge is visible in the first From cab09be64b459331159f9cc85efe2252b51a18b2 Mon Sep 17 00:00:00 2001 From: YeonGyu-Kim Date: Fri, 3 Jul 2026 09:34:54 +0900 Subject: [PATCH 17/35] feat(demo): rebuild the codex window to the real app anatomy Grounded in frames extracted from the desktop-app recordings: left sidebar (nav, pinned session, projects list that doubles as scene navigation), document-flow transcript (title bar, tool rows, step pill, pursuing-goal chip, composer), subagents panel. The external scene-tab strip is removed; playback is a screen-recording feel with a thin progress bar and in-chrome pause/replay/theme controls. e2e contract updated same-or-stronger (shift-free jumps, reduced-motion play affordance, sidebar collapse at 390px). Co-Authored-By: Claude Fable 5 --- packages/web/app/styles/ulw-demo-app.css | 221 +++++++++ packages/web/app/styles/ulw-demo-panel.css | 145 ++++++ .../web/app/styles/ulw-demo-transcript.css | 170 +++++++ packages/web/app/styles/ulw-demo.css | 420 ++---------------- .../components/site/ulw-demo/codex-window.tsx | 130 ++---- .../site/ulw-demo/window-chrome.tsx | 132 ++++++ .../components/site/ulw-demo/window-icons.tsx | 53 +++ .../components/site/ulw-demo/window-panes.tsx | 158 +++---- packages/web/e2e/ulw-demo.spec.ts | 176 +++++--- 9 files changed, 975 insertions(+), 630 deletions(-) create mode 100644 packages/web/app/styles/ulw-demo-app.css create mode 100644 packages/web/app/styles/ulw-demo-panel.css create mode 100644 packages/web/app/styles/ulw-demo-transcript.css create mode 100644 packages/web/components/site/ulw-demo/window-chrome.tsx create mode 100644 packages/web/components/site/ulw-demo/window-icons.tsx diff --git a/packages/web/app/styles/ulw-demo-app.css b/packages/web/app/styles/ulw-demo-app.css new file mode 100644 index 0000000..d5b3c89 --- /dev/null +++ b/packages/web/app/styles/ulw-demo-app.css @@ -0,0 +1,221 @@ +/* App-shell chrome for the interactive Ultrawork demo — the .ulw-app-* layer + rebuilt to the real Codex desktop anatomy (.omo/reference/app-frames/ + creation-03.png): sidebar session groups, per-session title bar with the + playback cluster, transcript document flow, decorative composer. + Split from ulw-demo.css to keep files under the size limit. + Motion: transform/opacity/color only. Zero outer layout shift: every + scene-variable region is single-line-with-code-scroll or min-height + reserved, so the window's outer box never changes between scenes. */ + +@layer components { + .ulw-window.ulw-app { + max-width: 1120px; + min-height: 680px; + display: flex; + flex-direction: column; + } + + /* Thin per-scene progress strip (screen-recording metaphor). The fill is + transform-only and paused via animation-play-state; the span remounts + per scene so the bar restarts on each beat. */ + .ulw-app-progress { + height: 3px; + background: var(--codex-window-chip); + flex-shrink: 0; + } + + .ulw-app-progress span { + display: block; + height: 100%; + width: 100%; + background: var(--codex-window-accent); + transform: scaleX(0); + transform-origin: left center; + animation: ulw-progress-fill 7000ms linear forwards; + animation-play-state: paused; + } + + .ulw-app-progress span[data-playing="true"] { + animation-play-state: running; + } + + @keyframes ulw-progress-fill { + to { + transform: scaleX(1); + } + } + + .ulw-app-frame { + flex: 1; + display: grid; + grid-template-columns: 212px minmax(0, 1fr) 264px; + min-height: 0; + } + + /* ---- Left sidebar: traffic lights, nav list, Pinned/Projects groups. */ + + .ulw-app-sidebar { + display: flex; + flex-direction: column; + gap: 14px; + padding: 14px 10px; + background: var(--codex-window-chrome); + border-right: 1px solid var(--codex-window-border); + min-width: 0; + overflow: hidden; + } + + .ulw-app-sidebar .ulw-traffic { + padding-left: 4px; + } + + .ulw-app-nav, + .ulw-app-group { + display: flex; + flex-direction: column; + gap: 1px; + } + + .ulw-app-row { + display: flex; + align-items: center; + gap: 8px; + padding: 5px 8px; + border-radius: 7px; + font-size: 12px; + color: var(--codex-window-text-soft); + white-space: nowrap; + overflow: hidden; + } + + .ulw-app-group-label { + padding: 6px 8px 2px; + font-size: 11px; + color: var(--codex-window-text-soft); + } + + /* Session rows double as scene navigation (app-native tab replacement). */ + .ulw-app-session { + display: block; + width: 100%; + text-align: left; + padding: 5px 8px 5px 30px; + border-radius: 7px; + font-size: 12px; + color: var(--codex-window-text-soft); + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + transition: background-color 150ms ease, color 150ms ease; + } + + .ulw-app-session:hover { + background: var(--codex-window-chip); + color: var(--codex-window-text); + } + + .ulw-app-session[aria-current="true"] { + background: var(--codex-window-active); + color: var(--codex-window-text); + font-weight: 600; + } + + .ulw-app-session:focus-visible, + .ulw-app-control:focus-visible { + outline: 2px solid var(--codex-window-accent); + outline-offset: 1px; + } + + .ulw-app-showmore { + padding-left: 30px; + } + + /* ---- Main column: title bar with playback controls, transcript, footer. */ + + .ulw-app-main { + display: flex; + flex-direction: column; + min-width: 0; + min-height: 0; + } + + .ulw-app-titlebar { + display: flex; + align-items: center; + gap: 8px; + padding: 9px 16px; + border-bottom: 1px solid var(--codex-window-border); + flex-shrink: 0; + } + + .ulw-app-title { + font-size: 13px; + font-weight: 600; + color: var(--codex-window-text); + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + } + + .ulw-app-title-dots { + color: var(--codex-window-text-soft); + } + + .ulw-app-controls { + margin-left: auto; + display: flex; + gap: 6px; + } + + .ulw-app-control { + display: inline-flex; + align-items: center; + justify-content: center; + width: 26px; + height: 26px; + border-radius: 7px; + border: 1px solid var(--codex-window-border); + color: var(--codex-window-text-soft); + transition: color 150ms ease, background-color 150ms ease, border-color 150ms ease; + } + + .ulw-app-control:hover { + background: var(--codex-window-chip); + color: var(--codex-window-text); + } + + .ulw-app-control[aria-pressed="true"] { + color: var(--codex-window-accent); + border-color: var(--codex-window-active-border); + background: var(--codex-window-active); + } + + .ulw-icon { + flex-shrink: 0; + } + + @media (max-width: 768px) { + .ulw-window.ulw-app { + min-height: 560px; + } + + .ulw-app-frame { + grid-template-columns: 1fr; + } + + .ulw-app-sidebar { + display: none; + } + } + + @media (prefers-reduced-motion: reduce) { + .ulw-app-progress span { + animation: none; + } + + .ulw-app-session, + .ulw-app-control { + transition: none; + } + } +} diff --git a/packages/web/app/styles/ulw-demo-panel.css b/packages/web/app/styles/ulw-demo-panel.css new file mode 100644 index 0000000..8be9245 --- /dev/null +++ b/packages/web/app/styles/ulw-demo-panel.css @@ -0,0 +1,145 @@ +/* Right-hand panel for the interactive Ultrawork demo window — Environment + and Subagents groups styled after the app frames (subagents-03.png and + the desktop-app reference). Keeps the full 13-worker roster: delegation + made observable is the differentiator. Imported by ulw-demo.css (split + for the file-size limit). */ + +@layer components { + /* ---- Right panel (subagents-03.png: Environment / Subagents groups). */ + + .ulw-side { + border-left: 1px solid var(--codex-window-border); + background: color-mix(in srgb, var(--codex-window-chrome) 55%, var(--codex-window-bg)); + padding: 16px 14px; + display: flex; + flex-direction: column; + gap: 12px; + min-width: 0; + } + + .ulw-side-card { + border: 1px solid var(--codex-window-border); + border-radius: 10px; + background: var(--codex-window-bg); + padding: 10px 12px; + display: flex; + flex-direction: column; + gap: 6px; + } + + .ulw-side-heading { + font-family: var(--font-mono); + font-size: 10.5px; + text-transform: uppercase; + letter-spacing: 0.08em; + color: var(--codex-window-text-soft); + } + + .ulw-side-row { + display: flex; + justify-content: space-between; + gap: 8px; + font-family: var(--font-mono); + font-size: 11px; + color: var(--codex-window-text); + } + + .ulw-side-row span:last-child { + color: var(--codex-window-text-soft); + } + + .ulw-workers { + display: flex; + flex-direction: column; + gap: 3px; + } + + .ulw-worker { + display: flex; + align-items: center; + gap: 8px; + padding: 4px 8px; + border-radius: 7px; + font-size: 11.5px; + color: var(--codex-window-text-soft); + transition: color 200ms ease, background-color 200ms ease; + } + + .ulw-worker[data-live="true"] { + background: var(--codex-window-active); + color: var(--codex-window-text); + font-weight: 500; + } + + .ulw-worker-name { + flex: 1; + min-width: 0; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + } + + .ulw-worker small { + font-family: var(--font-mono); + font-size: 9.5px; + color: var(--codex-window-text-soft); + white-space: nowrap; + } + + .ulw-worker-glyph { + width: 16px; + height: 16px; + border-radius: 4px; + display: inline-flex; + align-items: center; + justify-content: center; + font-family: var(--font-mono); + font-size: 9px; + font-weight: 700; + color: var(--codex-window-glyph-text); + flex-shrink: 0; + } + + /* Lane identity colors are per-window-theme custom props defined next to + the --codex-window-* adapter blocks (design-system.css). */ + .ulw-worker-glyph[data-lane="root"] { background: var(--lane-root); } + .ulw-worker-glyph[data-lane="explore"] { background: var(--lane-explore); } + .ulw-worker-glyph[data-lane="library"] { background: var(--lane-library); } + .ulw-worker-glyph[data-lane="plan"] { background: var(--lane-plan); } + .ulw-worker-glyph[data-lane="todo"] { background: var(--lane-todo); } + .ulw-worker-glyph[data-lane="execute"] { background: var(--lane-execute); } + .ulw-worker-glyph[data-lane="test"] { background: var(--lane-test); } + .ulw-worker-glyph[data-lane="qa"] { background: var(--lane-qa); } + .ulw-worker-glyph[data-lane="review"] { background: var(--lane-review); } + .ulw-worker-glyph[data-lane="continuation"] { background: var(--lane-continuation); } + + .ulw-app-side-note { + /* Reserve for the tallest sideTitle+sideBody pair (zero layout shift): + the tallest measured scene is ~112px at the 264px desktop column. */ + min-height: 126px; + } + + .ulw-app-side-note strong { + font-size: 12px; + font-weight: 600; + } + + .ulw-app-side-note span { + font-size: 11px; + line-height: 1.45; + color: var(--codex-window-text-soft); + } + + @media (max-width: 768px) { + .ulw-side { + border-left: none; + border-top: 1px solid var(--codex-window-border); + } + } + + @media (prefers-reduced-motion: reduce) { + .ulw-worker { + transition: none; + } + } +} diff --git a/packages/web/app/styles/ulw-demo-transcript.css b/packages/web/app/styles/ulw-demo-transcript.css new file mode 100644 index 0000000..9d3ce31 --- /dev/null +++ b/packages/web/app/styles/ulw-demo-transcript.css @@ -0,0 +1,170 @@ +/* Transcript + footer layer for the interactive Ultrawork demo window — + document flow faithful to the app frames (creation-03.png): user command + bubble, prose, tool-activity rows, inline code chip, then the Step pill, + Pursuing-goal row, and the decorative composer. Imported by ulw-demo.css + (split for the file-size limit). Scene-variable regions are single-line + code-scroll or min-height reserved: zero outer layout shift. */ + +@layer components { + /* ---- Transcript document flow. */ + + .ulw-app-transcript { + flex: 1; + display: flex; + flex-direction: column; + gap: 12px; + padding: 16px 22px 8px; + min-height: 0; + overflow: hidden; + } + + .ulw-app-user { + align-self: flex-end; + max-width: 92%; + min-width: 0; + background: var(--codex-window-chip); + border-radius: 12px; + padding: 8px 12px; + } + + .ulw-app-user code { + display: block; + font-family: var(--font-mono); + font-size: 11.5px; + white-space: nowrap; + /* Horizontal scroll is allowed ONLY inside code rows. */ + overflow-x: auto; + } + + .ulw-app-tools { + display: flex; + flex-direction: column; + gap: 5px; + /* Reserve three ledger rows so scene swaps stay shift-free. */ + min-height: 86px; + } + + .ulw-app-tool { + display: flex; + align-items: center; + gap: 8px; + font-family: var(--font-mono); + font-size: 11px; + color: var(--codex-window-text-soft); + } + + .ulw-app-tool span { + min-width: 0; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + } + + .ulw-app-code { + background: var(--codex-window-chip); + border-radius: 8px; + padding: 7px 10px; + min-width: 0; + } + + .ulw-app-code code { + display: block; + font-family: var(--font-mono); + font-size: 11px; + color: var(--codex-window-text-soft); + white-space: nowrap; + /* Horizontal scroll is allowed ONLY inside code rows. */ + overflow-x: auto; + } + + /* ---- Footer: Step pill, Pursuing-goal row, decorative composer. */ + + .ulw-app-footer { + display: flex; + flex-direction: column; + gap: 10px; + padding: 4px 22px 16px; + flex-shrink: 0; + } + + .ulw-app-step { + align-self: center; + font-family: var(--font-mono); + font-size: 10.5px; + padding: 3px 10px; + border-radius: 999px; + border: 1px solid var(--codex-window-border); + color: var(--codex-window-text-soft); + } + + .ulw-app-goal { + display: flex; + align-items: center; + gap: 8px; + border: 1px solid var(--codex-window-border); + border-radius: 10px; + padding: 7px 12px; + font-size: 11.5px; + color: var(--codex-window-text-soft); + } + + .ulw-app-goal strong { + font-weight: 600; + color: var(--codex-window-text); + white-space: nowrap; + } + + .ulw-app-goal span { + flex: 1; + min-width: 0; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + } + + .ulw-app-composer { + border: 1px solid var(--codex-window-border); + border-radius: 14px; + padding: 10px 12px; + display: flex; + flex-direction: column; + gap: 10px; + background: var(--codex-window-bg); + } + + .ulw-app-composer-placeholder { + font-size: 13px; + color: var(--codex-window-text-soft); + } + + .ulw-app-composer-row { + display: flex; + align-items: center; + gap: 10px; + } + + .ulw-app-composer-chip { + display: inline-flex; + align-items: center; + gap: 5px; + font-family: var(--font-mono); + font-size: 11px; + color: var(--codex-window-text-soft); + white-space: nowrap; + } + + .ulw-app-composer-grow { + flex: 1; + } + + .ulw-app-composer-send { + display: inline-flex; + align-items: center; + justify-content: center; + width: 24px; + height: 24px; + border-radius: 999px; + background: var(--codex-window-text); + color: var(--codex-window-bg); + } +} diff --git a/packages/web/app/styles/ulw-demo.css b/packages/web/app/styles/ulw-demo.css index 70d9b01..a92729f 100644 --- a/packages/web/app/styles/ulw-demo.css +++ b/packages/web/app/styles/ulw-demo.css @@ -1,15 +1,19 @@ -/* Interactive Ultrawork demo — Codex Desktop window on the light sage canvas, - themed light (default) or dark via data-window-theme on .ulw-window. - Tokens: the --codex-window-* adapter palette (DESIGN.md § Codex window adapter). - Motion: transform/opacity/color only; autoplay + caret disabled under - prefers-reduced-motion (DESIGN.md § ulw-demo timeline). */ +/* Interactive Ultrawork demo — Codex Desktop window on the site canvas, + themed light (default, faithful to the app frames) or dark via + data-window-theme on .ulw-window. Tokens: the --codex-window-* adapter + palette (DESIGN.md § Codex window adapter). The .ulw-app-* window-shell + layer lives in ulw-demo-app.css (split for the file-size limit). + .ulw-window/.ulw-titlebar/.ulw-traffic/.ulw-window-tab(s) below are ALSO + used by team-mode-section.tsx — keep them stable. */ + +@import "./ulw-demo-app.css"; +@import "./ulw-demo-transcript.css"; +@import "./ulw-demo-panel.css"; @layer components { .ulw-window { width: 100%; max-width: 1060px; - /* Fixed height floor per breakpoint: autoplay scene swaps must cause - ZERO layout shift below the window. */ min-height: 560px; border-radius: 14px; border: 1px solid var(--border-default); @@ -22,46 +26,13 @@ text-align: left; } - .ulw-menubar, - .ulw-titlebar, - .ulw-composer { - background: var(--codex-window-chrome); - border-bottom: 1px solid var(--codex-window-border); - } - - .ulw-menubar { - display: flex; - justify-content: space-between; - align-items: center; - gap: 12px; - padding: 6px 14px; - font-family: var(--font-mono); - font-size: 11px; - color: var(--codex-window-text-soft); - } - - .ulw-menubar strong { - color: var(--codex-window-text); - } - - .ulw-menubar-left { - display: flex; - gap: 12px; - min-width: 0; - } - - .ulw-mode-flag { - color: var(--codex-window-accent); - font-weight: 600; - letter-spacing: 0.04em; - white-space: nowrap; - } - .ulw-titlebar { display: flex; align-items: center; gap: 14px; padding: 8px 14px; + background: var(--codex-window-chrome); + border-bottom: 1px solid var(--codex-window-border); } .ulw-traffic { @@ -102,75 +73,46 @@ color: var(--codex-window-text); } - .ulw-content { - display: grid; - grid-template-columns: minmax(0, 1fr) 272px; - } - - .ulw-transcript { - padding: 22px 24px 18px; - display: flex; - flex-direction: column; - gap: 14px; - min-width: 0; - } + /* ---- Scene transcript content (strings from lib/ulw-demo-scenes.ts). */ - .ulw-command { - display: flex; - align-items: baseline; - gap: 8px; - padding: 8px 12px; - border-radius: 8px; - background: var(--codex-window-chip); + .ulw-mode-flag { font-family: var(--font-mono); - font-size: 12px; - overflow-wrap: anywhere; - /* Horizontal scroll is allowed ONLY inside code rows. */ - overflow-x: auto; - } - - .ulw-command > span { + font-size: 11px; color: var(--codex-window-accent); + font-weight: 600; + letter-spacing: 0.04em; } - .ulw-caret { - display: inline-block; - width: 7px; - height: 13px; - margin-left: 2px; - background: var(--codex-window-accent); - vertical-align: text-bottom; - animation: ulw-caret-blink 1.1s steps(2, start) infinite; - } - - @keyframes ulw-caret-blink { - to { opacity: 0; } + .ulw-scene-status { + font-family: var(--font-mono); + font-size: 11px; + letter-spacing: 0.02em; + color: var(--codex-window-text-soft); + /* Single line + reserve: scene swaps must not move the layout below. */ + min-height: 17px; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; } .ulw-scene-copy { display: flex; flex-direction: column; gap: 6px; + /* Reserve for the tallest headline+body pair: zero layout shift. */ min-height: 112px; } - .ulw-scene-status { - font-family: var(--font-mono); - font-size: 11px; - letter-spacing: 0.02em; - color: var(--codex-window-text-soft); - } - .ulw-scene-copy h3 { - font-size: clamp(20px, 2.4vw, 28px); + font-size: 19px; font-weight: 650; letter-spacing: -0.02em; - line-height: 1.15; + line-height: 1.2; text-wrap: balance; } .ulw-scene-copy p { - font-size: 13.5px; + font-size: 13px; line-height: 1.55; color: var(--codex-window-text-soft); max-width: 62ch; @@ -191,292 +133,9 @@ } } - .ulw-steps { - display: flex; - flex-direction: column; - gap: 6px; - } - - .ulw-step { - display: flex; - gap: 10px; - align-items: baseline; - border: 1px solid transparent; - border-radius: 9px; - padding: 7px 10px; - transition: background-color 200ms ease, border-color 200ms ease; - } - - .ulw-step[data-active="true"] { - background: var(--codex-window-active); - border-color: var(--codex-window-active-border); - } - - .ulw-step[data-active="true"] strong { - color: var(--codex-window-text); - } - - .ulw-step-number { - font-family: var(--font-mono); - font-size: 10.5px; - color: var(--codex-window-accent); - padding-top: 2px; - } - - .ulw-step strong { - font-size: 12.5px; - font-weight: 600; - color: var(--codex-window-text-soft); - transition: color 200ms ease; - } - - .ulw-step p { - font-size: 11.5px; - line-height: 1.45; - color: var(--codex-window-text-soft); - } - - .ulw-proofs { - display: flex; - flex-wrap: wrap; - gap: 6px; - } - - .ulw-proof { - font-family: var(--font-mono); - font-size: 10.5px; - padding: 4px 9px; - border-radius: 7px; - border: 1px solid var(--codex-window-border); - color: var(--codex-window-text-soft); - transition: color 200ms ease, background-color 200ms ease, border-color 200ms ease; - } - - .ulw-proof[data-active="true"] { - background: var(--codex-window-active); - border-color: var(--codex-window-active-border); - color: var(--codex-window-accent); - font-weight: 600; - } - - .ulw-composer { - display: flex; - align-items: center; - gap: 10px; - padding: 9px 14px; - border-top: 1px solid var(--codex-window-border); - border-bottom: none; - font-size: 12px; - color: var(--codex-window-text-soft); - min-width: 0; - } - - .ulw-composer-text { - flex: 1; - min-width: 0; - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; - } - - .ulw-composer-meta { - font-family: var(--font-mono); - font-size: 10.5px; - white-space: nowrap; - } - - .ulw-composer-send { - width: 22px; - height: 22px; - border-radius: 999px; - background: var(--codex-window-text); - flex-shrink: 0; - } - - .ulw-side { - border-left: 1px solid var(--codex-window-border); - background: color-mix(in srgb, var(--codex-window-chrome) 55%, var(--codex-window-bg)); - padding: 16px 14px; - display: flex; - flex-direction: column; - gap: 12px; - min-width: 0; - } - - .ulw-side-card { - border: 1px solid var(--codex-window-border); - border-radius: 10px; - background: var(--codex-window-bg); - padding: 10px 12px; - display: flex; - flex-direction: column; - gap: 6px; - } - - .ulw-side-heading { - font-family: var(--font-mono); - font-size: 10.5px; - text-transform: uppercase; - letter-spacing: 0.08em; - color: var(--codex-window-text-soft); - } - - .ulw-side-row { - display: flex; - justify-content: space-between; - gap: 8px; - font-family: var(--font-mono); - font-size: 11px; - color: var(--codex-window-text); - } - - .ulw-side-row span:last-child { - color: var(--codex-window-text-soft); - } - - .ulw-workers { - display: flex; - flex-direction: column; - gap: 3px; - } - - .ulw-worker { - display: flex; - align-items: center; - gap: 8px; - padding: 4px 8px; - border-radius: 7px; - font-size: 11.5px; - color: var(--codex-window-text-soft); - transition: color 200ms ease, background-color 200ms ease; - } - - .ulw-worker[data-live="true"] { - background: var(--codex-window-active); - color: var(--codex-window-text); - font-weight: 500; - } - - .ulw-worker-name { - flex: 1; - min-width: 0; - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; - } - - .ulw-worker small { - font-family: var(--font-mono); - font-size: 9.5px; - color: var(--codex-window-text-soft); - white-space: nowrap; - } - - .ulw-worker-glyph { - width: 16px; - height: 16px; - border-radius: 4px; - display: inline-flex; - align-items: center; - justify-content: center; - font-family: var(--font-mono); - font-size: 9px; - font-weight: 700; - color: var(--codex-window-glyph-text); - flex-shrink: 0; - } - - /* Lane identity colors are per-window-theme custom props defined next to - the --codex-window-* adapter blocks (design-system.css). */ - .ulw-worker-glyph[data-lane="root"] { background: var(--lane-root); } - .ulw-worker-glyph[data-lane="explore"] { background: var(--lane-explore); } - .ulw-worker-glyph[data-lane="library"] { background: var(--lane-library); } - .ulw-worker-glyph[data-lane="plan"] { background: var(--lane-plan); } - .ulw-worker-glyph[data-lane="todo"] { background: var(--lane-todo); } - .ulw-worker-glyph[data-lane="execute"] { background: var(--lane-execute); } - .ulw-worker-glyph[data-lane="test"] { background: var(--lane-test); } - .ulw-worker-glyph[data-lane="qa"] { background: var(--lane-qa); } - .ulw-worker-glyph[data-lane="review"] { background: var(--lane-review); } - .ulw-worker-glyph[data-lane="continuation"] { background: var(--lane-continuation); } - - .ulw-ledger pre { - font-family: var(--font-mono); - font-size: 10px; - line-height: 1.5; - color: var(--codex-window-text-soft); - white-space: pre-wrap; - overflow-wrap: anywhere; - /* Horizontal scroll is allowed ONLY inside code rows. */ - overflow-x: auto; - } - - .ulw-controls { - display: flex; - flex-wrap: wrap; - justify-content: center; - gap: 8px; - margin-top: 18px; - } - - .ulw-control { - font-family: var(--font-mono); - font-size: 12px; - padding: 8px 14px; - border-radius: 9px; - border: 1px solid var(--border-default); - background: var(--surface-2); - color: var(--text-secondary); - transition: color 150ms ease, background-color 150ms ease, border-color 150ms ease; - } - - .ulw-control:hover { - color: var(--text-primary); - background: var(--surface-3); - } - - .ulw-control[aria-selected="true"] { - background: var(--accent-primary); - border-color: var(--accent-primary); - /* --card-base (#ffffff) holds >= 4.5:1 on the forest-green accent. */ - color: var(--card-base); - font-weight: 600; - } - - .ulw-control[aria-pressed="true"] { - color: var(--accent-primary); - border-color: var(--accent-primary-border); - } - - .ulw-theme-group { - display: inline-flex; - gap: 8px; - margin-left: 6px; - padding-left: 14px; - border-left: 1px dotted var(--border-subtle); - } - @media (max-width: 768px) { - .ulw-window { - min-height: 480px; - } - - .ulw-content { - grid-template-columns: 1fr; - } - - .ulw-side { - border-left: none; - border-top: 1px solid var(--codex-window-border); - } - - .ulw-menubar-left span { - display: none; - } - - .ulw-theme-group { - margin-left: 0; - padding-left: 0; - border-left: none; + .ulw-scene-copy { + min-height: 168px; } } @@ -484,16 +143,5 @@ .ulw-scene-swap { animation: none; } - - .ulw-caret { - animation: none; - } - - .ulw-step, - .ulw-proof, - .ulw-worker, - .ulw-control { - transition: none; - } } } diff --git a/packages/web/components/site/ulw-demo/codex-window.tsx b/packages/web/components/site/ulw-demo/codex-window.tsx index e754243..f2edba9 100644 --- a/packages/web/components/site/ulw-demo/codex-window.tsx +++ b/packages/web/components/site/ulw-demo/codex-window.tsx @@ -1,25 +1,24 @@ "use client" -import { useEffect, useRef, useState, type JSX, type KeyboardEvent } from "react" -import { - ULW_DEMO_AUTOPLAY_MS, - ULW_DEMO_SCENES, -} from "../../../lib/ulw-demo-scenes" -import { ComposerBar, SideRail, TranscriptPane, WindowChrome } from "./window-panes" +import { useEffect, useRef, useState, type JSX } from "react" +import { ULW_DEMO_AUTOPLAY_MS, ULW_DEMO_SCENES } from "../../../lib/ulw-demo-scenes" +import { WindowSidebar, WindowTitlebar } from "./window-chrome" +import { SidePanel, TranscriptPane, WindowFooter } from "./window-panes" /** - * Scene state machine for the Codex-desktop window (DESIGN.md § CodexWindow). - * Autoplay arms on scroll-into-view, pauses on any scene interaction, and - * never starts under prefers-reduced-motion. Scene 0 is server-rendered. - * The window itself is themed light (default, faithful to the Codex app) or - * dark via a role=group toggle that sets data-window-theme on .ulw-window. + * Scene state machine for the Codex-desktop window (DESIGN.md § CodexWindow), + * rebuilt to the real app anatomy (.omo/reference/app-frames/): sidebar with + * session rows, transcript, decorative composer, subagents panel. Playback is + * screen-recording-like: a thin scaleX progress bar plus play/pause/replay in + * the title bar; sidebar session rows jump straight to a scene. Autoplay arms + * on scroll-into-view and never starts under prefers-reduced-motion (static + * scene 0 + play affordance). Scene 0 is server-rendered. */ export function CodexWindow(): JSX.Element { const [sceneIndex, setSceneIndex] = useState(0) const [playing, setPlaying] = useState(false) const [windowTheme, setWindowTheme] = useState<"light" | "dark">("light") const rootRef = useRef(null) - const tabRefs = useRef<(HTMLButtonElement | null)[]>([]) const scene = ULW_DEMO_SCENES[sceneIndex % ULW_DEMO_SCENES.length] ?? ULW_DEMO_SCENES[0] useEffect(() => { @@ -53,89 +52,40 @@ export function CodexWindow(): JSX.Element { setPlaying(false) } - function onTabKeyDown(event: KeyboardEvent, index: number): void { - const delta = event.key === "ArrowRight" ? 1 : event.key === "ArrowLeft" ? -1 : 0 - if (delta === 0) return - event.preventDefault() - const next = (index + delta + ULW_DEMO_SCENES.length) % ULW_DEMO_SCENES.length - selectScene(next) - tabRefs.current[next]?.focus() + function replay(): void { + setSceneIndex(0) + setPlaying(true) } return (
-
- -
- - +
+ {/* Per-scene playback progress: transform-only (compositor-safe), + paused via animation-play-state, remounted per scene key. */} + - -
- -
- - {/* display:contents keeps the shared flex-wrap layout while giving the - tablist only tab children (aria-required-children). */} -
- {ULW_DEMO_SCENES.map((entry, index) => ( - - ))} -
-
- - +
+ +
+ setPlaying((value) => !value)} + onReplay={replay} + onToggleTheme={() => + setWindowTheme((theme) => (theme === "light" ? "dark" : "light")) + } + /> + + +
+
diff --git a/packages/web/components/site/ulw-demo/window-chrome.tsx b/packages/web/components/site/ulw-demo/window-chrome.tsx new file mode 100644 index 0000000..ef35245 --- /dev/null +++ b/packages/web/components/site/ulw-demo/window-chrome.tsx @@ -0,0 +1,132 @@ +import type { JSX } from "react" +import { SITE_CONFIG } from "../../../lib/site-config" +import { ULW_DEMO_SCENES } from "../../../lib/ulw-demo-scenes" +import { UlwIcon, type UlwIconName } from "./window-icons" + +/** + * Window chrome for the Codex-desktop demo: left session sidebar plus the + * per-session title bar. Anatomy mirrors the real app frames + * (.omo/reference/app-frames/creation-03.png): traffic lights above a nav + * list, then Pinned and Projects session groups. The Projects session rows + * ARE the scene navigation — the app-native replacement for a tab strip — + * so they are plain buttons carrying aria-current, not a fake tablist. + */ + +const SIDEBAR_NAV: readonly { icon: UlwIconName; label: string }[] = [ + { icon: "compose", label: "New chat" }, + { icon: "search", label: "Search" }, + { icon: "plugins", label: "Plugins" }, + { icon: "clock", label: "Automations" }, +] + +export function WindowSidebar({ + sceneIndex, + onSelectScene, +}: { + readonly sceneIndex: number + readonly onSelectScene: (index: number) => void +}): JSX.Element { + return ( + + ) +} + +export function WindowTitlebar({ + sceneTab, + playing, + windowTheme, + onTogglePlay, + onReplay, + onToggleTheme, +}: { + readonly sceneTab: string + readonly playing: boolean + readonly windowTheme: "light" | "dark" + readonly onTogglePlay: () => void + readonly onReplay: () => void + readonly onToggleTheme: () => void +}): JSX.Element { + return ( +
+ {sceneTab} + +
+ + + +
+
+ ) +} diff --git a/packages/web/components/site/ulw-demo/window-icons.tsx b/packages/web/components/site/ulw-demo/window-icons.tsx new file mode 100644 index 0000000..ef43e58 --- /dev/null +++ b/packages/web/components/site/ulw-demo/window-icons.tsx @@ -0,0 +1,53 @@ +import type { JSX } from "react" + +/** + * Minimal stroke-only SVG glyphs for the Codex-window demo. Decorative + * (aria-hidden), currentColor, sized by the surrounding chrome — anatomy + * mirrors the small nav/tool glyphs in .omo/reference/app-frames/creation-03.png. + */ + +const ICON_PATHS = { + compose: + "M9 3H4a1.5 1.5 0 0 0-1.5 1.5V12A1.5 1.5 0 0 0 4 13.5h7.5A1.5 1.5 0 0 0 13 12V7M13.2 2.8a1.4 1.4 0 0 0-2 0L6.5 7.5 6 10l2.5-.5 4.7-4.7a1.4 1.4 0 0 0 0-2Z", + search: "M12.5 12.5 10 10M11 6.75a4.25 4.25 0 1 1-8.5 0 4.25 4.25 0 0 1 8.5 0Z", + plugins: "M3 3h4v4H3ZM9 3h4v4H9ZM3 9h4v4H3ZM9 9h4v4H9Z", + clock: "M8 4.5V8l2.3 1.4M14 8A6 6 0 1 1 2 8a6 6 0 0 1 12 0Z", + folder: + "M2.5 4A1.5 1.5 0 0 1 4 2.5h2.6l1.5 1.7H12A1.5 1.5 0 0 1 13.5 5.7V11A1.5 1.5 0 0 1 12 12.5H4A1.5 1.5 0 0 1 2.5 11Z", + terminal: + "M3 2.5h10A1.5 1.5 0 0 1 14.5 4v8a1.5 1.5 0 0 1-1.5 1.5H3A1.5 1.5 0 0 1 1.5 12V4A1.5 1.5 0 0 1 3 2.5ZM4.5 6l2 2-2 2M8.5 10.5h3", + agent: "M8 7.5a2.5 2.5 0 1 0 0-5 2.5 2.5 0 0 0 0 5ZM2.8 13.5a5.3 5.3 0 0 1 10.4 0", + check: "M2.5 8.5 6 12l7.5-8", + target: "M8 10.5a2.5 2.5 0 1 0 0-5 2.5 2.5 0 0 0 0 5ZM8 14A6 6 0 1 0 8 2a6 6 0 0 0 0 12Z", + alert: + "M8 6v3.2M8 11.4v.2M7 2.8 1.8 12a1.2 1.2 0 0 0 1 1.8h10.4a1.2 1.2 0 0 0 1-1.8L9 2.8a1.2 1.2 0 0 0-2 0Z", + plus: "M8 3.5v9M3.5 8h9", + mic: "M8 10.5A2.5 2.5 0 0 0 10.5 8V4.5a2.5 2.5 0 0 0-5 0V8A2.5 2.5 0 0 0 8 10.5ZM12.5 8a4.5 4.5 0 0 1-9 0M8 12.5V14", + "arrow-up": "M8 12.5v-9M4.5 7 8 3.5 11.5 7", + play: "M5.5 3.5v9l7-4.5Z", + pause: "M6 4v8M10 4v8", + replay: "M2.5 8a5.5 5.5 0 1 0 1.7-4M4 2.5v2.8h2.8", + moon: "M13.2 9.7A5.7 5.7 0 1 1 6.3 2.8a4.6 4.6 0 0 0 6.9 6.9Z", +} as const + +export type UlwIconName = keyof typeof ICON_PATHS + +export function UlwIcon({ name }: { readonly name: UlwIconName }): JSX.Element { + return ( + + ) +} diff --git a/packages/web/components/site/ulw-demo/window-panes.tsx b/packages/web/components/site/ulw-demo/window-panes.tsx index d4e376c..dfba17c 100644 --- a/packages/web/components/site/ulw-demo/window-panes.tsx +++ b/packages/web/components/site/ulw-demo/window-panes.tsx @@ -1,66 +1,37 @@ import type { JSX } from "react" import { ULW_DEMO_ENVIRONMENT, - ULW_DEMO_PROOFS, - ULW_DEMO_STEPS, + ULW_DEMO_SCENES, ULW_DEMO_WORKERS, type UlwScene, } from "../../../lib/ulw-demo-scenes" +import { UlwIcon, type UlwIconName } from "./window-icons" /** - * Presentational panes for the Codex window. Pure functions of the active - * scene — every visible string comes from `lib/ulw-demo-scenes.ts` - * (source-grounded, see .omo/evidence/copy-ledger.md). + * Presentational panes for the Codex window, pure functions of the active + * scene. Every visible string comes from `lib/ulw-demo-scenes.ts` or the + * generic chrome labels visible in our own app frames + * (.omo/reference/app-frames/creation-03.png, subagents-03.png). + * Transcript anatomy follows the real app: command bubble, prose, then + * tool-activity rows (the run-ledger lines) with small inline glyphs. */ -export function WindowChrome(): JSX.Element { - return ( - <> - -
-
- - ) +function ledgerIcon(line: string): UlwIconName { + if (line.includes("fail")) return "alert" + if (line.includes("evidence_captured") || line.includes("checkpoint") || line.includes("status=pass")) { + return "check" + } + if (line.startsWith("goal_") || line.includes("activeGoalId")) return "target" + return "terminal" } -export function TranscriptPane({ - scene, - sceneIndex, -}: { - readonly scene: UlwScene - readonly sceneIndex: number -}): JSX.Element { +export function TranscriptPane({ scene }: { readonly scene: UlwScene }): JSX.Element { return ( -
-
- - - {scene.command} - +
+

ULTRAWORK MODE ENABLED!

+ +
+ {scene.command}
{/* The live region stays OUTSIDE the keyed swap subtree: React must @@ -73,44 +44,71 @@ export function TranscriptPane({

{scene.body}

-
- {ULW_DEMO_STEPS.map((step, index) => ( -
- {String(index + 1).padStart(2, "0")} -
- {step.heading} -

{step.detail}

-
+
+ {scene.ledger.split("\n").map((line) => ( +
+ + {line}
))}
-
- {ULW_DEMO_PROOFS.map((proof, index) => ( - - {proof} - - ))} +
+ {scene.json}
) } -export function ComposerBar({ scene }: { readonly scene: UlwScene }): JSX.Element { +export function WindowFooter({ + scene, + sceneIndex, +}: { + readonly scene: UlwScene + readonly sceneIndex: number +}): JSX.Element { return ( -
- - {scene.composer} - Full access - 5.5 High -
-
- {scene.sideTitle} - - {scene.sideBody} - -
- -
- goals.json / ledger.jsonl -
{scene.ledger}
-
{scene.json}
+
+ {scene.sideTitle} + {scene.sideBody}
) diff --git a/packages/web/e2e/ulw-demo.spec.ts b/packages/web/e2e/ulw-demo.spec.ts index 86bf35a..daa7eff 100644 --- a/packages/web/e2e/ulw-demo.spec.ts +++ b/packages/web/e2e/ulw-demo.spec.ts @@ -1,20 +1,43 @@ -import { expect, test } from "@playwright/test" +import { expect, type Page, test } from "@playwright/test" import { ULW_DEMO_SCENES } from "../lib/ulw-demo-scenes" /** - * Interactive Ultrawork demo contract (TDD target state). + * Interactive Ultrawork demo contract — v2 (app-faithful window, natural playback). * - * The demo is a live-DOM Codex-desktop window driven by a typed scene machine: - * autoplay on scroll-into-view, scene tabs (role=tab), play/pause (aria-pressed), - * reduced-motion disables autoplay, and no horizontal overflow at 390px. + * CONTRACT CHANGE (v1 → v2): the external scene-tab strip (role=tab) is + * REMOVED. Scene navigation is now the app-native sidebar session list — + * plain buttons inside nav[aria-label="Demo scenes"] carrying aria-current + * on the active row (hidden at <=768px, like the real app sidebar). Playback + * controls moved into the window title bar: play/pause (aria-pressed), + * replay, and a single Light/Dark window-theme toggle (aria-pressed = dark). + * Assertion strength is preserved 1:1 versus the v1 suite: scene-0 SSR text, + * autoplay advance within 12s, direct navigation updating every pane, + * play/pause observable state, reduced-motion static scene 0 with a play + * affordance, theme flip via click AND keyboard, dark-theme visibility, and + * no horizontal overflow at 390px. New in v2: the window's outer height must + * not change across scenes (zero outer layout shift). */ const RESEARCH = ULW_DEMO_SCENES[0] +const PLAN = ULW_DEMO_SCENES[1] const RED = ULW_DEMO_SCENES[4] const CHECKPOINT = ULW_DEMO_SCENES[7] +function sceneRow(page: Page, tab: string) { + return page + .locator("#ulw-demo") + .getByRole("navigation", { name: "Demo scenes" }) + .getByRole("button", { name: tab, exact: true }) +} + +function themeToggle(page: Page) { + return page.getByRole("button", { name: "Toggle the dark window theme" }) +} + test.describe("ulw demo — happy path @happy", () => { - test("renders scene 0, autoplays forward, and tabs jump to checkpoint", async ({ page }) => { + test("renders scene 0, autoplays, and sidebar rows jump to checkpoint shift-free", async ({ + page, + }) => { await page.goto("/") const demo = page.locator("#ulw-demo") await demo.scrollIntoViewIfNeeded() @@ -22,35 +45,60 @@ test.describe("ulw demo — happy path @happy", () => { // Scene 0 is the server-rendered initial state. await expect(page.getByText(RESEARCH.title, { exact: true })).toBeVisible() await expect(page.getByText("ULTRAWORK MODE ENABLED!", { exact: true })).toBeVisible() + await expect(demo.getByText("Step 1 / 8", { exact: true })).toBeVisible() // Autoplay must advance beyond scene 0 once in view (interval ~7s). - await expect(page.getByRole("tab", { name: ULW_DEMO_SCENES[1].tab })).toHaveAttribute( - "aria-selected", - "true", - { timeout: 12_000 }, - ) + await expect(sceneRow(page, PLAN.tab)).toHaveAttribute("aria-current", "true", { + timeout: 12_000, + }) - // Direct scene selection: checkpoint updates every pane atomically. - await page.getByRole("tab", { name: CHECKPOINT.tab }).click() + // Zero outer layout shift: the window box is identical across scenes. + // Bring the whole window into view first so row clicks never auto-scroll + // (boundingBox is viewport-relative). + const ulwWindow = demo.locator(".ulw-window") + await ulwWindow.scrollIntoViewIfNeeded() + await sceneRow(page, RESEARCH.tab).click() + const boxA = await ulwWindow.boundingBox() + + // Direct scene selection via a session row updates every pane atomically. + await sceneRow(page, CHECKPOINT.tab).click() + await expect(sceneRow(page, CHECKPOINT.tab)).toHaveAttribute("aria-current", "true") await expect(page.getByText(CHECKPOINT.title, { exact: true })).toBeVisible() - await expect(demo.getByText("checkpoint --status complete", { exact: false }).first()).toBeVisible() + await expect(demo.getByText("checkpoint --status complete", { exact: true })).toBeVisible() await expect(demo.getByText(CHECKPOINT.sideTitle, { exact: true })).toBeVisible() - - // Play/pause is a real control with observable state. - const playToggle = page.getByRole("button", { name: /pause|play/i }).first() - const before = await playToggle.getAttribute("aria-pressed") + await expect(demo.getByText(CHECKPOINT.composer, { exact: true })).toBeVisible() + await expect(demo.getByText("Step 8 / 8", { exact: true })).toBeVisible() + + const boxB = await ulwWindow.boundingBox() + expect(boxA).not.toBeNull() + expect(boxB).not.toBeNull() + expect(Math.abs((boxA?.height ?? 0) - (boxB?.height ?? 0))).toBeLessThanOrEqual(1) + expect(Math.abs((boxA?.y ?? 0) - (boxB?.y ?? 0))).toBeLessThanOrEqual(1) + + // Selecting a row pauses playback; play/pause is a real observable toggle. + // Anchored: "Replay the demo…" must not match the play/pause button name. + const playToggle = page.getByRole("button", { name: /^(pause|play) the demo$/i }) + await expect(playToggle).toHaveAttribute("aria-pressed", "false") await playToggle.click() - await expect(playToggle).not.toHaveAttribute("aria-pressed", String(before)) + await expect(playToggle).toHaveAttribute("aria-pressed", "true") + + // Replay restarts the recording from scene 0 and keeps playing. + await page.getByRole("button", { name: "Replay the demo from the first scene" }).click() + await expect(sceneRow(page, RESEARCH.tab)).toHaveAttribute("aria-current", "true") + await expect(page.getByText(RESEARCH.title, { exact: true })).toBeVisible() + await expect(playToggle).toHaveAttribute("aria-pressed", "true") await page.screenshot({ - path: "../../.omo/evidence/g2-c1-demo-checkpoint.png", + path: "../../.omo/evidence/v2-demo-checkpoint.png", fullPage: false, }) }) }) test.describe("ulw demo — reduced motion + mobile @edge", () => { - test("reduced motion disables autoplay but tabs still switch scenes", async ({ page }) => { + test("reduced motion pins scene 0 but keeps the play affordance and rows working", async ({ + page, + }) => { await page.emulateMedia({ reducedMotion: "reduce" }) await page.goto("/") const demo = page.locator("#ulw-demo") @@ -58,25 +106,33 @@ test.describe("ulw demo — reduced motion + mobile @edge", () => { await expect(page.getByText(RESEARCH.title, { exact: true })).toBeVisible() - // No autoplay: after > one interval the first tab is still selected. + // No autoplay: after > one interval the first session row is still current. await page.waitForTimeout(9_000) - await expect(page.getByRole("tab", { name: RESEARCH.tab })).toHaveAttribute( - "aria-selected", - "true", - ) + await expect(sceneRow(page, RESEARCH.tab)).toHaveAttribute("aria-current", "true") + await expect(sceneRow(page, PLAN.tab)).not.toHaveAttribute("aria-current", "true") - await page.getByRole("tab", { name: RED.tab }).click() + // The play affordance stays available for explicit intent. + await expect(page.getByRole("button", { name: "Play the demo", exact: true })).toBeVisible() + + await sceneRow(page, RED.tab).click() await expect(page.getByText(RED.title, { exact: true })).toBeVisible() }) - test("no horizontal overflow at 390x844 with the last scene open", async ({ page }) => { + test("no horizontal overflow at 390x844 and the sidebar collapses", async ({ page }) => { await page.setViewportSize({ width: 390, height: 844 }) await page.goto("/") const demo = page.locator("#ulw-demo") - await demo.scrollIntoViewIfNeeded() + // Scroll the window itself into view: the tall mobile section otherwise + // leaves it below the fold and the IntersectionObserver never arms. + await demo.locator(".ulw-window").scrollIntoViewIfNeeded() - await page.getByRole("tab", { name: CHECKPOINT.tab }).click() - await expect(page.getByText(CHECKPOINT.title, { exact: true })).toBeVisible() + // The session sidebar is hidden at mobile widths, like the real app. + await expect(page.getByRole("navigation", { name: "Demo scenes" })).toBeHidden() + + // Autoplay still advances the recording; dynamic scenes must not overflow. + await expect(page.getByText(PLAN.title, { exact: true })).toBeVisible({ + timeout: 12_000, + }) const overflow = await page.evaluate( () => document.documentElement.scrollWidth - document.documentElement.clientWidth, @@ -84,14 +140,14 @@ test.describe("ulw demo — reduced motion + mobile @edge", () => { expect(overflow).toBeLessThanOrEqual(0) await page.screenshot({ - path: "../../.omo/evidence/g2-c2-demo-mobile.png", + path: "../../.omo/evidence/v2-demo-mobile.png", fullPage: false, }) }) }) test.describe("ulw demo — window theme toggle", () => { - test("defaults to the light window theme with an accessible toggle group @happy", async ({ + test("defaults to the light window theme with an accessible toggle @happy", async ({ page, }) => { await page.goto("/") @@ -99,55 +155,38 @@ test.describe("ulw demo — window theme toggle", () => { // Light is the default (faithful to the real Codex app; Lighthouse audits it). await expect(ulwWindow).toHaveAttribute("data-window-theme", "light") - - const group = page.getByRole("group", { name: "Demo window theme" }) - await expect(group.getByRole("button", { name: "Light" })).toHaveAttribute( - "aria-pressed", - "true", - ) - await expect(group.getByRole("button", { name: "Dark" })).toHaveAttribute( - "aria-pressed", - "false", - ) + await expect(themeToggle(page)).toHaveAttribute("aria-pressed", "false") }) - test("clicking Dark flips data-window-theme and aria-pressed states @happy", async ({ + test("clicking the toggle flips data-window-theme and aria-pressed @happy", async ({ page, }) => { await page.goto("/") const ulwWindow = page.locator("#ulw-demo .ulw-window") - const group = page.getByRole("group", { name: "Demo window theme" }) - const lightButton = group.getByRole("button", { name: "Light" }) - const darkButton = group.getByRole("button", { name: "Dark" }) - - await expect(darkButton).toBeVisible() - await darkButton.click() + await expect(themeToggle(page)).toBeVisible() + await themeToggle(page).click() await expect(ulwWindow).toHaveAttribute("data-window-theme", "dark") - await expect(darkButton).toHaveAttribute("aria-pressed", "true") - await expect(lightButton).toHaveAttribute("aria-pressed", "false") + await expect(themeToggle(page)).toHaveAttribute("aria-pressed", "true") + + await themeToggle(page).click() + await expect(ulwWindow).toHaveAttribute("data-window-theme", "light") + await expect(themeToggle(page)).toHaveAttribute("aria-pressed", "false") }) - test("keyboard: Tab reaches Dark and Enter flips the window theme @edge", async ({ + test("keyboard: Enter on the focused toggle flips the window theme @edge", async ({ page, }) => { await page.goto("/") const ulwWindow = page.locator("#ulw-demo .ulw-window") - const group = page.getByRole("group", { name: "Demo window theme" }) - const lightButton = group.getByRole("button", { name: "Light" }) - const darkButton = group.getByRole("button", { name: "Dark" }) - - // Standard tab order (locked contract): Light and Dark are plain buttons, - // so Tab moves focus from Light to Dark and Enter activates it. - await expect(lightButton).toBeVisible() - await lightButton.focus() - await page.keyboard.press("Tab") - await expect(darkButton).toBeFocused() + + await expect(themeToggle(page)).toBeVisible() + await themeToggle(page).focus() + await expect(themeToggle(page)).toBeFocused() await page.keyboard.press("Enter") await expect(ulwWindow).toHaveAttribute("data-window-theme", "dark") - await expect(darkButton).toHaveAttribute("aria-pressed", "true") - await expect(lightButton).toHaveAttribute("aria-pressed", "false") + await expect(themeToggle(page)).toHaveAttribute("aria-pressed", "true") }) test("dark window theme keeps the scene-0 transcript visible @edge", async ({ page }) => { @@ -155,12 +194,9 @@ test.describe("ulw demo — window theme toggle", () => { await page.emulateMedia({ reducedMotion: "reduce" }) await page.goto("/") const ulwWindow = page.locator("#ulw-demo .ulw-window") - const darkButton = page - .getByRole("group", { name: "Demo window theme" }) - .getByRole("button", { name: "Dark" }) - await expect(darkButton).toBeVisible() - await darkButton.click() + await expect(themeToggle(page)).toBeVisible() + await themeToggle(page).click() await expect(ulwWindow).toHaveAttribute("data-window-theme", "dark") await expect(page.getByText(RESEARCH.title, { exact: true })).toBeVisible() From b19c80948202d236c4cb67551e6e9115437e0297 Mon Sep 17 00:00:00 2001 From: YeonGyu-Kim Date: Fri, 3 Jul 2026 12:03:35 +0900 Subject: [PATCH 18/35] feat(demo): default the codex window to its dark theme User feedback: the white window on the near-black canvas reads as glare. Dark elevated layer becomes the resting state; light is the opt-in via a sun toggle (aria-pressed = light). TDD: spec flipped first (RED, 4 toggle tests failing for the right reason), then the component default (GREEN 7/7). Co-Authored-By: Claude Fable 5 --- .../components/site/ulw-demo/codex-window.tsx | 2 +- .../site/ulw-demo/window-chrome.tsx | 6 +++--- .../components/site/ulw-demo/window-icons.tsx | 1 + packages/web/e2e/ulw-demo.spec.ts | 19 ++++++++++--------- 4 files changed, 15 insertions(+), 13 deletions(-) diff --git a/packages/web/components/site/ulw-demo/codex-window.tsx b/packages/web/components/site/ulw-demo/codex-window.tsx index f2edba9..49b03bb 100644 --- a/packages/web/components/site/ulw-demo/codex-window.tsx +++ b/packages/web/components/site/ulw-demo/codex-window.tsx @@ -17,7 +17,7 @@ import { SidePanel, TranscriptPane, WindowFooter } from "./window-panes" export function CodexWindow(): JSX.Element { const [sceneIndex, setSceneIndex] = useState(0) const [playing, setPlaying] = useState(false) - const [windowTheme, setWindowTheme] = useState<"light" | "dark">("light") + const [windowTheme, setWindowTheme] = useState<"light" | "dark">("dark") const rootRef = useRef(null) const scene = ULW_DEMO_SCENES[sceneIndex % ULW_DEMO_SCENES.length] ?? ULW_DEMO_SCENES[0] diff --git a/packages/web/components/site/ulw-demo/window-chrome.tsx b/packages/web/components/site/ulw-demo/window-chrome.tsx index ef35245..a766d3f 100644 --- a/packages/web/components/site/ulw-demo/window-chrome.tsx +++ b/packages/web/components/site/ulw-demo/window-chrome.tsx @@ -120,11 +120,11 @@ export function WindowTitlebar({
diff --git a/packages/web/components/site/ulw-demo/window-icons.tsx b/packages/web/components/site/ulw-demo/window-icons.tsx index ef43e58..a88dba3 100644 --- a/packages/web/components/site/ulw-demo/window-icons.tsx +++ b/packages/web/components/site/ulw-demo/window-icons.tsx @@ -28,6 +28,7 @@ const ICON_PATHS = { pause: "M6 4v8M10 4v8", replay: "M2.5 8a5.5 5.5 0 1 0 1.7-4M4 2.5v2.8h2.8", moon: "M13.2 9.7A5.7 5.7 0 1 1 6.3 2.8a4.6 4.6 0 0 0 6.9 6.9Z", + sun: "M8 5.4a2.6 2.6 0 1 0 0 5.2 2.6 2.6 0 0 0 0-5.2ZM8 1.3v1.5M8 13.2v1.5M1.3 8h1.5M13.2 8h1.5M3.3 3.3l1 1M11.7 11.7l1 1M12.7 3.3l-1 1M4.3 11.7l-1 1", } as const export type UlwIconName = keyof typeof ICON_PATHS diff --git a/packages/web/e2e/ulw-demo.spec.ts b/packages/web/e2e/ulw-demo.spec.ts index daa7eff..39f2164 100644 --- a/packages/web/e2e/ulw-demo.spec.ts +++ b/packages/web/e2e/ulw-demo.spec.ts @@ -31,7 +31,7 @@ function sceneRow(page: Page, tab: string) { } function themeToggle(page: Page) { - return page.getByRole("button", { name: "Toggle the dark window theme" }) + return page.getByRole("button", { name: "Toggle the light window theme" }) } test.describe("ulw demo — happy path @happy", () => { @@ -147,14 +147,15 @@ test.describe("ulw demo — reduced motion + mobile @edge", () => { }) test.describe("ulw demo — window theme toggle", () => { - test("defaults to the light window theme with an accessible toggle @happy", async ({ + test("defaults to the dark window theme with an accessible toggle @happy", async ({ page, }) => { await page.goto("/") const ulwWindow = page.locator("#ulw-demo .ulw-window") - // Light is the default (faithful to the real Codex app; Lighthouse audits it). - await expect(ulwWindow).toHaveAttribute("data-window-theme", "light") + // Dark is the default: the window sits on a near-black canvas, so the + // elevated dark layer is the restful state; light is the opt-in. + await expect(ulwWindow).toHaveAttribute("data-window-theme", "dark") await expect(themeToggle(page)).toHaveAttribute("aria-pressed", "false") }) @@ -166,11 +167,11 @@ test.describe("ulw demo — window theme toggle", () => { await expect(themeToggle(page)).toBeVisible() await themeToggle(page).click() - await expect(ulwWindow).toHaveAttribute("data-window-theme", "dark") + await expect(ulwWindow).toHaveAttribute("data-window-theme", "light") await expect(themeToggle(page)).toHaveAttribute("aria-pressed", "true") await themeToggle(page).click() - await expect(ulwWindow).toHaveAttribute("data-window-theme", "light") + await expect(ulwWindow).toHaveAttribute("data-window-theme", "dark") await expect(themeToggle(page)).toHaveAttribute("aria-pressed", "false") }) @@ -185,11 +186,11 @@ test.describe("ulw demo — window theme toggle", () => { await expect(themeToggle(page)).toBeFocused() await page.keyboard.press("Enter") - await expect(ulwWindow).toHaveAttribute("data-window-theme", "dark") + await expect(ulwWindow).toHaveAttribute("data-window-theme", "light") await expect(themeToggle(page)).toHaveAttribute("aria-pressed", "true") }) - test("dark window theme keeps the scene-0 transcript visible @edge", async ({ page }) => { + test("light window theme keeps the scene-0 transcript visible @edge", async ({ page }) => { // Reduced motion pins the demo on scene 0 so the visibility check is stable. await page.emulateMedia({ reducedMotion: "reduce" }) await page.goto("/") @@ -197,7 +198,7 @@ test.describe("ulw demo — window theme toggle", () => { await expect(themeToggle(page)).toBeVisible() await themeToggle(page).click() - await expect(ulwWindow).toHaveAttribute("data-window-theme", "dark") + await expect(ulwWindow).toHaveAttribute("data-window-theme", "light") await expect(page.getByText(RESEARCH.title, { exact: true })).toBeVisible() await expect(page.getByText("ULTRAWORK MODE ENABLED!", { exact: true })).toBeVisible() From 1360261c3eb9f3456910936bbb25a6df3530bc4e Mon Sep 17 00:00:00 2001 From: YeonGyu-Kim Date: Fri, 3 Jul 2026 12:03:35 +0900 Subject: [PATCH 19/35] feat(design-system): restore the emerald atmosphere on a deeper canvas MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit User feedback: the flat graphite canvas lost the original identity's luminous background tone. Canvas deepens to #0a0b0d and PageShell mounts a static glow-backdrop (four low-alpha radial green washes; aurora peak 0.17) painted above the html canvas by DOM order — the body's opaque background was silently covering a negative-z-index layer. Zero CLS, no animation; contrast constants re-synced (ALL PASS), Lighthouse holds 100x4. Co-Authored-By: Claude Fable 5 --- packages/web/DESIGN.md | 32 ++++++++++++------ packages/web/app/styles/design-system.css | 33 ++++++++++++++----- .../web/components/design-system/layout.tsx | 9 ++++- 3 files changed, 55 insertions(+), 19 deletions(-) diff --git a/packages/web/DESIGN.md b/packages/web/DESIGN.md index dcb8fb9..cfb7edc 100644 --- a/packages/web/DESIGN.md +++ b/packages/web/DESIGN.md @@ -20,19 +20,31 @@ page itself. The brand color is green, not teal, cyan, purple, or blue. ## 2. Color +### Atmosphere + +The canvas is not flat black: a static emerald atmosphere restores the +original identity's luminous tone. `PageShell` mounts an `aria-hidden` +`.glow-backdrop` layer (absolute, `pointer-events-none`, painted below the +content wrapper by DOM order) carrying four low-alpha radial green washes — +an aurora behind the hero (peak `rgba(34,197,94,0.17)`), a faint right-side +pool near the demo, a mid-page pool, and a low anchor near the Hephaestus +band. Alphas stay ≤ 0.17 so every AA-audited text pair is unaffected, and the +layer never animates — zero paint cost after first frame, zero CLS. + + ### Palette | Role | Token | Value | Usage | | --- | --- | --- | --- | -| Surface/base | `--surface-base`, `--surface-0` | `#0e1012` | Page canvas | -| Surface/night | `--surface-night` | `#0a0c0e` | Footer and deeper page bands | +| Surface/base | `--surface-base`, `--surface-0` | `#0a0b0d` | Page canvas | +| Surface/night | `--surface-night` | `#07080a` | Footer and deeper page bands | | Surface/subtle | `--surface-1` | `rgba(255,255,255,0.04)` | Hover and quiet fills | | Surface/raised | `--surface-2` | `rgba(255,255,255,0.06)` | Secondary tonal layer | | Surface/strong | `--surface-3` | `rgba(255,255,255,0.09)` | Stronger tonal layer | -| Surface/card | `--card-base` | `#16181c` | Elevated dark panels, content cards | -| Surface/panel | `--surface-panel` | `#121417` | Panels, install bar | -| Surface/alt | `--surface-panel-alt` | `#131519` | Alternate panel | -| Surface/deep | `--surface-panel-deep` | `#101215` | Deep panel | +| Surface/card | `--card-base` | `#15171b` | Elevated dark panels, content cards | +| Surface/panel | `--surface-panel` | `#101216` | Panels, install bar | +| Surface/alt | `--surface-panel-alt` | `#111318` | Alternate panel | +| Surface/deep | `--surface-panel-deep` | `#0e1013` | Deep panel | | Brand/core | `--brand-core` | `#22c55e` | Green brand center (fills, gradients) | | Brand/mid | `--brand-mid` | `#16a34a` | Green gradient middle | | Brand/outer | `--brand-outer` | `#15803d` | Gradient edge | @@ -84,7 +96,7 @@ Light theme (default block on `.ulw-window`): | Window/traffic | `--codex-window-traffic-red/-amber/-green` | `#f87171` / `#fbbf24` / `#34d399` | macOS traffic-light ornaments | Dark theme (override block scoped `[data-window-theme="dark"]`, same 13 token names). It is -deliberately a touch LIGHTER than the page canvas (`#0e1012`) with a stronger hairline ring +deliberately a touch LIGHTER than the page canvas (`#0a0b0d`) with a stronger hairline ring (`rgba(255,255,255,0.18)`), so the dark window still reads as a distinct elevated layer instead of dissolving into the page: @@ -127,7 +139,7 @@ rule applies everywhere outside the window. - New UI uses `--accent-primary`; `--accent-cyan` and `--accent-teal` remain green aliases only for compatibility. - `--accent-mint` (`#86efac`) is a fill/decoration color first (glows, dots, code prompt glyphs). Interactive text and links stay on `--accent-primary` so the accent voice remains single and restrained. - Accent is reserved for interactivity, code emphasis, focus, and brand signal. -- Light surfaces are allowed ONLY inside the demo window's faithful light theme (`.ulw-window` default adapter block, also used by the Team Mode mock). Everything else sits on the dark canvas. Code blocks (`pre`), command surfaces (`CommandCodeSurface`), and the Hephaestus band (`ShowcaseSurface`) are slightly ELEVATED dark layers — a tonal lift plus a hairline ring, so they never vanish into the page. +- Light surfaces are allowed ONLY inside the demo window's OPT-IN light theme (`.ulw-window` light adapter block, also used by the Team Mode mock). The window DEFAULTS to its dark elevated theme — a full-white pane on the near-black canvas is glare, so light is a deliberate toggle, never the resting state. Everything else sits on the dark canvas. Code blocks (`pre`), command surfaces (`CommandCodeSurface`), and the Hephaestus band (`ShowcaseSurface`) are slightly ELEVATED dark layers — a tonal lift plus a hairline ring, so they never vanish into the page. - Raw colors belong in this file, `design-system.css`, or OG theme tokens. Component code references tokens or shared primitives. The sanctioned raw values in components are: `#16191e` (showcase band), `#1b1f24` (command code chip), `#15181d` (docs `pre`), `#dcfce7` (text on dark code chips), gradient stops `#86efac`/`#4ade80`/`#22c55e`, brand glow `rgba(74,222,128,0.16)`, card shadow `rgba(0,0,0,0.4)`, and the `white/10` hairline rings on elevated dark chips. ## 3. Typography @@ -231,7 +243,7 @@ All spacing resolves to a 4px rhythm. Existing Tailwind values map to the same r - **Variants**: 8 scenes (`research → plan → todo → assign → red → green → qa-retry → checkpoint`), each atomically updating command, status, headline, body, active step, roster lanes, proof chips, ledger, and JSON card. -- **Window themes**: light (default) and dark, driven by `data-window-theme="light|dark"` on +- **Window themes**: dark (default) and light (opt-in via the sun toggle, `aria-pressed` = light), driven by `data-window-theme="light|dark"` on `.ulw-window`. Light is the server-rendered default (faithful to the real Codex app and the state Lighthouse audits); dark re-themes only the window interior through the `[data-window-theme="dark"]` token block — the page canvas never changes. @@ -313,7 +325,7 @@ Codex window where real product chrome is shown. | Level | Treatment | Usage | | --- | --- | --- | -| Canvas | `--surface-base` (`#0e1012`) | Whole site background | +| Canvas | `--surface-base` (`#0a0b0d`) | Whole site background | | Panel | `--card-base` / `--surface-panel` with `--border-subtle` and `rgba(0,0,0,0.4)` shadow | Cards, install bar, docs input | | Accent panel | `--accent-primary` soft fill and border | Built-in skills, Lazy comparison, workflow code | | Elevated dark chip | `#16191e` / `#1b1f24` / `#15181d` surface + `white/10` ring, light-on-dark text | Code blocks, command surfaces, Hephaestus showcase, demo window dark theme | diff --git a/packages/web/app/styles/design-system.css b/packages/web/app/styles/design-system.css index 96feb2e..321929d 100644 --- a/packages/web/app/styles/design-system.css +++ b/packages/web/app/styles/design-system.css @@ -13,17 +13,19 @@ @layer base { :root { - /* Surfaces — deep graphite canvas, quiet and neutral (Linear-class dark). */ - --surface-base: #0e1012; - --surface-0: #0e1012; + /* Surfaces — near-black canvas where content emerges through luminance + (Linear-grammar darkness as the native medium), with the emerald + atmosphere restored by the .glow-backdrop layer below. */ + --surface-base: #0a0b0d; + --surface-0: #0a0b0d; --surface-1: rgba(255, 255, 255, 0.04); --surface-2: rgba(255, 255, 255, 0.06); --surface-3: rgba(255, 255, 255, 0.09); - --card-base: #16181c; - --surface-night: #0a0c0e; - --surface-panel: #121417; - --surface-panel-alt: #131519; - --surface-panel-deep: #101215; + --card-base: #15171b; + --surface-night: #07080a; + --surface-panel: #101216; + --surface-panel-alt: #111318; + --surface-panel-deep: #0e1013; /* Brand — green core (green-500 family), clearly green not teal. */ --brand-core: #22c55e; @@ -192,4 +194,19 @@ .rule-grid-dotted > * + * { border-left: 1px dotted var(--border-subtle); } + + /* Page atmosphere — the emerald-lit darkness of the original identity. + Static radial washes on an absolutely-positioned backdrop (PageShell): + an aurora behind the hero, a faint mid-page pool behind the demo, and a + low anchor near the Hephaestus band. Alphas stay <= 0.10 so every + AA-checked text pair is unaffected (worst case composites the canvas + from #0a0b0d toward #0d1410 — still darker than the audited #15171b + card ground). No animation: zero paint cost after first frame. */ + .glow-backdrop { + background: + radial-gradient(72rem 30rem at 50% 4rem, rgba(34, 197, 94, 0.17), rgba(34, 197, 94, 0.06) 45%, transparent 68%), + radial-gradient(50rem 26rem at 78% 26rem, rgba(74, 222, 128, 0.07), transparent 66%), + radial-gradient(70rem 42rem at 10% 118rem, rgba(22, 163, 74, 0.09), transparent 68%), + radial-gradient(84rem 48rem at 70% 100%, rgba(34, 197, 94, 0.06), transparent 70%); + } } diff --git a/packages/web/components/design-system/layout.tsx b/packages/web/components/design-system/layout.tsx index ef12775..2451c5b 100644 --- a/packages/web/components/design-system/layout.tsx +++ b/packages/web/components/design-system/layout.tsx @@ -16,7 +16,14 @@ interface SkipLinkProps { } export function PageShell({ children }: ChildrenProps): JSX.Element { - return
{children}
+ return ( +
+ {/* Atmosphere backdrop: static low-alpha green glows behind everything. + Absolute + pointer-events-none — zero layout cost, no CLS. */} +
+
{children}
+
+ ) } export function SkipLink({ From cf583b839e9d98165e940b5a81cdd0d93d983dec Mon Sep 17 00:00:00 2001 From: YeonGyu-Kim Date: Fri, 3 Jul 2026 12:10:55 +0900 Subject: [PATCH 20/35] docs(design-system): correct the glow-backdrop comment to real values Reviewer-caught contradiction: the comment predated the alpha lift and still claimed <=0.10 / three washes / a darker-than-card worst case. It now states the shipped truth: four washes, aurora peak 0.17, worst-case composite ~#0e2b1b where text-primary measures 14.3:1. Co-Authored-By: Claude Fable 5 --- packages/web/app/styles/design-system.css | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/packages/web/app/styles/design-system.css b/packages/web/app/styles/design-system.css index 321929d..e878b70 100644 --- a/packages/web/app/styles/design-system.css +++ b/packages/web/app/styles/design-system.css @@ -196,12 +196,13 @@ } /* Page atmosphere — the emerald-lit darkness of the original identity. - Static radial washes on an absolutely-positioned backdrop (PageShell): - an aurora behind the hero, a faint mid-page pool behind the demo, and a - low anchor near the Hephaestus band. Alphas stay <= 0.10 so every - AA-checked text pair is unaffected (worst case composites the canvas - from #0a0b0d toward #0d1410 — still darker than the audited #15171b - card ground). No animation: zero paint cost after first frame. */ + Four static radial washes on an absolutely-positioned backdrop + (PageShell): the hero aurora (peak alpha 0.17), a faint right-side pool + near the demo, a mid-page pool, and a low anchor near the Hephaestus + band. At the aurora peak the canvas composites from #0a0b0d to roughly + #0e2b1b; text-primary still measures 14.3:1 there (18.5:1 on the pure + canvas), so every AA-checked pair keeps a wide margin. No animation: + zero paint cost after first frame. */ .glow-backdrop { background: radial-gradient(72rem 30rem at 50% 4rem, rgba(34, 197, 94, 0.17), rgba(34, 197, 94, 0.06) 45%, transparent 68%), From d89e6888ce07bd348e88b155b1ccdd981f37855d Mon Sep 17 00:00:00 2001 From: YeonGyu-Kim Date: Fri, 3 Jul 2026 13:10:14 +0900 Subject: [PATCH 21/35] =?UTF-8?q?feat(demo):=20one=20session,=20one=20goal?= =?UTF-8?q?=20=E2=80=94=20the=20run=20narrative=20fixed?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit User-caught inconsistency: scenes rendered as separate Projects sessions, contradicting a single 30h+ run. The sidebar now shows ONE constant active session (ulw add authentication, running dot); scene navigation moves to the step pill's prev/next chevrons; the Pursuing-goal chip carries a per-scene elapsed time rising from 4m 08s to 1d 6h 47m. TDD: spec contract rewritten first, RED captured via stash (2 failing right-reason), then GREEN 7/7. Scene copy untouched; elapsed is an additive field. Co-Authored-By: Claude Fable 5 --- packages/web/app/styles/ulw-demo-app.css | 24 ++--- .../web/app/styles/ulw-demo-transcript.css | 40 ++++++++- .../components/site/ulw-demo/codex-window.tsx | 4 +- .../site/ulw-demo/window-chrome.tsx | 36 ++------ .../components/site/ulw-demo/window-icons.tsx | 2 + .../components/site/ulw-demo/window-panes.tsx | 29 ++++++- packages/web/e2e/ulw-demo.spec.ts | 87 ++++++++++++------- packages/web/lib/ulw-demo-scenes.ts | 9 ++ 8 files changed, 154 insertions(+), 77 deletions(-) diff --git a/packages/web/app/styles/ulw-demo-app.css b/packages/web/app/styles/ulw-demo-app.css index d5b3c89..ce0b9c8 100644 --- a/packages/web/app/styles/ulw-demo-app.css +++ b/packages/web/app/styles/ulw-demo-app.css @@ -94,24 +94,21 @@ color: var(--codex-window-text-soft); } - /* Session rows double as scene navigation (app-native tab replacement). */ + /* The ONE session of the run — static (not navigation; no hover): the + whole demo is a single goal being pursued, so the sidebar never changes. */ .ulw-app-session { - display: block; + display: flex; + align-items: center; + gap: 7px; width: 100%; text-align: left; - padding: 5px 8px 5px 30px; + padding: 5px 8px 5px 14px; border-radius: 7px; font-size: 12px; color: var(--codex-window-text-soft); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; - transition: background-color 150ms ease, color 150ms ease; - } - - .ulw-app-session:hover { - background: var(--codex-window-chip); - color: var(--codex-window-text); } .ulw-app-session[aria-current="true"] { @@ -120,7 +117,14 @@ font-weight: 600; } - .ulw-app-session:focus-visible, + .ulw-app-session-dot { + flex-shrink: 0; + width: 6px; + height: 6px; + border-radius: 999px; + background: var(--codex-window-accent); + } + .ulw-app-control:focus-visible { outline: 2px solid var(--codex-window-accent); outline-offset: 1px; diff --git a/packages/web/app/styles/ulw-demo-transcript.css b/packages/web/app/styles/ulw-demo-transcript.css index 9d3ce31..12574f8 100644 --- a/packages/web/app/styles/ulw-demo-transcript.css +++ b/packages/web/app/styles/ulw-demo-transcript.css @@ -87,8 +87,14 @@ flex-shrink: 0; } - .ulw-app-step { + .ulw-app-stepper { + display: flex; + align-items: center; align-self: center; + gap: 6px; + } + + .ulw-app-step { font-family: var(--font-mono); font-size: 10.5px; padding: 3px 10px; @@ -97,6 +103,38 @@ color: var(--codex-window-text-soft); } + .ulw-app-stepnav { + display: inline-flex; + align-items: center; + justify-content: center; + width: 22px; + height: 22px; + border-radius: 999px; + border: 1px solid var(--codex-window-border); + background: transparent; + color: var(--codex-window-text-soft); + cursor: pointer; + transition: color 150ms ease, border-color 150ms ease; + } + + .ulw-app-stepnav:hover:not(:disabled) { + color: var(--codex-window-text); + border-color: var(--codex-window-active-border); + } + + .ulw-app-stepnav:disabled { + opacity: 0.35; + cursor: default; + } + + .ulw-app-goal-elapsed { + margin-left: auto; + font-family: var(--font-mono); + font-size: 10.5px; + white-space: nowrap; + color: var(--codex-window-accent); + } + .ulw-app-goal { display: flex; align-items: center; diff --git a/packages/web/components/site/ulw-demo/codex-window.tsx b/packages/web/components/site/ulw-demo/codex-window.tsx index 49b03bb..4c08021 100644 --- a/packages/web/components/site/ulw-demo/codex-window.tsx +++ b/packages/web/components/site/ulw-demo/codex-window.tsx @@ -70,7 +70,7 @@ export function CodexWindow(): JSX.Element { />
- +
- +
diff --git a/packages/web/components/site/ulw-demo/window-chrome.tsx b/packages/web/components/site/ulw-demo/window-chrome.tsx index a766d3f..1ecae84 100644 --- a/packages/web/components/site/ulw-demo/window-chrome.tsx +++ b/packages/web/components/site/ulw-demo/window-chrome.tsx @@ -1,6 +1,5 @@ import type { JSX } from "react" import { SITE_CONFIG } from "../../../lib/site-config" -import { ULW_DEMO_SCENES } from "../../../lib/ulw-demo-scenes" import { UlwIcon, type UlwIconName } from "./window-icons" /** @@ -19,13 +18,7 @@ const SIDEBAR_NAV: readonly { icon: UlwIconName; label: string }[] = [ { icon: "clock", label: "Automations" }, ] -export function WindowSidebar({ - sceneIndex, - onSelectScene, -}: { - readonly sceneIndex: number - readonly onSelectScene: (index: number) => void -}): JSX.Element { +export function WindowSidebar(): JSX.Element { return (
- - -