Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
c47a76a
Portfolio: mention the Embedding Atlas constructs world
claude Sep 22, 2026
7389638
smoke: require only the dumbmodel link the portfolio still carries
claude Sep 22, 2026
b2d815a
Add shared frame: tokens, type, chrome, theme, icon set and social cards
claude Sep 23, 2026
689d7b4
Home: opening card and the work as a sequence of frames; add 404
claude Sep 23, 2026
fb42980
Family: move onto the shared frame and themes
claude Sep 23, 2026
7e9a8e5
Graphify: title-card header, themed panels and theme-aware graph
claude Sep 23, 2026
1379e70
Chips: shared chrome, themed page, stages kept as dark screens
claude Sep 23, 2026
e009992
Smoke: check every page's meta, local assets and sitemap; README
claude Sep 23, 2026
38b64af
Add redesign screenshots (1440 and 390, light and dark)
claude Sep 23, 2026
f6c4da7
Merge earlier branch history (its tree is already on master)
claude Sep 23, 2026
fd25d49
Remove the Family page from jcamd.com
claude Sep 23, 2026
caa6a6f
Merge the merged #19 branch history (its content is already on master)
claude Sep 23, 2026
114f70c
Move the vector games from the work frames into the Lab
claude Sep 23, 2026
76ea460
Dottie: add /dottie/, the platform, scout, the router, System One, do…
claude Sep 23, 2026
e90c779
Home: point the Dottie frame at /dottie/, rewrite scout, retire the A…
claude Sep 23, 2026
cbe25a6
Smoke, sitemap and docs for /dottie/
claude Sep 23, 2026
19c44bb
Merge the earlier branch history (its content is already on master)
claude Sep 23, 2026
4fd5b97
Dottie page: quote the current router eval report (83.6% tie on 61 me…
claude Sep 23, 2026
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
2 changes: 2 additions & 0 deletions 404.html
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
<li><a href="/chips/">Chips</a></li>
</ul>
<ul class="chrome__list chrome__list--r">
<li><a href="/dottie/">Dottie</a></li>
<li><a href="/#craft">Craft</a></li>
<li><a href="/#contact">Contact</a></li>
</ul>
Expand Down Expand Up @@ -71,6 +72,7 @@ <h1 class="title" id="nf-title">Page not found</h1>
<p class="label">Austin, Texas</p>
<ul class="colophon__links">
<li><a href="/#work">Work</a></li>
<li><a href="/dottie/">Dottie</a></li>
<li><a href="/graphify/">Graph</a></li>
<li><a href="/chips/">Chips</a></li>
<li><a href="https://github.com/jcdavis131" rel="noopener">GitHub</a></li>
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ Texas. Static HTML/CSS, no build step, served by the Vercel project `jcamd`.
| `index.html` | Portfolio: opening card, the work as a sequence of frames, timeline, craft, lab, stack, contact |
| `assets/frame.css` / `frame.js` | Shared design layer for every page: tokens (type scale, spacing, one accent, light + dark), header, footer, theme toggle, reveals, print |
| `assets/portfolio.css` | Home page composition |
| `dottie/index.html` | Dottie: the platform, scout, the router (one-point-perspective diagram), System One (Choice / Score / Noul), dottie-os, the hive, and an honest status ledger |
| `chips/index.html` | CPU vs GPU vs DPU, exploded in 3D (three.js); the stages stay dark in both themes |
| `graphify/` | Static knowledge-graph viewer |
| `404.html` | Not-found page (Vercel serves it automatically) |
Expand Down
Binary file added assets/og/og-dottie.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 2 additions & 0 deletions chips/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,7 @@
<li><a href="/chips/" aria-current="page">Chips</a></li>
</ul>
<ul class="chrome__list chrome__list--r">
<li><a href="/dottie/">Dottie</a></li>
<li><a href="/#craft">Craft</a></li>
<li><a href="/#contact">Contact</a></li>
</ul>
Expand Down Expand Up @@ -621,6 +622,7 @@ <h2>Provenance</h2>
<p class="label">Austin, Texas</p>
<ul class="colophon__links">
<li><a href="/#work">Work</a></li>
<li><a href="/dottie/">Dottie</a></li>
<li><a href="/graphify/">Graph</a></li>
<li><a href="/chips/" aria-current="page">Chips</a></li>
<li><a href="https://github.com/jcdavis131" rel="noopener">GitHub</a></li>
Expand Down
Binary file added docs/redesign/dottie-desktop-light.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/redesign/dottie-mobile-dark.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/redesign/dottie-router-desktop-dark.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/redesign/dottie-status-mobile-light.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/redesign/dottie-system-one-desktop-light.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/redesign/home-work-desktop-dark.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
732 changes: 732 additions & 0 deletions dottie/index.html

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions graphify/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@
<li><a href="/chips/">Chips</a></li>
</ul>
<ul class="chrome__list chrome__list--r">
<li><a href="/dottie/">Dottie</a></li>
<li><a href="/#craft">Craft</a></li>
<li><a href="/#contact">Contact</a></li>
</ul>
Expand Down Expand Up @@ -198,6 +199,7 @@ <h1 id="g-title">Personal Graphify</h1>
<p class="label">Austin, Texas</p>
<ul class="colophon__links">
<li><a href="/#work">Work</a></li>
<li><a href="/dottie/">Dottie</a></li>
<li><a href="/graphify/">Graph</a></li>
<li><a href="/chips/">Chips</a></li>
<li><a href="https://github.com/jcdavis131" rel="noopener">GitHub</a></li>
Expand Down
47 changes: 19 additions & 28 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
<title>JC Davis — Builds AI products</title>
<meta name="description" content="JC Davis is an independent builder in Austin, Texas. Embedding Atlas, Dottie, and the vector game suite — AI products on real data.">
<meta name="description" content="JC Davis is an independent builder in Austin, Texas. Embedding Atlas, Dottie (scout, the router and System One), and the vector game suite — AI products on real data.">
<link rel="canonical" href="https://jcamd.com/">
<script>(function(r){r.classList.add('js');try{var t=localStorage.getItem('jcamd-theme');if(t==='light'||t==='dark')r.setAttribute('data-theme',t);if(!matchMedia('(prefers-reduced-motion: reduce)').matches&&!sessionStorage.getItem('jcamd-intro')){r.classList.add('intro');sessionStorage.setItem('jcamd-intro','1')}}catch(e){}})(document.documentElement)</script>
<link rel="preload" href="/assets/fonts/jost-latin.woff2" as="font" type="font/woff2" crossorigin>
Expand All @@ -17,15 +17,15 @@
<meta property="og:type" content="website">
<meta property="og:site_name" content="JC Davis">
<meta property="og:title" content="JC Davis — Builds AI products">
<meta property="og:description" content="JC Davis is an independent builder in Austin, Texas. Embedding Atlas, Dottie, and the vector game suite — AI products on real data.">
<meta property="og:description" content="JC Davis is an independent builder in Austin, Texas. Embedding Atlas, Dottie (scout, the router and System One), and the vector game suite — AI products on real data.">
<meta property="og:url" content="https://jcamd.com/">
<meta property="og:image" content="https://jcamd.com/assets/og/og-home.png">
<meta property="og:image:width" content="1200">
<meta property="og:image:height" content="630">
<meta property="og:image:alt" content="JC Davis — Builds AI products. Austin, Texas.">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:title" content="JC Davis — Builds AI products">
<meta name="twitter:description" content="JC Davis is an independent builder in Austin, Texas. Embedding Atlas, Dottie, and the vector game suite — AI products on real data.">
<meta name="twitter:description" content="JC Davis is an independent builder in Austin, Texas. Embedding Atlas, Dottie (scout, the router and System One), and the vector game suite — AI products on real data.">
<meta name="twitter:image" content="https://jcamd.com/assets/og/og-home.png">
<script type="application/ld+json">
{
Expand Down Expand Up @@ -57,6 +57,7 @@
<li><a href="/chips/">Chips</a></li>
</ul>
<ul class="chrome__list chrome__list--r">
<li><a href="/dottie/">Dottie</a></li>
<li><a href="#craft">Craft</a></li>
<li><a href="#contact">Contact</a></li>
</ul>
Expand Down Expand Up @@ -103,12 +104,12 @@ <h1 class="opening__name" id="name"><span>JC</span> <span>Davis</span></h1>
<header class="section-head" data-reveal>
<p class="label label--accent">Flagship work</p>
<h2 class="title" id="work-title">Built and shipped</h2>
<p class="section-head__sub">Four things I've built and shipped, in sequence.</p>
<p class="section-head__sub">Three things I've built and shipped, in sequence.</p>
</header>

<ol class="frames">
<li class="frame" id="atlas">
<div class="frame__bar" aria-hidden="true"><span>01</span><span class="frame__bar-rule"></span><span>04</span></div>
<div class="frame__bar" aria-hidden="true"><span>01</span><span class="frame__bar-rule"></span><span>03</span></div>
<div class="frame__body" data-reveal>
<svg class="plate" viewBox="0 0 96 96" aria-hidden="true" focusable="false"><g fill="none" stroke="currentColor" stroke-width="1"><circle cx="48" cy="48" r="36"/><ellipse cx="48" cy="48" rx="14" ry="36"/><ellipse cx="48" cy="48" rx="28" ry="36"/><path d="M12 48h72M17 30h62M17 66h62"/></g><circle class="plate__dot" cx="62" cy="30" r="3"/></svg>
<p class="label frame__host">eye.jcamd.com</p>
Expand All @@ -122,43 +123,33 @@ <h3 class="frame__title">Embedding Atlas</h3>
</li>

<li class="frame" id="dottie">
<div class="frame__bar" aria-hidden="true"><span>02</span><span class="frame__bar-rule"></span><span>04</span></div>
<div class="frame__bar" aria-hidden="true"><span>02</span><span class="frame__bar-rule"></span><span>03</span></div>
<div class="frame__body" data-reveal>
<svg class="plate" viewBox="0 0 96 96" aria-hidden="true" focusable="false"><g fill="none" stroke="currentColor" stroke-width="1"><circle cx="48" cy="48" r="36"/><circle cx="48" cy="48" r="24"/><circle cx="48" cy="48" r="12"/><path d="M48 6v18M48 72v18M6 48h18M72 48h18"/></g><circle class="plate__dot" cx="48" cy="48" r="3"/></svg>
<p class="label frame__host">github.com/jcdavis131/dottie</p>
<p class="label frame__host">jcamd.com/dottie</p>
<h3 class="frame__title">Dottie</h3>
<p class="frame__text">A multipurpose AI harness for deep work — coding, research, inbox and CI triage — wired into the team's operations channel with goal tracking.</p>
<p class="frame__text">An orchestration platform built around a measured loop: one router sends each goal to the cheapest tier that can do the work, and System One answers typed questions as Choice, Score and Noul, served locally by dottie-os.</p>
<p class="frame__links">
<a class="tlink" href="/dottie/">Inside Dottie <span aria-hidden="true">→</span></a>
<a class="tlink" href="https://github.com/jcdavis131/dottie" rel="noopener">Repository <span aria-hidden="true">→</span></a>
</p>
</div>
</li>

<li class="frame" id="scout">
<div class="frame__bar" aria-hidden="true"><span>03</span><span class="frame__bar-rule"></span><span>04</span></div>
<div class="frame__bar" aria-hidden="true"><span>03</span><span class="frame__bar-rule"></span><span>03</span></div>
<div class="frame__body" data-reveal>
<svg class="plate" viewBox="0 0 96 96" aria-hidden="true" focusable="false"><g fill="none" stroke="currentColor" stroke-width="1"><rect x="10" y="18" width="76" height="60"/><path d="M10 30h76M24 46l10 8-10 8"/></g><rect class="plate__dot" x="42" y="59" width="14" height="4"/></svg>
<p class="label frame__host">github.com/jcdavis131/scout-cli</p>
<h3 class="frame__title">scout-cli</h3>
<p class="frame__text">A command-line orchestrator for agent swarms — jobs, runs, and handoffs from the terminal, with an always-on operator tempo.</p>
<p class="label frame__host">Dottie · apps/scout-cli</p>
<h3 class="frame__title">scout</h3>
<p class="frame__text">Dottie's command line. The harness gets one tool, and every capability is a plugin behind it, each declaring what it may touch. Route a goal, run it, and read the measured timeline.</p>
<p class="frame__links">
<a class="tlink" href="https://github.com/jcdavis131/scout-cli" rel="noopener">Repository <span aria-hidden="true">→</span></a>
<a class="tlink" href="/dottie/#scout">Install <span aria-hidden="true">→</span></a>
<a class="tlink" href="https://github.com/jcdavis131/dottie/tree/main/apps/scout-cli" rel="noopener">Source <span aria-hidden="true">→</span></a>
</p>
</div>
</li>

<li class="frame" id="arxiviq">
<div class="frame__bar" aria-hidden="true"><span>04</span><span class="frame__bar-rule"></span><span>04</span></div>
<div class="frame__body" data-reveal>
<svg class="plate" viewBox="0 0 96 96" aria-hidden="true" focusable="false"><g fill="none" stroke="currentColor" stroke-width="1"><rect x="30" y="10" width="46" height="60"/><rect x="24" y="18" width="46" height="60" fill="var(--bg)"/><rect x="18" y="26" width="46" height="60" fill="var(--bg)"/><path d="M26 42h30M26 50h30M26 58h20"/></g><circle class="plate__dot" cx="54" cy="70" r="3"/></svg>
<p class="label frame__host">arxiviq.com</p>
<h3 class="frame__title">Arxiviq</h3>
<p class="frame__text">arXiv paper discovery, reimagined — search and browse research papers through a fast, visual interface.</p>
<p class="frame__links">
<a class="tlink" href="https://www.arxiviq.com" rel="noopener">Live site <span aria-hidden="true">→</span></a>
</p>
</div>
</li>
</ol>
</section>

Expand All @@ -173,10 +164,9 @@ <h2 class="title" id="timeline-title">Shipped</h2>
<ol class="ledger__list">
<li data-reveal><span class="ledger__n">01</span><h3>Vector Hoops</h3><p>Embedding-map basketball strategy game — 12,966 player-seasons, MTNN v5 champion model, with daily games, pack battles, and a twenty-questions mode.</p></li>
<li data-reveal><span class="ledger__n">02</span><h3>Embedding Atlas</h3><p>One 3D map, many layers — aircraft, ships, satellites, earthquakes, launches — plus jobs &amp; wages across 393 US metros on real labor data.</p></li>
<li data-reveal><span class="ledger__n">03</span><h3>Dottie</h3><p>Multipurpose AI harness for deep work — coding, research, inbox and CI triage — wired into the team ops channel with goal tracking.</p></li>
<li data-reveal><span class="ledger__n">03</span><h3>Dottie</h3><p>Orchestration platform with a measured loop: one router, the System One decision model, and the local dottie-os sidecar.</p></li>
<li data-reveal><span class="ledger__n">04</span><h3>Vector game suite</h3><p>The same embedding-map engine across gridiron, pitch, equities, and arcade — one geometry, many games.</p></li>
<li data-reveal><span class="ledger__n">05</span><h3>Arxiviq</h3><p>arXiv paper discovery, reimagined — search and browse research papers through a fast, visual interface.</p></li>
<li data-reveal><span class="ledger__n">06</span><h3>scout-cli</h3><p>Terminal orchestrator for agent swarms — jobs, runs, and handoffs from the command line, with an always-on operator tempo.</p></li>
<li data-reveal><span class="ledger__n">05</span><h3>scout</h3><p>Dottie's command line: capability-declared plugins behind one entry point, and the harness's front door.</p></li>
</ol>
</div>
</section>
Expand Down Expand Up @@ -295,6 +285,7 @@ <h2 class="endcard__title" id="contact-title">The best way to reach me is GitHub
<p class="label">Austin, Texas</p>
<ul class="colophon__links">
<li><a href="#work">Work</a></li>
<li><a href="/dottie/">Dottie</a></li>
<li><a href="/graphify/">Graph</a></li>
<li><a href="/chips/">Chips</a></li>
<li><a href="https://github.com/jcdavis131" rel="noopener">GitHub</a></li>
Expand Down
56 changes: 54 additions & 2 deletions scripts/smoke.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@
Checks: index.html parses, the Lab links to every live game and the hub, no link
points at a retired host, vercel.json is valid JSON, every page exists, has a
title/description/OG image, and every local /asset it references is on disk,
and every indexable page is in sitemap.xml.
every indexable page is in sitemap.xml, every same-site link resolves to a
page on disk (and every in-page #anchor to an id), and no page links to a
superseded repository.
"""

from __future__ import annotations
Expand All @@ -21,18 +23,24 @@
REQUIRED_LINKS = [
"https://hoops.dumbmodel.com",
"/graphify/",
"/dottie/",
"https://github.com/jcdavis131/dottie",
"https://github.com/jcdavis131/dottie/tree/main/apps/scout-cli",
]
# Repositories replaced by a monorepo path; link the monorepo instead.
SUPERSEDED = ["github.com/jcdavis131/scout-cli"]
# Hosts that no longer serve anything of ours; a link to one is a dead click.
RETIRED_HOSTS = ["hoops.jcamd.com", "bhenre.com", "arcade.dumbmodel.com", "training.jcamd.com"]
REQUIRED_PAGES = [
"index.html", "graphify/index.html", "chips/index.html", "404.html",
"index.html", "graphify/index.html", "chips/index.html", "dottie/index.html", "404.html",
"vercel.json", "favicon.ico", "site.webmanifest", "sitemap.xml", "robots.txt",
]
# page -> public URL expected in sitemap.xml (404 is noindex, so it's excluded)
PAGES = {
"index.html": "https://jcamd.com/",
"chips/index.html": "https://jcamd.com/chips/",
"graphify/index.html": "https://jcamd.com/graphify/",
"dottie/index.html": "https://jcamd.com/dottie/",
"404.html": None,
}

Expand All @@ -41,15 +49,55 @@ class _Links(HTMLParser):
def __init__(self) -> None:
super().__init__()
self.hrefs: list[str] = []
self.ids: set[str] = set()
self.errors: list[str] = []

def handle_starttag(self, tag, attrs):
for k, v in attrs:
if k == "id" and v:
self.ids.add(v)
if tag == "a":
for k, v in attrs:
if k == "href" and v:
self.hrefs.append(v)


def _page_for(path: str) -> Path | None:
"""Map a same-site URL path to the file Vercel serves for it (cleanUrls)."""
rel = path.lstrip("/")
if rel == "" or rel.endswith("/"):
cand = ROOT / rel / "index.html"
else:
cand = ROOT / rel
if not cand.is_file():
cand = ROOT / (rel + ".html")
return cand if cand.is_file() else None


def _parse(path: Path) -> _Links:
p = _Links()
p.feed(path.read_text(encoding="utf-8"))
return p


def check_links(rel: str, failures: list[str]) -> None:
"""Same-site links must land on a page; #anchors must land on an id."""
page = _parse(ROOT / rel)
for href in page.hrefs:
if href.startswith(("http://", "https://", "mailto:")):
continue
path, _, frag = href.partition("#")
if path:
target = _page_for(path)
if target is None:
failures.append(f"{rel}: dead link {href}")
continue
else:
target = ROOT / rel
if frag and frag not in _parse(target).ids:
failures.append(f"{rel}: link {href} has no #{frag} target")


def main() -> int:
failures: list[str] = []
for rel in REQUIRED_PAGES:
Expand Down Expand Up @@ -87,6 +135,10 @@ def main() -> int:
for ref in re.findall(r'(?:href|src)="(/(?:assets/|favicon|site\.webmanifest)[^"#?]*)"', page):
if not (ROOT / ref.lstrip("/")).is_file():
failures.append(f"{rel}: references missing file {ref}")
check_links(rel, failures)
for repo in SUPERSEDED:
if re.search(rf'href="https?://{re.escape(repo)}', page):
failures.append(f"{rel}: links to superseded {repo}")
for ref in re.findall(r'content="https://jcamd\.com(/assets/[^"]+)"', page):
if not (ROOT / ref.lstrip("/")).is_file():
failures.append(f"{rel}: OG image missing on disk {ref}")
Expand Down
5 changes: 5 additions & 0 deletions sitemap.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@
<changefreq>monthly</changefreq>
<priority>1.0</priority>
</url>
<url>
<loc>https://jcamd.com/dottie/</loc>
<changefreq>monthly</changefreq>
<priority>0.8</priority>
</url>
<url>
<loc>https://jcamd.com/chips/</loc>
<changefreq>yearly</changefreq>
Expand Down
Loading