site(landing): demo-first CTAs, light theme, honest copy; restore positioning map
Now that demo.pcbjam.com is live, the landing page leads with it instead
of "coming soon":
- Hero: "Open the live demo" is the primary CTA; the coming-soon panel is
replaced by a DemoLaunchCard (screenshot + play overlay, new tab — the
editor needs COOP/COEP so it can never be iframed here); waitlist demoted
to a ghost button under a "Want early access to multiplayer?" lead-in.
- Removed the Gerber demo and positioning-map sections, then restored the
positioning map per review — recolored for light theme and without the
multiplayer badge/legend ("Everyone picks one. We do both.").
- Light theme: flipped the :root ink tokens, darkened accent/signal for
contrast on white; fixed two dark-assumption bugs it exposed (header CTA
text losing to .nav>a specificity, DemoVideo play scrim derived from --bg).
- Copy: positioned around what's live (real KiCad in a tab) with
multiplayer explicitly "coming — join the waitlist"; cut untrue claims
(GitHub import, self-host, offline PWA -> roadmap); cut the jam metaphor
outside the product name; TrustBar fake-stat grid -> plain claims strip;
footer tagline + fallback meta description aligned.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01REwWZGkAz1AZUJw8yqxkCN
This commit is contained in:
parent
bd00bef96d
commit
f9696ac503
19 changed files with 292 additions and 125 deletions
|
|
@ -1,15 +1,15 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 820 600" width="820" height="600" role="img" aria-labelledby="pq-title pq-desc" font-family="system-ui, -apple-system, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif">
|
||||
<title id="pq-title">PCB tool positioning map</title>
|
||||
<desc id="pq-desc">A quadrant chart. The horizontal axis runs from desktop-install on the left to browser-native on the right; the vertical axis from proprietary at the bottom to open at the top. LibrePCB and KiCad sit top-left (open but desktop). KiCanvas sits top-right but is viewer-only. Flux and EasyEDA sit bottom-right (browser but proprietary). Altium 365 and OrCAD X sit bottom-left (desktop and proprietary). PCBJam sits alone in the top-right as the only browser-native, open, real-time-multiplayer tool.</desc>
|
||||
<desc id="pq-desc">A quadrant chart. The horizontal axis runs from desktop-install on the left to browser-native on the right; the vertical axis from proprietary at the bottom to open at the top. LibrePCB and KiCad sit top-left (open but desktop). KiCanvas sits top-right but is viewer-only. Flux and EasyEDA sit bottom-right (browser but proprietary). Altium 365 and OrCAD X sit bottom-left (desktop and proprietary). PCBJam sits alone in the top-right as the only full editor that is both browser-native and open.</desc>
|
||||
|
||||
<!-- panel -->
|
||||
<rect x="8" y="8" width="804" height="584" rx="16" fill="#11182e" stroke="#233052" stroke-width="1"/>
|
||||
<rect x="8" y="8" width="804" height="584" rx="16" fill="#f4f7fc" stroke="#d9e1f0" stroke-width="1"/>
|
||||
|
||||
<!-- top-right "whitespace" tint -->
|
||||
<rect x="410" y="64" width="338" height="232" fill="#4f7cff" fill-opacity="0.09"/>
|
||||
|
||||
<!-- axes -->
|
||||
<g stroke="#34436b" stroke-width="2" fill="#34436b">
|
||||
<g stroke="#aebad2" stroke-width="2" fill="#aebad2">
|
||||
<line x1="80" y1="296" x2="748" y2="296"/>
|
||||
<line x1="410" y1="64" x2="410" y2="528"/>
|
||||
<polygon points="748,296 734,289 734,303" stroke="none"/>
|
||||
|
|
@ -19,7 +19,7 @@
|
|||
</g>
|
||||
|
||||
<!-- axis labels -->
|
||||
<g fill="#9aa6c0" font-size="14" font-weight="600">
|
||||
<g fill="#5b6784" font-size="14" font-weight="600">
|
||||
<text x="410" y="50" text-anchor="middle">Open & yours</text>
|
||||
<text x="410" y="554" text-anchor="middle">Proprietary, locked-in</text>
|
||||
<text x="92" y="316" text-anchor="start">Desktop install</text>
|
||||
|
|
@ -27,7 +27,7 @@
|
|||
</g>
|
||||
|
||||
<!-- competitors -->
|
||||
<g fill="#8794ad">
|
||||
<g fill="#8b98b3">
|
||||
<circle cx="210" cy="150" r="5"/>
|
||||
<circle cx="250" cy="205" r="5"/>
|
||||
<circle cx="540" cy="200" r="5"/>
|
||||
|
|
@ -36,7 +36,7 @@
|
|||
<circle cx="210" cy="388" r="5"/>
|
||||
<circle cx="250" cy="448" r="5"/>
|
||||
</g>
|
||||
<g fill="#b4bfd6" font-size="15">
|
||||
<g fill="#3d4a68" font-size="15">
|
||||
<text x="224" y="155">LibrePCB</text>
|
||||
<text x="264" y="210">KiCad</text>
|
||||
<text x="554" y="205">KiCanvas</text>
|
||||
|
|
@ -45,16 +45,10 @@
|
|||
<text x="224" y="393">Altium 365</text>
|
||||
<text x="264" y="453">OrCAD X</text>
|
||||
</g>
|
||||
<text x="554" y="222" font-size="11" fill="#6b7796">viewer only</text>
|
||||
<text x="554" y="222" font-size="11" fill="#8b98b3">viewer only</text>
|
||||
|
||||
<!-- PCBJam marker (the only "all three") -->
|
||||
<!-- PCBJam marker (the only browser-native + open editor) -->
|
||||
<circle cx="590" cy="120" r="30" fill="#4f7cff" fill-opacity="0.12"/>
|
||||
<text x="590" y="130" text-anchor="middle" font-size="30" fill="#32d583">★</text>
|
||||
<text x="614" y="128" text-anchor="start" font-size="19" font-weight="700" fill="#e7ecf5">PCBJam</text>
|
||||
<rect x="560" y="140" width="170" height="24" rx="12" fill="#32d583" fill-opacity="0.15" stroke="#32d583" stroke-opacity="0.6"/>
|
||||
<text x="645" y="156" text-anchor="middle" font-size="12" fill="#32d583" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace">real-time multiplayer</text>
|
||||
|
||||
<!-- legend -->
|
||||
<text x="34" y="580" font-size="14" fill="#32d583">★</text>
|
||||
<text x="50" y="580" font-size="12" fill="#9aa6c0">= true real-time multiplayer (PCBJam only)</text>
|
||||
<text x="590" y="130" text-anchor="middle" font-size="30" fill="#2f57f5">★</text>
|
||||
<text x="614" y="128" text-anchor="start" font-size="19" font-weight="700" fill="#101729">PCBJam</text>
|
||||
</svg>
|
||||
|
|
|
|||
|
Before Width: | Height: | Size: 3.3 KiB After Width: | Height: | Size: 2.8 KiB |
119
site/src/components/DemoLaunchCard.astro
Normal file
119
site/src/components/DemoLaunchCard.astro
Normal file
|
|
@ -0,0 +1,119 @@
|
|||
---
|
||||
/**
|
||||
* DemoLaunchCard — a clickable "open the live demo" card: a real product
|
||||
* screenshot dimmed under a play button + CTA, opening the editor in a new tab.
|
||||
*
|
||||
* New tab is load-bearing, not a style choice: the editor needs COOP/COEP
|
||||
* (SharedArrayBuffer) and the landing page deliberately isn't cross-origin
|
||||
* isolated (it would break the no-COEP YouTube/iframe embeds), so the demo
|
||||
* can never be iframed here. Same mechanic as the Gerber viewer card.
|
||||
*/
|
||||
import { Picture } from 'astro:assets';
|
||||
import type { ImageMetadata } from 'astro';
|
||||
|
||||
interface Props {
|
||||
href: string;
|
||||
image: ImageMetadata;
|
||||
alt: string;
|
||||
cta?: string;
|
||||
sub?: string;
|
||||
class?: string;
|
||||
}
|
||||
|
||||
const {
|
||||
href,
|
||||
image,
|
||||
alt,
|
||||
cta = 'Open the live demo',
|
||||
sub = 'Opens in a new tab · no install, no account',
|
||||
class: cls = '',
|
||||
} = Astro.props;
|
||||
---
|
||||
|
||||
<a class={`launch-card ${cls}`} href={href} target="_blank" rel="noopener">
|
||||
<Picture
|
||||
src={image}
|
||||
formats={['avif', 'webp']}
|
||||
alt={alt}
|
||||
widths={[480, 768, 1280]}
|
||||
sizes="(max-width: 880px) 92vw, 540px"
|
||||
loading="eager"
|
||||
decoding="async"
|
||||
/>
|
||||
<span class="launch-card__scrim" aria-hidden="true"></span>
|
||||
<span class="launch-card__play" aria-hidden="true">▶</span>
|
||||
<span class="launch-card__cta">{cta}</span>
|
||||
<span class="launch-card__sub">{sub}</span>
|
||||
</a>
|
||||
|
||||
<style>
|
||||
.launch-card {
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 0.6rem;
|
||||
width: 100%;
|
||||
aspect-ratio: 16 / 9;
|
||||
border: 1px solid var(--border);
|
||||
border-radius: var(--radius-lg);
|
||||
overflow: hidden;
|
||||
background: var(--bg-soft);
|
||||
color: var(--fg);
|
||||
text-decoration: none;
|
||||
transition: filter var(--dur) var(--ease);
|
||||
}
|
||||
.launch-card :global(img) {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
object-position: center top;
|
||||
}
|
||||
/* Dim the screenshot so the CTA stays legible. */
|
||||
.launch-card__scrim {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
background: linear-gradient(180deg, rgba(11, 16, 32, 0.45), rgba(11, 16, 32, 0.72));
|
||||
}
|
||||
.launch-card:hover {
|
||||
filter: brightness(1.06);
|
||||
text-decoration: none;
|
||||
}
|
||||
.launch-card__play,
|
||||
.launch-card__cta,
|
||||
.launch-card__sub {
|
||||
position: relative;
|
||||
}
|
||||
.launch-card__play {
|
||||
display: grid;
|
||||
place-items: center;
|
||||
width: 64px;
|
||||
height: 64px;
|
||||
border-radius: 999px;
|
||||
background: var(--brand-600);
|
||||
color: #fff;
|
||||
font-size: 1.4rem;
|
||||
padding-left: 4px;
|
||||
box-shadow: 0 6px 24px rgba(0, 0, 0, 0.35);
|
||||
}
|
||||
.launch-card__cta {
|
||||
font-weight: 600;
|
||||
font-size: 1.1rem;
|
||||
color: #fff;
|
||||
}
|
||||
.launch-card__sub {
|
||||
font-family: var(--font-mono);
|
||||
font-size: 0.78rem;
|
||||
color: rgba(255, 255, 255, 0.75);
|
||||
text-align: center;
|
||||
padding: 0 1rem;
|
||||
}
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
.launch-card {
|
||||
transition: none;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
@ -18,9 +18,11 @@ interface Props {
|
|||
poster?: string;
|
||||
caption?: string;
|
||||
ratio?: string; // default 16/9
|
||||
/** When true and no video yet, show a big "Demo coming soon" panel instead of
|
||||
/** When true and no video yet, show a big "coming soon" panel instead of
|
||||
* the internal PRODUCE placeholder. */
|
||||
comingSoon?: boolean;
|
||||
/** Panel text for the comingSoon state. */
|
||||
soonLabel?: string;
|
||||
class?: string;
|
||||
}
|
||||
|
||||
|
|
@ -31,6 +33,7 @@ const {
|
|||
caption,
|
||||
ratio = '16 / 9',
|
||||
comingSoon = false,
|
||||
soonLabel = 'Demo coming soon',
|
||||
class: cls = '',
|
||||
} = Astro.props;
|
||||
const hasVideo = Boolean(mp4 || webm);
|
||||
|
|
@ -58,7 +61,7 @@ const hasVideo = Boolean(mp4 || webm);
|
|||
</div>
|
||||
) : comingSoon ? (
|
||||
<div class="demo-soon bp-grid" style={`aspect-ratio:${ratio};`}>
|
||||
<span class="demo-soon-text">Demo coming soon</span>
|
||||
<span class="demo-soon-text">{soonLabel}</span>
|
||||
</div>
|
||||
) : (
|
||||
<Placeholder
|
||||
|
|
@ -95,7 +98,9 @@ const hasVideo = Boolean(mp4 || webm);
|
|||
display: grid;
|
||||
place-items: center;
|
||||
border: 0;
|
||||
background: color-mix(in srgb, var(--bg) 35%, transparent);
|
||||
/* Fixed dark scrim (not --bg-derived): white glyph over video needs a dark
|
||||
veil in both themes. */
|
||||
background: rgba(11, 16, 32, 0.35);
|
||||
color: #fff;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
|
@ -113,8 +118,8 @@ const hasVideo = Boolean(mp4 || webm);
|
|||
background-color: var(--bg-soft);
|
||||
}
|
||||
.demo-soon-text {
|
||||
font-size: clamp(1.6rem, 5.5vw, 3rem);
|
||||
font-weight: 800;
|
||||
font-size: clamp(1.1rem, 3vw, 1.75rem);
|
||||
font-weight: 700;
|
||||
letter-spacing: -0.01em;
|
||||
color: var(--fg);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ const BUILD_COMMIT_URL = `https://github.com/emergence-engineering/pcbjam/commit
|
|||
<img src="/favicon.svg" alt="" width="18" height="25" />
|
||||
<span>PCBJam</span>
|
||||
</a>
|
||||
<p class="tagline muted">KiCad, in your browser. Now multiplayer.</p>
|
||||
<p class="tagline muted">Real KiCad, in your browser. No install.</p>
|
||||
<nav class="links" aria-label="PCBJam">
|
||||
<a href={GITHUB_URL} rel="noopener" target="_blank">
|
||||
<Icon name="icons/github.svg" size="0.9rem" alt="" /> GitHub
|
||||
|
|
@ -35,7 +35,7 @@ const BUILD_COMMIT_URL = `https://github.com/emergence-engineering/pcbjam/commit
|
|||
<nav class="links stack" aria-label="Product">
|
||||
<a href="/#how-it-works">How it works</a>
|
||||
<a href="/#open">Open & yours</a>
|
||||
<a href="/#demo">Live demo</a>
|
||||
<a href="https://demo.pcbjam.com" target="_blank" rel="noopener">Live demo</a>
|
||||
<a href="/#waitlist">Join the waitlist</a>
|
||||
</nav>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -118,6 +118,12 @@ const isActive = (href: string, external?: boolean) =>
|
|||
padding-block: 0.5rem;
|
||||
font-size: 0.95rem;
|
||||
}
|
||||
/* `.nav > a` (higher specificity than .btn-primary) sets the muted link color;
|
||||
re-assert the button's white text — dark-on-blue otherwise. */
|
||||
.nav > a.cta-join,
|
||||
.nav > a.cta-join:hover {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
/* Mobile menu (CSS-only via checkbox toggle). */
|
||||
.hamburger {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
---
|
||||
/** Step — one numbered "how a jam works" step (§11). Body via default slot. */
|
||||
/** Step — one numbered how-it-works step (§11). Body via default slot. */
|
||||
import Icon from './Icon.astro';
|
||||
interface Props {
|
||||
n: number;
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ interface Props {
|
|||
|
||||
const {
|
||||
title,
|
||||
description = 'PCBJam — open-source PCB design in your browser, with real-time multiplayer. Built on KiCad.',
|
||||
description = 'PCBJam — open-source PCB design in your browser. Real KiCad, no install. Built on KiCad.',
|
||||
wide = false,
|
||||
ogImage = '/og/og-home.png',
|
||||
} = Astro.props;
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@ import TrustBar from '../sections/TrustBar.astro';
|
|||
import Pillars from '../sections/Pillars.astro';
|
||||
import HowItWorks from '../sections/HowItWorks.astro';
|
||||
import CapabilityProof from '../sections/CapabilityProof.astro';
|
||||
import GerberDemoSection from '../sections/GerberDemoSection.astro';
|
||||
import OpenYours from '../sections/OpenYours.astro';
|
||||
import MigrationStrip from '../sections/MigrationStrip.astro';
|
||||
import PositioningMap from '../sections/PositioningMap.astro';
|
||||
|
|
@ -14,11 +13,8 @@ import MakeMoney from '../sections/MakeMoney.astro';
|
|||
import AiNote from '../sections/AiNote.astro';
|
||||
import FinalCta from '../sections/FinalCta.astro';
|
||||
|
||||
// Toggle the optional positioning-map section (§15).
|
||||
const SHOW_MAP = true;
|
||||
|
||||
const description =
|
||||
'Open-source PCB design in your browser with real-time collaboration. Built on KiCad. No install, open format, free to start. Join the waitlist.';
|
||||
'Real KiCad in your browser — schematic capture, PCB layout, DRC, 3D, Gerber export. No install, open format, free. Multiplayer collaboration coming. Try the live demo.';
|
||||
|
||||
const jsonLd = {
|
||||
'@context': 'https://schema.org',
|
||||
|
|
@ -37,7 +33,7 @@ const jsonLd = {
|
|||
---
|
||||
|
||||
<BaseLayout
|
||||
title="PCBJam — KiCad in your browser, now multiplayer"
|
||||
title="PCBJam — real KiCad in your browser, no install"
|
||||
description={description}
|
||||
wide
|
||||
>
|
||||
|
|
@ -50,13 +46,12 @@ const jsonLd = {
|
|||
|
||||
<Hero />
|
||||
<TrustBar />
|
||||
<GerberDemoSection />
|
||||
<Pillars />
|
||||
<HowItWorks />
|
||||
<CapabilityProof />
|
||||
<OpenYours />
|
||||
<MigrationStrip />
|
||||
{SHOW_MAP && <PositioningMap />}
|
||||
<PositioningMap />
|
||||
<BuiltByEmergence />
|
||||
<MakeMoney />
|
||||
<AiNote />
|
||||
|
|
|
|||
|
|
@ -5,9 +5,10 @@ import WaitlistForm from '../components/WaitlistForm.astro';
|
|||
|
||||
<SectionBand grid class="final" labelledby="final-h2">
|
||||
<div class="final-inner">
|
||||
<h2 id="final-h2">Be there when the first jam opens.</h2>
|
||||
<h2 id="final-h2">Be first in when multiplayer opens.</h2>
|
||||
<p class="lead">
|
||||
Early access rolls out in waves. Join the waitlist and we’ll save you a seat.
|
||||
Multiplayer early access rolls out in waves. Join the waitlist and we’ll save you a
|
||||
seat.
|
||||
</p>
|
||||
|
||||
<WaitlistForm
|
||||
|
|
|
|||
|
|
@ -1,37 +1,41 @@
|
|||
---
|
||||
import WaitlistForm from '../components/WaitlistForm.astro';
|
||||
import DemoVideo from '../components/DemoVideo.astro';
|
||||
import Icon from '../components/Icon.astro';
|
||||
import DemoLaunchCard from '../components/DemoLaunchCard.astro';
|
||||
import pcbnew from '../assets/screens/pcbnew.png';
|
||||
---
|
||||
|
||||
<section class="hero bp-grid">
|
||||
<div class="container hero-grid">
|
||||
<div class="hero-copy">
|
||||
<span class="eyebrow">PCBJam · built on KiCad</span>
|
||||
<h1>KiCad, in your browser — now multiplayer.</h1>
|
||||
<h1>Real KiCad. In your browser. No install.</h1>
|
||||
<p class="lead">
|
||||
The PCB design tool millions trust — now zero-install and collaborative. Open a
|
||||
board in a tab, invite your team, and edit the same schematic and layout together
|
||||
in real time. Open format. No install. Free to start.
|
||||
The full KiCad suite, compiled to WebAssembly and running in a tab. Open your own
|
||||
board, route, run DRC, spin it in 3D, export Gerbers — the real engine, not a
|
||||
re-implementation. Multiplayer co-editing is coming: join the waitlist for early
|
||||
access.
|
||||
</p>
|
||||
|
||||
<WaitlistForm source="hero" id="waitlist" class="hero-form" />
|
||||
|
||||
<p class="hero-secondary">
|
||||
<p class="hero-cta">
|
||||
<a
|
||||
class="btn btn-primary btn-demo"
|
||||
href="https://demo.pcbjam.com"
|
||||
class="try"
|
||||
target="_blank"
|
||||
rel="noopener"
|
||||
>
|
||||
Open the live editor →
|
||||
</a>
|
||||
<span class="dot" aria-hidden="true">·</span>
|
||||
<a href="#multiplayer" class="watch">
|
||||
<Icon name="icons/play.svg" size="1.1rem" alt="" /> Watch the 90-second demo →
|
||||
▶ Open the live demo
|
||||
</a>
|
||||
<span class="hero-cta-sub">Free · no install, no account</span>
|
||||
</p>
|
||||
|
||||
<p class="hero-wl-lead">Want early access to multiplayer?</p>
|
||||
<WaitlistForm
|
||||
source="hero"
|
||||
id="waitlist"
|
||||
class="hero-form"
|
||||
microcopy="Collab rolls out in waves — get your invite."
|
||||
/>
|
||||
|
||||
<ul class="hero-trust">
|
||||
<li>Open source</li>
|
||||
<li>Your files stay in KiCad format</li>
|
||||
|
|
@ -40,11 +44,13 @@ import Icon from '../components/Icon.astro';
|
|||
</div>
|
||||
|
||||
<div class="hero-visual">
|
||||
{/* TODO(assets): swap for hero board still w/ presence cursors (§4b.3) or the
|
||||
multiplayer demo loop (§4b.2) once produced. */}
|
||||
<DemoVideo
|
||||
comingSoon
|
||||
caption="2 editors · live cursors · one board.kicad_pcb · no merge step"
|
||||
{/* TODO(assets): swap the poster for a hero board still w/ presence cursors
|
||||
(§4b.3) or the multiplayer demo loop (§4b.2) once produced. */}
|
||||
<DemoLaunchCard
|
||||
href="https://demo.pcbjam.com"
|
||||
image={pcbnew}
|
||||
alt="KiCad Pcbnew editing the pic_programmer demo board in a browser tab — open the live demo"
|
||||
sub="Real KiCad in your browser · opens in a new tab"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -64,32 +70,43 @@ import Icon from '../components/Icon.astro';
|
|||
font-size: clamp(2rem, 5vw, 3.25rem);
|
||||
margin-bottom: 0.75rem;
|
||||
}
|
||||
.hero-form {
|
||||
margin-top: 1.5rem;
|
||||
max-width: 30rem;
|
||||
}
|
||||
.hero-secondary {
|
||||
margin: 1rem 0 0;
|
||||
.hero-cta {
|
||||
margin: 1.5rem 0 0;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
gap: 0.4rem 0.75rem;
|
||||
gap: 0.5rem 1rem;
|
||||
}
|
||||
.try {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
font-weight: 600;
|
||||
color: var(--accent);
|
||||
.btn-demo {
|
||||
padding: 0.85rem 1.6rem;
|
||||
font-size: 1.05rem;
|
||||
}
|
||||
.dot {
|
||||
.hero-cta-sub {
|
||||
font-size: 0.85rem;
|
||||
color: var(--fg-muted);
|
||||
}
|
||||
.watch {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 0.4rem;
|
||||
.hero-wl-lead {
|
||||
margin: 1.75rem 0 0.5rem;
|
||||
font-weight: 600;
|
||||
font-size: 0.95rem;
|
||||
}
|
||||
.hero-form {
|
||||
max-width: 30rem;
|
||||
}
|
||||
/* One primary action per hero: the demo button. Demote the waitlist submit
|
||||
to ghost weight (it stays full-primary in the final CTA and footer).
|
||||
.hero-copy anchors the scope — .hero-form itself sits on the WaitlistForm
|
||||
root, which doesn't carry this component's scope attribute. */
|
||||
.hero-copy :global(.hero-form .btn-primary) {
|
||||
background: transparent;
|
||||
border-color: var(--border);
|
||||
color: var(--fg);
|
||||
}
|
||||
.hero-copy :global(.hero-form .btn-primary:hover) {
|
||||
border-color: var(--accent);
|
||||
color: var(--accent);
|
||||
filter: none;
|
||||
}
|
||||
.hero-trust {
|
||||
list-style: none;
|
||||
display: flex;
|
||||
|
|
|
|||
|
|
@ -5,20 +5,19 @@ import Step from '../components/Step.astro';
|
|||
|
||||
<SectionBand id="how-it-works" labelledby="hiw-h2">
|
||||
<div class="section-head">
|
||||
<h2 id="hiw-h2">From link to layout in three moves.</h2>
|
||||
<h2 id="hiw-h2">From file to fab in three moves.</h2>
|
||||
</div>
|
||||
<div class="steps">
|
||||
<Step n={1} title="Open a board.">
|
||||
Paste a link, drag in a <code>.kicad_pcb</code>, or pull from GitHub. It opens in seconds —
|
||||
no install, no account wall to <em>look</em>.
|
||||
Drag in a <code>.kicad_pcb</code> or start from the demo board. It opens in seconds —
|
||||
no install, no account.
|
||||
</Step>
|
||||
<Step n={2} title="Start a jam.">
|
||||
Share the URL. Teammates join with live cursors and presence. Everyone sees the same
|
||||
board update in real time.
|
||||
<Step n={2} title="Design and route.">
|
||||
Schematic capture, PCB layout, interactive routing, DRC/ERC, 3D view — the real KiCad
|
||||
toolset.
|
||||
</Step>
|
||||
<Step n={3} title="Design, route & export — together.">
|
||||
Schematic capture, PCB layout, DRC/ERC, 3D, BOM, and Gerbers — the full flow, then hand
|
||||
off to any fab. Your call.
|
||||
<Step n={3} title="Export and ship.">
|
||||
BOM and Gerbers straight from the browser — hand off to any fab. Your call.
|
||||
</Step>
|
||||
</div>
|
||||
</SectionBand>
|
||||
|
|
|
|||
|
|
@ -18,8 +18,8 @@ const row = [
|
|||
The editor and the open file format are <strong>free</strong> — design entirely in your
|
||||
browser, with your files stored locally on your own machine. When you want PCBJam’s
|
||||
<strong>cloud</strong> — hosted storage, sync across your devices, and shared workspaces for
|
||||
your team — that’s the paid part. The open core stays free, and your local files are always
|
||||
yours.
|
||||
your team — that will be the paid part. The open core stays free, and your local files are
|
||||
always yours.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
|
|
|
|||
|
|
@ -14,8 +14,7 @@ const sources = ['EAGLE', 'Altium', 'CADSTAR', 'OrCAD'];
|
|||
<h3 id="mig-h3">Coming from EAGLE, Altium, CADSTAR, or OrCAD?</h3>
|
||||
<p class="muted">
|
||||
KiCad is where designs are migrating — and PCBJam opens them in a browser tab, free,
|
||||
with nothing to install. <em>Bring your board. Invite your team. Pick up where you left
|
||||
off.</em>
|
||||
with nothing to install. <em>Bring your board. Pick up where you left off.</em>
|
||||
</p>
|
||||
<a class="btn btn-primary" href="#waitlist">Join the waitlist →</a>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -34,9 +34,13 @@ const subpoints = [
|
|||
</p>
|
||||
</div>
|
||||
|
||||
{/* Slim band, not a hero-sized panel: the single-user demo is live (see the
|
||||
hero), only the multiplayer demo video doesn't exist yet. */}
|
||||
<DemoVideo
|
||||
class="mp-demo"
|
||||
comingSoon
|
||||
soonLabel="Multiplayer demo video coming soon"
|
||||
ratio="21 / 5"
|
||||
caption="2 editors · live cursors · one board.kicad_pcb · no merge step"
|
||||
/>
|
||||
|
||||
|
|
|
|||
|
|
@ -2,25 +2,19 @@
|
|||
import SectionBand from '../components/SectionBand.astro';
|
||||
import Chip from '../components/Chip.astro';
|
||||
|
||||
const chips = [
|
||||
'Open .kicad_pcb / .kicad_sch',
|
||||
'Self-hostable',
|
||||
'Offline PWA',
|
||||
'Open source (GPL)',
|
||||
];
|
||||
const chips = ['Open .kicad_pcb / .kicad_sch', 'Open source (GPL)'];
|
||||
---
|
||||
|
||||
<SectionBand id="open" labelledby="open-h2">
|
||||
<div class="section-head open-copy">
|
||||
<span class="eyebrow">No lock-in. No data hostage.</span>
|
||||
<h2 id="open-h2">Design <em>and</em> collaborate in the browser — without surrendering your files.</h2>
|
||||
<h2 id="open-h2">Design in the browser — without surrendering your files.</h2>
|
||||
<p class="lead">
|
||||
Cloud EDA tools trap your designs in proprietary formats and clouds you can’t leave.
|
||||
Desktop open-source tools keep you free but strand you offline and solo. PCBJam refuses
|
||||
the trade-off: <strong>real KiCad format</strong> in and out, <strong>self-host</strong>
|
||||
it on your own server, run it <strong>offline as a PWA</strong>, and it’s
|
||||
<strong>open source</strong>. Collaborate in our cloud when it’s convenient — and walk
|
||||
away with every byte whenever you want.
|
||||
PCBJam refuses the trade-off: <strong>real KiCad format</strong> in and out, and it’s
|
||||
<strong>open source</strong> — the same <code>.kicad_pcb</code> your desktop KiCad opens,
|
||||
so you can walk away with every byte whenever you want. Self-hosting and an offline PWA
|
||||
are on the roadmap.
|
||||
</p>
|
||||
<div class="cluster">
|
||||
{chips.map((c) => <Chip label={c} />)}
|
||||
|
|
|
|||
|
|
@ -12,13 +12,13 @@ import Pillar from '../components/Pillar.astro';
|
|||
Zero install, zero toolchain. Mac, Linux, Windows, Chromebook, iPad — if it has a
|
||||
modern browser, it designs PCBs.
|
||||
</Pillar>
|
||||
<Pillar title="Truly multiplayer.">
|
||||
Live cursors, presence, and conflict-free co-editing on the same board. Plus
|
||||
pin-to-canvas comments for review.
|
||||
<Pillar title="Multiplayer, next.">
|
||||
Live cursors, presence, and conflict-free co-editing on the same board — rolling out
|
||||
to the waitlist first.
|
||||
</Pillar>
|
||||
<Pillar title="Open & yours.">
|
||||
Real KiCad format in, real KiCad format out. Self-host it, run it offline as a PWA, or
|
||||
use our cloud — your files are never held hostage.
|
||||
Real KiCad format in, real KiCad format out — your files are never held hostage.
|
||||
Self-hosting and an offline PWA are on the roadmap.
|
||||
</Pillar>
|
||||
</div>
|
||||
</SectionBand>
|
||||
|
|
|
|||
|
|
@ -4,11 +4,11 @@ import SectionBand from '../components/SectionBand.astro';
|
|||
|
||||
<SectionBand labelledby="pos-h3">
|
||||
<div class="section-head">
|
||||
<h3 id="pos-h3">Everyone picks two. We do all three.</h3>
|
||||
<h3 id="pos-h3">Everyone picks one. We do both.</h3>
|
||||
<p class="lead">
|
||||
Browser-native. Open & yours. Truly multiplayer. Flux is browser + collab but closed.
|
||||
KiCanvas is browser + open but read-only. LibrePCB is open + full but desktop-only.
|
||||
<strong>PCBJam is the only one in the middle.</strong>
|
||||
Browser-native. Open & yours. Flux and EasyEDA are browser-based but closed.
|
||||
KiCanvas is browser + open but a viewer. KiCad and LibrePCB are open but desktop-only.
|
||||
<strong>PCBJam is the only full editor that's both.</strong>
|
||||
</p>
|
||||
</div>
|
||||
<img
|
||||
|
|
@ -16,7 +16,7 @@ import SectionBand from '../components/SectionBand.astro';
|
|||
src="/graphics/positioning-quadrant.svg"
|
||||
width="820"
|
||||
height="600"
|
||||
alt="Positioning map: PCBJam is the only PCB tool that is browser-native, open, and truly real-time multiplayer. Flux and EasyEDA are browser-based but proprietary; KiCanvas is browser and open but viewer-only; LibrePCB and KiCad are open but desktop-only; Altium 365 and OrCAD X are desktop and proprietary."
|
||||
alt="Positioning map: PCBJam is the only full PCB editor that is both browser-native and open. Flux and EasyEDA are browser-based but proprietary; KiCanvas is browser and open but viewer-only; LibrePCB and KiCad are open but desktop-only; Altium 365 and OrCAD X are desktop and proprietary."
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -1,23 +1,54 @@
|
|||
---
|
||||
import SectionBand from '../components/SectionBand.astro';
|
||||
import StatBar from '../components/StatBar.astro';
|
||||
|
||||
// TODO(numbers): replace with defensible, current figures. Pull PCBJam-native
|
||||
// counts (boards opened in beta, GitHub stars) once they exist (§8, §31.6).
|
||||
const stats = [
|
||||
{ value: 'Millions', label: 'KiCad users worldwide' },
|
||||
{ value: 'Largest', label: 'open component & footprint library in EDA' },
|
||||
{ value: '100%', label: 'open file format — your .kicad_pcb / .kicad_sch' },
|
||||
{ value: 'Free', label: 'to start — no credit card' },
|
||||
// Plain claims, not stat headlines — no fake precision to source or defend.
|
||||
// Swap in PCBJam-native numbers (boards opened, GitHub stars) once they exist (§8).
|
||||
const claims = [
|
||||
'Built on KiCad — trusted by millions',
|
||||
'the largest open footprint library in EDA',
|
||||
'100% open .kicad_pcb format',
|
||||
'free to start',
|
||||
];
|
||||
---
|
||||
|
||||
<SectionBand tone="soft" flush class="trust">
|
||||
<StatBar stats={stats} />
|
||||
<p class="claims">
|
||||
{
|
||||
claims.map((c, i) => (
|
||||
<>
|
||||
{i > 0 && (
|
||||
<span class="sep" aria-hidden="true">
|
||||
·
|
||||
</span>
|
||||
)}
|
||||
<span class="claim">{c}</span>
|
||||
</>
|
||||
))
|
||||
}
|
||||
</p>
|
||||
</SectionBand>
|
||||
|
||||
<style>
|
||||
.trust :global(.container) {
|
||||
padding-block: 1.75rem;
|
||||
padding-block: 1.25rem;
|
||||
}
|
||||
.claims {
|
||||
margin: 0;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: center;
|
||||
align-items: baseline;
|
||||
gap: 0.35rem 0.75rem;
|
||||
text-align: center;
|
||||
font-size: 0.95rem;
|
||||
color: var(--fg-muted);
|
||||
}
|
||||
.claim:first-of-type {
|
||||
color: var(--fg);
|
||||
font-weight: 600;
|
||||
}
|
||||
.sep {
|
||||
color: var(--fg-muted);
|
||||
opacity: 0.5;
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -5,20 +5,23 @@
|
|||
@import "tailwindcss/utilities.css" layer(utilities);
|
||||
|
||||
:root {
|
||||
/* ── Ink neutrals (authoritative; existing names kept) ───────────────── */
|
||||
--bg: #0b1020; /* ink-950 */
|
||||
--bg-soft: #11182e; /* ink-900 / surface */
|
||||
--fg: #e7ecf5; /* ink-100 */
|
||||
--fg-muted: #9aa6c0; /* ink-400 */
|
||||
--border: #233052; /* ink-800 */
|
||||
color-scheme: light;
|
||||
|
||||
/* ── Ink neutrals (authoritative; existing names kept — the *roles* stayed,
|
||||
the values flipped to the light theme) ────────────────────────────── */
|
||||
--bg: #ffffff; /* page */
|
||||
--bg-soft: #f4f7fc; /* surface / soft band */
|
||||
--fg: #101729; /* ink-950 text */
|
||||
--fg-muted: #5b6784; /* muted text */
|
||||
--border: #d9e1f0; /* hairlines / bp-grid dots */
|
||||
|
||||
/* ── Primary (Circuit Blue) ─────────────────────────────────────────── */
|
||||
--accent: #4f7cff; /* brand-500 (links/accents) */
|
||||
--accent: #2f57f5; /* links/accents (darker than the dark-theme 4f7cff for contrast on white) */
|
||||
--brand-600: #2f57f5; /* primary button */
|
||||
--brand-700: #1d4ed8; /* favicon / deep */
|
||||
|
||||
/* ── Signal (green / "live" presence) ───────────────────────────────── */
|
||||
--signal-400: #32d583; /* online text */
|
||||
--signal-400: #0a9b62; /* online text/icons (dark-theme value 32d583 is illegible on white) */
|
||||
--signal-600: #039855; /* online fill / success */
|
||||
|
||||
/* ── Presence palette (peer cursors) ────────────────────────────────── */
|
||||
|
|
|
|||
Loading…
Reference in a new issue