feat(site): 🫙 PCBJam landing revisions — branding, accuracy, positioning graphic
Founder review pass on the landing page, plus commit the landing-page research/spec docs under features/lp. Branding & assets: - New PCBJam mark: convert the jam-jar image to favicon.svg (trimmed, rounded tile) and use it in the browser tab, header, and footer. - Footer "Built by": flower mark + "Emergence Engineering" in white Oswald (the blog's title font, self-hosted via @fontsource) so it's legible on dark. - Produce the positioning quadrant graphic (public/graphics) and drop the placeholder. Copy / accuracy: - Remove header GitHub link; point "Built by EE" + footer "About" to emergence-engineering.com; Built-by CTA -> mailto:contact@emergence-engineering.com. - Replace the wrong testimonial with Greg Detre's real quote from EE's site. - Drop blog icons from Multiplayer/Pillars/How-it-works; add "Coming soon" to live-cursors & pin-comment; drop the hard-coded Yjs mention. - Rework monetization to free+local / paid cloud-sync; remove "no metered AI", "no per-seat toll", and the Flux price claim; soften the AI section. - Reframe waitlist copy (incl. confirmation email) to newsletter + early access. Fixes: - Offset only #waitlist for the sticky header (scroll-margin-top); section anchors keep their original behavior. Docs: - Commit features/lp (copy spec, brand guide, competitive research) via force-add over the /features/ gitignore. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
7f9dbdd068
commit
735d8a48ee
31 changed files with 8149 additions and 135 deletions
BIN
site/brand/pcbjam-mark-source.png
Normal file
BIN
site/brand/pcbjam-mark-source.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.3 MiB |
10
site/package-lock.json
generated
10
site/package-lock.json
generated
|
|
@ -9,6 +9,7 @@
|
|||
"version": "0.0.1",
|
||||
"dependencies": {
|
||||
"@astrojs/vercel": "^10.0.8",
|
||||
"@fontsource/oswald": "^5.2.8",
|
||||
"astro": "^6.4.4",
|
||||
"resend": "^6.12.4"
|
||||
},
|
||||
|
|
@ -638,6 +639,15 @@
|
|||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@fontsource/oswald": {
|
||||
"version": "5.2.8",
|
||||
"resolved": "https://registry.npmjs.org/@fontsource/oswald/-/oswald-5.2.8.tgz",
|
||||
"integrity": "sha512-DFoPK1BqsFIQhVjs2xgO/oL9veF9oUJgFojEWIU+nazUrfqsBDtAMI4n9L9CZFX3kQNDLcCyzKx1xoEDvQT4WQ==",
|
||||
"license": "OFL-1.1",
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ayuhito"
|
||||
}
|
||||
},
|
||||
"node_modules/@img/colour": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@img/colour/-/colour-1.1.0.tgz",
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"@astrojs/vercel": "^10.0.8",
|
||||
"@fontsource/oswald": "^5.2.8",
|
||||
"astro": "^6.4.4",
|
||||
"resend": "^6.12.4"
|
||||
},
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
Before Width: | Height: | Size: 221 B After Width: | Height: | Size: 32 KiB |
60
site/public/graphics/positioning-quadrant.svg
Normal file
60
site/public/graphics/positioning-quadrant.svg
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
<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>
|
||||
|
||||
<!-- panel -->
|
||||
<rect x="8" y="8" width="804" height="584" rx="16" fill="#11182e" stroke="#233052" 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">
|
||||
<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"/>
|
||||
<polygon points="80,296 94,289 94,303" stroke="none"/>
|
||||
<polygon points="410,64 403,78 417,78" stroke="none"/>
|
||||
<polygon points="410,528 403,514 417,514" stroke="none"/>
|
||||
</g>
|
||||
|
||||
<!-- axis labels -->
|
||||
<g fill="#9aa6c0" 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>
|
||||
<text x="736" y="316" text-anchor="end">Browser-native</text>
|
||||
</g>
|
||||
|
||||
<!-- competitors -->
|
||||
<g fill="#8794ad">
|
||||
<circle cx="210" cy="150" r="5"/>
|
||||
<circle cx="250" cy="205" r="5"/>
|
||||
<circle cx="540" cy="200" r="5"/>
|
||||
<circle cx="540" cy="372" r="5"/>
|
||||
<circle cx="596" cy="440" r="5"/>
|
||||
<circle cx="210" cy="388" r="5"/>
|
||||
<circle cx="250" cy="448" r="5"/>
|
||||
</g>
|
||||
<g fill="#b4bfd6" font-size="15">
|
||||
<text x="224" y="155">LibrePCB</text>
|
||||
<text x="264" y="210">KiCad</text>
|
||||
<text x="554" y="205">KiCanvas</text>
|
||||
<text x="554" y="377">Flux</text>
|
||||
<text x="610" y="445">EasyEDA</text>
|
||||
<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>
|
||||
|
||||
<!-- PCBJam marker (the only "all three") -->
|
||||
<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>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.3 KiB |
|
|
@ -1,11 +1,14 @@
|
|||
---
|
||||
/**
|
||||
* EECredit — the "Built by Emergence Engineering" lockup. The EE wordmark keeps
|
||||
* its own (guest-brand) colors via Icon mode="img".
|
||||
* - variant="footer": wordmark + studio blurb + contact (footer column 3).
|
||||
* - variant="inline": compact wordmark + "Built by" label.
|
||||
* EECredit — the "Built by Emergence Engineering" lockup.
|
||||
* Uses the EE flower mark (keeps its orange) + the "Emergence Engineering"
|
||||
* wordmark set in Oswald (the blog's brand/title font) in a light color, so it
|
||||
* stays visible on the dark footer (the original wordmark SVG's text is near-black).
|
||||
* - variant="footer": lockup + studio blurb + contact (footer column 3).
|
||||
* - variant="inline": compact "Built by" lockup.
|
||||
*/
|
||||
import Icon from './Icon.astro';
|
||||
import '@fontsource/oswald/500.css';
|
||||
|
||||
interface Props {
|
||||
variant?: 'footer' | 'inline';
|
||||
|
|
@ -16,19 +19,33 @@ const { variant = 'footer', class: cls = '' } = Astro.props;
|
|||
|
||||
{
|
||||
variant === 'inline' ? (
|
||||
<a class={`ee-inline ${cls}`} href="/built-by-emergence">
|
||||
<a
|
||||
class={`ee-inline ${cls}`}
|
||||
href="https://emergence-engineering.com"
|
||||
target="_blank"
|
||||
rel="noopener"
|
||||
>
|
||||
<span class="ee-by">Built by</span>
|
||||
<Icon name="ee/ee-logo.svg" mode="img" size="1rem" alt="Emergence Engineering" />
|
||||
<Icon name="ee/ee-mark.svg" mode="img" size="1rem" alt="" />
|
||||
<span class="ee-wordmark">Emergence Engineering</span>
|
||||
</a>
|
||||
) : (
|
||||
<div class={`ee-footer ${cls}`}>
|
||||
<Icon name="ee/ee-logo.svg" mode="img" size="1.5rem" alt="Emergence Engineering" />
|
||||
<span class="ee-lockup">
|
||||
<Icon name="ee/ee-mark.svg" mode="img" size="1.6rem" alt="" />
|
||||
<span class="ee-wordmark">Emergence Engineering</span>
|
||||
</span>
|
||||
<p class="ee-blurb muted">
|
||||
PCBJam is a project by Emergence Engineering, a full-stack software studio. Need
|
||||
something hard built?{' '}
|
||||
<a href="mailto:contact@emergence-engineering.com">contact@emergence-engineering.com</a>
|
||||
</p>
|
||||
<a class="ee-link" href="/built-by-emergence">
|
||||
<a
|
||||
class="ee-link"
|
||||
href="https://emergence-engineering.com"
|
||||
target="_blank"
|
||||
rel="noopener"
|
||||
>
|
||||
About Emergence Engineering →
|
||||
</a>
|
||||
</div>
|
||||
|
|
@ -36,10 +53,17 @@ const { variant = 'footer', class: cls = '' } = Astro.props;
|
|||
}
|
||||
|
||||
<style>
|
||||
.ee-wordmark {
|
||||
font-family: 'Oswald', system-ui, sans-serif;
|
||||
font-weight: 500;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.04em;
|
||||
color: var(--fg);
|
||||
}
|
||||
.ee-inline {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
gap: 0.4rem;
|
||||
color: var(--fg-muted);
|
||||
}
|
||||
.ee-inline:hover {
|
||||
|
|
@ -55,6 +79,14 @@ const { variant = 'footer', class: cls = '' } = Astro.props;
|
|||
gap: 0.6rem;
|
||||
align-items: flex-start;
|
||||
}
|
||||
.ee-lockup {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
.ee-lockup .ee-wordmark {
|
||||
font-size: 1.05rem;
|
||||
}
|
||||
.ee-blurb {
|
||||
margin: 0;
|
||||
font-size: 0.85rem;
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ const GITHUB_URL = 'https://github.com/emergence-engineering';
|
|||
<div class="container cols">
|
||||
<div class="col col-brand">
|
||||
<a class="brand" href="/">
|
||||
<img src="/favicon.svg" alt="" width="22" height="22" />
|
||||
<img src="/favicon.svg" alt="" width="18" height="25" />
|
||||
<span>PCBJam</span>
|
||||
</a>
|
||||
<p class="tagline muted">KiCad, in your browser. Now multiplayer.</p>
|
||||
|
|
@ -85,6 +85,10 @@ const GITHUB_URL = 'https://github.com/emergence-engineering';
|
|||
font-weight: 700;
|
||||
color: var(--fg);
|
||||
}
|
||||
.brand img {
|
||||
height: 1.6rem;
|
||||
width: auto;
|
||||
}
|
||||
.tagline {
|
||||
margin: 0.6rem 0 0.9rem;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,28 +1,27 @@
|
|||
---
|
||||
import Icon from './Icon.astro';
|
||||
|
||||
// TODO(assets): replace favicon "K" + text wordmark with the real PCBJam logo (§4b.1).
|
||||
// TODO(links): add "Roadmap" → /roadmap and repoint How-it-works/Open to their own
|
||||
// pages once the supporting pages ship; for now they anchor to landing sections.
|
||||
// TODO(config): point at the public PCBJam repo when it exists.
|
||||
const GITHUB_URL = 'https://github.com/emergence-engineering';
|
||||
|
||||
const links = [
|
||||
{ href: '/#how-it-works', label: 'How it works' },
|
||||
{ href: '/#open', label: 'Open & yours' },
|
||||
{ href: '/blog', label: 'Blog' },
|
||||
{ href: '/#built-by', label: 'Built by Emergence Engineering' },
|
||||
{
|
||||
href: 'https://emergence-engineering.com',
|
||||
label: 'Built by Emergence Engineering',
|
||||
external: true,
|
||||
},
|
||||
];
|
||||
|
||||
const path = Astro.url.pathname;
|
||||
const isActive = (href: string) =>
|
||||
href.startsWith('/#') ? false : href === '/' ? path === '/' : path.startsWith(href);
|
||||
const isActive = (href: string, external?: boolean) =>
|
||||
external || href.startsWith('/#') ? false : href === '/' ? path === '/' : path.startsWith(href);
|
||||
---
|
||||
|
||||
<header class="site-header" transition:persist>
|
||||
<div class="container bar">
|
||||
<a class="brand" href="/">
|
||||
<img src="/favicon.svg" alt="" width="24" height="24" />
|
||||
<img src="/favicon.svg" alt="" width="20" height="28" />
|
||||
<span class="brand-name">PCBJam</span>
|
||||
<span class="brand-chip">built on KiCad</span>
|
||||
</a>
|
||||
|
|
@ -35,14 +34,16 @@ const isActive = (href: string) =>
|
|||
<nav class="nav" aria-label="Primary">
|
||||
{
|
||||
links.map((l) => (
|
||||
<a href={l.href} aria-current={isActive(l.href) ? 'page' : undefined}>
|
||||
<a
|
||||
href={l.href}
|
||||
aria-current={isActive(l.href, l.external) ? 'page' : undefined}
|
||||
rel={l.external ? 'noopener' : undefined}
|
||||
target={l.external ? '_blank' : undefined}
|
||||
>
|
||||
{l.label}
|
||||
</a>
|
||||
))
|
||||
}
|
||||
<a class="gh" href={GITHUB_URL} rel="noopener" target="_blank">
|
||||
<Icon name="icons/github.svg" size="1rem" alt="GitHub" /> <span>★</span>
|
||||
</a>
|
||||
<a class="btn btn-primary cta-join" href="/#waitlist">Join the waitlist</a>
|
||||
</nav>
|
||||
</div>
|
||||
|
|
@ -72,8 +73,8 @@ const isActive = (href: string) =>
|
|||
gap: 0.5rem;
|
||||
}
|
||||
.brand img {
|
||||
width: 1.5rem;
|
||||
height: 1.5rem;
|
||||
height: 1.85rem;
|
||||
width: auto;
|
||||
}
|
||||
.brand-chip {
|
||||
font-family: var(--font-mono);
|
||||
|
|
@ -99,11 +100,6 @@ const isActive = (href: string) =>
|
|||
.nav > a[aria-current='page'] {
|
||||
color: var(--fg);
|
||||
}
|
||||
.gh {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 0.25rem;
|
||||
}
|
||||
.cta-join {
|
||||
padding-block: 0.5rem;
|
||||
font-size: 0.95rem;
|
||||
|
|
@ -147,8 +143,7 @@ const isActive = (href: string) =>
|
|||
.nav-toggle:checked ~ .nav {
|
||||
display: flex;
|
||||
}
|
||||
.nav > a,
|
||||
.gh {
|
||||
.nav > a {
|
||||
padding-block: 0.6rem;
|
||||
border-bottom: 1px solid var(--border);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ const {
|
|||
source,
|
||||
id,
|
||||
layout = 'row',
|
||||
microcopy = "Early access rolls out in waves. We'll email you when your seat opens — no spam.",
|
||||
microcopy = 'Get early-access invites and the occasional product update — no spam, unsubscribe anytime.',
|
||||
class: cls = '',
|
||||
} = Astro.props;
|
||||
|
||||
|
|
@ -60,7 +60,7 @@ const hpId = `wl-hp-${source}`;
|
|||
|
||||
<div class="wl-success" hidden data-wl-success>
|
||||
<strong>You're on the list. 🎉</strong>
|
||||
<span class="muted">We'll email you when your early-access seat opens — no spam.</span>
|
||||
<span class="muted">We'll be in touch with product updates and your early-access invite.</span>
|
||||
</div>
|
||||
|
||||
{microcopy && <p class="wl-micro muted">{microcopy}</p>}
|
||||
|
|
|
|||
|
|
@ -79,10 +79,8 @@ export const POST: APIRoute = async ({ request }) => {
|
|||
text: [
|
||||
"You're on the list. 🎉",
|
||||
'',
|
||||
"We'll email you the moment your early-access seat opens. Early access rolls",
|
||||
'out in waves — no spam, just a heads-up when your seat is ready.',
|
||||
'',
|
||||
'In the meantime: star us on GitHub and follow along.',
|
||||
"We'll keep you posted with product updates, and send your early-access invite",
|
||||
'as seats open in waves. No spam — unsubscribe anytime.',
|
||||
'',
|
||||
'— The PCBJam team, built by Emergence Engineering',
|
||||
].join('\n'),
|
||||
|
|
|
|||
|
|
@ -7,11 +7,11 @@ import Icon from '../components/Icon.astro';
|
|||
<div class="ai">
|
||||
<Icon name="icons/ai.svg" mode="img" size="2.5rem" alt="" class="ai-icon" />
|
||||
<div>
|
||||
<h3 id="ai-h3">AI when you want it. Never a paywall, never a black box.</h3>
|
||||
<h3 id="ai-h3">AI when you want it — opt-in, never a black box.</h3>
|
||||
<p class="muted">
|
||||
Everyone else leads with an “AI hardware engineer.” We lead with <em>you</em> and an open
|
||||
tool you control. AI assistance is on the roadmap as an <strong>opt-in</strong> helper —
|
||||
never metered by the token, never the thing standing between you and your own board.
|
||||
never the thing standing between you and your own board.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -44,11 +44,12 @@ const clients = [
|
|||
</div>
|
||||
|
||||
<blockquote class="quote">
|
||||
“For any new product, they’re my go-to dev house. They work fast and to super high quality.”
|
||||
<cite>— Ben Whately</cite>
|
||||
“They are incredibly smart, you can trust them, and they’re great to work with. I cannot
|
||||
recommend them highly enough.”
|
||||
<cite>— Greg Detre, Chief Data Scientist & CTO</cite>
|
||||
</blockquote>
|
||||
|
||||
<a class="btn btn-ghost" href="/built-by-emergence">
|
||||
<a class="btn btn-ghost" href="mailto:contact@emergence-engineering.com">
|
||||
Need something hard built? → Talk to the team
|
||||
</a>
|
||||
</SectionBand>
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ import WaitlistForm from '../components/WaitlistForm.astro';
|
|||
<WaitlistForm
|
||||
source="final"
|
||||
class="final-form"
|
||||
microcopy="No spam. One email when your seat is ready. Unsubscribe anytime."
|
||||
microcopy="Get early-access invites and product updates. No spam, unsubscribe anytime."
|
||||
/>
|
||||
|
||||
<ul class="final-trust">
|
||||
|
|
|
|||
|
|
@ -8,15 +8,15 @@ import Step from '../components/Step.astro';
|
|||
<h2 id="hiw-h2">From link to layout in three moves.</h2>
|
||||
</div>
|
||||
<div class="steps">
|
||||
<Step n={1} title="Open a board." icon="icons/idea.svg">
|
||||
<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>.
|
||||
</Step>
|
||||
<Step n={2} title="Start a jam." icon="icons/prototype.svg">
|
||||
<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>
|
||||
<Step n={3} title="Design, route & export — together." icon="icons/product.svg">
|
||||
<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>
|
||||
|
|
|
|||
|
|
@ -2,11 +2,11 @@
|
|||
import SectionBand from '../components/SectionBand.astro';
|
||||
|
||||
const row = [
|
||||
{ title: 'Free core', body: 'The full editor and real-time collaboration, free to start.' },
|
||||
{ title: 'Free & local', body: 'The full editor, free. Your files live right in your browser.' },
|
||||
{ title: 'Open format', body: 'Your .kicad_pcb / .kicad_sch, open forever.' },
|
||||
{
|
||||
title: 'Paid for team scale',
|
||||
body: 'Private org workspaces, SSO, compliance, hosted storage.',
|
||||
title: 'Paid: cloud & sync',
|
||||
body: 'Hosted storage, cross-device sync, and shared team workspaces.',
|
||||
},
|
||||
];
|
||||
---
|
||||
|
|
@ -15,16 +15,11 @@ const row = [
|
|||
<div class="section-head">
|
||||
<h3 id="money-h3">Free to start — and the core stays open.</h3>
|
||||
<p class="lead">
|
||||
The full editor and real-time collaboration are <strong>free to start</strong>, and the
|
||||
file format is open, forever. Later, we’ll charge teams for the things teams actually need —
|
||||
private org workspaces, SSO and compliance, hosted storage, and optional AI assistance. The
|
||||
individual, open-source core isn’t the thing we paywall.
|
||||
<strong>No per-editor toll. No metered AI. No surprises.</strong>
|
||||
</p>
|
||||
{/* TODO(verify): point-in-time competitor pricing — Flux was ~$112–158/editor/mo.
|
||||
Re-verify before stating a hard number publicly (§17, §31.10). */}
|
||||
<p class="contrast muted">
|
||||
Some browser EDA tools charge over $100 per editor, per month. We won’t.
|
||||
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.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
|
|
@ -41,10 +36,6 @@ const row = [
|
|||
</SectionBand>
|
||||
|
||||
<style>
|
||||
.contrast {
|
||||
margin-top: 1rem;
|
||||
font-style: italic;
|
||||
}
|
||||
.money-card p {
|
||||
margin: 0.35rem 0 0;
|
||||
font-size: 0.95rem;
|
||||
|
|
|
|||
|
|
@ -1,23 +1,22 @@
|
|||
---
|
||||
import SectionBand from '../components/SectionBand.astro';
|
||||
import DemoVideo from '../components/DemoVideo.astro';
|
||||
import Icon from '../components/Icon.astro';
|
||||
|
||||
const subpoints = [
|
||||
{
|
||||
icon: 'icons/collab.svg',
|
||||
title: 'Live cursors & presence',
|
||||
body: 'See who’s here and where they’re working.',
|
||||
comingSoon: true,
|
||||
},
|
||||
{
|
||||
icon: 'icons/yjs.svg',
|
||||
title: 'Conflict-free editing',
|
||||
body: 'CRDT sync (Yjs) merges everyone’s edits — no overwrite wars.',
|
||||
body: 'CRDT sync merges everyone’s edits — no overwrite wars.',
|
||||
comingSoon: false,
|
||||
},
|
||||
{
|
||||
icon: 'icons/message.svg',
|
||||
title: 'Pin a comment to a pad',
|
||||
body: 'Review and resolve right on the canvas.',
|
||||
comingSoon: true,
|
||||
},
|
||||
];
|
||||
---
|
||||
|
|
@ -44,11 +43,11 @@ const subpoints = [
|
|||
{
|
||||
subpoints.map((s) => (
|
||||
<li class="subpoint">
|
||||
<Icon name={s.icon} mode="img" size="1.6rem" alt="" />
|
||||
<div>
|
||||
<strong>{s.title}</strong>
|
||||
<p class="muted">{s.body}</p>
|
||||
</div>
|
||||
<strong class="subpoint-title">
|
||||
{s.title}
|
||||
{s.comingSoon && <span class="badge">Coming soon</span>}
|
||||
</strong>
|
||||
<p class="muted">{s.body}</p>
|
||||
</li>
|
||||
))
|
||||
}
|
||||
|
|
@ -68,14 +67,30 @@ const subpoints = [
|
|||
grid-template-columns: repeat(3, 1fr);
|
||||
}
|
||||
.subpoint {
|
||||
padding-top: 0.85rem;
|
||||
border-top: 2px solid var(--accent);
|
||||
}
|
||||
.subpoint-title {
|
||||
display: flex;
|
||||
gap: 0.75rem;
|
||||
align-items: flex-start;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
.subpoint p {
|
||||
margin: 0.2rem 0 0;
|
||||
margin: 0.3rem 0 0;
|
||||
font-size: 0.95rem;
|
||||
}
|
||||
.badge {
|
||||
font-family: var(--font-mono);
|
||||
font-size: 0.7rem;
|
||||
font-weight: 600;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.04em;
|
||||
color: var(--signal-400);
|
||||
border: 1px solid color-mix(in srgb, var(--signal-400) 50%, transparent);
|
||||
border-radius: var(--radius-full, 9999px);
|
||||
padding: 0.1rem 0.5rem;
|
||||
}
|
||||
@media (max-width: 760px) {
|
||||
.subpoints {
|
||||
grid-template-columns: 1fr;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
---
|
||||
import SectionBand from '../components/SectionBand.astro';
|
||||
import Chip from '../components/Chip.astro';
|
||||
import Icon from '../components/Icon.astro';
|
||||
|
||||
const chips = [
|
||||
'Open .kicad_pcb / .kicad_sch',
|
||||
|
|
@ -12,40 +11,28 @@ const chips = [
|
|||
---
|
||||
|
||||
<SectionBand id="open" labelledby="open-h2">
|
||||
<div class="open-grid">
|
||||
<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>
|
||||
<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.
|
||||
</p>
|
||||
<div class="cluster">
|
||||
{chips.map((c) => <Chip label={c} />)}
|
||||
</div>
|
||||
<p class="reassure muted">
|
||||
PCBJam rides KiCad — a project backed for decades by CERN, the KiCad Services Corp, and a
|
||||
global community. This isn’t a VC bet that vanishes when the runway ends.
|
||||
</p>
|
||||
</div>
|
||||
<div class="open-art" aria-hidden="true">
|
||||
<Icon name="icons/cloud.svg" mode="img" size="5rem" />
|
||||
<Icon name="icons/github.svg" mode="mask" size="3rem" class="open-gh" />
|
||||
<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>
|
||||
<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.
|
||||
</p>
|
||||
<div class="cluster">
|
||||
{chips.map((c) => <Chip label={c} />)}
|
||||
</div>
|
||||
<p class="reassure muted">
|
||||
PCBJam rides KiCad — a project backed for decades by CERN, the KiCad Services Corp, and a
|
||||
global community. This isn’t a VC bet that vanishes when the runway ends.
|
||||
</p>
|
||||
</div>
|
||||
</SectionBand>
|
||||
|
||||
<style>
|
||||
.open-grid {
|
||||
display: grid;
|
||||
grid-template-columns: 1.4fr 0.6fr;
|
||||
gap: 2rem;
|
||||
align-items: center;
|
||||
}
|
||||
.open-copy {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
|
@ -57,19 +44,4 @@ const chips = [
|
|||
font-size: 0.9rem;
|
||||
max-width: 40rem;
|
||||
}
|
||||
.open-art {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 1rem;
|
||||
color: var(--accent);
|
||||
}
|
||||
@media (max-width: 820px) {
|
||||
.open-grid {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
.open-art {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -8,15 +8,15 @@ import Pillar from '../components/Pillar.astro';
|
|||
<h2 id="pillars-h2">Three things that set PCBJam apart.</h2>
|
||||
</div>
|
||||
<div class="cards-3">
|
||||
<Pillar title="Runs in a browser tab." icon="icons/responsive.svg" iconMode="img">
|
||||
<Pillar title="Runs in a browser tab.">
|
||||
Zero install, zero toolchain. Mac, Linux, Windows, Chromebook, iPad — if it has a
|
||||
modern browser, it designs PCBs.
|
||||
</Pillar>
|
||||
<Pillar title="Truly multiplayer." icon="icons/collab.svg" iconMode="img">
|
||||
<Pillar title="Truly multiplayer.">
|
||||
Live cursors, presence, and conflict-free co-editing on the same board. Plus
|
||||
pin-to-canvas comments for review.
|
||||
</Pillar>
|
||||
<Pillar title="Open & yours." icon="icons/github.svg" iconMode="mask">
|
||||
<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.
|
||||
</Pillar>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
---
|
||||
import SectionBand from '../components/SectionBand.astro';
|
||||
import Placeholder from '../components/Placeholder.astro';
|
||||
---
|
||||
|
||||
<SectionBand labelledby="pos-h3">
|
||||
|
|
@ -12,10 +11,25 @@ import Placeholder from '../components/Placeholder.astro';
|
|||
<strong>PCBJam is the only one in the middle.</strong>
|
||||
</p>
|
||||
</div>
|
||||
{/* TODO(assets): build the quadrant/Venn graphic on the you-are-here motif (§4b.5). */}
|
||||
<Placeholder
|
||||
label="PRODUCE: positioning quadrant — Browser × Open × Multiplayer (§15)"
|
||||
kind="image"
|
||||
ratio="2 / 1"
|
||||
<img
|
||||
class="pos-map"
|
||||
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."
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
/>
|
||||
</SectionBand>
|
||||
|
||||
<style>
|
||||
.pos-map {
|
||||
display: block;
|
||||
width: 100%;
|
||||
max-width: 46rem;
|
||||
height: auto;
|
||||
margin-inline: auto;
|
||||
border: 1px solid var(--border);
|
||||
border-radius: var(--radius-lg);
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ 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 card, no per-seat toll' },
|
||||
{ value: 'Free', label: 'to start — no credit card' },
|
||||
];
|
||||
---
|
||||
|
||||
|
|
|
|||
|
|
@ -225,6 +225,13 @@ main.wide {
|
|||
padding-block: 0;
|
||||
}
|
||||
|
||||
/* Only the hero waitlist form needs an anchor offset for the sticky header —
|
||||
the section anchors (#how-it-works, #open) already clear it via their own
|
||||
top padding, so we don't touch global scroll behavior. */
|
||||
#waitlist {
|
||||
scroll-margin-top: 5rem;
|
||||
}
|
||||
|
||||
/* Visually-hidden but accessible (labels, honeypot). */
|
||||
.sr-only {
|
||||
position: absolute;
|
||||
|
|
|
|||
Loading…
Reference in a new issue