superbee 0.1.3 → 0.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "superbee",
3
- "version": "0.1.3",
3
+ "version": "0.1.4",
4
4
  "type": "module",
5
5
  "description": "Agent-facing Superbee CLI for reading and writing local OKF knowledge bundles: context notes, docs, cross-links, and live bundle Views.",
6
6
  "keywords": [
@@ -24,6 +24,17 @@
24
24
  "bin": {
25
25
  "superbee": "dist/superbee.mjs"
26
26
  },
27
+ "exports": {
28
+ ".": "./dist/superbee.mjs",
29
+ "./publication": {
30
+ "types": "./dist/publication/index.d.ts",
31
+ "default": "./dist/publication.mjs"
32
+ },
33
+ "./publication/bridge": {
34
+ "types": "./dist/publication/bridge-entry.d.ts",
35
+ "default": "./dist/publication-bridge.mjs"
36
+ }
37
+ },
27
38
  "files": [
28
39
  "dist",
29
40
  "SKILL.md",
@@ -36,16 +47,14 @@
36
47
  "engines": {
37
48
  "node": ">=20"
38
49
  },
39
- "os": [
40
- "!win32"
41
- ],
42
50
  "scripts": {
43
51
  "build": "node build.mjs local-dev",
44
52
  "build:npm-package": "node build.mjs npm-package",
45
53
  "typecheck": "tsc --noEmit",
46
54
  "pretest": "node build.mjs local-dev",
47
- "test": "ASLITE_NO_UPDATE_CHECK=1 AGENTSTATE_LITE_NO_AUTOPULL=1 GIT_AUTHOR_NAME=test-suite GIT_AUTHOR_EMAIL=test-suite@example.invalid GIT_COMMITTER_NAME=test-suite GIT_COMMITTER_EMAIL=test-suite@example.invalid node --test --import ./test/ts-loader.mjs ./test/*.test.ts",
48
- "mutation": "ASLITE_NO_UPDATE_CHECK=1 AGENTSTATE_LITE_NO_AUTOPULL=1 GIT_AUTHOR_NAME=test-suite GIT_AUTHOR_EMAIL=test-suite@example.invalid GIT_COMMITTER_NAME=test-suite GIT_COMMITTER_EMAIL=test-suite@example.invalid stryker run",
55
+ "test:host-class": "node scripts/run-test-command.mjs node --test --import ./test/ts-loader.mjs ./test/private-state-bundle-boundary.test.ts ./test/filesystem-cross-process-cas.test.ts ./test/link.test.ts ./test/promote-pull.test.ts ./test/recipe-source.test.ts",
56
+ "test": "node scripts/run-test-command.mjs node --test --import ./test/ts-loader.mjs ./test/*.test.ts",
57
+ "mutation": "node scripts/run-test-command.mjs npm-exec stryker run",
49
58
  "gen:skill": "node scripts/gen-skill.mjs",
50
59
  "check:skill": "node scripts/gen-skill.mjs --check",
51
60
  "prepublishOnly": "node -e \"console.error('superbee is released by .github/workflows/release.yml (npm stage publish); do not run npm publish here'); process.exit(1)\""
@@ -56,6 +65,7 @@
56
65
  "@superbee/core": "*",
57
66
  "@superbee/markdown-renderer": "*",
58
67
  "@superbee/mcp-app": "*",
68
+ "@superbee/publication": "*",
59
69
  "@superbee/server": "*",
60
70
  "@superbee/ui-server": "*",
61
71
  "@toon-format/toon": "2.3.0",
@@ -5,44 +5,61 @@
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1">
6
6
  <title>About this bundle</title>
7
7
  <style>
8
+ /* Superbee View theme — mirrors the launcher shell, so a View framed inside it reads as
9
+ one surface rather than a foreign document.
10
+
11
+ TWO accent roles, not three. --structure carries structure AND state: "active" is the
12
+ same hue at full intensity, never a second colour, because hue should carry kind and
13
+ intensity should carry state. --signal carries liveness and the revealed answer. There
14
+ is deliberately no teal. Quiet metadata takes --slate, not an accent.
15
+
16
+ Fonts: a View is sandboxed under `font-src data:`, so it CANNOT load the shell's
17
+ self-hosted woff2 by URL. The brand faces are named first and resolve for anyone who
18
+ has them installed locally; the stacks behind them are the real fallback. Do not embed
19
+ a data: font — that is ~100KB in every View for a marginal gain. */
8
20
  :root {
9
- --bg: #fafaf8; --panel: #ffffff; --ink: #1a1a1e; --muted: #71717a;
10
- --line: #e4e4e7; --accent: #6d5ae6; --accent-soft: #ece9fc;
11
- --mono: ui-monospace, "SF Mono", Menlo, monospace;
21
+ --bg:#F3F7FA; --card:#FFFFFF; --alt:#E9EFF4; --rule:#DADEE2;
22
+ --ink:#0F1A24; --slate:#4A5D6E; --ghost:#9AAAB8;
23
+ --structure:#0073B0; --signal:#956300; --danger:#B00020;
24
+ --radius:2px;
25
+ --display:"Space Grotesk", system-ui, -apple-system, "Segoe UI", sans-serif;
26
+ --sans:"DM Sans", -apple-system, "Segoe UI", system-ui, sans-serif;
27
+ --mono:"JetBrains Mono", ui-monospace, "SF Mono", Menlo, monospace;
12
28
  }
13
29
  @media (prefers-color-scheme: dark) {
14
30
  :root {
15
- --bg: #101014; --panel: #17171c; --ink: #ececf1; --muted: #8e8e98;
16
- --line: #26262e; --accent: #9b8cf7; --accent-soft: #262040;
31
+ --bg:#0B1926; --card:#0F2A3F; --alt:#12314A; --rule:#26323D;
32
+ --ink:#F8F6F2; --slate:#B7C4D1; --ghost:#7E8FA0;
33
+ --structure:#3CAEF9; --signal:#E09707; --danger:#F2707A;
17
34
  }
18
35
  }
19
36
  * { box-sizing: border-box; margin: 0; }
20
37
  html, body { height: 100%; }
21
38
  body {
22
- font: 15px/1.6 -apple-system, "Segoe UI", system-ui, sans-serif;
39
+ font: 15px/1.6 var(--sans);
23
40
  background: var(--bg); color: var(--ink);
24
41
  }
25
42
  main { max-width: 40rem; margin: 0 auto; padding: 2.5rem 1.5rem 4rem; }
26
- h1 { font-size: 1.5rem; font-weight: 650; letter-spacing: -0.01em; margin-bottom: 0.4rem; }
43
+ h1 { font-family: var(--display); font-size: 1.5rem; font-weight: 650; letter-spacing: -0.01em; margin-bottom: 0.4rem; }
27
44
  .kicker {
28
- color: var(--accent); font-family: var(--mono); font-size: 0.8rem;
45
+ color: var(--structure); font-family: var(--mono); font-size: 0.8rem;
29
46
  text-transform: uppercase; letter-spacing: 0.06em; margin-bottom: 0.6rem;
30
47
  }
31
- p { color: var(--muted); margin-bottom: 1rem; }
48
+ p { color: var(--slate); margin-bottom: 1rem; }
32
49
  p strong { color: var(--ink); font-weight: 600; }
33
50
  .card {
34
- background: var(--panel); border: 1px solid var(--line); border-radius: 10px;
51
+ background: var(--card); border: 1px solid var(--rule); border-radius: 10px;
35
52
  padding: 1rem 1.2rem; margin: 1.5rem 0;
36
53
  }
37
54
  .card h2 { font-size: 0.95rem; margin-bottom: 0.5rem; }
38
- .card ul { margin: 0; padding-left: 1.2rem; color: var(--muted); }
55
+ .card ul { margin: 0; padding-left: 1.2rem; color: var(--slate); }
39
56
  .card li { margin-bottom: 0.35rem; }
40
57
  code {
41
- font-family: var(--mono); background: var(--accent-soft); color: var(--ink);
58
+ font-family: var(--mono); background: var(--alt); color: var(--ink);
42
59
  padding: 0.1rem 0.35rem; border-radius: 5px; font-size: 0.85em;
43
60
  }
44
61
  #toggle, #open-roadmap {
45
- border: 1px solid var(--line); background: var(--panel); color: var(--ink);
62
+ border: 1px solid var(--rule); background: var(--card); color: var(--ink);
46
63
  border-radius: 8px; padding: 0.4rem 0.9rem; font-size: 0.85rem; cursor: pointer;
47
64
  }
48
65
  #detail { display: none; margin-top: 0.75rem; }
@@ -5,106 +5,129 @@
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1">
6
6
  <title>Pulse</title>
7
7
  <style>
8
+ /* Superbee View theme — mirrors the launcher shell, so a View framed inside it reads as
9
+ one surface rather than a foreign document.
10
+
11
+ TWO accent roles, not three. --structure carries structure AND state: "active" is the
12
+ same hue at full intensity, never a second colour, because hue should carry kind and
13
+ intensity should carry state. --signal carries liveness and the revealed answer. There
14
+ is deliberately no teal. Quiet metadata takes --slate, not an accent.
15
+
16
+ Fonts: a View is sandboxed under `font-src data:`, so it CANNOT load the shell's
17
+ self-hosted woff2 by URL. The brand faces are named first and resolve for anyone who
18
+ has them installed locally; the stacks behind them are the real fallback. Do not embed
19
+ a data: font — that is ~100KB in every View for a marginal gain. */
8
20
  :root {
9
- --bg: #fafaf8; --panel: #ffffff; --ink: #1a1a1e; --muted: #71717a;
10
- --line: #e4e4e7; --accent: #6d5ae6; --accent-soft: #ece9fc;
11
- --glow: #f5f2ff; --chip: #f4f4f5; --ok: #16a34a; --warn: #d97706; --bad: #dc2626;
12
- --mono: ui-monospace, "SF Mono", Menlo, monospace;
21
+ --bg:#F3F7FA; --card:#FFFFFF; --alt:#E9EFF4; --rule:#DADEE2;
22
+ --ink:#0F1A24; --slate:#4A5D6E; --ghost:#9AAAB8;
23
+ --structure:#0073B0; --signal:#956300; --danger:#B00020;
24
+ --radius:2px;
25
+ --display:"Space Grotesk", system-ui, -apple-system, "Segoe UI", sans-serif;
26
+ --sans:"DM Sans", -apple-system, "Segoe UI", system-ui, sans-serif;
27
+ --mono:"JetBrains Mono", ui-monospace, "SF Mono", Menlo, monospace;
13
28
  }
14
29
  @media (prefers-color-scheme: dark) {
15
30
  :root {
16
- --bg: #101014; --panel: #17171c; --ink: #ececf1; --muted: #8e8e98;
17
- --line: #26262e; --accent: #9b8cf7; --accent-soft: #262040;
18
- --glow: #1d1930; --chip: #222228;
31
+ --bg:#0B1926; --card:#0F2A3F; --alt:#12314A; --rule:#26323D;
32
+ --ink:#F8F6F2; --slate:#B7C4D1; --ghost:#7E8FA0;
33
+ --structure:#3CAEF9; --signal:#E09707; --danger:#F2707A;
19
34
  }
20
35
  }
36
+
37
+ /* Functional status colours, NOT brand accents. The kit has no green; these exist so a
38
+ dashboard can say good/warning/bad, and they are deliberately kept out of the palette
39
+ vocabulary above so nobody mistakes them for brand colours. */
40
+ :root { --ok:#0F7B3F; --warn:#956300; --bad:#B00020; }
41
+ @media (prefers-color-scheme: dark) {
42
+ :root { --ok:#3FBF74; --warn:#E09707; --bad:#F2707A; }
43
+ }
21
44
  * { box-sizing: border-box; margin: 0; }
22
45
  html, body { height: 100%; }
23
46
  body {
24
- font: 14px/1.5 -apple-system, "Segoe UI", system-ui, sans-serif;
47
+ font: 14px/1.5 var(--sans);
25
48
  background: var(--bg); color: var(--ink); display: flex; flex-direction: column;
26
49
  }
27
50
  header {
28
51
  display: flex; align-items: center; gap: 10px; padding: 10px 16px;
29
- border-bottom: 1px solid var(--line); background: var(--panel); flex-wrap: wrap;
52
+ border-bottom: 1px solid var(--rule); background: var(--card); flex-wrap: wrap;
30
53
  }
31
- header h1 { font-size: 15px; font-weight: 650; letter-spacing: .01em; }
32
- header .bundle { color: var(--muted); font-size: 12px; font-family: var(--mono); }
54
+ header h1 { font-family: var(--display); font-size: 15px; font-weight: 650; letter-spacing: .01em; }
55
+ header .bundle { color: var(--slate); font-size: 12px; font-family: var(--mono); }
33
56
  #search {
34
- margin-left: auto; background: var(--chip); border: 1px solid var(--line); color: var(--ink);
57
+ margin-left: auto; background: var(--alt); border: 1px solid var(--rule); color: var(--ink);
35
58
  border-radius: 8px; padding: 5px 10px; font-size: 13px; width: 200px; outline: none;
36
59
  }
37
- #search:focus { border-color: var(--accent); }
60
+ #search:focus { border-color: var(--structure); }
38
61
  #follow {
39
- border: 1px solid var(--line); background: var(--chip); color: var(--muted); border-radius: 999px;
62
+ border: 1px solid var(--rule); background: var(--alt); color: var(--slate); border-radius: 999px;
40
63
  padding: 5px 12px; font-size: 12px; cursor: pointer; user-select: none; white-space: nowrap;
41
64
  }
42
- #follow.on { background: var(--accent-soft); color: var(--accent); border-color: var(--accent); }
65
+ #follow.on { background: var(--alt); color: var(--structure); border-color: var(--structure); }
43
66
  #follow.on .dot { animation: blink 1.2s infinite; }
44
67
  #follow .dot { display: inline-block; width: 7px; height: 7px; border-radius: 50%; background: currentColor; margin-right: 6px; }
45
68
  @keyframes blink { 50% { opacity: .25; } }
46
- #typebar { display: flex; gap: 6px; padding: 8px 16px; border-bottom: 1px solid var(--line); overflow-x: auto; background: var(--panel); }
69
+ #typebar { display: flex; gap: 6px; padding: 8px 16px; border-bottom: 1px solid var(--rule); overflow-x: auto; background: var(--card); }
47
70
  .tchip {
48
- font-size: 12px; padding: 3px 10px; border-radius: 999px; border: 1px solid var(--line);
49
- background: var(--chip); color: var(--muted); cursor: pointer; white-space: nowrap;
71
+ font-size: 12px; padding: 3px 10px; border-radius: 999px; border: 1px solid var(--rule);
72
+ background: var(--alt); color: var(--slate); cursor: pointer; white-space: nowrap;
50
73
  }
51
- .tchip.on { background: var(--accent-soft); color: var(--accent); border-color: var(--accent); font-weight: 600; }
74
+ .tchip.on { background: var(--alt); color: var(--structure); border-color: var(--structure); font-weight: 600; }
52
75
  main { flex: 1; display: flex; min-height: 0; }
53
- #feed { flex: 0 0 44%; max-width: 560px; overflow-y: auto; border-right: 1px solid var(--line); padding: 8px 0 40px; }
76
+ #feed { flex: 0 0 44%; max-width: 560px; overflow-y: auto; border-right: 1px solid var(--rule); padding: 8px 0 40px; }
54
77
  .group-label {
55
78
  position: sticky; top: 0; z-index: 1; font-size: 11px; font-weight: 700; text-transform: uppercase;
56
- letter-spacing: .08em; color: var(--muted); background: var(--bg); padding: 10px 16px 4px;
79
+ letter-spacing: .08em; color: var(--slate); background: var(--bg); padding: 10px 16px 4px;
57
80
  }
58
81
  .item {
59
82
  display: block; width: 100%; text-align: left; border: 0; background: none; color: inherit; font: inherit;
60
83
  padding: 9px 16px; cursor: pointer; border-left: 3px solid transparent;
61
84
  }
62
- .item:hover { background: var(--glow); }
63
- .item.sel { background: var(--accent-soft); border-left-color: var(--accent); }
85
+ .item:hover { background: var(--alt); }
86
+ .item.sel { background: var(--alt); border-left-color: var(--structure); }
64
87
  .item.fresh { animation: land 1.6s ease-out; }
65
- @keyframes land { 0% { background: var(--accent-soft); transform: translateX(-4px); } 100% { background: none; transform: none; } }
88
+ @keyframes land { 0% { background: var(--alt); transform: translateX(-4px); } 100% { background: none; transform: none; } }
66
89
  .item .row1 { display: flex; align-items: baseline; gap: 8px; }
67
90
  .item .title { font-weight: 570; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; flex: 1; }
68
- .item .when { color: var(--muted); font-size: 11.5px; flex: none; }
69
- .item .row2 { display: flex; align-items: center; gap: 8px; margin-top: 2px; font-size: 12px; color: var(--muted); }
91
+ .item .when { color: var(--slate); font-size: 11.5px; flex: none; }
92
+ .item .row2 { display: flex; align-items: center; gap: 8px; margin-top: 2px; font-size: 12px; color: var(--slate); }
70
93
  .item .id { font-family: var(--mono); font-size: 11px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
71
94
  .dotc { width: 8px; height: 8px; border-radius: 50%; flex: none; display: inline-block; }
72
- .badge { font-size: 10.5px; font-weight: 650; padding: 1px 7px; border-radius: 999px; background: var(--chip); color: var(--muted); flex: none; }
73
- .badge.st-todo { color: var(--muted); }
95
+ .badge { font-size: 10.5px; font-weight: 650; padding: 1px 7px; border-radius: 999px; background: var(--alt); color: var(--slate); flex: none; }
96
+ .badge.st-todo { color: var(--slate); }
74
97
  .badge.st-in_progress { color: var(--warn); background: color-mix(in srgb, var(--warn) 12%, transparent); }
75
98
  .badge.st-blocked, .badge.st-canceled { color: var(--bad); background: color-mix(in srgb, var(--bad) 10%, transparent); }
76
99
  .badge.st-done, .badge.st-active { color: var(--ok); background: color-mix(in srgb, var(--ok) 10%, transparent); }
77
100
  #detail { flex: 1; overflow-y: auto; padding: 20px 28px 60px; }
78
- #detail .empty { color: var(--muted); text-align: center; margin-top: 18vh; }
101
+ #detail .empty { color: var(--slate); text-align: center; margin-top: 18vh; }
79
102
  #detail .empty .big { font-size: 40px; margin-bottom: 12px; }
80
- #crumbs { display: flex; gap: 4px; align-items: center; font-size: 12px; color: var(--muted); margin-bottom: 10px; flex-wrap: wrap; }
81
- #crumbs button { border: 0; background: none; color: var(--accent); cursor: pointer; font: inherit; font-family: var(--mono); padding: 0; }
103
+ #crumbs { display: flex; gap: 4px; align-items: center; font-size: 12px; color: var(--slate); margin-bottom: 10px; flex-wrap: wrap; }
104
+ #crumbs button { border: 0; background: none; color: var(--structure); cursor: pointer; font: inherit; font-family: var(--mono); padding: 0; }
82
105
  #crumbs .sep { opacity: .5; }
83
106
  .doc h2 { font-size: 20px; margin-bottom: 2px; }
84
107
  .doc .meta { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; margin: 8px 0 14px; }
85
108
  .kv {
86
109
  display: grid; grid-template-columns: max-content 1fr; gap: 3px 14px; font-size: 12.5px;
87
- background: var(--panel); border: 1px solid var(--line); border-radius: 10px; padding: 10px 14px; margin-bottom: 16px;
110
+ background: var(--card); border: 1px solid var(--rule); border-radius: 10px; padding: 10px 14px; margin-bottom: 16px;
88
111
  }
89
- .kv .k { color: var(--muted); font-family: var(--mono); }
112
+ .kv .k { color: var(--slate); font-family: var(--mono); }
90
113
  .kv .v { word-break: break-word; }
91
- .kv .v.ver { font-family: var(--mono); font-size: 11px; color: var(--muted); }
114
+ .kv .v.ver { font-family: var(--mono); font-size: 11px; color: var(--slate); }
92
115
  .body { max-width: 72ch; }
93
116
  .body h1, .body h2, .body h3 { margin: 18px 0 6px; line-height: 1.25; }
94
- .body h1 { font-size: 18px; } .body h2 { font-size: 16px; } .body h3 { font-size: 14.5px; }
117
+ .body h1 { font-family: var(--display); font-size: 18px; } .body h2 { font-size: 16px; } .body h3 { font-size: 14.5px; }
95
118
  .body p, .body ul, .body ol { margin: 8px 0; }
96
119
  .body li { margin: 3px 0 3px 18px; }
97
- .body code { font-family: var(--mono); font-size: 12.5px; background: var(--chip); border-radius: 4px; padding: 1px 5px; }
98
- .body pre { background: var(--chip); border: 1px solid var(--line); border-radius: 8px; padding: 10px 12px; overflow-x: auto; margin: 10px 0; }
120
+ .body code { font-family: var(--mono); font-size: 12.5px; background: var(--alt); border-radius: 4px; padding: 1px 5px; }
121
+ .body pre { background: var(--alt); border: 1px solid var(--rule); border-radius: 8px; padding: 10px 12px; overflow-x: auto; margin: 10px 0; }
99
122
  .body pre code { background: none; padding: 0; }
100
- .body a.doclink { color: var(--accent); text-decoration: none; border-bottom: 1px dashed var(--accent); cursor: pointer; }
101
- .body .extlink { color: var(--muted); border-bottom: 1px dotted var(--muted); cursor: help; }
123
+ .body a.doclink { color: var(--structure); text-decoration: none; border-bottom: 1px dashed var(--structure); cursor: pointer; }
124
+ .body .extlink { color: var(--slate); border-bottom: 1px dotted var(--slate); cursor: help; }
102
125
  .doc .live-note {
103
- font-size: 12px; color: var(--accent); background: var(--accent-soft); border-radius: 8px;
126
+ font-size: 12px; color: var(--structure); background: var(--alt); border-radius: 8px;
104
127
  padding: 6px 10px; margin-bottom: 12px; display: none;
105
128
  }
106
- footer { padding: 6px 16px; border-top: 1px solid var(--line); background: var(--panel); font-size: 11.5px; color: var(--muted); display: flex; gap: 14px; }
107
- footer .keys span { font-family: var(--mono); background: var(--chip); border-radius: 4px; padding: 0 5px; margin: 0 2px; }
129
+ footer { padding: 6px 16px; border-top: 1px solid var(--rule); background: var(--card); font-size: 11.5px; color: var(--slate); display: flex; gap: 14px; }
130
+ footer .keys span { font-family: var(--mono); background: var(--alt); border-radius: 4px; padding: 0 5px; margin: 0 2px; }
108
131
  </style>
109
132
  </head>
110
133
  <body>
@@ -191,7 +214,10 @@
191
214
  "use strict";
192
215
  var docs = [], selId = null, typeFilter = null, textFilter = "", follow = false;
193
216
  var freshIds = new Set(), crumbs = [];
194
- var PALETTE = ["#6d5ae6","#0891b2","#d97706","#16a34a","#dc2626","#c026d3","#4f46e5","#0d9488"];
217
+ // Categorical series colours. Brand-first: series 1 and 2 are --structure and --signal,
218
+ // so the common case is on-theme; the rest are distinguishable hues, because a chart
219
+ // needs separable series more than it needs a two-colour palette.
220
+ var PALETTE = ["#0073B0","#956300","#0D7A6F","#7A3FA8","#B00020","#0891B2","#4F46E5","#8A6D00"];
195
221
  var typeColor = {};
196
222
  function colorFor(t) {
197
223
  if (!typeColor[t]) typeColor[t] = PALETTE[Object.keys(typeColor).length % PALETTE.length];
@@ -5,51 +5,66 @@
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1">
6
6
  <title>Roadmap</title>
7
7
  <style>
8
+ /* Superbee View theme — mirrors the launcher shell, so a View framed inside it reads as
9
+ one surface rather than a foreign document.
10
+
11
+ TWO accent roles, not three. --structure carries structure AND state: "active" is the
12
+ same hue at full intensity, never a second colour, because hue should carry kind and
13
+ intensity should carry state. --signal carries liveness and the revealed answer. There
14
+ is deliberately no teal. Quiet metadata takes --slate, not an accent.
15
+
16
+ Fonts: a View is sandboxed under `font-src data:`, so it CANNOT load the shell's
17
+ self-hosted woff2 by URL. The brand faces are named first and resolve for anyone who
18
+ has them installed locally; the stacks behind them are the real fallback. Do not embed
19
+ a data: font — that is ~100KB in every View for a marginal gain. */
8
20
  :root {
9
- --paper:#F8F6F2; --white:#fff; --rule:#E0DDD8; --mist:#EDF0F3;
21
+ --bg:#F3F7FA; --card:#FFFFFF; --alt:#E9EFF4; --rule:#DADEE2;
10
22
  --ink:#0F1A24; --slate:#4A5D6E; --ghost:#9AAAB8;
11
- --blue:#1B6A9E; --teal:#0A8A7A; --amber:#B8832A;
23
+ --structure:#0073B0; --signal:#956300; --danger:#B00020;
12
24
  --radius:2px;
13
- --serif: "Cormorant Garamond", "Iowan Old Style", Georgia, "Times New Roman", serif;
14
- --sans: -apple-system, "Segoe UI", system-ui, sans-serif;
15
- --mono: ui-monospace, "SF Mono", Menlo, monospace;
25
+ --display:"Space Grotesk", system-ui, -apple-system, "Segoe UI", sans-serif;
26
+ --sans:"DM Sans", -apple-system, "Segoe UI", system-ui, sans-serif;
27
+ --mono:"JetBrains Mono", ui-monospace, "SF Mono", Menlo, monospace;
16
28
  }
17
29
  @media (prefers-color-scheme: dark) {
18
- :root { --paper:#0B1926; --white:#0F2A3F; --rule:#26323d; --mist:#132636;
19
- --ink:#F8F6F2; --slate:#9fb2c2; --ghost:#6f8494; --amber:#E0AA40; }
30
+ :root {
31
+ --bg:#0B1926; --card:#0F2A3F; --alt:#12314A; --rule:#26323D;
32
+ --ink:#F8F6F2; --slate:#B7C4D1; --ghost:#7E8FA0;
33
+ --structure:#3CAEF9; --signal:#E09707; --danger:#F2707A;
34
+ }
20
35
  }
21
36
  * { box-sizing:border-box; margin:0; }
22
- body { background:var(--paper); color:var(--ink); font:15px/1.55 var(--sans); }
23
- header { padding:22px 32px 14px; border-bottom:1px solid var(--rule); background:var(--white); }
24
- header h1 { font-family:var(--serif); font-weight:500; font-size:30px; letter-spacing:.01em; display:flex; align-items:baseline; gap:12px; }
25
- header h1 .chev { color:var(--blue); font-family:var(--sans); font-weight:700; }
37
+ body { background:var(--bg); color:var(--ink); font:15px/1.55 var(--sans); }
38
+ header { padding:22px 32px 14px; border-bottom:1px solid var(--rule); background:var(--card); }
39
+ header h1 { font-family:var(--display); font-weight:500; font-size:30px; letter-spacing:.01em; display:flex; align-items:baseline; gap:12px; }
40
+ header h1 .chev { color:var(--structure); font-family:var(--sans); font-weight:700; }
26
41
  header .sub { color:var(--slate); font-size:13px; margin-top:2px; }
27
- header .live { float:right; font-size:11.5px; color:var(--teal); font-family:var(--mono); }
28
- header .live .dot { display:inline-block; width:7px; height:7px; border-radius:50%; background:var(--teal); margin-right:5px; animation:pulse 1.4s infinite; }
42
+ header .live { float:right; font-size:11.5px; color:var(--signal); font-family:var(--mono); }
43
+ header .live .dot { display:inline-block; width:7px; height:7px; border-radius:50%; background:var(--signal); margin-right:5px; animation:pulse 1.4s infinite; }
29
44
  @keyframes pulse { 50%{opacity:.3} }
30
45
  main { max-width:900px; margin:0 auto; padding:26px 32px 80px; }
31
46
  .group { margin-bottom:34px; }
32
47
  .group > h2 { font-family:var(--sans); font-size:12px; font-weight:700; text-transform:uppercase; letter-spacing:.09em; color:var(--slate); display:flex; align-items:center; gap:9px; margin-bottom:4px; }
33
48
  .group > h2 .swatch { width:10px; height:10px; border-radius:2px; }
34
49
  .group > .note { font-size:12px; color:var(--ghost); margin-bottom:12px; }
35
- .item { background:var(--white); border:1px solid var(--rule); border-radius:var(--radius); border-left:3px solid var(--rule); margin-bottom:10px; overflow:hidden; }
36
- .item.active { border-left-color:var(--teal); }
37
- .item.committed { border-left-color:var(--blue); }
38
- .item.candidate { border-left-color:var(--amber); }
50
+ .item { background:var(--card); border:1px solid var(--rule); border-radius:var(--radius); border-left:3px solid var(--rule); margin-bottom:10px; overflow:hidden; }
51
+ .item.active { border-left-color:var(--structure); }
52
+ .item.committed { border-left-color:var(--structure); }
53
+ .item.candidate { border-left-color:var(--signal); }
39
54
  .item .head { display:flex; align-items:center; gap:12px; padding:13px 16px; cursor:pointer; }
40
- .item .head:hover { background:var(--mist); }
41
- .item .title { font-family:var(--serif); font-size:19px; font-weight:500; flex:1; line-height:1.2; }
55
+ .item .head:hover { background:var(--alt); }
56
+ .item .title { font-family:var(--display); font-size:19px; font-weight:500; flex:1; line-height:1.2; }
42
57
  .item .caret { color:var(--ghost); font-size:12px; transition:transform .15s; }
43
58
  .item.open .caret { transform:rotate(90deg); }
44
59
  .badge { font-family:var(--sans); font-size:10.5px; font-weight:600; padding:2px 8px; border-radius:999px; white-space:nowrap; letter-spacing:.02em; }
45
- .badge.active { color:var(--teal); background:color-mix(in srgb,var(--teal) 13%,transparent); }
46
- .badge.queued { color:var(--slate); background:var(--mist); }
47
- .badge.candidate { color:var(--amber); background:color-mix(in srgb,var(--amber) 15%,transparent); }
48
- .badge.done { color:var(--slate); background:var(--mist); }
60
+ .badge.active { color:var(--structure); background:color-mix(in srgb,var(--structure) 13%,transparent); }
61
+ .badge.queued { color:var(--slate); background:var(--alt); }
62
+ .badge.candidate { color:var(--signal); background:color-mix(in srgb,var(--signal) 15%,transparent); }
63
+ .badge.done { color:var(--slate); background:var(--alt); }
49
64
  .roll { display:flex; align-items:center; gap:9px; padding:0 16px 12px; }
50
- .bar { flex:1; height:5px; background:var(--mist); border-radius:3px; overflow:hidden; display:flex; }
65
+ .bar { flex:1; height:5px; background:var(--alt); border-radius:3px; overflow:hidden; display:flex; }
51
66
  .bar i { height:100%; display:block; }
52
- .bar i.done { background:var(--teal); } .bar i.prog { background:var(--amber); } .bar i.open { background:var(--rule); }
67
+ .bar i.done { background:var(--structure); } .bar i.prog { background:var(--signal); } .bar i.open { background:var(--rule); }
53
68
  .roll .count { font-family:var(--mono); font-size:11.5px; color:var(--slate); white-space:nowrap; }
54
69
  .roll .none { font-size:11.5px; color:var(--ghost); font-style:italic; }
55
70
  .body { display:none; padding:2px 16px 14px; border-top:1px solid var(--rule); }
@@ -57,16 +72,16 @@
57
72
  .desc { font-size:13.5px; color:var(--slate); margin:12px 0; max-width:70ch; }
58
73
  .tasks { display:flex; flex-direction:column; gap:1px; }
59
74
  .task { display:flex; align-items:center; gap:10px; padding:6px 8px; border-radius:2px; }
60
- .task:hover { background:var(--mist); }
75
+ .task:hover { background:var(--alt); }
61
76
  .task .tdot { width:7px; height:7px; border-radius:50%; flex:none; }
62
77
  .task .ttitle { flex:1; font-size:13.5px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
63
78
  .task .tid { font-family:var(--mono); font-size:11px; color:var(--ghost); }
64
- .st-todo{color:var(--slate)} .st-in_progress{color:var(--amber)} .st-blocked,.st-canceled{color:#c0392b} .st-done{color:var(--teal)}
65
- .d-todo{background:var(--ghost)} .d-in_progress{background:var(--amber)} .d-blocked,.d-canceled{background:#c0392b} .d-done{background:var(--teal)}
79
+ .st-todo{color:var(--slate)} .st-in_progress{color:var(--signal)} .st-blocked,.st-canceled{color:var(--danger)} .st-done{color:var(--structure)}
80
+ .d-todo{background:var(--ghost)} .d-in_progress{background:var(--signal)} .d-blocked,.d-canceled{background:var(--danger)} .d-done{background:var(--structure)}
66
81
  .item.fresh { animation:land 1.8s ease-out; }
67
- @keyframes land { 0%{background:color-mix(in srgb,var(--amber) 18%,var(--white))} 100%{background:var(--white)} }
82
+ @keyframes land { 0%{background:color-mix(in srgb,var(--signal) 18%,var(--card))} 100%{background:var(--card)} }
68
83
  footer { text-align:center; color:var(--ghost); font-size:11.5px; padding:20px; font-family:var(--mono); }
69
- .empty { color:var(--ghost); text-align:center; margin-top:16vh; font-family:var(--serif); font-size:20px; }
84
+ .empty { color:var(--ghost); text-align:center; margin-top:16vh; font-family:var(--display); font-size:20px; }
70
85
  </style>
71
86
  </head>
72
87
  <body>
@@ -140,9 +155,9 @@
140
155
  return (fm(it).sequence!=null && String(fm(it).sequence).trim()!=="") ? "committed" : "candidate";
141
156
  }
142
157
  var GROUPS=[
143
- {key:"active", label:"In motion", swatch:"var(--teal)", note:"actively being worked"},
144
- {key:"committed",label:"Committed", swatch:"var(--blue)", note:"sequenced, not yet started"},
145
- {key:"candidate",label:"Candidate", swatch:"var(--amber)",note:"recognized direction — not yet committed or sequenced (queued + no sequence). Awaiting a founders' decision."},
158
+ {key:"active", label:"In motion", swatch:"var(--structure)", note:"actively being worked"},
159
+ {key:"committed",label:"Committed", swatch:"var(--structure)", note:"sequenced, not yet started"},
160
+ {key:"candidate",label:"Candidate", swatch:"var(--signal)",note:"recognized direction — not yet committed or sequenced (queued + no sequence). Awaiting a founders' decision."},
146
161
  {key:"done", label:"Done", swatch:"var(--slate)",note:""}
147
162
  ];
148
163