diff --git a/apps/landing/src/App.tsx b/apps/landing/src/App.tsx index 20b6071..0c643dd 100644 --- a/apps/landing/src/App.tsx +++ b/apps/landing/src/App.tsx @@ -12,12 +12,13 @@ import { Faq } from './sections/Faq'; import { Footer } from './sections/Footer'; /** - * The mx landing + docs site: a single scrolling page that teaches mx from zero - * — hook (Hero), problem (Why), the core agent pitch (Agents), vocabulary - * (Concepts), hands-on (Quickstart), capabilities (Features), reference - * (Commands), objections (Faq), then a closing CTA (Footer). Ordered so each - * section builds on the last. Workflow (after Quickstart) shows one concrete - * end-to-end setup for using it day to day. + * The mx landing + docs site: a single scrolling page that teaches mx from zero. + * The story opens concrete — hook (Hero, with the Mission Control board), the + * pain (Why), then immediately the day-to-day Mission Control workflow + * (Workflow) so a newcomer "gets it" fast. Only then does it go into detail: + * the agent pitch (Agents), vocabulary (Concepts), hands-on (Quickstart), + * capabilities (Features), reference (Commands), objections (Faq), and a closing + * CTA (Footer). */ export function App() { const { theme, toggle } = useTheme(); @@ -27,10 +28,10 @@ export function App() {
+ - diff --git a/apps/landing/src/content.ts b/apps/landing/src/content.ts index 1e83ec8..82e0678 100644 --- a/apps/landing/src/content.ts +++ b/apps/landing/src/content.ts @@ -120,7 +120,7 @@ export const CONCEPTS: Concept[] = [ term: 'Runtime', plain: 'One folder on your machine where mx keeps everything.', detail: - 'Think of it as mx’s home base (default ~/mx). It holds your cloned repos and one folder per feature you’re working on. You can have several runtimes and switch with an environment variable.', + 'Think of it as mx’s home base (default ~/mx) — one runtime for everything. It holds your cloned repos and one folder per feature you’re working on.', }, { icon: 'box', @@ -186,7 +186,7 @@ export const STEPS: Step[] = [ title: 'Start a feature and dive in', cmd: 'mx work new my-feature app', comment: 'creates a worktree of "app" on branch my-feature', - body: 'This creates a feature and a git worktree for it. cd into works/my-feature/wt/app and you’re in a normal checkout on your feature branch — build, run, commit, push as usual. Start a second feature the same way; both stay isolated.', + body: 'This creates the feature and a worktree of app. Start your coding-agent session from the feature folder (works/my-feature) — it sees every worktree the feature has. The code lives in wt/app, a normal checkout on your branch; cd there when you want to run the dev server or git commands. Start a second feature the same way; both stay isolated.', }, ]; @@ -359,9 +359,8 @@ export const FAQS: Faq[] = [ */ export const NAV_LINKS: { label: string; href: string }[] = [ { label: 'Why mx', href: '#why' }, + { label: 'Workflow', href: '#workflow' }, { label: 'Agents', href: '#agents' }, { label: 'Concepts', href: '#concepts' }, - { label: 'Quickstart', href: '#quickstart' }, - { label: 'Workflow', href: '#workflow' }, { label: 'Commands', href: '#commands' }, ]; diff --git a/apps/landing/src/index.css b/apps/landing/src/index.css index 2fc9fc2..6865d5f 100644 --- a/apps/landing/src/index.css +++ b/apps/landing/src/index.css @@ -9,10 +9,10 @@ @custom-variant dark (&:where([data-theme='dark'], [data-theme='dark'] *)); /* - * Semantic design tokens — a calm, mostly-monochrome grayscale base with a warm - * amber/yellow accent drawn from the Tailwind palette (amber for the UI accent; - * the logo itself stays multi-pastel — teal/amber/rose with a violet source - * node). Emphasis comes from ink + * Semantic design tokens — a calm, mostly-monochrome grayscale base with a teal + * accent drawn from the Tailwind palette (teal for the UI accent, tying into the + * logo, which stays multi-pastel — teal/amber/rose with a violet source node). + * Emphasis comes from ink * weight and gray steps; the accent is used sparingly for the logo, one hero * phrase, prompts, links, icon chips, and the primary button. Light values are * the base; the dark override block below swaps them when @@ -37,13 +37,13 @@ --text-soft: #3f3f46; --muted: #71717a; --faint: #a1a1aa; - --accent: #d97706; /* amber-600 (readable amber on white) */ - --accent-ink: #b45309; /* amber-700 (readable link on white) */ - --accent-2: #d97706; - --accent-soft: rgba(245, 158, 11, 0.14); /* amber-500 @ 14% */ + --accent: #0d9488; /* teal-600 (readable teal on white) */ + --accent-ink: #0f766e; /* teal-700 (readable link on white) */ + --accent-2: #0d9488; + --accent-soft: rgba(20, 184, 166, 0.12); /* teal-500 @ 12% */ --accent-strong: #18181b; --on-accent: #ffffff; - --cta: #f59e0b; /* amber-500 button, white text */ + --cta: #0d9488; /* teal-600 button, white text */ --on-cta: #ffffff; --amber: #71717a; --code-bg: #f6f6f7; @@ -60,13 +60,13 @@ --text-soft: #c8c8ce; --muted: #9a9aa4; --faint: #63636d; - --accent: #fbbf24; /* amber-400 (bright gold on the dark canvas) */ - --accent-ink: #fcd34d; /* amber-300 */ - --accent-2: #fbbf24; - --accent-soft: rgba(251, 191, 36, 0.16); /* amber-400 @ 16% */ + --accent: #2dd4bf; /* teal-400 (bright teal on the dark canvas) */ + --accent-ink: #5eead4; /* teal-300 */ + --accent-2: #2dd4bf; + --accent-soft: rgba(45, 212, 191, 0.16); /* teal-400 @ 16% */ --accent-strong: #fafafa; --on-accent: #18181b; - --cta: #f59e0b; /* amber-500 button, white text */ + --cta: #0d9488; /* teal-600 button, white text */ --on-cta: #ffffff; --amber: #a1a1aa; --code-bg: #0d0d11; diff --git a/apps/landing/src/sections/Hero.tsx b/apps/landing/src/sections/Hero.tsx index d1ec9e1..9e46349 100644 --- a/apps/landing/src/sections/Hero.tsx +++ b/apps/landing/src/sections/Hero.tsx @@ -1,4 +1,5 @@ import { CopyButton, Icon, Logo } from '../ui'; +import { MissionControlStrip } from './MissionControlStrip'; import { PKG, REPO_URL } from '../content'; /** @@ -64,6 +65,16 @@ export function Hero() { Why mx? + + {/* The Mission Control board: every feature is its own Space, grouped by + stage — the whole "many parallel features" idea in one glance. */} +
+ +

+ Your whole board in macOS Mission Control — a Space per feature, grouped by stage with{' '} + mx divider. +

+
); diff --git a/apps/landing/src/sections/MissionControlStrip.tsx b/apps/landing/src/sections/MissionControlStrip.tsx new file mode 100644 index 0000000..4b44df9 --- /dev/null +++ b/apps/landing/src/sections/MissionControlStrip.tsx @@ -0,0 +1,71 @@ +/** + * The ordered contents of the Mission Control Spaces board: either a labeled + * `mx divider` Space (a group header) or one or more feature Spaces (small + * thumbnails) belonging to the preceding group. Kept compact so the whole board + * — every stage label — fits within the content width without horizontal + * scrolling. Mirrors a real board: MAIN, then in-progress features, then review + * stages. + */ +const STRIP: ({ divider: string } | { spaces: number })[] = [ + { divider: 'IN PROGRESS' }, + { spaces: 4 }, + { divider: 'IN REVIEWS' }, + { spaces: 2 }, + { divider: 'PR REVIEWS' }, + { spaces: 2 }, +]; + +/** + * A mock of the macOS Mission Control Spaces board: big block-text divider + * Spaces (from `mx divider`) act as group headers, with small feature-Space + * thumbnails clustered under each. Recreated as markup (not a screenshot) so it + * stays crisp and theme-aware. Wraps (rather than scrolls) on narrow screens so + * every stage stays visible. Shared by the hero and the workflow section. + */ +export function MissionControlStrip() { + return ( +
+
+ {STRIP.map((item, i) => + 'divider' in item ? ( +
+ {item.divider} +
+ ) : ( + Array.from({ length: item.spaces }).map((_, j) => ) + ), + )} +
+
+ ); +} + +/** + * One feature-Space thumbnail in the Mission Control board — a tiny split-pane + * window (terminal | editor) rendered abstractly with a few faint lines. + */ +function SpaceThumb() { + return ( +
+
+ + +
+
+
+ + + +
+
+ + + +
+
+
+ ); +} diff --git a/apps/landing/src/sections/Quickstart.tsx b/apps/landing/src/sections/Quickstart.tsx index 5f593d3..5508f98 100644 --- a/apps/landing/src/sections/Quickstart.tsx +++ b/apps/landing/src/sections/Quickstart.tsx @@ -34,9 +34,11 @@ export function Quickstart() {

- Now cd works/my-feature/wt/app and you’re in a normal git checkout on your - feature branch. Build it, run it, commit, push, open a PR — all the usual way. Start a - second feature with another mx work new and the two stay completely isolated. + Your coding-agent session runs from the feature folder (works/my-feature) — + its home base, with all the worktrees in view. The code itself lives in{' '} + wt/app, a normal git checkout on your branch; cd there to start + the dev server, commit, or push. Spin up another feature with mx work new and + the two stay completely isolated.

diff --git a/apps/landing/src/sections/Workflow.tsx b/apps/landing/src/sections/Workflow.tsx index 672c6cb..5837b32 100644 --- a/apps/landing/src/sections/Workflow.tsx +++ b/apps/landing/src/sections/Workflow.tsx @@ -2,19 +2,19 @@ import { Section, Command, Icon } from '../ui'; import { WORKFLOW_STEPS } from '../content'; /** - * The "In practice" section: one concrete, opinionated daily workflow — a - * fullscreen macOS Space per feature (terminal split with the editor), the - * agent in the first terminal tab, and a three-finger swipe to switch. It opens - * with a visual of the split layout, then the numbered steps. The lede stresses - * that mx doesn't mandate any of this; it's a starting shape to copy. + * The workflow section — the concrete story of how a feature goes from new to + * merged with mx: one fullscreen macOS Space per feature (terminal split with + * the editor), the coding agent in the first terminal tab, a three-finger swipe + * to switch, and archive on merge. Told as *the* workflow (not a hedged "one of + * many"), with the it-doesn't-have-to-be-this-way note saved for the end. */ export function Workflow() { return (
@@ -43,92 +43,21 @@ export function Workflow() { ))} -
-

Grouped in Mission Control

-

- Swipe up with three fingers and your whole board appears: feature Spaces clustered between{' '} - mx divider labels, so you always know what’s - in progress, in review, and merged. + {/* The flexibility note lives at the END — so the story reads as concrete + first, and "you don't have to do it this way" is the closing reassurance. */} +

+

+ This is the setup mx was built around — not a + requirement.{' '} + Use any editor, terminal, or window manager you like; mx just owns the folders, branches, + and ports underneath and stays out of the way. Once you have the loop, bend it to your own + tools.

-
); } -/** - * The ordered contents of the Mission Control Spaces strip: either a labeled - * `mx divider` Space (a group header) or one or more feature Spaces (small - * thumbnails) that belong to the preceding group. Mirrors the real layout a - * user arranges — MAIN, then in-progress features, then review stages. - */ -const STRIP: ({ divider: string } | { spaces: number })[] = [ - { divider: 'MAIN' }, - { spaces: 3 }, - { divider: 'IN PROGRESS' }, - { spaces: 4 }, - { divider: 'IN REVIEWS' }, - { spaces: 2 }, - { divider: 'PR REVIEWS' }, - { spaces: 1 }, - { divider: 'MX' }, - { spaces: 1 }, -]; - -/** - * A horizontally-scrolling mock of the macOS Mission Control Spaces bar: big - * block-text divider Spaces (from `mx divider`) act as group headers, with small - * feature-Space thumbnails clustered under each. Recreates the user's real - * board rather than a screenshot, so it stays crisp and theme-aware. - */ -function SpacesStrip() { - return ( -
-
- {STRIP.map((item, i) => - 'divider' in item ? ( -
- {item.divider} -
- ) : ( - Array.from({ length: item.spaces }).map((_, j) => ) - ), - )} -
-
- ); -} - -/** - * One feature-Space thumbnail in the Mission Control strip — a tiny split-pane - * window (terminal | editor) rendered abstractly with a few faint lines. - */ -function SpaceThumb() { - return ( -
-
- - -
-
-
- - - -
-
- - - -
-
-
- ); -} - /** * A stylized mock of one feature's fullscreen Space: a terminal pane on the left * (tab 1 = the agent session, tab 2 = the dev server) and the editor on the @@ -216,10 +145,7 @@ function TermTab({ label, active }: { label: string; active?: boolean }) { function SwipeArrow({ direction }: { direction: 'left' | 'right' }) { return (
- + {direction === 'left' ? 'prev feature' : 'next feature'}