@augurworks/augur 0.15.1
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/CANVAS.md +858 -0
- package/INSTALL.md +603 -0
- package/LICENSE +27 -0
- package/README.md +150 -0
- package/TRADEMARKS.md +72 -0
- package/agents/README.md +65 -0
- package/agents/canon-extract.md +117 -0
- package/agents/canon.md +151 -0
- package/agents/canvas.md +88 -0
- package/agents/currency.md +74 -0
- package/agents/drafts.md +92 -0
- package/agents/identity.md +148 -0
- package/agents/prototype-contract.md +69 -0
- package/agents/publishing.md +324 -0
- package/agents/review-feedback.md +76 -0
- package/agents/space-json.md +132 -0
- package/agents/ui-skill.md +101 -0
- package/agents/working-marks.md +86 -0
- package/brand/augur-eye.svg +3 -0
- package/brand/augur-icon.svg +41 -0
- package/brand/augur-mark.svg +5 -0
- package/brand/lentianova-bulky.otf +0 -0
- package/brand/lentianova-median.otf +0 -0
- package/brand/lentianova.woff2 +0 -0
- package/build.js +8409 -0
- package/changelog.md +133 -0
- package/fonts/inter-latin-wght-normal.woff2 +0 -0
- package/package.json +57 -0
- package/pitis/PETS.md +121 -0
- package/pitis/README.md +117 -0
- package/pitis/index.html +266 -0
- package/pitis/piti.build.js +81 -0
- package/pitis/piti.js +929 -0
- package/pitis/roast-agent.md +185 -0
- package/realtime/src/index.js +119 -0
- package/realtime/wrangler.example.toml +44 -0
- package/scripts/adopt.mjs +106 -0
- package/scripts/board-snapshot.mjs +197 -0
- package/scripts/build-seed-pack.mjs +33 -0
- package/scripts/bundle-rekey.mjs +112 -0
- package/scripts/bundle-tenancy-rehearsal.mjs +781 -0
- package/scripts/canon-extract.mjs +578 -0
- package/scripts/canon.mjs +599 -0
- package/scripts/canvas-screen.mjs +333 -0
- package/scripts/check-local.mjs +136 -0
- package/scripts/clawd-art.mjs +75 -0
- package/scripts/clawd-canvas.mjs +741 -0
- package/scripts/cli.mjs +100 -0
- package/scripts/clone.mjs +422 -0
- package/scripts/close.mjs +30 -0
- package/scripts/connect.mjs +103 -0
- package/scripts/deploy.mjs +157 -0
- package/scripts/dev.mjs +54 -0
- package/scripts/doc-lint.mjs +143 -0
- package/scripts/export.mjs +300 -0
- package/scripts/fork.mjs +64 -0
- package/scripts/freeze.mjs +74 -0
- package/scripts/frontdoor-parity.mjs +180 -0
- package/scripts/hook.mjs +67 -0
- package/scripts/identity-rekey.mjs +112 -0
- package/scripts/init.mjs +122 -0
- package/scripts/land.mjs +40 -0
- package/scripts/lib/adapters.mjs +156 -0
- package/scripts/lib/board-snapshot.mjs +511 -0
- package/scripts/lib/draft.mjs +385 -0
- package/scripts/lib/graduate.mjs +276 -0
- package/scripts/lib/instance.mjs +74 -0
- package/scripts/lib/marks.mjs +107 -0
- package/scripts/lib/materialize.mjs +138 -0
- package/scripts/lib/merge3.mjs +124 -0
- package/scripts/lib/offline-posture.mjs +120 -0
- package/scripts/lib/offline-respawn.mjs +18 -0
- package/scripts/lib/offline-wrangler.mjs +78 -0
- package/scripts/lib/publish-compose.mjs +12 -0
- package/scripts/lib/publish-conflict.mjs +78 -0
- package/scripts/lib/publish-evidence.mjs +144 -0
- package/scripts/lib/refine-compare.mjs +140 -0
- package/scripts/lib/refine-ledger.mjs +150 -0
- package/scripts/lib/refine-png.mjs +149 -0
- package/scripts/lib/seed-pack-build.mjs +141 -0
- package/scripts/lib/state-compare.mjs +68 -0
- package/scripts/lib/store.mjs +122 -0
- package/scripts/login.mjs +84 -0
- package/scripts/mark.mjs +112 -0
- package/scripts/migrate-board-keys.mjs +164 -0
- package/scripts/migrate.mjs +265 -0
- package/scripts/no-foreign-vocabulary.mjs +216 -0
- package/scripts/no-product-names.mjs +157 -0
- package/scripts/no-tenant-globals.mjs +1134 -0
- package/scripts/offline.mjs +247 -0
- package/scripts/og.mjs +170 -0
- package/scripts/one-tenant-resolver.mjs +146 -0
- package/scripts/open.mjs +63 -0
- package/scripts/publish.mjs +1041 -0
- package/scripts/read.mjs +31 -0
- package/scripts/refine.mjs +455 -0
- package/scripts/release-drift.mjs +138 -0
- package/scripts/restore.mjs +322 -0
- package/scripts/review.mjs +125 -0
- package/scripts/save.mjs +21 -0
- package/scripts/shell-lint.mjs +189 -0
- package/scripts/ship.mjs +460 -0
- package/scripts/shoot.mjs +264 -0
- package/scripts/smoke-invite.mjs +113 -0
- package/scripts/state-inventory.mjs +223 -0
- package/scripts/status.mjs +177 -0
- package/scripts/sync.mjs +27 -0
- package/scripts/tenant-do-rehearsal.mjs +1314 -0
- package/scripts/ui-copy-lint.mjs +202 -0
- package/scripts/watch.mjs +32 -0
- package/scripts/wrangler-preflight.mjs +246 -0
- package/seed/CANON.md +43 -0
- package/seed/README.md +119 -0
- package/seed/prototype-status.json +9 -0
- package/seed/registry.json +88 -0
- package/seed/skills/starter-ui/SKILL.md +52 -0
- package/seed/skills/starter-ui/skill.json +11 -0
- package/seed/skills/starter-ui/starter-tokens.css +73 -0
- package/seed/skills/starter-ui/starter-ui.css +318 -0
- package/seed/skills/starter-ui/starter-ui.js +50 -0
- package/seed/space.json +5 -0
- package/seed/start-here/prototypes/connect-your-terminal/index.html +428 -0
- package/seed/start-here/prototypes/connect-your-terminal/preview.webp +0 -0
- package/seed/start-here/prototypes/sample-with-comments/index.html +172 -0
- package/seed/start-here/prototypes/sample-with-comments/preview.webp +0 -0
- package/seed/start-here/prototypes/set-up-your-design-system/index.html +353 -0
- package/seed/start-here/prototypes/set-up-your-design-system/preview.webp +0 -0
- package/seed/threads.json +52 -0
- package/seed/worked-examples/prototypes/field-readings/index.html +273 -0
- package/seed/worked-examples/prototypes/field-readings/preview.webp +0 -0
- package/seed/worked-examples/prototypes/slide-deck/index.html +214 -0
- package/seed/worked-examples/prototypes/slide-deck/preview.webp +0 -0
- package/seed/worked-examples/prototypes/specimen-viewer/index.html +203 -0
- package/seed/worked-examples/prototypes/specimen-viewer/preview.webp +0 -0
- package/src/_worker.js +12668 -0
- package/src/board-key.mjs +57 -0
- package/src/board-room.mjs +881 -0
- package/src/bundle-keys.mjs +138 -0
- package/src/canon/collect-in-browser.js +215 -0
- package/src/canon/emit.mjs +232 -0
- package/src/canon/observe.mjs +260 -0
- package/src/canon/schema.mjs +451 -0
- package/src/canvas/DSEG-LICENSE.txt +95 -0
- package/src/canvas/DSEG7Classic-Bold.woff2 +0 -0
- package/src/canvas/canvas.css +885 -0
- package/src/canvas/canvas.js +5780 -0
- package/src/canvas/capture.js +485 -0
- package/src/chrome/appchrome.mjs +568 -0
- package/src/currency.mjs +203 -0
- package/src/delete-confirmation.mjs +254 -0
- package/src/drafts/drafts.js +326 -0
- package/src/entry.js +58 -0
- package/src/galleries.mjs +400 -0
- package/src/health-cron.mjs +173 -0
- package/src/identity.json +1 -0
- package/src/kv-codec.mjs +135 -0
- package/src/kv-identity.mjs +259 -0
- package/src/mail.mjs +599 -0
- package/src/provenance.mjs +74 -0
- package/src/publish-compose.mjs +363 -0
- package/src/publish-fork.mjs +221 -0
- package/src/publish-units.mjs +44 -0
- package/src/purge.mjs +81 -0
- package/src/review/COMMENTING-UX.md +306 -0
- package/src/review/cat.png +0 -0
- package/src/review/comment-cursor.svg +7 -0
- package/src/review/comments.js +1738 -0
- package/src/room-ticket.mjs +96 -0
- package/src/roster-chip.mjs +32 -0
- package/src/seed-pack.mjs +261 -0
- package/src/state-inventory.mjs +249 -0
- package/src/sw-logic.mjs +48 -0
- package/src/tenant-cache.mjs +141 -0
- package/src/tenant-context.mjs +386 -0
- package/src/tenant-do.js +2940 -0
- package/src/tenant-host.mjs +144 -0
- package/src/tenant-quotas.mjs +140 -0
- package/src/unit-core.mjs +103 -0
- package/src/unit-object.mjs +338 -0
- package/templates/README.md +67 -0
- package/templates/shell/deploy.yml +145 -0
- package/templates/shell/engine-bump.yml +142 -0
- package/templates/shell/health.yml +233 -0
- package/templates/shell/kv-backup.yml +201 -0
- package/templates/shell/roster-update.yml +110 -0
- package/templates/shell/space-preflight.yml +35 -0
- package/templates/shell/space-rebake.yml +79 -0
- package/templates/shell/store-backup.yml +152 -0
- package/templates/shell/wrangler.example.toml +266 -0
- package/templates/space/publish.yml +91 -0
|
@@ -0,0 +1,273 @@
|
|
|
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>Field readings</title>
|
|
7
|
+
<meta name="description" content="A week of readings from three instruments, drawn as small multiples with a shared crosshair — charts with no chart library, keyboard included.">
|
|
8
|
+
<link rel="stylesheet" href="../../../skills/starter-ui/starter-tokens.css">
|
|
9
|
+
<link rel="stylesheet" href="../../../skills/starter-ui/starter-ui.css">
|
|
10
|
+
<style>
|
|
11
|
+
.tiles { display: grid; grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr)); gap: var(--starter-s3); }
|
|
12
|
+
.tile { padding: var(--starter-s4); border: var(--starter-hair); border-radius: var(--starter-radius-2); }
|
|
13
|
+
.tile__k { margin: 0 0 var(--starter-s1); font: 600 var(--starter-text-xs)/1.6 var(--starter-font-display); letter-spacing: .12em; text-transform: uppercase; color: var(--starter-ink-2); }
|
|
14
|
+
.tile__v { margin: 0; font: 600 var(--starter-text-2xl)/1 var(--starter-font-display); letter-spacing: -.03em; font-variant-numeric: tabular-nums; }
|
|
15
|
+
.tile__u { font-size: var(--starter-text-md); color: var(--starter-ink-2); }
|
|
16
|
+
.tile__n { margin: var(--starter-s2) 0 0; font-size: var(--starter-text-sm); color: var(--starter-ink-2); }
|
|
17
|
+
|
|
18
|
+
.plot { border: var(--starter-hair); border-radius: var(--starter-radius-2); overflow: hidden; }
|
|
19
|
+
.plot:focus-visible { outline: 2px solid var(--starter-mark); outline-offset: 2px; }
|
|
20
|
+
.panel { display: grid; grid-template-columns: 9rem minmax(0, 1fr); align-items: center; border-top: var(--starter-hair); }
|
|
21
|
+
.panel:first-child { border-top: 0; }
|
|
22
|
+
.panel__meta { padding: var(--starter-s3) var(--starter-s4); }
|
|
23
|
+
.panel__name { margin: 0; font: 600 var(--starter-text-sm)/1.3 var(--starter-font-display); }
|
|
24
|
+
.panel__val { margin: 0; font: var(--starter-text-xs)/1.6 var(--starter-font-display); color: var(--starter-ink-2); font-variant-numeric: tabular-nums; }
|
|
25
|
+
.panel__mark { display: inline-block; width: 10px; height: 10px; border-radius: 2px; margin-right: .4rem; vertical-align: -1px; }
|
|
26
|
+
.panel svg { display: block; width: 100%; height: auto; }
|
|
27
|
+
|
|
28
|
+
.axis { display: grid; grid-template-columns: 9rem minmax(0, 1fr);
|
|
29
|
+
border-top: var(--starter-hair); background: var(--starter-inset); }
|
|
30
|
+
.axis__days { display: grid; grid-template-columns: repeat(7, 1fr); padding: var(--starter-s2) 0;
|
|
31
|
+
font: var(--starter-text-xs)/1 var(--starter-font-display); letter-spacing: .1em;
|
|
32
|
+
text-transform: uppercase; color: var(--starter-ink-3); }
|
|
33
|
+
.axis__days span { padding-left: 4px; }
|
|
34
|
+
|
|
35
|
+
.readout { display: flex; flex-wrap: wrap; gap: var(--starter-s3); align-items: baseline;
|
|
36
|
+
margin: 0 0 var(--starter-s3); font: var(--starter-text-sm)/1.6 var(--starter-font-display);
|
|
37
|
+
color: var(--starter-ink-2); font-variant-numeric: tabular-nums; }
|
|
38
|
+
.readout b { color: var(--starter-ink); font-weight: 600; }
|
|
39
|
+
|
|
40
|
+
@media (max-width: 700px) {
|
|
41
|
+
.panel, .axis { grid-template-columns: minmax(0, 1fr); }
|
|
42
|
+
.panel__meta { padding-bottom: 0; }
|
|
43
|
+
}
|
|
44
|
+
</style>
|
|
45
|
+
</head>
|
|
46
|
+
<body class="s-page">
|
|
47
|
+
|
|
48
|
+
<main class="s-sheet">
|
|
49
|
+
|
|
50
|
+
<header class="s-block">
|
|
51
|
+
<div class="s-block__rail">03 / 03</div>
|
|
52
|
+
<div>
|
|
53
|
+
<p class="s-eyebrow">Examples</p>
|
|
54
|
+
<h1 class="s-title s-title--hero">Field readings</h1>
|
|
55
|
+
<p class="s-lede">Seven days from three instruments, one hour apart. Three measures with three
|
|
56
|
+
units never share an axis — they get a panel each and one shared cursor.</p>
|
|
57
|
+
</div>
|
|
58
|
+
</header>
|
|
59
|
+
|
|
60
|
+
<section class="s-block">
|
|
61
|
+
<div class="s-block__rail">Latest</div>
|
|
62
|
+
<div>
|
|
63
|
+
<div class="tiles" id="tiles"></div>
|
|
64
|
+
</div>
|
|
65
|
+
</section>
|
|
66
|
+
|
|
67
|
+
<section class="s-block">
|
|
68
|
+
<div class="s-block__rail">The week</div>
|
|
69
|
+
<div>
|
|
70
|
+
<p class="readout" id="readout" aria-live="polite"></p>
|
|
71
|
+
<div class="plot" id="plot" tabindex="0" role="group"
|
|
72
|
+
aria-label="Three instrument readings over seven days. Use the left and right arrow keys to move the cursor.">
|
|
73
|
+
<div class="panel" data-series="0">
|
|
74
|
+
<div class="panel__meta">
|
|
75
|
+
<p class="panel__name"><span class="panel__mark"></span>Temperature</p>
|
|
76
|
+
<p class="panel__val" data-range></p>
|
|
77
|
+
</div>
|
|
78
|
+
<div data-chart></div>
|
|
79
|
+
</div>
|
|
80
|
+
<div class="panel" data-series="1">
|
|
81
|
+
<div class="panel__meta">
|
|
82
|
+
<p class="panel__name"><span class="panel__mark"></span>Humidity</p>
|
|
83
|
+
<p class="panel__val" data-range></p>
|
|
84
|
+
</div>
|
|
85
|
+
<div data-chart></div>
|
|
86
|
+
</div>
|
|
87
|
+
<div class="panel" data-series="2">
|
|
88
|
+
<div class="panel__meta">
|
|
89
|
+
<p class="panel__name"><span class="panel__mark"></span>Light</p>
|
|
90
|
+
<p class="panel__val" data-range></p>
|
|
91
|
+
</div>
|
|
92
|
+
<div data-chart></div>
|
|
93
|
+
</div>
|
|
94
|
+
<div class="axis"><span></span><div class="axis__days" id="axis"></div></div>
|
|
95
|
+
</div>
|
|
96
|
+
|
|
97
|
+
<details class="s-disclosure" style="margin-top: var(--starter-s4)">
|
|
98
|
+
<summary>Read it as a table</summary>
|
|
99
|
+
<table class="s-table" style="margin-top: var(--starter-s3)" id="table"></table>
|
|
100
|
+
</details>
|
|
101
|
+
</div>
|
|
102
|
+
</section>
|
|
103
|
+
|
|
104
|
+
<p class="s-note"><strong>No chart library.</strong> This is inline SVG drawn from an array — a few
|
|
105
|
+
dozen lines, and every mark, tick and hover state is yours to change. The readings are synthetic and
|
|
106
|
+
generated from a fixed seed, so the picture is the same every time it opens.</p>
|
|
107
|
+
|
|
108
|
+
</main>
|
|
109
|
+
|
|
110
|
+
<script src="../../../skills/starter-ui/starter-ui.js" defer></script>
|
|
111
|
+
<script>
|
|
112
|
+
(function () {
|
|
113
|
+
"use strict";
|
|
114
|
+
|
|
115
|
+
/* ── Synthetic readings, fixed seed so the chart never changes under you ── */
|
|
116
|
+
function rng(seed) {
|
|
117
|
+
return function () {
|
|
118
|
+
seed |= 0; seed = seed + 0x6d2b79f5 | 0;
|
|
119
|
+
var t = Math.imul(seed ^ seed >>> 15, 1 | seed);
|
|
120
|
+
t = t + Math.imul(t ^ t >>> 7, 61 | t) ^ t;
|
|
121
|
+
return ((t ^ t >>> 14) >>> 0) / 4294967296;
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
var rand = rng(20260514);
|
|
125
|
+
var HOURS = 24 * 7;
|
|
126
|
+
var DAYS = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"];
|
|
127
|
+
|
|
128
|
+
/* The first series wears the workspace's own hot ink, read from the token rather than
|
|
129
|
+
written down here — otherwise a workspace that changes its design system gets a
|
|
130
|
+
chart still drawn in the colour it used to have. The other two are this prototype's
|
|
131
|
+
own choice: a categorical chart palette is not something the design system names. */
|
|
132
|
+
var MARK = getComputedStyle(document.documentElement).getPropertyValue("--starter-mark").trim() || "#cf4224";
|
|
133
|
+
var SERIES = [
|
|
134
|
+
{ name: "Temperature", unit: "°C", colour: MARK, dp: 1, data: [] },
|
|
135
|
+
{ name: "Humidity", unit: "%", colour: "#2f6db5", dp: 0, data: [] },
|
|
136
|
+
{ name: "Light", unit: " lx", colour: "#b58200", dp: 0, data: [] }
|
|
137
|
+
];
|
|
138
|
+
|
|
139
|
+
for (var h = 0; h < HOURS; h++) {
|
|
140
|
+
var hour = h % 24;
|
|
141
|
+
var day = Math.floor(h / 24);
|
|
142
|
+
var sun = Math.max(0, Math.sin((hour - 6) / 12 * Math.PI)); // 06:00 → 18:00
|
|
143
|
+
var warmth = 12 + 9 * sun + day * 0.35 + (rand() - 0.5) * 1.4;
|
|
144
|
+
var damp = 86 - 34 * sun - day * 0.9 + (rand() - 0.5) * 5;
|
|
145
|
+
var lux = Math.round(sun * sun * (760 - day * 28) + rand() * 22);
|
|
146
|
+
SERIES[0].data.push(warmth);
|
|
147
|
+
SERIES[1].data.push(Math.max(18, Math.min(98, damp)));
|
|
148
|
+
SERIES[2].data.push(lux);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/* ── Draw one panel ───────────────────────────────────────────────────── */
|
|
152
|
+
var W = 720, H = 96, PAD = 8;
|
|
153
|
+
|
|
154
|
+
function path(data, min, max) {
|
|
155
|
+
var span = (max - min) || 1;
|
|
156
|
+
return data.map(function (v, i) {
|
|
157
|
+
var x = (i / (data.length - 1)) * W;
|
|
158
|
+
var y = PAD + (1 - (v - min) / span) * (H - PAD * 2);
|
|
159
|
+
return (i ? "L" : "M") + x.toFixed(1) + " " + y.toFixed(1);
|
|
160
|
+
}).join(" ");
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
var panels = Array.prototype.slice.call(document.querySelectorAll(".panel"));
|
|
164
|
+
panels.forEach(function (panel, s) {
|
|
165
|
+
var series = SERIES[s];
|
|
166
|
+
var min = Math.min.apply(null, series.data);
|
|
167
|
+
var max = Math.max.apply(null, series.data);
|
|
168
|
+
series.min = min; series.max = max;
|
|
169
|
+
|
|
170
|
+
panel.querySelector(".panel__mark").style.background = series.colour;
|
|
171
|
+
panel.querySelector("[data-range]").textContent =
|
|
172
|
+
min.toFixed(series.dp) + "–" + max.toFixed(series.dp) + series.unit;
|
|
173
|
+
|
|
174
|
+
panel.querySelector("[data-chart]").innerHTML =
|
|
175
|
+
'<svg viewBox="0 0 ' + W + " " + H + '" preserveAspectRatio="none" role="img" aria-label="' +
|
|
176
|
+
series.name + ' over seven days, ' + min.toFixed(series.dp) + " to " + max.toFixed(series.dp) +
|
|
177
|
+
series.unit + '">' +
|
|
178
|
+
/* day gridlines, recessive */
|
|
179
|
+
DAYS.map(function (_, d) {
|
|
180
|
+
var x = (d * 24 / (HOURS - 1)) * W;
|
|
181
|
+
return '<line x1="' + x.toFixed(1) + '" y1="0" x2="' + x.toFixed(1) + '" y2="' + H +
|
|
182
|
+
'" stroke="var(--starter-rule)" stroke-width="1"/>';
|
|
183
|
+
}).join("") +
|
|
184
|
+
'<path d="' + path(series.data, min, max) + '" fill="none" stroke="' + series.colour +
|
|
185
|
+
'" stroke-width="2" stroke-linejoin="round" stroke-linecap="round" vector-effect="non-scaling-stroke"/>' +
|
|
186
|
+
'<line data-cursor y1="0" y2="' + H + '" stroke="var(--starter-ink)" stroke-width="1" ' +
|
|
187
|
+
'vector-effect="non-scaling-stroke" opacity="0"/>' +
|
|
188
|
+
'<circle data-dot r="4" fill="' + series.colour + '" stroke="var(--starter-sheet)" ' +
|
|
189
|
+
'stroke-width="2" opacity="0"/>' +
|
|
190
|
+
"</svg>";
|
|
191
|
+
});
|
|
192
|
+
|
|
193
|
+
document.getElementById("axis").innerHTML = DAYS.map(function (d) { return "<span>" + d + "</span>"; }).join("");
|
|
194
|
+
|
|
195
|
+
/* ── The shared cursor ────────────────────────────────────────────────── */
|
|
196
|
+
var readout = document.getElementById("readout");
|
|
197
|
+
var plot = document.getElementById("plot");
|
|
198
|
+
var at = HOURS - 1;
|
|
199
|
+
|
|
200
|
+
function label(i) {
|
|
201
|
+
return DAYS[Math.floor(i / 24)] + " " + String(i % 24).padStart(2, "0") + ":00";
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
function show(i, visible) {
|
|
205
|
+
at = Math.max(0, Math.min(HOURS - 1, i));
|
|
206
|
+
var x = (at / (HOURS - 1)) * W;
|
|
207
|
+
panels.forEach(function (panel, s) {
|
|
208
|
+
var series = SERIES[s];
|
|
209
|
+
var span = (series.max - series.min) || 1;
|
|
210
|
+
var y = PAD + (1 - (series.data[at] - series.min) / span) * (H - PAD * 2);
|
|
211
|
+
var cur = panel.querySelector("[data-cursor]");
|
|
212
|
+
var dot = panel.querySelector("[data-dot]");
|
|
213
|
+
cur.setAttribute("x1", x); cur.setAttribute("x2", x);
|
|
214
|
+
cur.setAttribute("opacity", visible ? "0.35" : "0");
|
|
215
|
+
dot.setAttribute("cx", x); dot.setAttribute("cy", y);
|
|
216
|
+
dot.setAttribute("opacity", visible ? "1" : "0");
|
|
217
|
+
});
|
|
218
|
+
readout.innerHTML = "<b>" + label(at) + "</b>" + SERIES.map(function (series) {
|
|
219
|
+
return "<span>" + series.name.toLowerCase() + " <b>" +
|
|
220
|
+
series.data[at].toFixed(series.dp) + series.unit + "</b></span>";
|
|
221
|
+
}).join("");
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
function indexFrom(e) {
|
|
225
|
+
var box = plot.getBoundingClientRect();
|
|
226
|
+
var chart = panels[0].querySelector("[data-chart]").getBoundingClientRect();
|
|
227
|
+
var t = (e.clientX - chart.left) / (chart.width || 1);
|
|
228
|
+
return Math.round(Math.max(0, Math.min(1, t)) * (HOURS - 1));
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
plot.addEventListener("pointermove", function (e) { show(indexFrom(e), true); });
|
|
232
|
+
plot.addEventListener("pointerleave", function () { show(HOURS - 1, false); });
|
|
233
|
+
plot.addEventListener("focus", function () { show(at, true); });
|
|
234
|
+
plot.addEventListener("blur", function () { show(HOURS - 1, false); });
|
|
235
|
+
plot.addEventListener("keydown", function (e) {
|
|
236
|
+
var step = e.shiftKey ? 24 : 1;
|
|
237
|
+
if (e.key === "ArrowRight") { show(at + step, true); e.preventDefault(); }
|
|
238
|
+
else if (e.key === "ArrowLeft") { show(at - step, true); e.preventDefault(); }
|
|
239
|
+
else if (e.key === "Home") { show(0, true); e.preventDefault(); }
|
|
240
|
+
else if (e.key === "End") { show(HOURS - 1, true); e.preventDefault(); }
|
|
241
|
+
});
|
|
242
|
+
|
|
243
|
+
/* ── Tiles and table ──────────────────────────────────────────────────── */
|
|
244
|
+
var tiles = document.getElementById("tiles");
|
|
245
|
+
SERIES.forEach(function (series) {
|
|
246
|
+
var last = series.data[HOURS - 1];
|
|
247
|
+
var mean = series.data.reduce(function (a, b) { return a + b; }, 0) / HOURS;
|
|
248
|
+
var el = document.createElement("div");
|
|
249
|
+
el.className = "tile";
|
|
250
|
+
el.innerHTML =
|
|
251
|
+
'<p class="tile__k">' + series.name + "</p>" +
|
|
252
|
+
'<p class="tile__v">' + last.toFixed(series.dp) + '<span class="tile__u">' + series.unit + "</span></p>" +
|
|
253
|
+
'<p class="tile__n">week mean ' + mean.toFixed(series.dp) + series.unit + "</p>";
|
|
254
|
+
tiles.appendChild(el);
|
|
255
|
+
});
|
|
256
|
+
|
|
257
|
+
var rows = DAYS.map(function (d, day) {
|
|
258
|
+
var cells = SERIES.map(function (series) {
|
|
259
|
+
var slice = series.data.slice(day * 24, day * 24 + 24);
|
|
260
|
+
var lo = Math.min.apply(null, slice), hi = Math.max.apply(null, slice);
|
|
261
|
+
return "<td>" + lo.toFixed(series.dp) + " – " + hi.toFixed(series.dp) + series.unit + "</td>";
|
|
262
|
+
}).join("");
|
|
263
|
+
return "<tr><td>" + d + "</td>" + cells + "</tr>";
|
|
264
|
+
}).join("");
|
|
265
|
+
document.getElementById("table").innerHTML =
|
|
266
|
+
"<thead><tr><th>Day</th><th>Temperature</th><th>Humidity</th><th>Light</th></tr></thead><tbody>" +
|
|
267
|
+
rows + "</tbody>";
|
|
268
|
+
|
|
269
|
+
show(HOURS - 1, false);
|
|
270
|
+
})();
|
|
271
|
+
</script>
|
|
272
|
+
</body>
|
|
273
|
+
</html>
|
|
Binary file
|
|
@@ -0,0 +1,214 @@
|
|
|
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>Slide deck</title>
|
|
7
|
+
<meta name="description" content="A six-slide deck you drive with the arrow keys — every slide is a linkable URL, so a comment lands on the slide it was left on.">
|
|
8
|
+
<link rel="stylesheet" href="../../../skills/starter-ui/starter-tokens.css">
|
|
9
|
+
<link rel="stylesheet" href="../../../skills/starter-ui/starter-ui.css">
|
|
10
|
+
<style>
|
|
11
|
+
html, body { height: 100%; }
|
|
12
|
+
body.s-page { display: flex; flex-direction: column; overflow: hidden; }
|
|
13
|
+
|
|
14
|
+
.deck { flex: 1; display: grid; grid-template-rows: auto minmax(0, 1fr) auto; gap: var(--starter-s3);
|
|
15
|
+
padding: var(--starter-s4); max-width: 76rem; width: 100%; margin: 0 auto; }
|
|
16
|
+
|
|
17
|
+
.deck__bar { display: flex; align-items: baseline; gap: var(--starter-s3);
|
|
18
|
+
font: var(--starter-text-xs)/1.6 var(--starter-font-display);
|
|
19
|
+
letter-spacing: .14em; text-transform: uppercase; color: var(--starter-ink-3); }
|
|
20
|
+
.deck__bar b { color: var(--starter-mark-ink); font-weight: 600; }
|
|
21
|
+
.deck__count { margin-left: auto; font-variant-numeric: tabular-nums; }
|
|
22
|
+
|
|
23
|
+
.stage { position: relative; background: var(--starter-sheet); border: var(--starter-hair);
|
|
24
|
+
border-radius: var(--starter-radius-1); box-shadow: var(--starter-lift); overflow: hidden; }
|
|
25
|
+
|
|
26
|
+
.slide { position: absolute; inset: 0; display: grid; align-content: center; gap: var(--starter-s4);
|
|
27
|
+
padding: clamp(var(--starter-s5), 5vw, var(--starter-s8));
|
|
28
|
+
opacity: 0; transform: translateY(10px); pointer-events: none;
|
|
29
|
+
transition: opacity var(--starter-slow), transform var(--starter-slow); }
|
|
30
|
+
.slide[data-active] { opacity: 1; transform: none; pointer-events: auto; }
|
|
31
|
+
.slide__no { position: absolute; top: var(--starter-s5); right: var(--starter-s5);
|
|
32
|
+
font: var(--starter-text-xs)/1 var(--starter-font-display); letter-spacing: .14em;
|
|
33
|
+
color: var(--starter-ink-3); }
|
|
34
|
+
.slide h2 { margin: 0; font: 600 clamp(1.8rem, 4.4vw, 3.2rem)/1.05 var(--starter-font-display);
|
|
35
|
+
letter-spacing: -.035em; max-width: 22ch; }
|
|
36
|
+
.slide p { margin: 0; max-width: 46ch; font-size: clamp(var(--starter-text-md), 1.7vw, var(--starter-text-lg));
|
|
37
|
+
color: var(--starter-ink-2); }
|
|
38
|
+
.slide--title h2 { font-size: clamp(2.4rem, 7vw, 4.6rem); }
|
|
39
|
+
.slide--title .rule { width: 4rem; border-top: 3px solid var(--starter-mark); }
|
|
40
|
+
|
|
41
|
+
.beat { display: flex; flex-wrap: wrap; gap: var(--starter-s3); align-items: center;
|
|
42
|
+
font: var(--starter-text-sm)/1 var(--starter-font-display); color: var(--starter-ink-3); }
|
|
43
|
+
.beat span[data-on] { color: var(--starter-mark-ink); }
|
|
44
|
+
|
|
45
|
+
.deck__foot { display: flex; align-items: center; gap: var(--starter-s3); }
|
|
46
|
+
.dots { display: flex; gap: 6px; margin-right: auto; }
|
|
47
|
+
.dot { width: 26px; height: 6px; padding: 0; border: 0; border-radius: 3px;
|
|
48
|
+
background: var(--starter-rule); cursor: pointer; }
|
|
49
|
+
.dot[aria-current="true"] { background: var(--starter-mark); }
|
|
50
|
+
.hint { font: var(--starter-text-xs)/1.6 var(--starter-font-display); color: var(--starter-ink-3);
|
|
51
|
+
letter-spacing: .1em; text-transform: uppercase; }
|
|
52
|
+
kbd { font: inherit; border: var(--starter-hair); border-bottom-width: 2px; border-radius: 4px;
|
|
53
|
+
padding: 1px 5px; background: var(--starter-sheet); }
|
|
54
|
+
@media (max-width: 700px) { .hint { display: none; } }
|
|
55
|
+
</style>
|
|
56
|
+
</head>
|
|
57
|
+
<body class="s-page">
|
|
58
|
+
|
|
59
|
+
<div class="deck">
|
|
60
|
+
<div class="deck__bar">
|
|
61
|
+
<span><b>The loop</b> · workspace deck</span>
|
|
62
|
+
<span class="deck__count"><span id="now">1</span> / 6</span>
|
|
63
|
+
</div>
|
|
64
|
+
|
|
65
|
+
<div class="stage" id="stage">
|
|
66
|
+
|
|
67
|
+
<section class="slide slide--title" data-active>
|
|
68
|
+
<div class="slide__no">01</div>
|
|
69
|
+
<div class="rule"></div>
|
|
70
|
+
<h2>Brief. Build. Review. Ship.</h2>
|
|
71
|
+
<p>Four moves. Everything else in this workspace is detail hanging off them.
|
|
72
|
+
Arrow keys to walk through it.</p>
|
|
73
|
+
</section>
|
|
74
|
+
|
|
75
|
+
<section class="slide">
|
|
76
|
+
<div class="slide__no">02</div>
|
|
77
|
+
<div class="beat"><span data-on>Brief</span><span>Build</span><span>Review</span><span>Ship</span></div>
|
|
78
|
+
<h2>You describe the screen</h2>
|
|
79
|
+
<p>Not the markup — the screen. Who it is for, what is on it, what happens when it is
|
|
80
|
+
used, and what it should feel like. A designer's brief, typed to an agent.</p>
|
|
81
|
+
<div class="s-cmd s-cmd--paste" style="max-width: 46rem">
|
|
82
|
+
<code class="s-cmd__text s-cmd__text--plain" id="brief">Returns desk. One screen the counter staff use with a customer standing there: type an order number, see what is in the box, pick a reason, print the label. Four reasons, not twelve. Nothing else on the screen.</code>
|
|
83
|
+
<button type="button" class="s-cmd__btn" data-s-copy="#brief">Copy</button>
|
|
84
|
+
</div>
|
|
85
|
+
</section>
|
|
86
|
+
|
|
87
|
+
<section class="slide">
|
|
88
|
+
<div class="slide__no">03</div>
|
|
89
|
+
<div class="beat"><span>Brief</span><span data-on>Build</span><span>Review</span><span>Ship</span></div>
|
|
90
|
+
<h2>It comes back as a real page</h2>
|
|
91
|
+
<p>One folder, one <code>index.html</code>, no build step and no framework. It runs the moment
|
|
92
|
+
it exists — in the browser, on the board, and straight off the disk.</p>
|
|
93
|
+
<table class="s-table" style="max-width: 40rem">
|
|
94
|
+
<tbody>
|
|
95
|
+
<tr><td>What you get</td><td><code>returns-desk/index.html</code></td></tr>
|
|
96
|
+
<tr><td>What it needs</td><td>Nothing. It is HTML.</td></tr>
|
|
97
|
+
</tbody>
|
|
98
|
+
</table>
|
|
99
|
+
</section>
|
|
100
|
+
|
|
101
|
+
<section class="slide">
|
|
102
|
+
<div class="slide__no">04</div>
|
|
103
|
+
<div class="beat"><span>Brief</span><span>Build</span><span data-on>Review</span><span>Ship</span></div>
|
|
104
|
+
<h2>Comments land on the pixels</h2>
|
|
105
|
+
<p>Shift + C, then click the thing you mean. The pin sticks to that element, the thread
|
|
106
|
+
keeps the conversation, and the next brief is usually a sentence someone already wrote
|
|
107
|
+
in one.</p>
|
|
108
|
+
</section>
|
|
109
|
+
|
|
110
|
+
<section class="slide">
|
|
111
|
+
<div class="slide__no">05</div>
|
|
112
|
+
<div class="beat"><span>Brief</span><span>Build</span><span>Review</span><span data-on>Ship</span></div>
|
|
113
|
+
<h2>Shipping is one word</h2>
|
|
114
|
+
<p>Open the prototype, edit, land. Every edit is live at your own draft address as you go;
|
|
115
|
+
landing moves the real URL and keeps the history. Seconds, not a deploy.</p>
|
|
116
|
+
<div class="s-cmd" style="max-width: 26rem">
|
|
117
|
+
<code class="s-cmd__text" id="ship">augur land</code>
|
|
118
|
+
<button type="button" class="s-cmd__btn" data-s-copy="#ship">Copy</button>
|
|
119
|
+
</div>
|
|
120
|
+
</section>
|
|
121
|
+
|
|
122
|
+
<section class="slide slide--title">
|
|
123
|
+
<div class="slide__no">06</div>
|
|
124
|
+
<div class="rule"></div>
|
|
125
|
+
<h2>Now do it once</h2>
|
|
126
|
+
<p>The loop only teaches by being run. Brief the smallest real screen you actually need —
|
|
127
|
+
not a demo of one — and put it in front of somebody today.</p>
|
|
128
|
+
</section>
|
|
129
|
+
|
|
130
|
+
</div>
|
|
131
|
+
|
|
132
|
+
<div class="deck__foot">
|
|
133
|
+
<div class="dots" id="dots" role="tablist" aria-label="Slides"></div>
|
|
134
|
+
<span class="hint"><kbd>←</kbd> <kbd>→</kbd> to move</span>
|
|
135
|
+
<button type="button" class="s-btn" id="prev" aria-label="Previous slide">←</button>
|
|
136
|
+
<button type="button" class="s-btn" id="next" aria-label="Next slide">→</button>
|
|
137
|
+
</div>
|
|
138
|
+
</div>
|
|
139
|
+
|
|
140
|
+
<script src="../../../skills/starter-ui/starter-ui.js" defer></script>
|
|
141
|
+
<script>
|
|
142
|
+
(function () {
|
|
143
|
+
"use strict";
|
|
144
|
+
|
|
145
|
+
var slides = Array.prototype.slice.call(document.querySelectorAll(".slide"));
|
|
146
|
+
var dots = document.getElementById("dots");
|
|
147
|
+
var now = document.getElementById("now");
|
|
148
|
+
var i = 0;
|
|
149
|
+
|
|
150
|
+
slides.forEach(function (s, n) {
|
|
151
|
+
s.setAttribute("aria-hidden", String(n !== 0));
|
|
152
|
+
var d = document.createElement("button");
|
|
153
|
+
d.type = "button";
|
|
154
|
+
d.className = "dot";
|
|
155
|
+
d.setAttribute("role", "tab");
|
|
156
|
+
d.setAttribute("aria-label", "Slide " + (n + 1));
|
|
157
|
+
d.setAttribute("aria-current", String(n === 0));
|
|
158
|
+
d.addEventListener("click", function () { go(n); });
|
|
159
|
+
dots.appendChild(d);
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
/* Each slide is its own URL. That is what lets a pinned comment belong to the
|
|
163
|
+
slide it was left on rather than to the deck as a whole. */
|
|
164
|
+
function go(n, quiet) {
|
|
165
|
+
i = Math.max(0, Math.min(slides.length - 1, n));
|
|
166
|
+
slides.forEach(function (s, k) {
|
|
167
|
+
if (k === i) s.setAttribute("data-active", ""); else s.removeAttribute("data-active");
|
|
168
|
+
s.setAttribute("aria-hidden", String(k !== i));
|
|
169
|
+
});
|
|
170
|
+
Array.prototype.forEach.call(dots.children, function (d, k) {
|
|
171
|
+
d.setAttribute("aria-current", String(k === i));
|
|
172
|
+
});
|
|
173
|
+
now.textContent = String(i + 1);
|
|
174
|
+
if (!quiet) {
|
|
175
|
+
var h = "#" + (i + 1);
|
|
176
|
+
if (location.hash !== h) history.replaceState(null, "", h);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
function fromHash() {
|
|
181
|
+
var n = parseInt((location.hash || "").replace("#", ""), 10);
|
|
182
|
+
go(isNaN(n) ? 0 : n - 1, true);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
document.addEventListener("keydown", function (e) {
|
|
186
|
+
if (e.metaKey || e.ctrlKey || e.altKey) return;
|
|
187
|
+
var k = e.key;
|
|
188
|
+
if (k === "ArrowRight" || k === "PageDown" || k === " " || k === "Enter") { go(i + 1); e.preventDefault(); }
|
|
189
|
+
else if (k === "ArrowLeft" || k === "PageUp" || k === "Backspace") { go(i - 1); e.preventDefault(); }
|
|
190
|
+
else if (k === "Home") { go(0); e.preventDefault(); }
|
|
191
|
+
else if (k === "End") { go(slides.length - 1); e.preventDefault(); }
|
|
192
|
+
else if (/^[1-9]$/.test(k)) { go(parseInt(k, 10) - 1); e.preventDefault(); }
|
|
193
|
+
});
|
|
194
|
+
|
|
195
|
+
document.getElementById("next").addEventListener("click", function () { go(i + 1); });
|
|
196
|
+
document.getElementById("prev").addEventListener("click", function () { go(i - 1); });
|
|
197
|
+
window.addEventListener("hashchange", fromHash);
|
|
198
|
+
|
|
199
|
+
/* Touch: a flick either way. */
|
|
200
|
+
var x0 = null;
|
|
201
|
+
var stage = document.getElementById("stage");
|
|
202
|
+
stage.addEventListener("touchstart", function (e) { x0 = e.touches[0].clientX; }, { passive: true });
|
|
203
|
+
stage.addEventListener("touchend", function (e) {
|
|
204
|
+
if (x0 === null) return;
|
|
205
|
+
var dx = e.changedTouches[0].clientX - x0;
|
|
206
|
+
if (Math.abs(dx) > 45) go(i + (dx < 0 ? 1 : -1));
|
|
207
|
+
x0 = null;
|
|
208
|
+
});
|
|
209
|
+
|
|
210
|
+
fromHash();
|
|
211
|
+
})();
|
|
212
|
+
</script>
|
|
213
|
+
</body>
|
|
214
|
+
</html>
|
|
Binary file
|