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:
Viktor Vaczi 2026-07-04 21:04:37 +02:00
commit f9696ac503
19 changed files with 292 additions and 125 deletions

View file

@ -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 &amp; 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

Before After
Before After

View 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>

View file

@ -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);
}

View file

@ -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 &amp; 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>

View file

@ -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 {

View file

@ -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;

View file

@ -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;

View file

@ -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 />

View file

@ -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 well save you a seat.
Multiplayer early access rolls out in waves. Join the waitlist and well save you a
seat.
</p>
<WaitlistForm

View file

@ -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 →
▶&nbsp; 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;

View file

@ -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>

View file

@ -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 PCBJams
<strong>cloud</strong> — hosted storage, sync across your devices, and shared workspaces for
your team — thats 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>

View file

@ -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>

View file

@ -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"
/>

View file

@ -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 cant 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 its
<strong>open source</strong>. Collaborate in our cloud when its convenient — and walk
away with every byte whenever you want.
PCBJam refuses the trade-off: <strong>real KiCad format</strong> in and out, and its
<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} />)}

View file

@ -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>

View file

@ -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 &amp; 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 &amp; 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"
/>

View file

@ -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>

View file

@ -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) ────────────────────────────────── */