+ {/* Header: ADE logo, with GitHub/Docs/close */}
-
}
- >
- GitHub
-
-
}>
- Docs
-
-
}
- >
- Install mobile app
-
-
}
- >
- Open video
-
-
-
-
+
+ {/* Body: video (left) + iOS QR panel (right) */}
+
+
setPlaying(true)}
+ />
+
+
+
+ {/* Surfaces strip: one app, every surface */}
+
+
+ One app, every surface
+
+
+ {SURFACES.map((surface, index) => (
+
+ ))}
+
+
@@ -243,6 +345,436 @@ export function WelcomeVideoGate({ onVisibilityChange }: WelcomeVideoGateProps)
);
}
+function VideoPanel({
+ playing,
+ onPlay,
+}: {
+ playing: boolean;
+ onPlay: () => void;
+}) {
+ return (
+
+ {playing ? (
+
+ ) : (
+
+
+
+
+
+ Watch the intro guide
+
+
+ )}
+
+ );
+}
+
+function PhonePanel({
+ copyState,
+ onDownload,
+ onCopy,
+}: {
+ copyState: CopyState;
+ onDownload: () => void;
+ onCopy: () => void;
+}) {
+ const copied = copyState === "copied";
+ const copyFailed = copyState === "failed";
+ let copyLabel = "Copy install link";
+ let copyColor = "var(--color-fg, #F5F3FF)";
+ if (copied) {
+ copyLabel = "Link copied";
+ copyColor = "var(--color-accent-bright, #C4B5FD)";
+ } else if (copyFailed) {
+ copyLabel = "Copy failed";
+ copyColor = "#FCA5A5";
+ }
+
+ return (
+
+ );
+}
+
+function SurfaceTile({
+ index,
+ surface,
+}: {
+ index: number;
+ surface: Surface;
+}) {
+ return (
+
openExternalUrl(surface.url)}
+ className="ade-welcome-card__tile"
+ aria-label={`${surface.label}: ${surface.blurb}`}
+ style={{
+ display: "flex",
+ flexDirection: "column",
+ alignItems: "center",
+ padding: 0,
+ border: "none",
+ background: "transparent",
+ color: "var(--color-fg, #F5F3FF)",
+ cursor: "pointer",
+ animationDelay: `${(index + 1) * 60}ms`,
+ }}
+ >
+
+ {surface.device === "macbook" &&
}
+ {surface.device === "phone" &&
}
+ {surface.device === "terminal" &&
}
+
+
+
{surface.label}
+
+ {surface.blurb}
+
+
+
+ );
+}
+
+function MacBookFrame({ src }: { src: string }) {
+ return (
+
+
+
+

+
+
+ {/* Base and hinge, wider than the screen for the laptop silhouette. */}
+
+
+ );
+}
+
+function PhoneFrame({ src }: { src: string }) {
+ return (
+
+ {/* dynamic island */}
+
+
+

+
+
+ );
+}
+
+function TerminalFrame({ src }: { src: string }) {
+ return (
+
+
+
+
+
+
+ ade - zsh
+
+
+
+

+
+
+ );
+}
+
function WelcomeActionButton({
children,
icon,
@@ -262,7 +794,7 @@ function WelcomeActionButton({
alignItems: "center",
gap: 7,
border: "1px solid color-mix(in srgb, var(--color-fg, #fff) 12%, transparent)",
- borderRadius: 7,
+ borderRadius: 8,
background: "color-mix(in srgb, var(--color-fg, #fff) 5%, transparent)",
color: "var(--color-fg, #F5F3FF)",
padding: "0 11px",
diff --git a/apps/desktop/src/renderer/index.css b/apps/desktop/src/renderer/index.css
index dc3f28d2f..fabf96140 100644
--- a/apps/desktop/src/renderer/index.css
+++ b/apps/desktop/src/renderer/index.css
@@ -3976,3 +3976,95 @@ button:active, [role="button"]:active {
.ade-fade-in {
animation: ade-fade-slide-up 0.3s ease-out both;
}
+
+/*
+ Welcome card (onboarding): split-hero layout.
+*/
+
+/* Card-specific entrance that preserves vertical centering (the global
+ dialog keyframe drops the -50% Y offset, which jumps a tall card). */
+.ade-welcome-card[data-state="open"] {
+ animation: ade-welcome-card-in 220ms cubic-bezier(0.34, 1.4, 0.64, 1);
+}
+
+@keyframes ade-welcome-card-in {
+ from { opacity: 0; transform: translate(-50%, -50%) scale(0.97); }
+ to { opacity: 1; transform: translate(-50%, -50%) scale(1); }
+}
+
+.ade-welcome-card__glow {
+ position: absolute;
+ top: 0;
+ left: 0;
+ right: 0;
+ height: 220px;
+ pointer-events: none;
+ z-index: 0;
+ background:
+ radial-gradient(120% 140% at 18% -20%, var(--color-accent-glow-strong, rgba(168, 130, 255, 0.22)), transparent 60%),
+ radial-gradient(90% 120% at 100% -10%, rgba(124, 58, 237, 0.16), transparent 55%);
+}
+
+.ade-welcome-card__body {
+ display: grid;
+ grid-template-columns: 1.55fr 1fr;
+ gap: 24px;
+ align-items: stretch;
+}
+
+.ade-welcome-card__surfaces {
+ display: grid;
+ grid-template-columns: repeat(3, 1fr);
+ gap: 16px;
+}
+
+.ade-welcome-card__tile {
+ animation: ade-welcome-tile-in 380ms cubic-bezier(0.34, 1.2, 0.64, 1) both;
+ transition: transform 160ms ease;
+}
+.ade-welcome-card__tile:hover {
+ transform: translateY(-3px);
+}
+
+.ade-welcome-card__qr {
+ transition: transform 180ms ease;
+}
+.ade-welcome-card__qr:hover {
+ transform: scale(1.06);
+}
+
+.ade-welcome-card__play {
+ transition: transform 160ms ease, box-shadow 160ms ease;
+}
+.ade-welcome-card__poster:hover .ade-welcome-card__play {
+ transform: translate(-50%, -50%) scale(1.08);
+}
+
+@keyframes ade-welcome-tile-in {
+ from { opacity: 0; transform: translateY(10px); }
+ to { opacity: 1; transform: translateY(0); }
+}
+
+@media (max-width: 720px) {
+ .ade-welcome-card__body { grid-template-columns: 1fr; }
+}
+
+@media (max-width: 640px) {
+ .ade-welcome-card__surfaces {
+ grid-template-columns: 1fr;
+ gap: 12px;
+ }
+}
+
+@media (prefers-reduced-motion: reduce) {
+ .ade-welcome-card[data-state="open"] { animation: none; }
+ .ade-welcome-card__tile,
+ .ade-welcome-card__qr,
+ .ade-welcome-card__play {
+ animation: none !important;
+ transition: none !important;
+ }
+ .ade-welcome-card__tile:hover { transform: none; }
+ .ade-welcome-card__qr:hover { transform: none; }
+ .ade-welcome-card__poster:hover .ade-welcome-card__play { transform: translate(-50%, -50%); }
+}
diff --git a/apps/desktop/src/renderer/public/welcome/ade-icon.webp b/apps/desktop/src/renderer/public/welcome/ade-icon.webp
new file mode 100644
index 000000000..c935dee53
Binary files /dev/null and b/apps/desktop/src/renderer/public/welcome/ade-icon.webp differ
diff --git a/apps/desktop/src/renderer/public/welcome/desktop.webp b/apps/desktop/src/renderer/public/welcome/desktop.webp
new file mode 100644
index 000000000..fffebdb96
Binary files /dev/null and b/apps/desktop/src/renderer/public/welcome/desktop.webp differ
diff --git a/apps/desktop/src/renderer/public/welcome/mobile.webp b/apps/desktop/src/renderer/public/welcome/mobile.webp
new file mode 100644
index 000000000..9f560def4
Binary files /dev/null and b/apps/desktop/src/renderer/public/welcome/mobile.webp differ
diff --git a/apps/desktop/src/renderer/public/welcome/tui.webp b/apps/desktop/src/renderer/public/welcome/tui.webp
new file mode 100644
index 000000000..e4a4a30f9
Binary files /dev/null and b/apps/desktop/src/renderer/public/welcome/tui.webp differ
diff --git a/apps/desktop/src/renderer/public/welcome/video-poster.jpg b/apps/desktop/src/renderer/public/welcome/video-poster.jpg
new file mode 100644
index 000000000..1f5eead5c
Binary files /dev/null and b/apps/desktop/src/renderer/public/welcome/video-poster.jpg differ
diff --git a/docs/ARCHITECTURE.md b/docs/ARCHITECTURE.md
index 2565d2390..325f9c8cd 100644
--- a/docs/ARCHITECTURE.md
+++ b/docs/ARCHITECTURE.md
@@ -664,7 +664,7 @@ Themes: six shipped themes (`e-paper`, `bloomberg`, `github`, `rainbow`, `sky`,
- `renderer/lib/dialogBus.ts` — tiny pub/sub that lets shared UI open/close dialogs by a stable id (`lanes.create`, `settings.ai`, etc.) without prop-drilling. Dialogs subscribe by id; a `subscribeAll` channel exists for devtools. Default singleton export `dialogBus`.
- `renderer/onboarding/docsLinks.ts` — typed registry of internal/public doc URLs (`docs.lanes`, `docs.cto`, …) used by `DidYouKnow`, glossary/help surfaces, and the `HelpMenu`.
-- `renderer/components/onboarding/WelcomeVideoGate.tsx` — app-level one-time welcome video overlay. Seen/dismissed state is stored in the global app state file, separate from per-project setup onboarding.
+- `renderer/components/onboarding/WelcomeVideoGate.tsx` — app-level one-time welcome card overlay with sanitized bundled screenshots/assets, a lazy intro video, and an ADE Mobile TestFlight QR/download/copy panel. Seen/dismissed state is stored in the global app state file, separate from per-project setup onboarding.
Related UI docs: [Terminals UI surfaces](./features/terminals-and-sessions/ui-surfaces.md), [Files and editor](./features/files-and-editor/README.md), and [Onboarding and settings](./features/onboarding-and-settings/README.md).
diff --git a/docs/features/onboarding-and-settings/README.md b/docs/features/onboarding-and-settings/README.md
index c0d2f28d3..14defbdf3 100644
--- a/docs/features/onboarding-and-settings/README.md
+++ b/docs/features/onboarding-and-settings/README.md
@@ -104,10 +104,13 @@ Renderer — onboarding:
video gate plus `DidYouKnow`; guided per-tab tours and the old
welcome wizard are no longer mounted.
- `apps/desktop/src/renderer/components/onboarding/WelcomeVideoGate.tsx`
- — one-time app-level welcome screen backed by global app state. It
- links to GitHub, the docs site, the ADE Mobile TestFlight install,
- and the current welcome YouTube video. The Help menu can replay it
+ — one-time app-level welcome card backed by global app state. It
+ uses sanitized bundled welcome assets, lazy-loads the intro video,
+ links to GitHub and the docs site, and includes an ADE Mobile
+ TestFlight QR/download/copy panel. The Help menu can replay it
without resetting setup.
+- `apps/desktop/src/renderer/public/welcome/` — sanitized bundled
+ screenshots/poster/icon assets consumed by the welcome card.
- `apps/desktop/src/renderer/components/onboarding/HelpMenu.tsx`
— persistent help menu in the top bar: glossary, docs links, welcome
video replay, and help preferences. Tour replay entries were removed