@bongos/core 1.19.457 → 1.19.459
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/.bongos-core.json +126 -46
- package/.claude/skills/design/SKILL.md +10 -0
- package/docs/adr/0219-a-look-is-a-branding-pack-the-style-library.md +30 -0
- package/docs/adr/README.md +1 -0
- package/docs/branding-contract.md +1 -1
- package/docs/copy-inventory.md +160 -177
- package/docs/copy-registry.json +445 -606
- package/docs/file-map.md +2 -2
- package/docs/module-api-changelog.md +4 -0
- package/docs/recipes/ui-look-before-you-ship.md +2 -0
- package/modules/hall-ui/public/gate.css +20 -88
- package/modules/hall-ui/public/gate.html +24 -12
- package/modules/hall-ui/public/gate.js +77 -60
- package/modules/hall-ui/public/gate.states.json +19 -1
- package/modules/hall-ui/public/government.css +96 -154
- package/modules/hall-ui/public/government.html +80 -52
- package/modules/hall-ui/public/government.js +227 -136
- package/modules/hall-ui/public/government.states.json +71 -1
- package/modules/hall-ui/public/harbor.css +9 -120
- package/modules/hall-ui/public/harbor.html +23 -11
- package/modules/hall-ui/public/harbor.js +109 -83
- package/modules/hall-ui/public/harbor.states.json +19 -1
- package/modules/hall-ui/public/oversight.css +296 -0
- package/modules/hall-ui/public/watch.css +56 -170
- package/modules/hall-ui/public/watch.html +48 -37
- package/modules/hall-ui/public/watch.js +363 -298
- package/modules/hall-ui/public/watch.states.json +48 -1
- package/modules/ui-design/kit/README.md +7 -5
- package/modules/ui-design/kit/check-mock.js +12 -5
- package/modules/ui-design/kit/contrast.js +13 -6
- package/modules/ui-design/kit/lib.js +39 -2
- package/modules/ui-design/kit/probe.js +4 -1
- package/modules/ui-design/kit/render.js +7 -4
- package/modules/ui-design/kit/serve.js +9 -2
- package/modules/ui-design/styles/README.md +54 -2
- package/modules/ui-design/styles/chrome-world/DESIGN.md +56 -0
- package/modules/ui-design/styles/chrome-world/mock.html +275 -0
- package/modules/ui-design/styles/chrome-world/mock.states.json +11 -0
- package/modules/ui-design/styles/chrome-world/pack.json +33 -0
- package/modules/ui-design/styles/expedition/DESIGN.md +141 -0
- package/modules/ui-design/styles/expedition/mock.html +285 -0
- package/modules/ui-design/styles/expedition/mock.states.json +11 -0
- package/modules/ui-design/styles/expedition/pack.json +33 -0
- package/modules/ui-design/styles/grove/DESIGN.md +148 -0
- package/modules/ui-design/styles/grove/mock.html +294 -0
- package/modules/ui-design/styles/grove/mock.states.json +11 -0
- package/modules/ui-design/styles/grove/pack.json +33 -0
- package/package-lock.json +2 -2
- package/package.json +1 -1
- package/src/module-api.js +1 -1
- package/tests/cosmos_token_contrast.mjs +9 -2
- package/tests/hall_oversight_world.mjs +118 -0
- package/tests/hall_tokens.mjs +15 -6
- package/tests/ui_design_styles.mjs +218 -0
- package/tests/world_tokens.mjs +9 -2
|
@@ -0,0 +1,285 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
6
|
+
<title>{{productName}} · the expedition, on a sheet</title>
|
|
7
|
+
<script>
|
|
8
|
+
(function(){try{var q=new URLSearchParams(location.search);var m=q.get('mode');if(m==='light'||m==='dark')document.documentElement.setAttribute('data-mode',m);}catch(e){}})();
|
|
9
|
+
</script>
|
|
10
|
+
<style>
|
|
11
|
+
html { color-scheme: light; }
|
|
12
|
+
body {
|
|
13
|
+
/* the expedition's derived tier, by the recipes in this style's DESIGN.md. The fifteen
|
|
14
|
+
arrive from the pack the stub splices after this sheet; nothing below is a colour of its
|
|
15
|
+
own: a var(), a color-mix(), or black or white with alpha. The paper carries a printed
|
|
16
|
+
halftone screen (dots of ink at low alpha) and hairline frames; corners are 0 on every
|
|
17
|
+
container and a pill on every control. */
|
|
18
|
+
--font-mono: "JetBrains Mono", ui-monospace, "Cascadia Mono", Consolas, monospace;
|
|
19
|
+
--glass: var(--bg-card);
|
|
20
|
+
--glass-strong: var(--bg-deep);
|
|
21
|
+
--glass-edge: var(--rule);
|
|
22
|
+
--accent-ink: var(--accent-deep);
|
|
23
|
+
--accent-lift: color-mix(in srgb, var(--accent) 70%, #ffffff);
|
|
24
|
+
--accent-tint: color-mix(in srgb, var(--accent) 18%, var(--bg-card));
|
|
25
|
+
--accent-on: color-mix(in srgb, var(--accent) 10%, #000000);
|
|
26
|
+
--accent-glow: 0 0 0 0 transparent;
|
|
27
|
+
--focus: var(--accent-deep);
|
|
28
|
+
--type-halo: none;
|
|
29
|
+
--dots: rgba(0, 0, 0, .085);
|
|
30
|
+
--dot-pitch: 5px;
|
|
31
|
+
--frame: var(--ink);
|
|
32
|
+
--label-face: var(--font-mono);
|
|
33
|
+
--label-size: 11px;
|
|
34
|
+
--label-space: .12em;
|
|
35
|
+
--radius: 0;
|
|
36
|
+
--radius-sm: 0;
|
|
37
|
+
--radius-pill: 999px;
|
|
38
|
+
--top-h: 64px;
|
|
39
|
+
--gutter: clamp(16px, 4vw, 26px);
|
|
40
|
+
--band: clamp(40px, 7vh, 72px);
|
|
41
|
+
margin: 0;
|
|
42
|
+
background: var(--bg);
|
|
43
|
+
background-image: radial-gradient(var(--dots) .9px, transparent 1px);
|
|
44
|
+
background-size: var(--dot-pitch) var(--dot-pitch);
|
|
45
|
+
color: var(--ink);
|
|
46
|
+
font-family: var(--font-body);
|
|
47
|
+
font-size: 16px;
|
|
48
|
+
line-height: 1.5;
|
|
49
|
+
-webkit-font-smoothing: antialiased;
|
|
50
|
+
}
|
|
51
|
+
:root[data-mode="dark"] body {
|
|
52
|
+
color-scheme: dark;
|
|
53
|
+
--bg: #000000;
|
|
54
|
+
--bg-card: color-mix(in srgb, #ffffff 7%, #000000);
|
|
55
|
+
--bg-deep: #000000;
|
|
56
|
+
--bg-frame: color-mix(in srgb, #ffffff 4%, #000000);
|
|
57
|
+
--ink: #ffffff;
|
|
58
|
+
--ink-soft: rgba(255, 255, 255, .72);
|
|
59
|
+
--ink-faint: rgba(255, 255, 255, .62);
|
|
60
|
+
--rule: rgba(255, 255, 255, .18);
|
|
61
|
+
--rule-soft: rgba(255, 255, 255, .09);
|
|
62
|
+
--accent-deep: color-mix(in srgb, var(--accent) 70%, #ffffff);
|
|
63
|
+
--glass: rgba(255, 255, 255, .06);
|
|
64
|
+
--glass-strong: rgba(255, 255, 255, .12);
|
|
65
|
+
--glass-edge: rgba(255, 255, 255, .18);
|
|
66
|
+
--accent-ink: var(--accent);
|
|
67
|
+
--accent-tint: color-mix(in srgb, var(--accent) 16%, #000000);
|
|
68
|
+
--focus: var(--accent);
|
|
69
|
+
--dots: rgba(255, 255, 255, .10);
|
|
70
|
+
--dot-pitch: 4.5px;
|
|
71
|
+
--frame: rgba(255, 255, 255, .28);
|
|
72
|
+
--label-face: var(--font-body);
|
|
73
|
+
--label-size: 11.5px;
|
|
74
|
+
--label-space: .1em;
|
|
75
|
+
}
|
|
76
|
+
@media (prefers-color-scheme: dark) {
|
|
77
|
+
:root:not([data-mode="light"]) body {
|
|
78
|
+
color-scheme: dark;
|
|
79
|
+
--bg: #000000;
|
|
80
|
+
--bg-card: color-mix(in srgb, #ffffff 7%, #000000);
|
|
81
|
+
--bg-deep: #000000;
|
|
82
|
+
--bg-frame: color-mix(in srgb, #ffffff 4%, #000000);
|
|
83
|
+
--ink: #ffffff;
|
|
84
|
+
--ink-soft: rgba(255, 255, 255, .72);
|
|
85
|
+
--ink-faint: rgba(255, 255, 255, .62);
|
|
86
|
+
--rule: rgba(255, 255, 255, .18);
|
|
87
|
+
--rule-soft: rgba(255, 255, 255, .09);
|
|
88
|
+
--accent-deep: color-mix(in srgb, var(--accent) 70%, #ffffff);
|
|
89
|
+
--glass: rgba(255, 255, 255, .06);
|
|
90
|
+
--glass-strong: rgba(255, 255, 255, .12);
|
|
91
|
+
--glass-edge: rgba(255, 255, 255, .18);
|
|
92
|
+
--accent-ink: var(--accent);
|
|
93
|
+
--accent-tint: color-mix(in srgb, var(--accent) 16%, #000000);
|
|
94
|
+
--focus: var(--accent);
|
|
95
|
+
--dots: rgba(255, 255, 255, .10);
|
|
96
|
+
--dot-pitch: 4.5px;
|
|
97
|
+
--frame: rgba(255, 255, 255, .28);
|
|
98
|
+
--label-face: var(--font-body);
|
|
99
|
+
--label-size: 11.5px;
|
|
100
|
+
--label-space: .1em;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
*, *::before, *::after { box-sizing: border-box; }
|
|
105
|
+
a { color: inherit; }
|
|
106
|
+
:focus-visible { outline: 2px solid var(--focus); outline-offset: 3px; }
|
|
107
|
+
.skip { position: absolute; left: 12px; top: -60px; padding: 11px 18px; border-radius: var(--radius-pill); background: var(--bg-card); color: var(--ink); text-decoration: none; }
|
|
108
|
+
.skip:focus { top: 12px; }
|
|
109
|
+
.wrap { max-width: 1180px; margin: 0 auto; padding: 0 var(--gutter); }
|
|
110
|
+
|
|
111
|
+
/* the framed bar: a hairline rule, a yellow plate behind the mark */
|
|
112
|
+
.bar { height: var(--top-h); border-bottom: 1px solid var(--frame); background: var(--bg); }
|
|
113
|
+
.bar .wrap { height: 100%; display: flex; align-items: center; gap: 18px; }
|
|
114
|
+
.mark { display: inline-flex; align-items: center; height: 36px; padding: 0 12px; background: var(--accent); color: var(--accent-on); font-weight: 700; letter-spacing: -.01em; text-transform: uppercase; font-size: 14px; text-decoration: none; }
|
|
115
|
+
.nav { margin-left: auto; display: flex; align-items: center; gap: 4px; }
|
|
116
|
+
.nav a { text-decoration: none; text-transform: uppercase; font-family: var(--label-face); font-size: 12px; letter-spacing: .1em; color: var(--ink-soft); padding: 14px 10px; display: inline-block; line-height: 16px; }
|
|
117
|
+
.nav a:hover { color: var(--ink); }
|
|
118
|
+
.pill { display: inline-flex; align-items: center; height: 46px; padding: 0 22px; border-radius: var(--radius-pill); text-decoration: none; font-weight: 600; letter-spacing: 0; text-transform: none; font-family: var(--font-body); font-size: 15px; transition: background-color 200ms cubic-bezier(.2, .7, .3, 1); }
|
|
119
|
+
.pill.in { background: var(--ink); color: var(--bg); }
|
|
120
|
+
.who { display: none; align-items: center; gap: 8px; height: 46px; padding: 0 6px; border-radius: var(--radius-pill); border: 1px solid var(--rule); }
|
|
121
|
+
.who .dot { width: 30px; height: 30px; border-radius: 50%; background: var(--bg-deep); border: 1px solid var(--rule); }
|
|
122
|
+
body[data-state="signed-in"] .pill.in { display: none; }
|
|
123
|
+
body[data-state="signed-in"] .who { display: inline-flex; }
|
|
124
|
+
|
|
125
|
+
/* the bands: framed columns, not padded cards */
|
|
126
|
+
.band { padding: var(--band) 0; border-top: 1px solid var(--rule); }
|
|
127
|
+
.band:first-of-type { border-top: 0; }
|
|
128
|
+
h1 { font-family: var(--font-display); font-weight: 700; font-size: clamp(38px, 7.2vw, 96px); line-height: .92; letter-spacing: -.035em; text-transform: uppercase; margin: 0 0 18px; max-width: 12ch; }
|
|
129
|
+
h2 { font-family: var(--font-display); font-weight: 600; font-size: clamp(24px, 3vw, 40px); line-height: 1.04; letter-spacing: -.025em; margin: 0 0 14px; }
|
|
130
|
+
.lede { color: var(--ink-soft); max-width: 52ch; margin: 0; font-size: 15px; }
|
|
131
|
+
.label { font-family: var(--label-face); font-size: var(--label-size); letter-spacing: var(--label-space); text-transform: uppercase; color: var(--ink-faint); }
|
|
132
|
+
.kicker { display: inline-block; border-left: 3px solid var(--accent); padding-left: 10px; margin-bottom: 14px; }
|
|
133
|
+
|
|
134
|
+
/* the thirteen, as a specimen strip inside a frame */
|
|
135
|
+
.sw { display: grid; grid-template-columns: repeat(auto-fill, minmax(72px, 1fr)); gap: 0; margin: 0; padding: 0; list-style: none; border: 1px solid var(--frame); }
|
|
136
|
+
.sw li { margin: 0; padding: 10px; border-right: 1px solid var(--rule-soft); border-bottom: 1px solid var(--rule-soft); }
|
|
137
|
+
.sw i { display: block; height: 52px; border: 1px solid var(--rule); background: var(--c); }
|
|
138
|
+
.sw b { display: block; margin-top: 6px; font-family: var(--font-mono); font-weight: 400; font-size: 11px; color: var(--ink-faint); overflow-wrap: anywhere; }
|
|
139
|
+
|
|
140
|
+
/* the door pair: pills on paper, the primary in lamp yellow */
|
|
141
|
+
.doors { display: inline-flex; flex-wrap: wrap; gap: 8px; }
|
|
142
|
+
.door { display: inline-flex; align-items: center; height: 48px; padding: 0 28px; border-radius: var(--radius-pill); text-decoration: none; font-weight: 600; transition: background-color 200ms cubic-bezier(.2, .7, .3, 1); }
|
|
143
|
+
.door.go { background: var(--accent); color: var(--accent-on); }
|
|
144
|
+
.door.go:hover { background: var(--accent-lift); }
|
|
145
|
+
.door.more { color: var(--ink); border: 1px solid var(--ink); }
|
|
146
|
+
.door.more:hover { background: var(--glass-strong); }
|
|
147
|
+
|
|
148
|
+
/* the lifecycle rail: compartments with a visible frame */
|
|
149
|
+
.rail { display: grid; grid-template-columns: repeat(5, 1fr); gap: 0; margin: 0; padding: 0; list-style: none; border: 1px solid var(--frame); }
|
|
150
|
+
.rail li { padding: 14px; border-right: 1px solid var(--rule-soft); }
|
|
151
|
+
.rail li:last-child { border-right: 0; }
|
|
152
|
+
.rail .dot { display: block; width: 8px; height: 8px; border: 1px solid var(--ink-faint); margin-bottom: 10px; }
|
|
153
|
+
.rail .lit { background: var(--accent-tint); }
|
|
154
|
+
.rail .lit .dot { background: var(--accent); border-color: var(--accent-deep); }
|
|
155
|
+
.rail .lit .label { color: var(--ink); }
|
|
156
|
+
.rail p { margin: 6px 0 0; color: var(--ink-soft); font-size: 14px; }
|
|
157
|
+
|
|
158
|
+
/* ledger rows: the journal's index */
|
|
159
|
+
.ledger { margin: 0; padding: 0; list-style: none; border-top: 1px solid var(--frame); }
|
|
160
|
+
.ledger li { display: grid; grid-template-columns: 88px 1fr 152px 96px; gap: 20px; align-items: baseline; padding: 14px 0; border-bottom: 1px solid var(--rule); }
|
|
161
|
+
.ledger .id { font-family: var(--font-mono); font-size: 13px; color: var(--ink-faint); font-variant-numeric: tabular-nums; }
|
|
162
|
+
.ledger .by, .ledger .when { color: var(--ink-soft); font-size: 15px; }
|
|
163
|
+
.ledger .when { text-align: right; font-variant-numeric: tabular-nums; }
|
|
164
|
+
.ledger a { color: var(--accent-ink); text-underline-offset: 3px; display: inline-block; padding: 2px 0; }
|
|
165
|
+
|
|
166
|
+
footer { border-top: 1px solid var(--frame); padding: 26px 0 40px; }
|
|
167
|
+
footer .wrap { display: flex; flex-wrap: wrap; gap: 8px 22px; align-items: baseline; color: var(--ink-soft); font-size: 14px; }
|
|
168
|
+
footer p { margin: 0; flex: 1 1 320px; }
|
|
169
|
+
footer a { color: var(--accent-ink); display: inline-block; padding: 4px 0; font-family: var(--label-face); font-size: 12px; letter-spacing: .08em; text-transform: uppercase; }
|
|
170
|
+
|
|
171
|
+
@media (max-width: 900px) {
|
|
172
|
+
body { --top-h: 60px; }
|
|
173
|
+
.rail { grid-template-columns: 1fr; }
|
|
174
|
+
.rail li { border-right: 0; border-bottom: 1px solid var(--rule-soft); }
|
|
175
|
+
.rail li:last-child { border-bottom: 0; }
|
|
176
|
+
}
|
|
177
|
+
@media (max-width: 600px) {
|
|
178
|
+
.ledger li { grid-template-columns: 1fr; gap: 4px; }
|
|
179
|
+
.ledger .when { text-align: left; }
|
|
180
|
+
.nav a { display: none; }
|
|
181
|
+
}
|
|
182
|
+
@media (prefers-reduced-motion: reduce) {
|
|
183
|
+
*, *::before, *::after { animation: none !important; transition: none !important; }
|
|
184
|
+
}
|
|
185
|
+
</style>
|
|
186
|
+
</head>
|
|
187
|
+
<body>
|
|
188
|
+
<!-- THESIS: the expedition as a specimen sheet. The thirteen colours and the two faces the pack carries, laid through this look's own derived recipes (its DESIGN.md frontmatter): a framed bar with the mark on a yellow plate, an uppercase neo-grotesque display voice, a halftone screen printed over the paper, door pills with the primary in lamp yellow, a compartmented rail with one lit cell, the journal's index as ledger rows. This page declares no :root and no colour of its own: the pack is spliced by the stub (STYLE=expedition) and every value is a var() or a color-mix() of it. Dark restates the platform's black tier on body, since a mock links no sheet; this look reaches dark through its yellow and its faces, which is all a pack carries. STATES: rest (signed out), signed-in. MODES: ?mode=dark|light. -->
|
|
189
|
+
<a class="skip" href="#main">Skip to content</a>
|
|
190
|
+
<header class="bar">
|
|
191
|
+
<div class="wrap">
|
|
192
|
+
<a class="mark" href="/">{{productName}}</a>
|
|
193
|
+
<nav class="nav" aria-label="Primary">
|
|
194
|
+
<a href="#swatches">Projects</a>
|
|
195
|
+
<a href="#type">Docs</a>
|
|
196
|
+
<a class="pill in" href="#main">Sign in</a>
|
|
197
|
+
<span class="who"><span class="dot" aria-hidden="true"></span><span class="label">builder</span></span>
|
|
198
|
+
</nav>
|
|
199
|
+
</div>
|
|
200
|
+
</header>
|
|
201
|
+
<main id="main" tabindex="-1">
|
|
202
|
+
<section class="band">
|
|
203
|
+
<div class="wrap">
|
|
204
|
+
<p class="label kicker">A look from the style library</p>
|
|
205
|
+
<h1>The expedition</h1>
|
|
206
|
+
<p class="lede">A printed field journal. Warm paper under a halftone screen, hairline frames instead of a grid, headlines set big and heavy, and one lamp yellow that lights only the mark, the primary door and the live step.</p>
|
|
207
|
+
</div>
|
|
208
|
+
</section>
|
|
209
|
+
<section class="band" id="swatches">
|
|
210
|
+
<div class="wrap">
|
|
211
|
+
<h2>The thirteen</h2>
|
|
212
|
+
<ul class="sw">
|
|
213
|
+
<li><i style="--c: var(--bg)"></i><b>bg</b></li>
|
|
214
|
+
<li><i style="--c: var(--bg-card)"></i><b>bg-card</b></li>
|
|
215
|
+
<li><i style="--c: var(--bg-deep)"></i><b>bg-deep</b></li>
|
|
216
|
+
<li><i style="--c: var(--bg-frame)"></i><b>bg-frame</b></li>
|
|
217
|
+
<li><i style="--c: var(--ink)"></i><b>ink</b></li>
|
|
218
|
+
<li><i style="--c: var(--ink-soft)"></i><b>ink-soft</b></li>
|
|
219
|
+
<li><i style="--c: var(--ink-faint)"></i><b>ink-faint</b></li>
|
|
220
|
+
<li><i style="--c: var(--rule)"></i><b>rule</b></li>
|
|
221
|
+
<li><i style="--c: var(--rule-soft)"></i><b>rule-soft</b></li>
|
|
222
|
+
<li><i style="--c: var(--accent)"></i><b>accent</b></li>
|
|
223
|
+
<li><i style="--c: var(--accent-deep)"></i><b>accent-deep</b></li>
|
|
224
|
+
<li><i style="--c: var(--sea)"></i><b>sea</b></li>
|
|
225
|
+
<li><i style="--c: var(--terracotta)"></i><b>terracotta</b></li>
|
|
226
|
+
</ul>
|
|
227
|
+
</div>
|
|
228
|
+
</section>
|
|
229
|
+
<section class="band" id="type">
|
|
230
|
+
<div class="wrap">
|
|
231
|
+
<h2>One grotesque, three sizes</h2>
|
|
232
|
+
<p class="lede">The display face is a neo-grotesque set heavy and uppercase at display size, the way a journal prints its chapter titles. Body copy is the same family at reading weight in a narrow column. Labels take the mono on paper and the grotesque in dark.</p>
|
|
233
|
+
<p class="label" style="margin-top: 22px">Label face, tracked and uppercase</p>
|
|
234
|
+
<p style="margin: 6px 0 0; font-family: var(--font-mono); font-size: 13px; font-variant-numeric: tabular-nums">1003323 · 14,987 credits · 7 ships in 24h</p>
|
|
235
|
+
</div>
|
|
236
|
+
</section>
|
|
237
|
+
<section class="band">
|
|
238
|
+
<div class="wrap">
|
|
239
|
+
<h2>The doors</h2>
|
|
240
|
+
<p class="lede" style="margin-bottom: 22px">Two pills side by side. The primary is the lamp yellow with near-black ink on it; the secondary is a hairline outline, filled only on hover.</p>
|
|
241
|
+
<div class="doors">
|
|
242
|
+
<a class="door more" href="#swatches">Open the map</a>
|
|
243
|
+
<a class="door go" href="#main">Start a project</a>
|
|
244
|
+
</div>
|
|
245
|
+
</div>
|
|
246
|
+
</section>
|
|
247
|
+
<section class="band">
|
|
248
|
+
<div class="wrap">
|
|
249
|
+
<h2>The lifecycle rail</h2>
|
|
250
|
+
<ol class="rail">
|
|
251
|
+
<li><span class="dot"></span><span class="label">Claim</span><p>A builder locks a task.</p></li>
|
|
252
|
+
<li><span class="dot"></span><span class="label">Build</span><p>The code is written in a worktree.</p></li>
|
|
253
|
+
<li class="lit" aria-current="step"><span class="dot"></span><span class="label">Grade</span><p>An adversarial panel reads the diff.</p></li>
|
|
254
|
+
<li><span class="dot"></span><span class="label">Ship</span><p>Green checks land it on main.</p></li>
|
|
255
|
+
<li><span class="dot"></span><span class="label">Credit</span><p>The ledger pays on landing.</p></li>
|
|
256
|
+
</ol>
|
|
257
|
+
</div>
|
|
258
|
+
</section>
|
|
259
|
+
<section class="band">
|
|
260
|
+
<div class="wrap">
|
|
261
|
+
<h2>Ledger rows</h2>
|
|
262
|
+
<ul class="ledger">
|
|
263
|
+
<li><span class="id">1003320</span><span>The look-before-you-ship kit: a stub, a renderer, the probes</span><span class="by">jaxri</span><span class="when">3d ago</span></li>
|
|
264
|
+
<li><span class="id">1003321</span><span>The vetted UI skills: the vendoring policy and the platform preamble</span><span class="by">jaxri</span><span class="when">3d ago</span></li>
|
|
265
|
+
<li><span class="id">1003323</span><span><a href="#main">The style library: looks as branding packs</a></span><span class="by">jaxri</span><span class="when">today</span></li>
|
|
266
|
+
</ul>
|
|
267
|
+
</div>
|
|
268
|
+
</section>
|
|
269
|
+
</main>
|
|
270
|
+
<footer>
|
|
271
|
+
<div class="wrap">
|
|
272
|
+
<p>{{productName}} is built by AI agents claiming tasks from a ledger. This sheet is served through the kit with the look's pack spliced in.</p>
|
|
273
|
+
<a href="#main">Privacy</a>
|
|
274
|
+
<a href="#main">Terms</a>
|
|
275
|
+
<a href="#main">Contact</a>
|
|
276
|
+
</div>
|
|
277
|
+
</footer>
|
|
278
|
+
<script>
|
|
279
|
+
(function () {
|
|
280
|
+
var state = new URLSearchParams(location.search).get('state');
|
|
281
|
+
if (state === 'signed-in') document.body.setAttribute('data-state', 'signed-in');
|
|
282
|
+
})();
|
|
283
|
+
</script>
|
|
284
|
+
</body>
|
|
285
|
+
</html>
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
{
|
|
2
|
+
"_doc": "The specimen's states for the kit (task 1003323): node modules/ui-design/kit/render.js --states modules/ui-design/styles/expedition/mock.states.json --style expedition. Both modes; the mock reads ?mode= itself.",
|
|
3
|
+
"page": "/mock",
|
|
4
|
+
"surface": "modules/ui-design/styles/expedition",
|
|
5
|
+
"modes": ["dark", "light"],
|
|
6
|
+
"states": {
|
|
7
|
+
"rest": { "auth": false },
|
|
8
|
+
"signed-in": { "auth": true, "url": "/mock?state=signed-in", "expect": { "visible": [".who"], "hidden": [".pill.in"] } }
|
|
9
|
+
},
|
|
10
|
+
"reducedMotion": { "auth": false }
|
|
11
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
{
|
|
2
|
+
"_doc": "A look from the ui-design module's style library (task 1003323): the theme.ui overlay a branding pack carries, and nothing else. The stub lays it over the instance's pack (STYLE=expedition); an instance adopts it by copying `theme` into config/branding.json. Light values only, as the contract says: dark is each sheet's own black tier, which this look reaches through the accent and the faces.",
|
|
3
|
+
"name": "expedition",
|
|
4
|
+
"title": "The Expedition",
|
|
5
|
+
"summary": "A printed field journal: warm paper, hairline frames instead of a grid, big neo-grotesque headlines, one lamp yellow that lights only the pressable and the live.",
|
|
6
|
+
"origin": "docs/design/mocks/world/natgeo-editorial (the world round, task 1003296; kept by the owner in round 1, retuned to the contract here: ink-faint deepened to #66645b so the thinnest pair clears 4.5:1 on paper, and sea lifted from #2c5464 to #427d97 because the hall derives its info state from sea at 80% into white in dark, which the deep lake blue could not carry on black)",
|
|
7
|
+
"theme": {
|
|
8
|
+
"ui": {
|
|
9
|
+
"colors": {
|
|
10
|
+
"bg": "#f4f3ef",
|
|
11
|
+
"bgCard": "#ffffff",
|
|
12
|
+
"bgDeep": "#e9e7e0",
|
|
13
|
+
"bgFrame": "#eceae3",
|
|
14
|
+
"ink": "#141412",
|
|
15
|
+
"inkSoft": "#55544f",
|
|
16
|
+
"inkFaint": "#66645b",
|
|
17
|
+
"rule": "#d9d7cf",
|
|
18
|
+
"ruleSoft": "#e8e6df",
|
|
19
|
+
"accent": "#ffd214",
|
|
20
|
+
"accentDeep": "#7f6209",
|
|
21
|
+
"sea": "#427d97",
|
|
22
|
+
"terracotta": "#b4592f"
|
|
23
|
+
},
|
|
24
|
+
"fonts": {
|
|
25
|
+
"display": "\"Archivo\", \"Hanken Grotesk\", \"Helvetica Neue\", Helvetica, Arial, sans-serif",
|
|
26
|
+
"body": "\"Archivo\", \"Hanken Grotesk\", \"Helvetica Neue\", Helvetica, Arial, sans-serif",
|
|
27
|
+
"links": [
|
|
28
|
+
"https://fonts.googleapis.com/css2?family=Archivo:wght@300;400;500;600;700&family=JetBrains+Mono:wght@400&display=swap"
|
|
29
|
+
]
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: The Grove
|
|
3
|
+
description: A sculpted paper garden. Pale sage paper, soft corners on everything that holds content, shadows tinted from the ink and never grey, the sea green as a second voice, one lit tan on everything pressable.
|
|
4
|
+
colors:
|
|
5
|
+
# ---- contract tier, LIGHT: the thirteen this look's pack.json carries, value for value
|
|
6
|
+
# (tests/ui_design_styles.mjs holds the two in lockstep). Spliced into :root at the end of
|
|
7
|
+
# <head> at (0,1,0) on any instance that adopts the look.
|
|
8
|
+
bg: "#e1eadb"
|
|
9
|
+
bg-card: "#f6f9f3"
|
|
10
|
+
bg-deep: "#cad8c2"
|
|
11
|
+
bg-frame: "#eaf0e5"
|
|
12
|
+
ink: "#0f3226"
|
|
13
|
+
ink-soft: "#2f5240"
|
|
14
|
+
ink-faint: "#3f5a48"
|
|
15
|
+
rule: "#9db69a"
|
|
16
|
+
rule-soft: "#d0ddcb"
|
|
17
|
+
accent: "#e3c39c"
|
|
18
|
+
accent-deep: "#6d4b34"
|
|
19
|
+
sea: "#3d8562"
|
|
20
|
+
terracotta: "#b07a4e"
|
|
21
|
+
# ---- contract tier, DARK: NOT this look's to set. A pack carries light values only; dark is
|
|
22
|
+
# each sheet's own black tier, which the look reaches through the tan, the sea and the faces.
|
|
23
|
+
# The candidate's own green dark ground (#2f6049) cannot travel in a pack.
|
|
24
|
+
bg-dark: "#000000"
|
|
25
|
+
ink-dark: "#ffffff"
|
|
26
|
+
accent-deep-dark: "color-mix(in srgb, var(--accent) 70%, #ffffff)"
|
|
27
|
+
# ---- derived: the four fields. Sea is the SLAB (a whole band sits on it), bark (accent-deep)
|
|
28
|
+
# is every quiet mark and every accent-as-text job, tan (accent) is the lit thing, wood
|
|
29
|
+
# (terracotta) is held for a small drum's shell and for warn / err. The slab's field is the
|
|
30
|
+
# sea deepened 38% into black in BOTH modes: the contract's sea sits in the lightness band
|
|
31
|
+
# the hall's info state needs, and a slab that cream can be read on is darker than that.
|
|
32
|
+
accent-ink: "var(--accent-deep)"
|
|
33
|
+
accent-ink-dark: "var(--accent)"
|
|
34
|
+
accent-on: "color-mix(in srgb, var(--accent) 12%, #000000)"
|
|
35
|
+
accent-lift: "color-mix(in srgb, var(--accent) 72%, #ffffff)"
|
|
36
|
+
accent-tint: "color-mix(in srgb, var(--accent) 34%, var(--bg-card))"
|
|
37
|
+
accent-tint-dark: "color-mix(in srgb, var(--accent) 18%, #000000)"
|
|
38
|
+
field: "color-mix(in srgb, var(--sea) 62%, #000000)"
|
|
39
|
+
on-field: "color-mix(in srgb, var(--accent) 55%, #ffffff)"
|
|
40
|
+
on-field-soft: "color-mix(in srgb, var(--accent) 40%, #ffffff)"
|
|
41
|
+
field-rule: "color-mix(in srgb, #ffffff 20%, transparent)"
|
|
42
|
+
focus: "var(--accent-deep)"
|
|
43
|
+
focus-dark: "var(--accent)"
|
|
44
|
+
# ---- derived: the sculpted paper. Shadows are TINTED from the ink, never grey.
|
|
45
|
+
shade: "color-mix(in srgb, var(--ink) 16%, transparent)"
|
|
46
|
+
shade-soft: "color-mix(in srgb, var(--ink) 7%, transparent)"
|
|
47
|
+
shade-dark: "rgba(0, 0, 0, .6)"
|
|
48
|
+
shade-soft-dark: "rgba(0, 0, 0, .35)"
|
|
49
|
+
typography:
|
|
50
|
+
display: { fontFamily: "Nunito, Trebuchet MS, system-ui, sans-serif", fontSize: "clamp(34px, 6.4vw, 84px)", fontWeight: 800, lineHeight: 0.96, letterSpacing: "-0.03em" }
|
|
51
|
+
headline: { fontFamily: "{typography.display.fontFamily}", fontSize: "clamp(24px, 3vw, 38px)", fontWeight: 800, lineHeight: 1.08, letterSpacing: "-0.02em" }
|
|
52
|
+
body: { fontFamily: "Nunito, Trebuchet MS, system-ui, sans-serif", fontSize: "17px", fontWeight: 400, lineHeight: 1.55 }
|
|
53
|
+
label: { fontFamily: "JetBrains Mono, ui-monospace, Cascadia Mono, Consolas, monospace", fontSize: "11px", fontWeight: 500, letterSpacing: "0.08em", textTransform: "uppercase" }
|
|
54
|
+
mono: { fontFamily: "{typography.label.fontFamily}", fontSize: "13px", fontWeight: 400, fontFeature: "tabular-nums" }
|
|
55
|
+
rounded:
|
|
56
|
+
pill: "999px"
|
|
57
|
+
panel: "22px"
|
|
58
|
+
tile: "12px"
|
|
59
|
+
spacing:
|
|
60
|
+
band: "clamp(40px, 7vh, 72px)"
|
|
61
|
+
gutter: "clamp(16px, 4vw, 26px)"
|
|
62
|
+
container: "1180px"
|
|
63
|
+
components:
|
|
64
|
+
bar-card: { backgroundColor: "{colors.bg-card}", rounded: "{rounded.pill}", shadow: "0 10px 26px -14px {colors.shade}, 0 2px 6px {colors.shade-soft}" }
|
|
65
|
+
door-primary: { backgroundColor: "{colors.accent}", textColor: "{colors.accent-on}", rounded: "{rounded.pill}", height: "48px", padding: "0 28px" }
|
|
66
|
+
door-secondary: { backgroundColor: "transparent", textColor: "{colors.ink}", rounded: "{rounded.pill}", height: "48px" }
|
|
67
|
+
sign-in: { backgroundColor: "{colors.field}", textColor: "{colors.on-field}", rounded: "{rounded.pill}", height: "42px" }
|
|
68
|
+
slab: { backgroundColor: "{colors.field}", textColor: "{colors.on-field}", rounded: "{rounded.panel}" }
|
|
69
|
+
tile: { backgroundColor: "{colors.bg-card}", rounded: "{rounded.tile}", padding: "16px" }
|
|
70
|
+
badge: { backgroundColor: "{colors.accent-tint}", textColor: "{colors.accent-ink}", rounded: "{rounded.tile}", height: "26px" }
|
|
71
|
+
---
|
|
72
|
+
|
|
73
|
+
# Style: The Grove
|
|
74
|
+
|
|
75
|
+
**Origin.** The `organic-cards` candidate of the world round ([task 1003296](https://cloudbongos.com/builders#/task/1003296), `docs/design/mocks/world/organic-cards/`), kept by the owner in round 1 and not picked in round 2. Ported into the style library ([task 1003323](https://cloudbongos.com/builders#/task/1003323)) as a **branding pack**, never a sheet: the thirteen light colours and the two faces in `pack.json`, retuned against the contract. The retune is a measurement, not a taste: the candidate's sage ground (`#c8d7bf`) put the hub's fixed status vocabulary and the hall's chips under 4.5:1, so the ground lifted to `#e1eadb` and the inks deepened until every pair the three sheets paint cleared. The candidate's green **dark** ground (`#2f6049`) cannot travel in a pack (a pack carries light values only); in dark this look is the sheets' black under the tan and the sea.
|
|
76
|
+
|
|
77
|
+
## Overview
|
|
78
|
+
|
|
79
|
+
**Creative North Star: "A sculpted paper garden"**
|
|
80
|
+
|
|
81
|
+
Everything in this look is cut from soft paper and set down in a garden. Containers have real corners (22px on a panel, 12px on a tile, a pill on anything pressable), they lift off the ground on a shadow that is tinted from the ink and never grey, and the ground itself is a pale sage rather than white. Three named fields carry the system: sea green as a slab a whole band can sit on, bark brown for every quiet mark, and a lit tan on everything that can be pressed. Type is a rounded, wide-aperture face set heavy for headlines and plain for body.
|
|
82
|
+
|
|
83
|
+
**Key Characteristics:**
|
|
84
|
+
|
|
85
|
+
- Pale sage paper (`#e1eadb`); pure black in dark, where the tan and the slab do the work.
|
|
86
|
+
- Soft corners on everything that holds content; pills on everything pressable.
|
|
87
|
+
- Tinted shadows mixed from the ink; a hairline only where a shadow would be too much.
|
|
88
|
+
- Nunito 800 for display, 400 for body, JetBrains Mono for labels on paper.
|
|
89
|
+
- The sea green as a field, not an accent; the tan as the one lit thing.
|
|
90
|
+
|
|
91
|
+
## Colors
|
|
92
|
+
|
|
93
|
+
- **Tan** (`accent`, `#e3c39c`): the lit thing. It fills the primary door, the identity disc and the lit rail tile. It is a fill colour: at 1.6:1 against white it never paints words, so every accent-as-text job is `accent-deep`.
|
|
94
|
+
- **Bark** (`accent-deep`, `#6d4b34`): every quiet mark, every link, the badge's ink, 6.01:1 on the sage and 7.17:1 on the card. In dark it derives from the tan, never restated.
|
|
95
|
+
- **Ink on tan** (`accent-on`): `color-mix(in srgb, var(--accent) 12%, #000000)`, a near black warmed by the tan.
|
|
96
|
+
- **Sea** (`#3d8562`): the second voice. The contract's sea sits in the narrow lightness band the hall's info state needs (sea at 80% into white in dark, 86% into black in light), so the candidate's deep `#2a5a46` could not travel; the **slab** derives its field from it, `color-mix(in srgb, var(--sea) 62%, #000000)`, a deep green a whole band sits on with cream type (`on-field`: the tan mixed 55% into white, above 6:1). The sign-in door takes the field too, so the bar has one green thing.
|
|
97
|
+
- **Wood** (`terracotta`, `#b07a4e`): held for a small drum's shell and as the warn / error source.
|
|
98
|
+
- **Sage, card, deep, frame** (`bg`, `bg-card`, `bg-deep`, `bg-frame`): the ground and its layers. Card is a near-white with a green cast, so a tile reads as paper on paper, not white on green.
|
|
99
|
+
- **Ink, ink-soft, ink-faint**: deep forest inks. Ink-faint on the sage is 5.88:1; it was deepened from the candidate's `#476350` (4.29:1), the pair that failed first.
|
|
100
|
+
- **Rule, rule-soft**: the sage's own hairlines, for the rare divider a shadow cannot do.
|
|
101
|
+
|
|
102
|
+
## Typography
|
|
103
|
+
|
|
104
|
+
**Display Font:** Nunito 800 (with Trebuchet MS, system-ui, sans-serif)
|
|
105
|
+
**Body Font:** Nunito 400/600 (same stack)
|
|
106
|
+
**Label / Mono Font:** JetBrains Mono 400/500 (with ui-monospace, Cascadia Mono, Consolas)
|
|
107
|
+
|
|
108
|
+
**Character:** A rounded, wide-aperture humanist sans that is friendly at every size. Display is set at 800 with tracking pulled to `-0.03em`, sentence case: the grove never shouts. Labels take the mono on paper, at a looser `0.08em` than the chrome world, and the body face in dark.
|
|
109
|
+
|
|
110
|
+
## Shapes
|
|
111
|
+
|
|
112
|
+
**All soft.** 22px on panels and slabs, 12px on tiles and badges, a pill on every door, chip and input. The bar itself is a pill-shaped card floating on the sage. There is no square corner anywhere in this look.
|
|
113
|
+
|
|
114
|
+
## Materials
|
|
115
|
+
|
|
116
|
+
- **Tinted shadows.** `0 10px 26px -14px shade, 0 2px 6px shade-soft`, where `shade` is the ink at 16% and `shade-soft` the ink at 7%; in dark, black at 60% and 35%. Grey shadows are banned: a shadow is the ground's own colour, deepened.
|
|
117
|
+
- **The slab.** A deep-green panel (the sea mixed 62% into black, the same in both modes) with cream type and a 20%-white hairline inside it.
|
|
118
|
+
- **Plates** (when a surface adds them): photographic leaf plates over the paper, a real-alpha hero object. A surface's plates are its own; this look brings none.
|
|
119
|
+
|
|
120
|
+
## Motion
|
|
121
|
+
|
|
122
|
+
Gentle. Entry motion at 200ms on `cubic-bezier(.2,.7,.3,1)`; a tile lifts 2px on hover; no ambient loops in this look. The kill switch stands as the platform's.
|
|
123
|
+
|
|
124
|
+
## Do's and Don'ts
|
|
125
|
+
|
|
126
|
+
### Do
|
|
127
|
+
|
|
128
|
+
- **Do** fill with `accent` and write with `accent-deep`; put `accent-on` on any tan.
|
|
129
|
+
- **Do** tint every drop from the ink; keep the two-part lift recipe as the one elevation.
|
|
130
|
+
- **Do** spend the sea as a field, one slab per view at most.
|
|
131
|
+
- **Do** round everything: 22 / 12 / pill.
|
|
132
|
+
- **Do** keep the label face mono on paper and the body face in dark.
|
|
133
|
+
|
|
134
|
+
### Don't
|
|
135
|
+
|
|
136
|
+
- **Don't** write words in the tan, or put white on it.
|
|
137
|
+
- **Don't** use an em dash or en dash in visible copy, an emoji, gradient text, or a coloured text glow.
|
|
138
|
+
- **Don't** put a square corner on a container, or a hairline where a lift would do.
|
|
139
|
+
- **Don't** pin the accent, sea or terracotta in a dark block; dark derives.
|
|
140
|
+
- **Don't** declare a `:root` in a page; page tokens live on `body`.
|
|
141
|
+
|
|
142
|
+
## Accessibility Floors
|
|
143
|
+
|
|
144
|
+
The platform's, unchanged: 4.5:1 body text and 3:1 large text and non-text in both modes, measured from the real stylesheet; every control 24px on both sides (the doors are 48, the sign-in pill 42); the kill switch at the foot of the token layer. This pack measures clean against every pair the landing's `world.css`, the hub's `cosmos.css` and the hall's `style.css` paint (`tests/ui_design_styles.mjs` runs their suites under it) and on its own grounds (`node modules/ui-design/kit/contrast.js --pack grove`).
|
|
145
|
+
|
|
146
|
+
## Adopting this look
|
|
147
|
+
|
|
148
|
+
Copy `pack.json`'s `theme` into the instance's `config/branding.json` (a fresh instance's `cloudbongos init` writes that file; an existing one merges the block over its own). Nothing else changes: every sheet reads the contract and only the contract, so the landing, the hub, the hall and the status pages re-theme at once. What stays the platform's: the dark ground (black), the hall's fixed green / amber / red verification vocabulary, the status ledger's pillars, and every derived recipe a sheet already carries; the surfaces keep their hairlines, since a corner radius and a shadow are a sheet's derived tier, not a pack's. Look before you ship: `node modules/ui-design/kit/render.js --page / --style grove`.
|