Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
311 changes: 164 additions & 147 deletions apps/www/src/app.css

Large diffs are not rendered by default.

4 changes: 3 additions & 1 deletion apps/www/src/app.html
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
<!doctype html>
<html lang="en" data-theme="dark">
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="icon" href="%sveltekit.assets%/favicon.svg" />
<link rel="preload" href="%sveltekit.assets%/fonts/geist-latin-variable.woff2" as="font" type="font/woff2" crossorigin />
<script>document.documentElement.classList.add('js')</script>
<meta name="theme-color" content="#1A0602" />
%sveltekit.head%
</head>
<body data-sveltekit-preload-data="hover" class="antialiased">
Expand Down
6 changes: 4 additions & 2 deletions apps/www/src/lib/AppPreview.svelte
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
<script lang="ts">
import { ChevronRight, CornerDownLeft, Plus } from '@lucide/svelte';

let { kind }: { kind: string } = $props();
let { kind, bare = false }: { kind: string; bare?: boolean } = $props();

// UI details follow the app captures in design-references/2026-09-20.
</script>

<div class="app-preview" role="img" aria-label={kind === 'agent' ? 'Close-up of the Powermove prompt box with provider, model, and reasoning controls.' : kind === 'extensions' ? 'Example extensions in Powermove Settings, with Motion tracking switched off and Audio-reactive visuals switched on.' : 'Close-up of the Powermove Export dialog showing Code and Video choices and the live animation export description.'}>
<div class="app-preview" class:bare role="img" aria-label={kind === 'agent' ? 'Close-up of the Powermove prompt box with provider, model, and reasoning controls.' : kind === 'extensions' ? 'Example extensions in Powermove Settings, with Motion tracking switched off and Audio-reactive visuals switched on.' : 'Close-up of the Powermove Export dialog showing Code and Video choices and the live animation export description.'}>
{#if kind === 'agent'}
<div class="agent-crop">
<div class="agent" aria-hidden="true">
Expand Down Expand Up @@ -60,6 +60,8 @@
<style>
.app-preview{text-align:left;display:flex;align-items:center;justify-content:center;box-sizing:border-box;min-width:0;background:var(--bg-panel-2);font-family:var(--f-ui);font-size:13px;line-height:1.45;color:var(--tx);user-select:none}
.app-preview{position:relative;width:min(calc(100% - 16px),1280px);aspect-ratio:16/9;padding:0;border-radius:var(--r-xl);box-shadow:var(--shadow-panel);overflow:hidden;isolation:isolate;container-type:inline-size}
.app-preview.bare{width:100%;border-radius:0;box-shadow:none}
.app-preview.bare::after{display:none}
.app-preview::after{content:"";position:absolute;inset:0;border-radius:inherit;box-shadow:inset 0 0 0 1px rgb(var(--ink-rgb) / .08);pointer-events:none}
.preview-scene{position:absolute;left:0;top:0;width:360px;height:202.5px;transform:scale(calc(100cqw / 360px));transform-origin:top left}
.extension-settings{position:absolute;left:50%;top:50%;width:312px;transform:translate(-50%,-50%)}
Expand Down
27 changes: 8 additions & 19 deletions apps/www/src/lib/Features.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -23,23 +23,12 @@

</script>

<section class="features" aria-labelledby="features-title">
<div class="wrap">
<h2 id="features-title" class="section-heading"><span class="strong">Welcome to malleable software.</span></h2>
<div class="feature-layout">
<div class="blocks">
{#each features as f (f.id)}
<article class="block" id={f.id}>
<AppPreview kind={f.id} />
<div class="copy">
<div>
<h3>{f.label}</h3>
<p class="lead"><span class="strong">{f.lead}</span> {f.text}</p>
</div>
</div>
</article>
{/each}
</div>
{#each features as f (f.id)}
<article class="row" id={f.id} aria-labelledby="{f.id}-title">
<div class="row-copy">
<h3 id="{f.id}-title">{f.label}</h3>
<p><span class="strong">{f.lead}</span> {f.text}</p>
</div>
</div>
</section>
<div class="row-media"><AppPreview kind={f.id} bare /></div>
</article>
{/each}
81 changes: 81 additions & 0 deletions apps/www/src/lib/Footer.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
<script lang="ts">
import { GITHUB, RELEASES } from '$lib/links';
import { download, resolveDownload, stars } from '$lib/download.svelte';

type Link = { label: string; href: string; external?: boolean };

const year = new Date().getFullYear();
const columns: { title: string; links: Link[] }[] = [
{
title: 'Product',
links: [
{ label: 'Editor', href: '/#editor' },
{ label: 'Agent', href: '/#agent' },
{ label: 'Extensions', href: '/#extensions' },
{ label: 'Export', href: '/#export' },
],
},
{
title: 'Open source',
links: [
{ label: 'Source code', href: GITHUB, external: true },
{ label: 'Releases', href: RELEASES, external: true },
{ label: 'Launch video', href: 'https://www.youtube.com/watch?v=r2t1dhxHjkQ', external: true },
],
},
{
title: 'Company',
links: [
{ label: 'Iterative Computer', href: 'https://iterative.computer', external: true },
{ label: 'hello@iterative.computer', href: 'mailto:hello@iterative.computer' },
{ label: 'Privacy', href: '/privacy' },
{ label: 'Terms', href: '/terms' },
],
},
];

$effect(() => { resolveDownload(); });
</script>

<!-- The page sinks back into the stage it opened on: paper warming through our
orange into near-black, with everything set at the header's scale. -->
<footer class="site-footer">
<div class="foot-dusk" aria-hidden="true"></div>
<div class="foot-inner">
<div class="foot-lead">
<a class="foot-mark" href="/#top" aria-label="Powermove home"><span aria-hidden="true"></span></a>
<p class="foot-line">Powermove is free and open source, for Macs with Apple silicon.</p>
<div class="foot-cta">
<a class="pill light" href={download.href}>Download for Mac</a>
<a class="pill glass" href={GITHUB} target="_blank" rel="noopener">Star on GitHub{#if stars.label} <span class="pill-count tabular">{stars.label}</span>{/if}</a>
</div>
</div>

<nav class="foot-nav" aria-label="Footer">
{#each columns as column (column.title)}
<div>
<h2>{column.title}</h2>
<ul>
{#each column.links as link (link.href)}
<li>
{#if link.external}
<a href={link.href} target="_blank" rel="noopener">{link.label}<span class="ext" aria-hidden="true">↗</span></a>
{:else}
<a href={link.href}>{link.label}</a>
{/if}
</li>
{/each}
</ul>
</div>
{/each}
</nav>

<div class="foot-base">
<span>© <span class="tabular">{year}</span> Iterative Computer</span>
<span class="foot-meta">
{#if download.version}<a href={RELEASES} target="_blank" rel="noopener">Version <span class="tabular">{download.version}</span></a>{/if}
<a href="{GITHUB}/blob/main/LICENSE" target="_blank" rel="noopener">AGPL-3.0</a>
</span>
</div>
</div>
</footer>
67 changes: 29 additions & 38 deletions apps/www/src/lib/Header.svelte
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
<script lang="ts">
import { X } from '@lucide/svelte';
import { GITHUB } from '$lib/links';
import { download, resolveDownload, stars } from '$lib/download.svelte';
import { download, resolveDownload } from '$lib/download.svelte';

// `onDark` is for the home page, where the bar sits on the hero's gradient.
let { onDark = false }: { onDark?: boolean } = $props();

const items = [
{ label: 'Editor', href: '/#editor' },
{ label: 'Agent', href: '/#agent' },
{ label: 'Extensions', href: '/#extensions' },
{ label: 'Export', href: '/#export' },
{ label: 'Features', href: '/#features' },
];

let open = $state(false);
Expand All @@ -16,7 +17,7 @@

$effect(() => {
if (!open) return;
const query = matchMedia('(max-width: 1023px)');
const query = matchMedia('(max-width: 767px)');
const apply = () => document.documentElement.classList.toggle('overflow-hidden', query.matches);
apply();
query.addEventListener('change', apply);
Expand All @@ -27,38 +28,28 @@
});
</script>

<header class="site-header" data-state={open ? 'active' : undefined}>
<nav aria-label="Main navigation">
<div class="bar">
<a class="logo" href="/#top" aria-label="Powermove home">
<img src="/powermove-logo.svg" width="24" height="21" alt="" />
<span>Powermove</span>
</a>
<ul class="links">
{#each items as item (item.href)}
<li><a href={item.href} onclick={() => (open = false)}>{item.label}</a></li>
{/each}
</ul>
<div class="actions">
<a class="button" href={GITHUB} target="_blank" rel="noopener" aria-label="Star Powermove on GitHub"><svg viewBox="0 0 24 24" width="16" height="16" aria-hidden="true"><path fill="currentColor" d="M12 .5C5.65.5.5 5.65.5 12c0 5.08 3.29 9.39 7.86 10.91.58.1.79-.25.79-.56v-2c-3.2.7-3.87-1.36-3.87-1.36-.52-1.33-1.28-1.68-1.28-1.68-1.04-.71.08-.7.08-.7 1.15.08 1.76 1.19 1.76 1.19 1.03 1.76 2.69 1.25 3.34.96.1-.75.4-1.25.73-1.54-2.55-.29-5.24-1.28-5.24-5.68 0-1.26.45-2.28 1.19-3.09-.12-.29-.52-1.46.11-3.05 0 0 .97-.31 3.17 1.18a11 11 0 0 1 5.78 0c2.2-1.49 3.17-1.18 3.17-1.18.63 1.59.23 2.76.11 3.05.74.81 1.19 1.83 1.19 3.09 0 4.41-2.69 5.38-5.26 5.67.41.36.78 1.05.78 2.12v3.14c0 .31.21.67.8.56A11.5 11.5 0 0 0 23.5 12C23.5 5.65 18.35.5 12 .5Z"/></svg>Star{#if stars.label} <span class="muted">{stars.label}</span>{/if}</a>
<a class="button primary" href={download.href}>Download</a>
</div>
<button class="menu" type="button" aria-label={open ? 'Close menu' : 'Open menu'} aria-expanded={open} onclick={() => (open = !open)}>
<span class="lines" aria-hidden="true"><i></i><i></i></span>
<X class="close" size={22} aria-hidden="true" />
</button>
</div>
<div class="sheet">
<ul>
{#each items as item (item.href)}
<li><a href={item.href} onclick={() => (open = false)}>{item.label}</a></li>
{/each}
</ul>
<div class="sheet-actions">
<a class="button" href={GITHUB} target="_blank" rel="noopener">Star on GitHub{#if stars.label} <span class="muted">{stars.label}</span>{/if}</a>
<a class="button primary" href={download.href}>Download for macOS</a>
</div>
</div>
<header class="site-header" data-on-dark={onDark ? '' : undefined} data-state={open ? 'active' : undefined}>
<nav class="bar" aria-label="Main navigation">
<a class="mark" href="/#top" aria-label="Powermove home"><span aria-hidden="true"></span></a>
<ul class="links">
{#each items as item (item.href)}
<li><a class="quiet" href={item.href} onclick={() => (open = false)}>{item.label}</a></li>
{/each}
<li><a href={GITHUB} target="_blank" rel="noopener">GitHub</a></li>
<li><a href={download.href}>Download</a></li>
</ul>
<button class="menu" type="button" aria-label={open ? 'Close menu' : 'Open menu'} aria-expanded={open} onclick={() => (open = !open)}>
<span class="lines" aria-hidden="true"><i></i><i></i></span>
<X class="close" size={20} aria-hidden="true" />
</button>
</nav>
<div class="sheet">
<ul>
{#each items as item (item.href)}
<li><a href={item.href} onclick={() => (open = false)}>{item.label}</a></li>
{/each}
<li><a href={GITHUB} target="_blank" rel="noopener">GitHub</a></li>
</ul>
<a class="pill dark" href={download.href}>Download for Mac</a>
</div>
</header>
<div class="header-fade" aria-hidden="true"></div>
Loading
Loading