Skip to content

Commit ca927e3

Browse files
morph-eosclaude
andcommitted
web: live GitHub-parsed stats, visitor-first copy, ibm validated, mobile pass
- hero stats parse from GitHub at view time: project count from the org's public repos, maintainer count from shotgate's MAINTAINERS.md roster table, license SPDX id, stage from the dev-status classifier and latest release tag; static values remain as fallback - copy: replaced design-system-internal language with visitor-facing copy (projects intro, planned-project card, shared-system panel) - shotgate card: ibm chip now working (validated on ibm_fez), docs link points at the rendered docs reader - mobile: nav links become a scrollable mono row instead of disappearing, denser stats/cards/panels at small widths Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
1 parent fc830e8 commit ca927e3

3 files changed

Lines changed: 107 additions & 19 deletions

File tree

index.html

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -47,26 +47,27 @@
4747
<h1>coldqubit</h1>
4848
<p class="tagline">The missing <span class="c">layers</span> between a quantum circuit and production.</p>
4949

50+
<!-- values are static fallbacks; js/site.js re-parses them from GitHub -->
5051
<div class="stats">
5152
<div class="stat">
5253
<div class="l">Active projects</div>
53-
<div class="v"><span class="tick"></span>01</div>
54-
<div class="s">shotgate · more planned</div>
54+
<div class="v"><span class="tick"></span><span id="s-projects">01</span></div>
55+
<div class="s" id="s-projects-sub">shotgate · more planned</div>
5556
</div>
5657
<div class="stat">
5758
<div class="l">Maintainers</div>
58-
<div class="v">1</div>
59-
<div class="s">co-maintainers welcome</div>
59+
<div class="v" id="s-maintainers">1</div>
60+
<div class="s">from MAINTAINERS.md · co-maintainers welcome</div>
6061
</div>
6162
<div class="stat">
6263
<div class="l">License</div>
63-
<div class="v">Apache-2.0</div>
64+
<div class="v" id="s-license">Apache-2.0</div>
6465
<div class="s">permissive, OSI-approved</div>
6566
</div>
6667
<div class="stat">
6768
<div class="l">Stage</div>
68-
<div class="v">alpha</div>
69-
<div class="s">structured to grow</div>
69+
<div class="v" id="s-stage">alpha</div>
70+
<div class="s" id="s-stage-sub">latest release v0.2.2</div>
7071
</div>
7172
</div>
7273
</div>
@@ -77,7 +78,7 @@ <h1>coldqubit</h1>
7778
<div class="sec-head">
7879
<span class="kicker"><span class="tick"></span>Projects under coldqubit</span>
7980
<h2>One home, growing into an ecosystem.</h2>
80-
<p>Every project inherits the shared system, palette, type, and the tile-based mark language, and adds a single glyph and accent. Today there is one.</p>
81+
<p>Independent tools that share one standard: declarative workflows, container-first reproducibility, statistical rigor, and honest status reporting. Today there is one, and room for more.</p>
8182
</div>
8283

8384
<div class="projects">
@@ -92,12 +93,12 @@ <h2>One home, growing into an ecosystem.</h2>
9293
<span class="chip alpha"><span class="dot"></span>alpha</span>
9394
</div>
9495
</div>
95-
<p class="proj-desc">CI/CD quality gates for quantum circuits. Statistically validate the probabilistic output of quantum programs across simulators and real QPUs, as declarative YAML, with drop-in exit-code gating.</p>
96+
<p class="proj-desc">CI/CD quality gates for quantum circuits. Statistically validate the probabilistic output of quantum programs across simulators and real QPUs, as declarative YAML, with drop-in exit-code gating. Validated on real hardware: ibm_fez, Bell/GHZ/Grover at 4096 shots.</p>
9697

9798
<div class="field-label">Backends</div>
9899
<div class="row">
99100
<span class="chip working"><span class="dot"></span>local-aer</span>
100-
<span class="chip alpha"><span class="dot"></span>ibm</span>
101+
<span class="chip working"><span class="dot"></span>ibm</span>
101102
<span class="chip planned"><span class="dot"></span>braket</span>
102103
</div>
103104

@@ -106,7 +107,7 @@ <h2>One home, growing into an ecosystem.</h2>
106107
<div class="proj-links">
107108
<a class="plink" href="https://shotgate.coldqubit.org">Site <span class="arr"></span></a>
108109
<a class="plink" href="https://github.com/coldqubit/shotgate">GitHub <span class="arr"></span></a>
109-
<a class="plink" href="https://github.com/coldqubit/shotgate/tree/main/docs">Docs <span class="arr"></span></a>
110+
<a class="plink" href="https://shotgate.coldqubit.org/docs/">Docs <span class="arr"></span></a>
110111
</div>
111112
</div>
112113

@@ -118,9 +119,9 @@ <h2>One home, growing into an ecosystem.</h2>
118119
<div class="proj-role">planned</div>
119120
</div>
120121
</div>
121-
<p class="proj-desc">Reuses the shared tile and type, adds one new glyph and accent. The system is built to grow into an ecosystem, not a one-off. Proposals start as an issue under the project home.</p>
122+
<p class="proj-desc">The gap between a runnable circuit and production is wider than one tool: scheduling, observability, policy, cost. If you want to build one of those layers in the open, start the conversation with an issue.</p>
122123
<div class="proj-links">
123-
<a class="plink" href="https://github.com/coldqubit">Watch the home <span class="arr"></span></a>
124+
<a class="plink" href="https://github.com/coldqubit/shotgate/issues">Propose a project <span class="arr"></span></a>
124125
</div>
125126
</div>
126127
</div>
@@ -147,9 +148,9 @@ <h3>One maintainer today, structured to grow.</h3>
147148
</div>
148149

149150
<div class="panel" id="system">
150-
<span class="kicker"><span class="tick"></span>Shared design system</span>
151-
<h3>coldqubit owns the system; products inherit it.</h3>
152-
<p>One palette, one type family, one tile-based mark language. The violet tile is the shared base; each product adds a glyph and owns exactly one accent. Cyan is the home's; shotgate runs solar coral.</p>
151+
<span class="kicker"><span class="tick"></span>One recognizable system</span>
152+
<h3>You should always know where you are.</h3>
153+
<p>Every coldqubit surface, from CLI output to docs to this page, speaks the same language: terminal-native type, green/red PASS/FAIL semantics, one accent per project. Cyan means you are at the home; solar coral means shotgate.</p>
153154
<div class="mark-row">
154155
<img src="assets/coldqubit-logomark.svg" alt="coldqubit mark">
155156
<div>

js/site.js

Lines changed: 72 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
// coldqubit.org · surface behavior
2-
// One effect: show the navbar name only while the hero "coldqubit" is off screen.
2+
// Two effects: the scroll-reveal navbar name, and hero stats parsed live
3+
// from GitHub (org repos, MAINTAINERS.md, license, release/stage).
4+
5+
// Show the navbar name only while the hero "coldqubit" is off screen.
36
(function () {
47
var nav = document.getElementById('topnav');
58
var heroName = document.querySelector('.hero h1');
@@ -8,3 +11,71 @@
811
nav.classList.toggle('scrolled', !entries[0].isIntersecting);
912
}, { threshold: 0 }).observe(heroName);
1013
})();
14+
15+
// Hero stats, parsed from GitHub. The HTML values are static fallbacks;
16+
// anything that fails (offline, rate limit) keeps the baked-in value.
17+
// Responses cache in sessionStorage for 10 minutes to respect the
18+
// unauthenticated GitHub API limit (60 req/h per IP).
19+
(function () {
20+
var ORG = 'coldqubit';
21+
var TTL = 10 * 60 * 1000;
22+
23+
function cached(url, asText) {
24+
var key = 'cq:' + url;
25+
try {
26+
var hit = JSON.parse(sessionStorage.getItem(key));
27+
if (hit && Date.now() - hit.t < TTL) return Promise.resolve(hit.v);
28+
} catch (e) { /* fall through to network */ }
29+
return fetch(url).then(function (r) {
30+
if (!r.ok) throw new Error(String(r.status));
31+
return asText ? r.text() : r.json();
32+
}).then(function (v) {
33+
try { sessionStorage.setItem(key, JSON.stringify({ t: Date.now(), v: v })); } catch (e) { /* quota */ }
34+
return v;
35+
});
36+
}
37+
38+
function set(id, value) {
39+
var el = document.getElementById(id);
40+
if (el && value != null) el.textContent = value;
41+
}
42+
43+
// Active projects: public, non-fork, non-archived repos that are products
44+
// (the .github org-management repo is the home itself, not a project).
45+
cached('https://api.github.com/orgs/' + ORG + '/repos?per_page=100&type=public').then(function (repos) {
46+
var projects = repos.filter(function (r) {
47+
return !r.fork && !r.archived && r.name !== '.github';
48+
});
49+
if (!projects.length) return;
50+
set('s-projects', String(projects.length).padStart(2, '0'));
51+
var names = projects.map(function (r) { return r.name; }).sort().join(' · ');
52+
set('s-projects-sub', names + ' · more planned');
53+
}).catch(function () {});
54+
55+
// Maintainers: count the rows of the "Current maintainers" table in
56+
// shotgate's MAINTAINERS.md, the project's source of truth for the roster.
57+
cached('https://raw.githubusercontent.com/' + ORG + '/shotgate/main/MAINTAINERS.md', true).then(function (md) {
58+
var section = md.split(/^## Current maintainers/m)[1];
59+
if (!section) return;
60+
section = section.split(/^## /m)[0];
61+
var rows = section.split('\n').filter(function (l) {
62+
return /^\|\s*\[/.test(l); // table rows whose first cell is a [link]
63+
});
64+
if (rows.length) set('s-maintainers', rows.length);
65+
}).catch(function () {});
66+
67+
// License: SPDX id of the flagship repo.
68+
cached('https://api.github.com/repos/' + ORG + '/shotgate').then(function (r) {
69+
var spdx = r.license && r.license.spdx_id;
70+
if (spdx && spdx !== 'NOASSERTION') set('s-license', spdx);
71+
}).catch(function () {});
72+
73+
// Stage: dev-status classifier + latest release tag.
74+
cached('https://raw.githubusercontent.com/' + ORG + '/shotgate/main/pyproject.toml', true).then(function (t) {
75+
var st = t.match(/Development Status :: \d+ - ([A-Za-z/ ]+)"/);
76+
if (st) set('s-stage', st[1].trim().toLowerCase());
77+
}).catch(function () {});
78+
cached('https://api.github.com/repos/' + ORG + '/shotgate/releases/latest').then(function (r) {
79+
if (r.tag_name) set('s-stage-sub', 'latest release ' + r.tag_name);
80+
}).catch(function () {});
81+
})();

styles/site.css

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -119,11 +119,27 @@ a { color: inherit; text-decoration: none; }
119119
@media (max-width: 980px) {
120120
.stats { grid-template-columns: repeat(2, 1fr); }
121121
.projects, .lower { grid-template-columns: 1fr; }
122-
.topnav-links { display: none; }
122+
}
123+
124+
/* mobile nav: never hide the links; they become a scrollable mono row */
125+
@media (max-width: 980px) {
126+
.topnav-inner { flex-wrap: wrap; height: auto; padding-top: 12px; column-gap: 16px; }
127+
.topnav-brand { order: 1; }
128+
.gh-link { order: 2; margin-left: auto; }
129+
.topnav-links { order: 3; flex-basis: 100%; margin-left: 0; gap: 18px; font-size: 13px; padding: 10px 2px 12px; overflow-x: auto; -webkit-overflow-scrolling: touch; scrollbar-width: none; }
130+
.topnav-links::-webkit-scrollbar { display: none; }
131+
:is(.section, .panel)[id] { scroll-margin-top: 112px; }
123132
}
124133

125134
@media (max-width: 640px) {
126135
.wrap { padding: 0 22px; }
127-
.hero-inner { padding-left: 22px; padding-right: 22px; }
136+
.hero-inner { padding-left: 22px; padding-right: 22px; padding-top: 46px; }
128137
.kicker { white-space: normal; }
138+
.section { padding: 44px 0; }
139+
.stats { grid-template-columns: 1fr 1fr; gap: 10px; }
140+
.stat { padding: 14px 16px; }
141+
.stat .v { font-size: 22px; }
142+
.panel { padding: 22px 20px; }
143+
.proj { padding: 20px 18px 18px; }
144+
.foot-inner .right { margin-left: 0; }
129145
}

0 commit comments

Comments
 (0)