bearings 0.5.2 → 0.5.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.
@@ -0,0 +1,144 @@
1
+ ---
2
+ description: Resolve exact pending bearings update or reconstruction tasks and reconciliations. First-time setup resumes through bearings init.
3
+ ---
4
+
5
+ # /update-bearings-setup
6
+
7
+ Use the **bearings Commands for This Task** header's exact resume and completion
8
+ commands when supplied. They select the initiating executable. Otherwise use
9
+ `npx bearings`, or the established local bearings invocation.
10
+
11
+ ## 1. Select Pending Update Work
12
+
13
+ Read `.agents/bearings.json` and the exact setup scope supplied by bearings.
14
+ Require `setupPending.kind` to be `update` or `reconstruction`.
15
+
16
+ - `init`: stop this command and use `bearings init` to resume first-time setup.
17
+ - No pending setup: report no pending update work and stop.
18
+ - Missing, invalid, or inconsistent journal/scope: report the blocker and use
19
+ `bearings init` to obtain the current handoff.
20
+
21
+ Resolve only listed tasks, file `reconciliations`, and
22
+ `migrationReconciliations`. Inspect their current targets and recorded
23
+ artifacts before asking questions. Preserve completed work on resume. Ask one
24
+ necessary question at a time, with a recommendation based on the evidence.
25
+ Checkpoint each fully resolved task through step 5. Reread the journal after
26
+ each checkpoint and process only its remaining tasks.
27
+
28
+ Skills whose upstream template is unchanged stay untouched, including locally
29
+ customized versions. Preserve `protectedSkills` and all other out-of-scope
30
+ skills even when they have unrelated verify warnings. New ordinary runtime or
31
+ checklist bundle files alone need no setup.
32
+ Do not re-interview the project or adapt every installed skill. A
33
+ `skippedTemplate` is a declined template revision; do not apply it as cleanup.
34
+
35
+ ## 2. Resolve Listed File Reconciliations
36
+
37
+ Read each record's target and backup, plus baseline and incoming artifacts
38
+ when present. Summarize the differences and get the developer's choice before
39
+ applying backed-up changes. For an ordinary collision or `update-merge`, offer
40
+ merge, keep parts, keep either version, or discard backed-up content. Apply
41
+ the choice directly to that target regardless of owner.
42
+
43
+ For a `retired` file, ask whether to keep useful content as an untracked target
44
+ or discard it. After an explicit discard choice, a missing retired target can
45
+ be resolved by selecting its path with `--setup-path` during completion.
46
+ Preserve its backup until the CLI accepts the choice. A deliberately discarded
47
+ retired map needs no refresh.
48
+
49
+ Map edits go through `/refresh-repo-map` in step 4, with the developer's
50
+ resolution as input. If a map reconciliation has no explicit map task, report
51
+ the scope mismatch as blocked rather than edit it or expand the scope.
52
+
53
+ ### Starter Skill Updates (`skill-update`)
54
+
55
+ Read the live skill, `backup`, and `incomingPath`. Check whether `basePath`
56
+ exists before attempting a baseline diff.
57
+
58
+ - **Base available:** compare local versus base and incoming versus base.
59
+ Offer **Take new template**, **Keep local**, **Three-way merge**, or
60
+ **Freeform**, one skill at a time. Recommend Three-way merge when both diffs
61
+ contain useful changes.
62
+ - **Base missing:** explain that a historical base is unavailable. Offer only
63
+ **Take new template**, **Keep local**, or **Freeform**. Never fabricate a base
64
+ or present a two-way comparison as a three-way merge.
65
+
66
+ Take new template writes incoming content to the live skill. Keep local leaves
67
+ the live content intact and declines the incoming revision. Three-way merge
68
+ combines both sides while preserving local intent. Freeform writes the agreed
69
+ result; establish whether the developer accepts or declines the incoming
70
+ revision. For Keep local or a Freeform result that declines the incoming
71
+ revision, include that scoped skill-update path in `--keep-local` when
72
+ checkpointing it with `--setup-path`. Omit `--keep-local` for accepted incoming
73
+ templates and merges. The CLI owns `owner`,
74
+ `hash`, `lastTemplateHash`, `skippedTemplate`, and baseline updates.
75
+
76
+ ## 3. Resolve Listed Checklist Migrations
77
+
78
+ For each migration record, follow the installed `checklist` skill's authored
79
+ schema and validation workflow.
80
+
81
+ - **`testplan-collision`:** read `target` and the pre-existing checklist in
82
+ `backup`. Summarize both and ask whether to keep either version or combine
83
+ them. Write the chosen useful content to `target`.
84
+ - **`invalid-testplan`:** read `backup`, explain each contract problem, and
85
+ agree with the developer how to preserve its useful authored content in a
86
+ repaired checklist. Use the exact repair destination printed in the supplied
87
+ scope. When the record has no `target`, the CLI's `migrationTarget` supplies
88
+ a deterministic safe `checklists/repairs/<id>.json` path. Read any existing
89
+ checklist there before writing and obtain the developer's choice to keep
90
+ either version or combine useful content. Discard content only on an explicit
91
+ developer choice; do not choose a different destination or edit the journal.
92
+
93
+ Validate each repaired checklist and run the checklist skill's full-library
94
+ build. Both must pass for that repair to be complete. An unrelated invalid
95
+ checklist is a reported blocker, not permission to rewrite it. Only after useful
96
+ content is preserved in the chosen target and validation/build pass, remove the
97
+ recorded legacy `source` if it still exists. Keep backups and incoming artifacts
98
+ until the completion CLI accepts their outcomes and performs cleanup; preserve
99
+ useful content if a record remains blocked.
100
+
101
+ ## 4. Complete Listed Tailoring and Map Tasks
102
+
103
+ For `reason: tailor`, or a reconciled seed, index, or starter-skill target,
104
+ fill only its remaining placeholders. Inspect current project evidence and
105
+ preserve existing entries and decisions. Use real commands or explicit
106
+ `not configured`. Keep seed routing thin and skill safety workflows intact.
107
+ For a listed `AGENTS.md`, remove a legacy `## Setup Required` blocking section
108
+ and any obsolete `## Pending bearings Setup` section before checkpointing it.
109
+
110
+ For `reason: map`, pass only the exact listed map paths to `/refresh-repo-map`
111
+ as an explicit setup target scope, together with any reconciliation choices.
112
+ A missing, added, restored, or accepted changed map can need refresh; a package
113
+ version or unrelated skill change does not. With no map task, skip map refresh.
114
+ With one map task, refresh only that artifact. Create C4 source only when
115
+ `docs/diagrams/c4-component.puml` is explicitly listed. The selected targets
116
+ still require the command's artifact contracts, sync markers, and probes.
117
+
118
+ ## 5. Complete Through the CLI
119
+
120
+ Check each completed task and reconciliation against the developer's choices.
121
+ Use the header's **Complete** command from the repository and append
122
+ `--setup-path <path...>` with only the fully completed paths. Quote each path
123
+ as a shell argument. For scoped `skill-update` paths whose incoming template
124
+ the developer declined, also append `--keep-local <path...>`. Both flags require
125
+ `--complete-setup`; `--keep-local` must refer only to selected skill updates.
126
+
127
+ Without a supplied header, use
128
+ `npx bearings init --complete-setup --setup-path <path...>`, with the established
129
+ local bearings invocation when applicable. Omit `--setup-path` only when all
130
+ remaining tasks are ready to complete. After each successful checkpoint, reread
131
+ the journal and continue only its remaining paths. A partial checkpoint is
132
+ progress, not whole-setup completion.
133
+
134
+ The CLI owns the manifest, reconciliation records, hashes, ownership, template
135
+ lineage, baselines, exposure copies, and artifact cleanup. Never remove
136
+ `setupPending`, delete reconciliation artifacts, or change bookkeeping by hand.
137
+ Neither `bearings verify` nor an agent exit code proves scoped completion.
138
+
139
+ On validation failure, preserve progress and report **setup pending**, exact
140
+ blocked paths, and the next action. Fix only in-scope content problems; leave
141
+ unrelated warnings and unchanged skills outside this follow-up. Report
142
+ completion only after the completion CLI succeeds and the journal confirms
143
+ no pending setup. Finish with changed paths, developer choices, and validation
144
+ result; stop without first-time setup.
@@ -8,30 +8,64 @@
8
8
  <link rel="stylesheet" href="./viewer.css">
9
9
  </head>
10
10
  <body>
11
+ <a class="skip-link" href="#content">Skip to current checklist</a>
11
12
  <header class="masthead">
12
13
  <div class="masthead-inner">
13
- <p class="eyebrow">Bearings / local checklist library</p>
14
+ <p class="eyebrow">Bearings / operator console</p>
14
15
  <h1 id="title">Choose a checklist</h1>
15
16
  <p id="summary" class="summary">Browse the checklists generated from this repository.</p>
16
17
  </div>
17
18
  </header>
18
19
  <div class="toolbar">
19
20
  <div class="toolbar-inner">
20
- <label class="picker-label" for="checklist-picker">Checklist</label>
21
- <select id="checklist-picker"><option value="">Loading...</option></select>
21
+ <div class="picker">
22
+ <label class="toolbar-label" for="checklist-picker">Checklist</label>
23
+ <select id="checklist-picker"><option value="">Loading...</option></select>
24
+ </div>
25
+ <div class="task-pointer">
26
+ <span class="toolbar-label">Next unresolved</span>
27
+ <a id="current-task-link" href="#content">Choose a checklist</a>
28
+ <span id="next-task-copy" class="next-task">Next: —</span>
29
+ </div>
22
30
  <div class="progress" aria-live="polite">
23
- <span id="progress-copy">0 / 0 resolved</span>
24
- <span class="progress-track" aria-hidden="true"><span id="progress-fill"></span></span>
31
+ <div class="progress-heading">
32
+ <strong id="progress-copy">0 / 0 complete</strong>
33
+ <span class="progress-outcomes">
34
+ <span class="outcome outcome-failed"><b id="failed-count">0</b> failed</span>
35
+ <span class="outcome outcome-blocked"><b id="blocked-count">0</b> blocked</span>
36
+ <span class="outcome outcome-na"><b id="na-count">0</b> N/A</span>
37
+ </span>
38
+ </div>
39
+ <progress id="progress-track" class="progress-track" aria-label="Checklist completion" max="1" value="0"></progress>
25
40
  </div>
26
- <button id="export-progress" type="button">Export</button>
27
- <button id="import-progress" type="button">Import</button>
28
- <input id="import-file" type="file" accept="application/json,.json" hidden>
29
- <button id="reset-progress" type="button">Reset</button>
41
+ <details id="action-menu" class="action-menu">
42
+ <summary>Actions</summary>
43
+ <div class="action-panel">
44
+ <button id="export-progress" type="button">Export progress</button>
45
+ <button id="import-progress" type="button">Import progress</button>
46
+ <input id="import-file" type="file" accept="application/json,.json" hidden>
47
+ <button id="reset-progress" class="danger-button" type="button">Reset progress</button>
48
+ <p id="action-status" class="action-status" role="status" aria-live="polite" hidden></p>
49
+ </div>
50
+ </details>
30
51
  </div>
52
+ <p class="shortcut-legend" aria-label="Keyboard shortcuts">
53
+ <span><kbd>j</kbd>/<kbd>k</kbd> actions</span>
54
+ <span><kbd>[</kbd>/<kbd>]</kbd> sections</span>
55
+ <span><kbd>y</kbd> copy / choose</span>
56
+ <span><kbd>x</kbd> complete</span>
57
+ <span><kbd>f</kbd> failed</span>
58
+ <span><kbd>b</kbd> blocked</span>
59
+ <span><kbd>-</kbd> N/A</span>
60
+ <span><kbd>u</kbd> not started</span>
61
+ <span><kbd>R</kbd> reset</span>
62
+ <span><kbd>Enter</kbd> details</span>
63
+ <span><kbd>Esc</kbd> return</span>
64
+ </p>
31
65
  </div>
32
66
  <p id="storage-warning" class="storage-warning" role="status" hidden></p>
33
67
  <p id="status" class="status" role="status" aria-live="polite"></p>
34
- <main id="content"></main>
68
+ <main id="content" tabindex="-1"></main>
35
69
  <script src="./data.generated.js"></script>
36
70
  <script src="./viewer.js"></script>
37
71
  </body>
@@ -1,93 +1,337 @@
1
1
  :root {
2
2
  color-scheme: light;
3
- --ink: #17211f;
4
- --muted: #5b6662;
5
- --paper: #f1efe7;
6
- --card: #fffefa;
7
- --line: #d2cec1;
8
- --pine: #164b3c;
9
- --coral: #c64e32;
10
- --gold: #a87013;
11
- --danger: #9d3027;
12
- --blocked: #684b88;
13
- font-family: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
3
+ --ink: #0f172a;
4
+ --muted: #475569;
5
+ --paper: #e2e8f0;
6
+ --surface: #ffffff;
7
+ --surface-muted: #f8fafc;
8
+ --line: #cbd5e1;
9
+ --chrome: #0f172a;
10
+ --chrome-soft: #1e293b;
11
+ --accent: #2563eb;
12
+ --success: #15803d;
13
+ --success-soft: #f0fdf4;
14
+ --danger: #b91c1c;
15
+ --danger-soft: #fef2f2;
16
+ --blocked: #b45309;
17
+ --blocked-soft: #fffbeb;
18
+ --na: #64748b;
19
+ --sticky-offset: 140px;
20
+ font-family: "IBM Plex Sans", Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
14
21
  }
15
22
 
16
23
  * { box-sizing: border-box; }
24
+ [hidden] { display: none !important; }
25
+ html { scroll-behavior: smooth; }
17
26
  body { margin: 0; color: var(--ink); background: var(--paper); }
18
27
  button, select, input { font: inherit; }
19
- button, select { min-height: 40px; border: 1px solid var(--pine); border-radius: 4px; }
20
- button { padding: 8px 13px; color: var(--pine); background: transparent; font-weight: 750; cursor: pointer; }
21
- button:hover { color: white; background: var(--pine); }
22
- button:focus-visible, select:focus-visible, a:focus-visible { outline: 3px solid #e5952f; outline-offset: 3px; }
28
+ button, select, summary { min-height: 40px; }
29
+ button {
30
+ padding: 8px 12px;
31
+ color: var(--ink);
32
+ background: var(--surface);
33
+ border: 1px solid var(--line);
34
+ border-radius: 6px;
35
+ font-weight: 700;
36
+ cursor: pointer;
37
+ }
38
+ button:hover { background: #e8eef7; border-color: #94a3b8; }
39
+ button:focus-visible, select:focus-visible, summary:focus-visible, a:focus-visible {
40
+ outline: 3px solid #60a5fa;
41
+ outline-offset: 3px;
42
+ }
23
43
 
24
- .masthead { color: white; background: var(--pine); border-bottom: 6px solid var(--coral); }
25
- .masthead-inner, .toolbar-inner, main, .storage-warning, .status { width: min(1100px, calc(100% - 32px)); margin-inline: auto; }
26
- .masthead-inner { padding: 34px 0 29px; }
27
- .eyebrow { margin: 0 0 9px; color: #c7ded6; font: 800 11px/1.2 ui-monospace, monospace; letter-spacing: .13em; text-transform: uppercase; }
28
- h1 { max-width: 860px; margin: 0; font: 750 clamp(31px, 6vw, 58px)/1.04 Georgia, serif; letter-spacing: -.02em; overflow-wrap: anywhere; }
29
- .summary { max-width: 780px; margin: 12px 0 0; color: #e0ece8; line-height: 1.55; overflow-wrap: anywhere; }
44
+ .skip-link {
45
+ position: fixed;
46
+ top: 8px;
47
+ left: 8px;
48
+ z-index: 20;
49
+ padding: 10px 13px;
50
+ color: white;
51
+ background: var(--accent);
52
+ border-radius: 6px;
53
+ transform: translateY(-150%);
54
+ }
55
+ .skip-link:focus { transform: translateY(0); }
30
56
 
31
- .toolbar { position: sticky; top: 0; z-index: 5; border-bottom: 1px solid var(--line); background: rgb(241 239 231 / 96%); backdrop-filter: blur(8px); }
32
- .toolbar-inner { min-height: 70px; display: flex; align-items: center; gap: 10px; }
33
- .picker-label { color: var(--muted); font: 800 11px/1 ui-monospace, monospace; letter-spacing: .08em; text-transform: uppercase; }
34
- #checklist-picker { min-width: 230px; max-width: 360px; padding: 8px 30px 8px 10px; color: var(--ink); background: var(--card); }
35
- .progress { min-width: 180px; flex: 1; display: grid; gap: 5px; color: var(--muted); font-size: 13px; font-weight: 700; }
36
- .progress-track { height: 7px; overflow: hidden; background: #d9d4c7; border-radius: 99px; }
37
- #progress-fill { display: block; width: 0; height: 100%; background: var(--pine); transition: width .2s ease; }
38
- .storage-warning, .status { margin-top: 14px; margin-bottom: 0; }
39
- .storage-warning { padding: 12px 15px; color: #6a3d00; background: #fff4d8; border: 1px solid #d9af58; }
40
- .status { min-height: 1.5em; color: var(--muted); font-size: 14px; }
57
+ .masthead { color: white; background: var(--chrome); border-bottom: 1px solid #334155; }
58
+ .masthead-inner, .toolbar-inner, .shortcut-legend, main, .storage-warning, .status {
59
+ width: min(1180px, calc(100% - 32px));
60
+ margin-inline: auto;
61
+ }
62
+ .masthead-inner { padding: 25px 0 23px; }
63
+ .eyebrow, .toolbar-label, .field-label, .hierarchy-label {
64
+ font: 750 11px/1.2 ui-monospace, SFMono-Regular, Menlo, monospace;
65
+ letter-spacing: .08em;
66
+ text-transform: uppercase;
67
+ }
68
+ .eyebrow { margin: 0 0 7px; color: #93c5fd; }
69
+ h1 { max-width: 920px; margin: 0; font-size: clamp(28px, 5vw, 42px); line-height: 1.08; letter-spacing: -.025em; overflow-wrap: anywhere; }
70
+ .summary { max-width: 820px; margin: 9px 0 0; color: #cbd5e1; line-height: 1.45; overflow-wrap: anywhere; }
41
71
 
42
- main { padding: 22px 0 80px; }
43
- .empty, .error { padding: 28px; background: var(--card); border: 1px dashed var(--line); text-align: center; white-space: pre-wrap; }
44
- .error { color: #751f18; background: #fff0ed; border-color: #d88f86; }
45
- .intro, .callout, .conventions { max-width: 880px; margin: 0 0 18px; line-height: 1.6; white-space: pre-wrap; overflow-wrap: anywhere; }
46
- .callout { padding: 17px 19px; background: #fff0e9; border-left: 6px solid var(--coral); }
47
- .conventions { padding: 17px 19px; background: #e4ede9; border-left: 5px solid var(--pine); }
48
- section { margin-top: 48px; }
49
- .section-heading { display: grid; grid-template-columns: auto 1fr; gap: 13px; align-items: baseline; padding-bottom: 11px; border-bottom: 2px solid var(--pine); }
50
- .section-number { color: var(--coral); font: 850 13px/1 ui-monospace, monospace; }
51
- h2 { margin: 0; font: 750 clamp(23px, 4vw, 32px)/1.1 Georgia, serif; overflow-wrap: anywhere; }
52
- .section-intro { max-width: 840px; color: var(--muted); line-height: 1.55; white-space: pre-wrap; }
53
- .items { display: grid; gap: 15px; margin-top: 20px; }
54
- .item { padding: 20px; background: var(--card); border: 1px solid var(--line); border-left: 6px solid var(--line); border-radius: 5px; box-shadow: 0 3px 0 rgb(23 33 31 / 5%); overflow-wrap: anywhere; }
55
- .item[data-state="complete"] { border-left-color: var(--pine); background: #f3faf6; }
56
- .item[data-state="failed"] { border-left-color: var(--danger); background: #fff5f3; }
57
- .item[data-state="blocked"] { border-left-color: var(--blocked); background: #f8f4fc; }
58
- .item[data-state="not-applicable"] { border-left-color: var(--muted); opacity: .76; }
59
- .item.info { border-left-color: var(--gold); }
60
- .item-head { display: flex; gap: 13px; justify-content: space-between; align-items: start; }
72
+ .toolbar {
73
+ position: sticky;
74
+ top: 0;
75
+ z-index: 10;
76
+ color: white;
77
+ background: rgb(30 41 59 / 98%);
78
+ border-bottom: 1px solid #475569;
79
+ box-shadow: 0 4px 12px rgb(15 23 42 / 18%);
80
+ backdrop-filter: blur(8px);
81
+ }
82
+ .toolbar-inner {
83
+ min-height: 92px;
84
+ display: grid;
85
+ grid-template-columns: minmax(190px, 250px) minmax(190px, 1fr) minmax(300px, 1.35fr) auto;
86
+ gap: 18px;
87
+ align-items: center;
88
+ }
89
+ .picker, .task-pointer, .progress { min-width: 0; }
90
+ .toolbar-label { display: block; margin-bottom: 6px; color: #94a3b8; }
91
+ #checklist-picker {
92
+ width: 100%;
93
+ padding: 8px 30px 8px 10px;
94
+ color: var(--ink);
95
+ background: var(--surface);
96
+ border: 1px solid #64748b;
97
+ border-radius: 6px;
98
+ }
99
+ .task-pointer { display: grid; }
100
+ #current-task-link { color: white; font-weight: 750; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
101
+ .next-task { margin-top: 4px; color: #94a3b8; font-size: 12px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
102
+ .progress { display: grid; gap: 8px; }
103
+ .progress-heading { display: flex; gap: 12px; justify-content: space-between; align-items: center; font-size: 13px; }
104
+ .progress-outcomes { display: flex; flex-wrap: wrap; gap: 5px; justify-content: end; }
105
+ .outcome { padding: 3px 6px; border: 1px solid #64748b; border-radius: 99px; color: #e2e8f0; font-size: 11px; white-space: nowrap; }
106
+ .outcome-failed { border-color: #f87171; }
107
+ .outcome-blocked { border-color: #fbbf24; }
108
+ .outcome-na { border-color: #94a3b8; }
109
+ .progress-track { width: 100%; height: 9px; overflow: hidden; appearance: none; background: #475569; border: 0; border-radius: 99px; }
110
+ .progress-track::-webkit-progress-bar { background: #475569; border-radius: 99px; }
111
+ .progress-track::-webkit-progress-value { background: #22c55e; border-radius: 99px; transition: width .2s ease; }
112
+ .progress-track::-moz-progress-bar { background: #22c55e; border-radius: 99px; transition: width .2s ease; }
113
+ .action-menu { position: relative; }
114
+ .action-menu > summary {
115
+ display: inline-flex;
116
+ align-items: center;
117
+ justify-content: center;
118
+ gap: 8px;
119
+ padding: 8px 12px;
120
+ color: white;
121
+ border: 1px solid #64748b;
122
+ border-radius: 6px;
123
+ font-weight: 750;
124
+ cursor: pointer;
125
+ list-style: none;
126
+ white-space: nowrap;
127
+ }
128
+ .action-menu > summary::-webkit-details-marker { display: none; }
129
+ .action-menu > summary::after { content: "⋯"; color: #93c5fd; }
130
+ .action-menu[open] > summary, .action-menu > summary:hover { background: #334155; }
131
+ .action-panel {
132
+ position: absolute;
133
+ top: calc(100% + 9px);
134
+ right: 0;
135
+ width: 230px;
136
+ display: grid;
137
+ gap: 8px;
138
+ padding: 12px;
139
+ color: var(--ink);
140
+ background: var(--surface);
141
+ border: 1px solid var(--line);
142
+ border-radius: 8px;
143
+ box-shadow: 0 16px 35px rgb(15 23 42 / 28%);
144
+ }
145
+ .action-panel button { width: 100%; text-align: left; }
146
+ .danger-button { color: var(--danger); border-color: #fca5a5; }
147
+ .danger-button:hover { color: #7f1d1d; background: var(--danger-soft); border-color: #ef4444; }
148
+ .action-status { margin: 2px 0 0; padding-top: 8px; border-top: 1px solid var(--line); color: var(--muted); font-size: 12px; line-height: 1.4; }
149
+ .action-status[data-tone="error"] { color: var(--danger); font-weight: 700; }
150
+ .shortcut-legend {
151
+ display: flex;
152
+ flex-wrap: wrap;
153
+ gap: 7px 14px;
154
+ margin-top: -5px;
155
+ margin-bottom: 0;
156
+ padding: 0 0 9px;
157
+ color: #cbd5e1;
158
+ font-size: 11px;
159
+ }
160
+ .shortcut-legend span { flex: 0 0 auto; white-space: nowrap; }
161
+ kbd {
162
+ display: inline-block;
163
+ min-width: 19px;
164
+ padding: 2px 5px;
165
+ color: white;
166
+ background: #334155;
167
+ border: 1px solid #64748b;
168
+ border-bottom-width: 2px;
169
+ border-radius: 4px;
170
+ font: 750 10px/1.2 ui-monospace, SFMono-Regular, Menlo, monospace;
171
+ text-align: center;
172
+ }
173
+
174
+ .storage-warning, .status { margin-top: 12px; margin-bottom: 0; }
175
+ .storage-warning { padding: 12px 15px; color: #78350f; background: #fef3c7; border: 1px solid #f59e0b; border-radius: 6px; }
176
+ .status { min-height: 1.5em; color: var(--muted); font-size: 13px; }
177
+ .status[data-tone="error"] { color: var(--danger); font-weight: 700; }
178
+
179
+ main { padding: 12px 0 80px; }
180
+ .empty, .error { padding: 32px; background: var(--surface); border: 1px dashed var(--line); border-radius: 8px; text-align: center; white-space: pre-wrap; }
181
+ .error { color: #7f1d1d; background: var(--danger-soft); border-color: #fca5a5; }
182
+ .checklist-shell { display: grid; grid-template-columns: 220px minmax(0, 1fr); gap: 26px; align-items: start; }
183
+ .section-nav {
184
+ position: sticky;
185
+ top: var(--sticky-offset);
186
+ padding: 15px;
187
+ background: var(--chrome-soft);
188
+ border: 1px solid #334155;
189
+ border-radius: 8px;
190
+ box-shadow: 0 4px 12px rgb(15 23 42 / 10%);
191
+ }
192
+ .section-nav .section-nav-title { margin: 0 0 9px; color: #94a3b8; }
193
+ .section-nav-list { display: grid; gap: 5px; margin: 0; padding: 0; list-style: none; }
194
+ .section-nav-link {
195
+ display: grid;
196
+ grid-template-columns: auto minmax(0, 1fr) auto;
197
+ gap: 8px;
198
+ align-items: baseline;
199
+ padding: 9px;
200
+ color: #cbd5e1;
201
+ border-left: 3px solid transparent;
202
+ border-radius: 4px;
203
+ text-decoration: none;
204
+ }
205
+ .section-nav-link:hover { color: white; background: #334155; }
206
+ .section-nav-link[aria-current="location"] { color: white; background: #334155; border-left-color: #60a5fa; }
207
+ .nav-number, .nav-count { color: #94a3b8; font: 700 11px/1 ui-monospace, SFMono-Regular, Menlo, monospace; }
208
+ .nav-title { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
209
+ .checklist-body { min-width: 0; }
210
+ .intro, .callout, .conventions { margin: 0 0 14px; line-height: 1.55; white-space: pre-wrap; overflow-wrap: anywhere; }
211
+ .intro { color: var(--muted); }
212
+ .callout, .conventions { padding: 15px 17px; background: var(--surface); border: 1px solid var(--line); border-left-width: 5px; border-radius: 6px; }
213
+ .callout { border-left-color: var(--blocked); }
214
+ .conventions { border-left-color: var(--accent); }
215
+
216
+ section { margin-top: 34px; scroll-margin-top: var(--sticky-offset); }
217
+ section:first-of-type { margin-top: 22px; }
218
+ .checklist-section[data-keyboard-current="true"] { outline: 2px dashed #334155; outline-offset: 8px; border-radius: 4px; }
219
+ .section-heading { display: grid; grid-template-columns: auto 1fr; gap: 11px; align-items: baseline; padding-bottom: 10px; border-bottom: 2px solid #94a3b8; }
220
+ .section-number { color: var(--accent); font: 800 12px/1 ui-monospace, SFMono-Regular, Menlo, monospace; }
221
+ h2 { margin: 0; font-size: clamp(22px, 4vw, 29px); line-height: 1.15; overflow-wrap: anywhere; }
222
+ .section-intro { max-width: 840px; margin-bottom: 0; color: var(--muted); line-height: 1.5; white-space: pre-wrap; }
223
+ .items { display: grid; gap: 13px; margin-top: 16px; }
224
+
225
+ .item {
226
+ background: var(--surface);
227
+ border: 1px solid var(--line);
228
+ border-left: 5px solid #94a3b8;
229
+ border-radius: 8px;
230
+ box-shadow: 0 2px 5px rgb(15 23 42 / 7%);
231
+ overflow: hidden;
232
+ overflow-wrap: anywhere;
233
+ scroll-margin-top: var(--sticky-offset);
234
+ }
235
+ .item[data-state="complete"] { border-left-color: var(--success); }
236
+ .item[data-state="failed"] { border-left-color: var(--danger); background: var(--danger-soft); }
237
+ .item[data-state="blocked"] { border-left-color: var(--blocked); background: var(--blocked-soft); }
238
+ .item[data-state="not-applicable"] { border-left-color: var(--na); background: #f1f5f9; }
239
+ .item[data-keyboard-current="true"] { outline: 4px solid #2563eb; outline-offset: 3px; box-shadow: 0 8px 24px rgb(37 99 235 / 22%); }
240
+ .item[data-contains-next="true"] { border-color: #60a5fa; }
241
+ .item.info { border-left-color: var(--accent); }
242
+ .item-head { display: grid; grid-template-columns: minmax(0, 1fr) auto auto; gap: 12px; align-items: center; padding: 16px 17px; }
61
243
  .item-heading { min-width: 0; }
244
+ .hierarchy-label { display: block; margin-bottom: 5px; color: var(--muted); }
62
245
  h3, h4 { margin: 0; font-size: 18px; line-height: 1.35; }
63
246
  h4 { font-size: 16px; }
64
- .item-id { margin-right: 9px; color: var(--coral); font: 800 12px/1 ui-monospace, monospace; }
65
- .optional { display: inline-block; margin-left: 8px; padding: 2px 6px; color: var(--muted); border: 1px solid var(--line); border-radius: 3px; font: 750 10px/1.4 ui-monospace, monospace; text-transform: uppercase; }
66
- .state-label { flex: 0 0 auto; color: var(--muted); font-size: 12px; font-weight: 750; }
67
- .state-select { display: block; min-width: 150px; margin-top: 4px; padding: 6px 27px 6px 8px; color: var(--ink); background: white; }
68
- .instruction { margin: 14px 0 0; line-height: 1.6; white-space: pre-wrap; }
69
- .warning, .expected, .failure { margin: 15px 0 0; padding: 13px 15px; white-space: pre-wrap; }
70
- .warning { color: #692c1d; background: #fff0e9; border-left: 4px solid var(--coral); }
71
- .expected { background: #eaf4ef; border-left: 4px solid var(--pine); }
72
- .failure { background: #f4edf9; border-left: 4px solid var(--blocked); }
73
- .field-label { display: block; margin-bottom: 5px; font: 850 10px/1 ui-monospace, monospace; letter-spacing: .1em; text-transform: uppercase; }
74
- pre { overflow-x: auto; margin: 14px 0 0; padding: 15px; color: #e8f0ed; background: #13211d; border-radius: 4px; }
247
+ .item-id { margin-right: 8px; color: var(--accent); font: 800 12px/1 ui-monospace, SFMono-Regular, Menlo, monospace; }
248
+ .optional { display: inline-block; margin-left: 8px; padding: 2px 6px; color: var(--muted); border: 1px solid var(--line); border-radius: 3px; font: 750 10px/1.4 ui-monospace, SFMono-Regular, Menlo, monospace; text-transform: uppercase; }
249
+ .next-unresolved-marker { display: inline-block; margin-top: 7px; padding: 2px 6px; color: #1e3a8a; background: #dbeafe; border: 1px dashed #60a5fa; border-radius: 99px; font-size: 10px; font-weight: 800; }
250
+ .focused-task-marker { display: inline-block; margin: 7px 0 0 5px; padding: 2px 6px; color: #172554; background: white; border: 2px solid #2563eb; border-radius: 3px; font-size: 10px; font-weight: 800; }
251
+ .status-badge { display: inline-flex; gap: 6px; align-items: center; padding: 5px 8px; color: var(--muted); background: var(--surface-muted); border: 1px solid var(--line); border-radius: 99px; font-size: 12px; font-weight: 800; white-space: nowrap; }
252
+ .status-badge[data-state="complete"] { color: #166534; background: #dcfce7; border-color: #86efac; }
253
+ .status-badge[data-state="failed"] { color: #991b1b; background: #fee2e2; border-color: #fca5a5; }
254
+ .status-badge[data-state="blocked"] { color: #92400e; background: #fef3c7; border-color: #fcd34d; }
255
+ .status-badge[data-state="not-applicable"] { color: #334155; background: #e2e8f0; border-color: #94a3b8; }
256
+ .status-symbol { font: 900 14px/1 ui-monospace, SFMono-Regular, Menlo, monospace; }
257
+ .item-toggle { min-width: 105px; padding: 6px 9px; color: var(--muted); background: var(--surface-muted); font-size: 12px; }
258
+ .item-body { padding: 0 17px 17px; border-top: 1px solid #e2e8f0; }
259
+ .item-body[hidden] { display: none; }
260
+ .step-block { margin: 14px 0 0; padding: 13px 15px; line-height: 1.55; white-space: pre-wrap; }
261
+ .instruction { background: var(--surface-muted); border-left: 4px solid var(--accent); }
262
+ .warning { color: #78350f; background: #fef3c7; border-left: 4px solid var(--blocked); }
263
+ .expected { color: #14532d; background: var(--success-soft); border-left: 4px solid var(--success); }
264
+ .failure { color: #7f1d1d; background: var(--danger-soft); border-left: 4px solid var(--danger); }
265
+ .field-label { display: block; margin-bottom: 6px; color: inherit; }
266
+ .code-block { margin-top: 14px; overflow: hidden; background: #020617; border: 1px solid #334155; border-radius: 6px; }
267
+ .code-heading { min-height: 38px; display: flex; justify-content: space-between; align-items: center; gap: 10px; padding: 5px 7px 5px 13px; color: #94a3b8; background: #0f172a; border-bottom: 1px solid #334155; }
268
+ .language { font: 750 10px/1 ui-monospace, SFMono-Regular, Menlo, monospace; letter-spacing: .09em; text-transform: uppercase; }
269
+ .copy-button { min-height: 28px; padding: 4px 9px; color: #e2e8f0; background: #1e293b; border-color: #475569; font-size: 11px; }
270
+ .copy-button:hover { color: white; background: #334155; border-color: #64748b; }
271
+ .copy-chooser { width: min(620px, calc(100% - 28px)); max-height: min(80vh, 720px); margin: auto; padding: 18px; color: var(--ink); background: #eff6ff; border: 2px solid #60a5fa; border-radius: 8px; box-shadow: 0 24px 70px rgb(15 23 42 / 45%); }
272
+ .copy-chooser::backdrop { background: rgb(15 23 42 / 72%); }
273
+ .copy-chooser-title { margin: 0; color: #1e3a8a; font-weight: 800; }
274
+ .copy-chooser-hint { margin: 4px 0 10px; color: #334155; font-size: 12px; line-height: 1.4; }
275
+ .copy-choices { max-height: min(55vh, 520px); display: grid; gap: 7px; overflow-y: auto; }
276
+ .copy-choice { min-width: 0; display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 9px; align-items: center; text-align: left; }
277
+ .copy-choice:focus-visible { outline-offset: -4px; }
278
+ .copy-choice-key { min-width: 24px; padding: 3px 6px; color: white; background: var(--accent); border-radius: 4px; font: 800 11px/1.3 ui-monospace, SFMono-Regular, Menlo, monospace; text-align: center; }
279
+ .copy-choice-command { min-width: 0; overflow: hidden; font: 12px/1.4 ui-monospace, SFMono-Regular, Menlo, monospace; text-overflow: ellipsis; white-space: nowrap; }
280
+ .copy-chooser-actions { display: flex; justify-content: flex-end; margin-top: 12px; }
281
+ .copy-source { position: fixed; opacity: 0; pointer-events: none; }
282
+ pre { overflow-x: auto; margin: 0; padding: 15px; color: #e2e8f0; }
75
283
  pre code { font: 13px/1.55 ui-monospace, SFMono-Regular, Menlo, monospace; white-space: pre; }
76
- .language { display: block; margin-bottom: 8px; color: #9ebdb2; font: 750 10px/1 ui-monospace, monospace; letter-spacing: .09em; text-transform: uppercase; }
77
- .links { display: flex; flex-wrap: wrap; gap: 8px 15px; margin: 14px 0 0; padding: 0; list-style: none; }
78
- a { color: #075f7b; }
79
- .sub-items { display: grid; gap: 10px; margin-top: 16px; padding-left: 18px; border-left: 2px solid var(--line); }
80
- .sub-items .item { padding: 15px; box-shadow: none; }
284
+ .resources { margin-top: 14px; }
285
+ .links { display: flex; flex-wrap: wrap; gap: 8px 15px; margin: 0; padding: 0; list-style: none; }
286
+ a { color: #0369a1; }
287
+ .state-actions { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 16px; padding-top: 14px; border-top: 1px solid var(--line); }
288
+ .state-action { min-height: 38px; }
289
+ .primary-action { color: white; background: var(--success); border-color: var(--success); }
290
+ .primary-action:hover { color: white; background: #166534; border-color: #166534; }
291
+ .state-action[data-state-value="failed"] { color: var(--danger); }
292
+ .state-action[data-state-value="blocked"] { color: #92400e; }
293
+ .state-action[data-selected="true"] { box-shadow: inset 0 0 0 2px currentColor; }
294
+ .state-more { position: relative; }
295
+ .state-more > summary { display: inline-flex; align-items: center; justify-content: center; gap: 7px; padding: 7px 11px; border: 1px solid var(--line); border-radius: 6px; font-weight: 700; cursor: pointer; list-style: none; white-space: nowrap; }
296
+ .state-more > summary::-webkit-details-marker { display: none; }
297
+ .state-more > summary::after { content: "▾"; }
298
+ .state-more-menu { position: absolute; right: 0; bottom: calc(100% + 6px); z-index: 4; width: 175px; display: grid; gap: 6px; padding: 8px; background: var(--surface); border: 1px solid var(--line); border-radius: 7px; box-shadow: 0 10px 25px rgb(15 23 42 / 20%); }
299
+ .state-more-menu button { text-align: left; }
300
+ .substeps { margin-top: 17px; padding-top: 15px; border-top: 2px solid var(--line); }
301
+ .substeps-heading { display: flex; justify-content: space-between; gap: 10px; margin-bottom: 10px; color: var(--muted); font-size: 12px; font-weight: 800; }
302
+ .sub-items { display: grid; gap: 10px; padding-left: 17px; border-left: 2px solid #94a3b8; }
303
+ .sub-items .item { box-shadow: none; }
304
+ .task-group { padding-bottom: 17px; }
305
+ .task-group > .item-head { border-bottom: 1px solid #e2e8f0; }
306
+ .task-group > .substeps { margin: 15px 17px 0; padding-top: 0; border-top: 0; }
307
+
308
+ @media (max-width: 980px) {
309
+ .toolbar-inner { grid-template-columns: minmax(180px, 230px) 1fr auto; gap: 12px; padding: 10px 0; }
310
+ .task-pointer { display: none; }
311
+ .checklist-shell { grid-template-columns: 1fr; }
312
+ .section-nav { display: none; }
313
+ }
314
+
315
+ @media (max-width: 700px) {
316
+ :root { --sticky-offset: 210px; }
317
+ .masthead-inner, .toolbar-inner, .shortcut-legend, main, .storage-warning, .status { width: min(100% - 22px, 1180px); }
318
+ .toolbar-inner { grid-template-columns: 1fr auto; }
319
+ .picker { grid-column: 1 / -1; }
320
+ .progress { min-width: 0; }
321
+ .progress-heading { display: grid; }
322
+ .progress-outcomes { justify-content: start; }
323
+ .action-menu { align-self: end; }
324
+ .item-head { grid-template-columns: minmax(0, 1fr) auto; }
325
+ .status-badge { grid-column: 1; justify-self: start; }
326
+ .item-toggle { grid-column: 2; grid-row: 1 / span 2; }
327
+ .item-head, .item-body { padding-left: 13px; padding-right: 13px; }
328
+ .state-actions { display: grid; grid-template-columns: 1fr 1fr; }
329
+ .state-actions > *, .state-action { width: 100%; }
330
+ .state-more-menu { right: auto; left: 0; }
331
+ .sub-items { padding-left: 10px; }
332
+ }
81
333
 
82
- @media (max-width: 760px) {
83
- .masthead-inner, .toolbar-inner, main, .storage-warning, .status { width: min(100% - 22px, 1100px); }
84
- .toolbar-inner { flex-wrap: wrap; padding: 10px 0; }
85
- .picker-label { width: 100%; }
86
- #checklist-picker { max-width: none; flex: 1 1 100%; }
87
- .progress { flex-basis: 100%; }
88
- .item { padding: 16px 14px; }
89
- .item-head { display: grid; }
90
- .state-label { width: 100%; }
91
- .state-select { width: 100%; }
92
- section { margin-top: 37px; }
334
+ @media (prefers-reduced-motion: reduce) {
335
+ html { scroll-behavior: auto; }
336
+ *, *::before, *::after { scroll-behavior: auto !important; transition: none !important; }
93
337
  }