eidosmd 0.1.0 → 0.2.0
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/README.md +50 -29
- package/browser/dist/assets/index-C2NMN_D4.css +1 -0
- package/browser/dist/assets/index-C65k1ihb.js +46 -0
- package/browser/dist/favicon.svg +5 -0
- package/browser/dist/index.html +15 -0
- package/browser/dist/mark.svg +4 -0
- package/dist/src/cli.js +7 -0
- package/dist/src/commands/agents.js +1 -1
- package/dist/src/commands/canvas.js +77 -0
- package/dist/src/commands/check.js +1 -1
- package/dist/src/commands/framework.js +24 -5
- package/dist/src/commands/index.js +4 -4
- package/dist/src/commands/init.js +1 -0
- package/dist/src/commands/instructions.js +1 -1
- package/dist/src/commands/list.js +8 -8
- package/dist/src/commands/migrate.js +32 -0
- package/dist/src/commands/new.js +3 -3
- package/dist/src/commands/seeds.js +5 -5
- package/dist/src/commands/setup.js +119 -0
- package/dist/src/commands/version.js +44 -0
- package/dist/src/commands/whoami.js +4 -4
- package/dist/src/context.js +5 -5
- package/dist/src/core/blueprint.js +16 -11
- package/dist/src/core/canvas-schema.js +148 -0
- package/dist/src/core/canvas.js +722 -0
- package/dist/src/core/check.js +127 -51
- package/dist/src/core/convert.js +7 -6
- package/dist/src/core/framework-markdown.js +113 -34
- package/dist/src/core/framework-model.js +27 -10
- package/dist/src/core/framework-structured.js +132 -33
- package/dist/src/core/framework.js +13 -13
- package/dist/src/core/git.js +59 -0
- package/dist/src/core/index-leaf.js +2 -2
- package/dist/src/core/me.js +16 -8
- package/dist/src/core/migrate.js +243 -0
- package/dist/src/core/naming.js +1 -1
- package/dist/src/core/root.js +2 -2
- package/dist/src/core/scaffold.js +19 -19
- package/dist/src/core/seed.js +151 -60
- package/dist/src/core/server.js +1236 -52
- package/dist/src/core/settings.js +181 -0
- package/dist/src/core/store.js +259 -0
- package/dist/src/core/template.js +32 -0
- package/dist/src/core/versions.js +79 -0
- package/dist/src/output.js +4 -1
- package/dist/src/program.js +134 -39
- package/instructions/authoring.md +13 -12
- package/instructions/configuring.md +65 -34
- package/instructions/init-required.md +4 -4
- package/instructions/overview.md +17 -7
- package/instructions/validating.md +5 -4
- package/package.json +21 -12
- package/standard/EIDOS.md +129 -188
- package/standard/seeds/README.md +6 -6
- package/standard/seeds/book/Framework.yaml +81 -0
- package/standard/seeds/book/README.md +9 -5
- package/standard/seeds/book/_gitignore +3 -3
- package/standard/seeds/book/me.md +1 -1
- package/standard/seeds/book/roles/README.md +3 -3
- package/standard/seeds/book/roles/framework-owner.md +2 -2
- package/standard/seeds/book/{shapes → templates}/chapter.full.md +0 -8
- package/standard/seeds/book/{shapes → templates}/chapter.sketch.md +0 -7
- package/standard/seeds/book/{shapes → templates}/frame.market.md +0 -6
- package/standard/seeds/book/templates/frame.premise.md +17 -0
- package/standard/seeds/book/{shapes → templates}/frame.reader.md +0 -6
- package/standard/seeds/book/{shapes → templates}/frame.voice.md +0 -7
- package/standard/seeds/research/Framework.yaml +81 -0
- package/standard/seeds/research/README.md +9 -5
- package/standard/seeds/research/_gitignore +3 -3
- package/standard/seeds/research/me.md +1 -1
- package/standard/seeds/research/roles/README.md +3 -3
- package/standard/seeds/research/roles/framework-owner.md +2 -2
- package/standard/seeds/research/{shapes → templates}/frame.ethics.md +0 -6
- package/standard/seeds/research/{shapes → templates}/frame.method.md +0 -7
- package/standard/seeds/research/{shapes → templates}/frame.prior-work.md +0 -6
- package/standard/seeds/research/{shapes → templates}/frame.question.md +0 -7
- package/standard/seeds/research/{shapes → templates}/investigation.full.md +0 -8
- package/standard/seeds/research/{shapes → templates}/investigation.note.md +0 -7
- package/standard/seeds/software/Framework.yaml +82 -0
- package/standard/seeds/software/README.md +5 -5
- package/standard/seeds/software/_gitignore +3 -3
- package/standard/seeds/software/me.md +1 -1
- package/standard/seeds/software/roles/README.md +3 -3
- package/standard/seeds/software/roles/framework-owner.md +2 -2
- package/standard/seeds/software/roles/project-manager.md +2 -2
- package/standard/seeds/software/roles/stakeholder.md +1 -1
- package/standard/seeds/software/{shapes → templates}/frame.architecture.md +0 -7
- package/standard/seeds/software/{shapes → templates}/frame.audience.md +1 -8
- package/standard/seeds/software/{shapes → templates}/frame.criteria.md +0 -8
- package/standard/seeds/software/{shapes → templates}/frame.market.md +0 -8
- package/standard/seeds/software/{shapes → templates}/spec.full.md +0 -8
- package/standard/seeds/software/{shapes → templates}/spec.micro.md +0 -9
- package/browser/index.html +0 -268
- package/dist/src/commands/convert.js +0 -30
- package/dist/src/core/shape.js +0 -26
- package/standard/seeds/book/Framework.md +0 -87
- package/standard/seeds/book/shapes/frame.premise.md +0 -24
- package/standard/seeds/research/Framework.md +0 -88
- package/standard/seeds/software/Framework.md +0 -88
- /package/standard/seeds/software/{shapes → templates}/.gitkeep +0 -0
package/README.md
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# eidosmd
|
|
2
2
|
|
|
3
|
-
The command line for [Eidos](https://github.com/BuildableWorks/Eidos/blob/main/README.md): a
|
|
3
|
+
The command line for [Eidos](https://github.com/BuildableWorks/Eidos/blob/main/README.md): a system of organization for defining a product, in which one markdown file is the complete source of truth for one unit of it, true whether or not it has been built.
|
|
4
4
|
|
|
5
|
-
`eidos` scaffolds a root, generates blueprints that are born conforming, validates them against the root's own framework, regenerates the indexes, and hands any coding agent the workflow it needs to work in one. Plain files, no service, no hidden state. It carries **Eidos
|
|
5
|
+
`eidos` scaffolds a root, generates blueprints that are born conforming, validates them against the root's own framework, regenerates the indexes, and hands any coding agent the workflow it needs to work in one. Plain files, no service, no hidden state. It carries **Eidos 5.0.0**.
|
|
6
6
|
|
|
7
7
|
```bash
|
|
8
8
|
npm install -g eidosmd
|
|
@@ -20,18 +20,18 @@ cd Blueprints
|
|
|
20
20
|
eidos framework # what this root declares
|
|
21
21
|
eidos new specs "Session Management" --group identity --summary "Keeps a signed-in user signed in."
|
|
22
22
|
eidos check # a review, not a gate
|
|
23
|
-
eidos index #
|
|
23
|
+
eidos index # the index inside Framework.yaml
|
|
24
24
|
```
|
|
25
25
|
|
|
26
|
-
`init` copies a seed into `Blueprints
|
|
26
|
+
`init` copies a seed into `Blueprints/.eidos/` (the framework: templates, roles, `Framework.yaml`), creates a folder per collection, and scaffolds one blank frame per framing variant. It writes no prose. Everything a seed ships is reshapeable afterwards.
|
|
27
27
|
|
|
28
28
|
### The framework document
|
|
29
29
|
|
|
30
|
-
The
|
|
30
|
+
The framework document is `.eidos/Framework.yaml`: the framework as data, comments where you want them (a seed ships its guidance that way), and every collection's index inside it under `index` (which `eidos index` rewrites and nothing else). A root still on the markdown `Framework.md` of the 4.x standard is moved by `eidos migrate`, and every other command says so:
|
|
31
31
|
|
|
32
32
|
```bash
|
|
33
|
-
eidos
|
|
34
|
-
eidos
|
|
33
|
+
eidos migrate --dry-run # the moves it would make
|
|
34
|
+
eidos migrate # Framework.yaml with the index inside; Framework.md and each index.md removed
|
|
35
35
|
```
|
|
36
36
|
|
|
37
37
|
The markdown form's prose has no field to land in and is left behind; each collection's description travels.
|
|
@@ -40,26 +40,41 @@ The markdown form's prose has no field to land in and is left behind; each colle
|
|
|
40
40
|
|
|
41
41
|
| Command | What it does |
|
|
42
42
|
| --- | --- |
|
|
43
|
-
| `eidos init [root]` | Create a root from a seed: `--seed`, `--naming`, `--group` (repeatable), `--product`, `--dry-run` |
|
|
44
|
-
| `eidos
|
|
45
|
-
| `eidos
|
|
46
|
-
| `eidos
|
|
47
|
-
| `eidos list [collection]` | List blueprints; filter with `--group`, `--flavor`, `--where key=value` |
|
|
43
|
+
| `eidos init [root]` | Create a root from a seed: `--seed`, `--naming`, `--group` (repeatable), `--product`, `--no-framing`, `--dry-run` |
|
|
44
|
+
| `eidos seeds` | List the bundled seeds (software, book, research) with their collections and variants |
|
|
45
|
+
| `eidos framework` | Show the root's framework: version, naming, top-level docs, collections, units, variants, groups, Properties table, vocabulary; `--as yaml` prints it as the document, normalized |
|
|
46
|
+
| `eidos list [collection]` | List blueprints; filter with `--group`, `--variant`, `--where key=value` |
|
|
48
47
|
| `eidos show <id\|file\|path>` | Print one blueprint, or its properties and sections with `--json` |
|
|
49
|
-
| `eidos
|
|
48
|
+
| `eidos setup` | The CLI's own settings for the root: the git switch, the users (name, @alias, role, email), who this machine acts as; asked in the terminal or set with flags |
|
|
49
|
+
| `eidos new <collection> <title>` | Scaffold a blueprint: frontmatter from the Properties table (every owner's block), body from the variant's template, filename in convention |
|
|
50
50
|
| `eidos check [paths...]` | Validate the root (or the named blueprints) against its own framework; `--strict`, `--json` |
|
|
51
51
|
| `eidos index` | Regenerate the indexes, the `index` key inside `Framework.yaml`; `--check` verifies without writing |
|
|
52
|
-
| `eidos browser` | Open the root in a local web page on 127.0.0.1: browse, read, create, edit, check, index |
|
|
53
|
-
| `eidos
|
|
54
|
-
| `eidos
|
|
52
|
+
| `eidos browser` | Open the root in a local web page on 127.0.0.1: the canvas maps, browse, read, create, edit, check, index |
|
|
53
|
+
| `eidos canvas new\|list` | Create or list the canvas maps under `.eidos/plugins/eidosmd/maps/`; the browser draws them |
|
|
54
|
+
| `eidos version [record]` | The root's own versions, snapshots taken on purpose, this CLI's record under `.eidos/plugins/eidosmd/`; `record <version> [--commit <sha>] [--tag]` writes one, only when asked |
|
|
55
|
+
| `eidos roles` | The roles the framework installed under `.eidos/roles/` |
|
|
56
|
+
| `eidos whoami` | Show or set who you are in `.eidos/me.md` (role and calibration) |
|
|
57
|
+
| `eidos migrate` | Move a root to the standard this CLI carries (the 4.x → 5.0.0 hop, a markdown root becoming `Framework.yaml`), mechanically; `--dry-run` lists the moves |
|
|
55
58
|
| `eidos instructions [guide]` | The workflow an agent follows: overview, authoring, validating, configuring, init-required |
|
|
56
59
|
| `eidos standard` | Print the text of the standard this CLI carries; `--version` for just the number |
|
|
57
60
|
| `eidos agents` | Print the nudge that points agents at `eidos instructions`; `--write` puts it in `AGENTS.md` |
|
|
58
61
|
|
|
59
|
-
Every command takes `--root <path>`; without it the root is found from the working directory by its
|
|
62
|
+
Every command takes `--root <path>`; without it the root is found from the working directory by its `.eidos/` marker, looking up the tree and then two levels down, so the commands work from a repository root that keeps its blueprints in `Blueprints/`.
|
|
60
63
|
|
|
61
64
|
`framework`, `list`, `show`, `check`, `index`, `new`, and `whoami` take `--json` for stable output. Exit codes: `0` done, `1` the check found errors (or an index is stale under `--check`), `2` the command could not run.
|
|
62
65
|
|
|
66
|
+
## Canvas maps
|
|
67
|
+
|
|
68
|
+
The design tool, and the browser's landing view for a root that has one. A canvas is one YAML file under `.eidos/plugins/eidosmd/maps/` (the folder the standard reserves for this tool), Figma-style: pages, and on each page nodes, flows between them, frames, and comment threads. A node is a **sketch** (a label, a kind, a status, a note), a **sticky** (free text on a coloured square), or a **blueprint**, referenced by id and drawn from the file at render time; a sketch is **promoted** into a blueprint through the same scaffold as `eidos new`, and the node keeps its place. The browser is a whiteboard: a toolbar of modes (select, hand, sketch, sticky, text, blueprint, frame, connect, comment), marquee and multi-select, a pages panel, frames drawn around a region that move what is inside, flows drawn with elbows along the grid that meet a node at one of eight anchors with a draggable bend, comment pins that ride on the object they were left on with threads and a resolved state, locks, undo, image export, and preferences for how the wheel and the mouse buttons behave. Nodes are styled by the framework's own properties: this tool's field on a Properties row, `eidosmd: { canvas: { shape, color, show } }`, and `eidos init` writes the legend as defaults on the software seed's `type` and `status`. A snapshot of the whole root is a version the CLI keeps under `.eidos/plugins/eidosmd/` (`eidos version record`). A page exports as JSON Canvas 1.0 for Obsidian.
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
eidos canvas new "Product Map" # .eidos/plugins/eidosmd/maps/product-map.yaml, one empty page
|
|
72
|
+
eidos canvas list
|
|
73
|
+
eidos browser # draw
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
`eidos check` reports a node whose blueprint does not exist, a module link to a missing page or canvas, an edge to a missing node, and a canvas that does not parse.
|
|
77
|
+
|
|
63
78
|
## The browser
|
|
64
79
|
|
|
65
80
|
```bash
|
|
@@ -67,14 +82,16 @@ eidos browser # http://127.0.0.1:6180, this machine only; Ctrl+C to s
|
|
|
67
82
|
eidos browser --no-open --port 7000
|
|
68
83
|
```
|
|
69
84
|
|
|
70
|
-
The root in a local web page:
|
|
85
|
+
The root in a local web page: the canvas maps, each collection as a table with the Properties table's properties as columns, a reader over the table (`Esc` to come back, Expand for a page), typed property editing the way Obsidian shows frontmatter, `/` for search across every blueprint's text, and Settings to edit the framework, the templates, the roles, and `me.md`. There is nothing in the page that is not a command: every write runs the same core function as `new`, `index`, `check`, or `canvas`. The files stay the truth: the server keeps the parsed root and a SQLite search index (`node:sqlite`, nothing to compile) until a file changes, then reads again and tells the page.
|
|
86
|
+
|
|
87
|
+
The page is a Preact app (written against the React API) under `browser/`, built by `pnpm build` into `browser/dist/` and shipped as static files. In a checkout, `pnpm dev:browser` runs it with hot reload against `eidos browser --no-open` on port 6180.
|
|
71
88
|
|
|
72
89
|
## What `check` reports
|
|
73
90
|
|
|
74
|
-
Validation is framework-defined: every rule reads
|
|
91
|
+
Validation is framework-defined: every rule reads `.eidos/Framework.yaml` and the templates in `.eidos/templates/`, never a contract hardcoded in the tool.
|
|
75
92
|
|
|
76
|
-
- **Errors** are wrong on any reading: frontmatter that does not parse, a missing `id` or `title`, an `id`
|
|
77
|
-
- **Warnings** are gaps the standard says to surface, never refuse: a property the
|
|
93
|
+
- **Errors** are wrong on any reading: frontmatter that does not parse, a missing `id` or `title`, an `id` used twice (its form is free: a slug, a number, a GUID), a `variant` the collection does not declare, a link to a file that does not exist, a template the framework points at but lacks.
|
|
94
|
+
- **Warnings** are gaps the standard says to surface, never refuse: a property the Properties table applies here but the blueprint lacks or leaves empty, a property no block of the Properties table declares (the core, yours, or a tool's), a work-tracking field, a section the variant's template declares but the body lacks, a section the template does not know, sections out of order, a grouping value that does not match its folder, a declared frame nobody has written, a stale index, a version gap between the framework and the standard the CLI carries.
|
|
78
95
|
|
|
79
96
|
Frontmatter that is not valid YAML (an unquoted summary with a colon in it) is read leniently and reported as a warning, because Obsidian will refuse it even though a person can read it. `--strict` fails on warnings too, for CI.
|
|
80
97
|
|
|
@@ -98,7 +115,7 @@ Two things version separately.
|
|
|
98
115
|
|
|
99
116
|
`standard/` is a committed copy of that repository's `EIDOS.md` and `seeds/`, refreshed from the monorepo's `standard/` submodule by `pnpm sync-standard` (`--check` exits 1 if it has drifted from the pin); `npm pack` ships only what sits inside this package, so the copy has to be here. Each seed's `.gitignore` travels as `_gitignore`, because npm never packs a file by that name, and `eidos init` renames it back. Never edit `standard/` by hand: sync it.
|
|
100
117
|
|
|
101
|
-
A root on a newer or older standard still works: the framework in front of the tool is the operative contract, and the gap is reported once by `check`.
|
|
118
|
+
A root on a newer or older standard still works: the framework in front of the tool is the operative contract, and the gap is reported once by `check`. `eidos migrate` makes the mechanical hop to the standard this CLI carries; the judgment calls a hop may need are in [`versions/MIGRATIONS.md`](https://github.com/BuildableWorks/Eidos/blob/main/versions/MIGRATIONS.md).
|
|
102
119
|
|
|
103
120
|
## Development
|
|
104
121
|
|
|
@@ -118,23 +135,27 @@ src/
|
|
|
118
135
|
program.ts every command, its options, and its help (commander)
|
|
119
136
|
context.ts find the root, load its framework and blueprints
|
|
120
137
|
commands/ one module per command: what each prints and returns
|
|
121
|
-
browser/ the
|
|
138
|
+
browser/ the Preact app `eidos browser` serves, built into browser/dist/
|
|
122
139
|
core/ the testable model, no printing:
|
|
123
|
-
root.ts finding a root by its
|
|
140
|
+
root.ts finding a root by its .eidos/ marker
|
|
124
141
|
framework.ts finding and loading the framework document
|
|
125
|
-
framework-model.ts the model: collections,
|
|
126
|
-
framework-markdown.ts parsing Framework.md, for
|
|
142
|
+
framework-model.ts the model: collections, variants, groups, Properties table
|
|
143
|
+
framework-markdown.ts parsing a 4.x Framework.md, for migrate
|
|
127
144
|
framework-structured.ts parsing and writing Framework.yaml, and the index inside it
|
|
128
|
-
|
|
145
|
+
template.ts reading a template file's sections and template
|
|
129
146
|
blueprint.ts loading blueprints from a collection's folder
|
|
130
147
|
frontmatter.ts YAML in, house-style frontmatter out
|
|
131
148
|
check.ts every validation rule
|
|
132
149
|
index-leaf.ts the index inside Framework.yaml
|
|
133
|
-
convert.ts moving a markdown root to Framework.yaml
|
|
150
|
+
convert.ts moving a 4.x markdown root to Framework.yaml, for migrate
|
|
151
|
+
canvas.ts canvas maps: the file, layout, styling from the framework's hints, export
|
|
152
|
+
versions.ts the root's own versions, this CLI's record under .eidos/plugins/eidosmd/
|
|
153
|
+
git.ts the little git the CLI needs: HEAD, resolving a commit, a tag
|
|
134
154
|
seed.ts installing a seed into a new root
|
|
155
|
+
store.ts the browser's cache: the parsed root until a file changes, and the SQLite search index
|
|
135
156
|
server.ts the browser's http server and JSON API, over the same core
|
|
136
157
|
scaffold.ts generating one conforming blueprint
|
|
137
|
-
me.ts roles and
|
|
158
|
+
me.ts roles and me.md
|
|
138
159
|
instructions/ the guides `eidos instructions` prints
|
|
139
160
|
standard/ the committed copy of EIDOS.md and seeds/ (synced from Buildable's repo, never hand-edited)
|
|
140
161
|
scripts/ sync-standard.mjs
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
:root{--lightningcss-light:initial;--lightningcss-dark: ;color-scheme:light dark;--accent:var(--lightningcss-light,#a8492a)var(--lightningcss-dark,#e08a63);--accent-strong:var(--lightningcss-light,#8a3a20)var(--lightningcss-dark,#f0a683);--accent-dim:var(--lightningcss-light,#c9714f)var(--lightningcss-dark,#a8532f);--accent-soft:color-mix(in srgb, var(--accent) 16%, transparent);--bg:var(--lightningcss-light,#faf8f4)var(--lightningcss-dark,#101216);--bg-raised:var(--lightningcss-light,#fff)var(--lightningcss-dark,#171a20);--bg-sunken:var(--lightningcss-light,#f2eee6)var(--lightningcss-dark,#0b0d10);--bg-hover:var(--lightningcss-light,#efeae1)var(--lightningcss-dark,#1d2129);--border:var(--lightningcss-light,#e2dbcf)var(--lightningcss-dark,#262a31);--border-strong:var(--lightningcss-light,#cfc6b6)var(--lightningcss-dark,#343a43);--text:var(--lightningcss-light,#191b1f)var(--lightningcss-dark,#ece9e3);--text-muted:var(--lightningcss-light,#575c65)var(--lightningcss-dark,#9ba2ac);--text-faint:var(--lightningcss-light,#7b818b)var(--lightningcss-dark,#6f7680);--error:var(--lightningcss-light,#b23a2a)var(--lightningcss-dark,#e2705f);--warn:var(--lightningcss-light,#9a6a12)var(--lightningcss-dark,#d8a437);--ok:var(--lightningcss-light,#2f6b3a)var(--lightningcss-dark,#7bc48a);--shadow-color:var(--lightningcss-light,#1e140a2e)var(--lightningcss-dark,#00000073);--shadow:0 12px 40px var(--shadow-color);--font:ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;--font-display:"Newsreader", "Iowan Old Style", Palatino, Georgia, serif;--mono:ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;--radius:10px;--sidebar:248px}@media (prefers-color-scheme:dark){:root{--lightningcss-light: ;--lightningcss-dark:initial}}:root[data-theme=light]{--lightningcss-light:initial;--lightningcss-dark: ;color-scheme:light}:root[data-theme=dark]{--lightningcss-light: ;--lightningcss-dark:initial;color-scheme:dark}*{box-sizing:border-box}html,body,#app{height:100%}body{font:14px/1.5 var(--font);color:var(--text);background:var(--bg);-webkit-font-smoothing:antialiased;margin:0}a{color:var(--accent);text-decoration:none}a:hover{text-decoration:underline}button,input,select,textarea{font:inherit;color:inherit}button{background:var(--bg-raised);border:1px solid var(--border);cursor:pointer;border-radius:7px;padding:5px 11px;line-height:1.3}button:hover{border-color:var(--border-strong);background:var(--bg-hover)}button:disabled{opacity:.5;cursor:default}button.primary{background:var(--accent);color:#fff;border-color:var(--accent)}button.primary:hover{background:var(--accent-strong);border-color:var(--accent-strong)}button.quiet{color:var(--text-muted);background:0 0;border-color:#0000}button.quiet:hover{background:var(--bg-hover);color:var(--text)}button.danger{color:var(--error)}button.small{padding:2px 8px;font-size:12px}input,select,textarea{background:var(--bg-sunken);border:1px solid var(--border);border-radius:7px;outline:none;width:100%;padding:6px 9px}input:focus,select:focus,textarea:focus{border-color:var(--accent)}select{width:auto}textarea{resize:vertical}.select{vertical-align:middle;max-width:100%;display:inline-block;position:relative}.select__btn{text-align:left;width:100%;font:inherit;color:inherit;justify-content:space-between;align-items:center;gap:6px;padding:5px 8px 5px 10px;display:inline-flex}.select__btn svg{width:12px;height:12px;color:var(--text-faint);flex:none;transition:transform .12s}.select.open .select__btn svg{transform:rotate(180deg)}.suggest{min-width:0;display:block;position:relative}.suggest input{width:100%}.suggest__menu{max-height:240px}.datepick{align-items:center;gap:2px;min-width:0;display:flex;position:relative}.datepick input{flex:1;min-width:0}.datepick__btn{height:24px;color:var(--text-faint);background:0 0;border-color:#0000;align-items:center;padding:0 5px;display:inline-flex}.datepick__btn:hover{color:var(--text)}.datepick__menu{width:256px;padding:10px}.datepick__head{justify-content:space-between;align-items:center;margin-bottom:6px;display:flex}.datepick__head strong{font-size:13px}.datepick__head button{color:var(--text-muted);background:0 0;border:0;padding:2px 8px;font-size:16px;line-height:1}.datepick__head button:hover{color:var(--text)}.datepick__grid{grid-template-columns:repeat(7,1fr);gap:2px;display:grid}.datepick__grid span{text-align:center;color:var(--text-faint);padding:2px 0;font-size:10px}.datepick__grid button{height:28px;color:var(--text);background:0 0;border:0;border-radius:6px;padding:0;font-size:12px}.datepick__grid button:hover{background:var(--bg-hover)}.datepick__grid button.faint{color:var(--text-faint)}.datepick__grid button.today{box-shadow:inset 0 0 0 1px var(--accent)}.datepick__grid button.on{background:var(--accent);color:#fff}.datepick__time{color:var(--text-muted);align-items:center;gap:8px;margin-top:8px;font-size:12px;display:flex}.datepick__time input{width:80px}.datepick__foot{justify-content:space-between;margin-top:8px;display:flex}.datepick__foot button{color:var(--accent);background:0 0;border:0;padding:2px 4px;font-size:12px}.select__val{white-space:nowrap;text-overflow:ellipsis;flex:1;min-width:0;overflow:hidden}.select__menu{flex-direction:column;gap:1px;min-width:100%;max-height:300px;padding:6px;display:flex;overflow:auto}.select__menu button{text-align:left;white-space:nowrap;color:var(--text);background:0 0;border:0;border-radius:5px;padding:5px 8px;font-size:13px}.select__menu button:hover{background:var(--bg-hover)}.select__menu button.on{background:var(--accent-soft);color:var(--text)}.select__menu button:disabled{opacity:.5}.select__menu button.held:not(.on){font-weight:600}[data-tip][data-tip-off]:hover:after,[data-tip][data-tip-off]:focus-within:after{display:none}.longtext{align-items:flex-start;gap:8px;min-width:0;display:flex}.longtext__text{-webkit-line-clamp:3;white-space:pre-wrap;word-break:break-word;-webkit-box-orient:vertical;flex:1;min-width:0;font-size:13px;line-height:1.45;display:-webkit-box;overflow:hidden}.longtext__editor{width:100%;min-height:240px;font-size:14px;line-height:1.5}.pager{border:1px solid var(--border);background:var(--bg-raised);border-radius:8px;align-items:center;display:inline-flex;overflow:hidden}.pager>*+*{border-left:1px solid var(--border)}.pager .select__btn,.pager button.icon{background:0 0;border:0;border-radius:0;height:30px}.pager .select__btn{padding:0 8px 0 10px}.pager__count{color:var(--text-muted);white-space:nowrap;padding:0 10px;font-size:12px;line-height:30px}code{font-family:var(--mono);font-size:.92em}pre{background:var(--bg-sunken);border:1px solid var(--border);border-radius:8px;padding:10px 12px;overflow-x:auto}[data-tip]{position:relative}[data-tip]:hover:after,[data-tip]:focus-visible:after{content:attr(data-tip);background:var(--text);color:var(--bg);font:12px/1.35 var(--font);white-space:pre;z-index:80;pointer-events:none;text-transform:none;letter-spacing:0;border-radius:6px;padding:5px 9px;font-weight:400;position:absolute;bottom:calc(100% + 8px);left:50%;transform:translate(-50%);box-shadow:0 4px 14px #00000040}[data-tip][data-tip-pos=bottom]:hover:after,[data-tip][data-tip-pos=bottom]:focus-visible:after{top:calc(100% + 8px);bottom:auto}[data-tip][data-tip-pos=right]:hover:after,[data-tip][data-tip-pos=right]:focus-visible:after{top:50%;bottom:auto;left:calc(100% + 8px);transform:translateY(-50%)}[data-tip][data-tip-pos=left]:hover:after,[data-tip][data-tip-pos=left]:focus-visible:after{inset:50% calc(100% + 8px) auto auto;transform:translateY(-50%)}button.icon{justify-content:center;align-items:center;width:28px;height:28px;padding:4px;display:inline-flex}button.icon svg{width:14px;height:14px}button.danger-fill{background:var(--error);border-color:var(--error);color:#fff}.tabs{border-bottom:1px solid var(--border);gap:2px;margin-bottom:18px;display:flex}.tabs a{color:var(--text-muted);border-bottom:2px solid #0000;margin-bottom:-1px;padding:8px 12px;text-decoration:none}.tabs a:hover{color:var(--text)}.tabs a.on{color:var(--text);border-bottom-color:var(--accent)}kbd{font:12px/1.5 var(--font);border:1px solid var(--border-strong);color:var(--text);background:var(--bg-raised);text-align:center;border-bottom-width:2px;border-radius:4px;min-width:22px;padding:1px 6px;display:inline-block}kbd.mod{padding:0 5px;font-size:13px}.keys{flex-wrap:wrap;align-items:center;gap:4px;display:inline-flex}.keys__alt{align-items:center;gap:2px;display:inline-flex}.keys__or{color:var(--text-faint);margin:0 4px;font-size:11px}::-webkit-scrollbar{width:10px;height:10px}::-webkit-scrollbar-thumb{background:var(--border-strong);border:2px solid var(--bg);border-radius:6px}.shell{grid-template-columns:var(--sidebar) 1fr;height:100%;display:grid;overflow:hidden}.sidebar{background:var(--bg-sunken);border-right:1px solid var(--border);flex-direction:column;min-height:0;display:flex}.brand{align-items:center;gap:9px;padding:16px 16px 10px;display:flex}.brand__mark{width:24px;height:24px;color:var(--accent);flex-shrink:0}.brand__word{font-family:var(--font-display);letter-spacing:-.012em;font-size:22px;font-weight:500;line-height:1}.brand__root{color:var(--text-faint);font-size:12px;font-family:var(--mono);white-space:nowrap;text-overflow:ellipsis;margin:0 16px 12px;overflow:hidden}.sidebar__search{border:1px solid var(--border);background:var(--bg);color:var(--text-faint);cursor:text;border-radius:8px;align-items:center;gap:8px;margin:0 12px 10px;padding:6px 10px;font-size:13px;display:flex}.sidebar__search:hover{border-color:var(--border-strong)}.sidebar__search span{flex:1}.nav{flex-direction:column;flex:1;min-height:0;padding:0 8px 12px;display:flex;overflow-y:auto}.nav>a,.nav>.nav__group,.nav>.faint{flex:none}.nav__foot{border-top:1px solid var(--border);margin-top:auto;margin-left:-8px;margin-right:-8px;padding-top:10px;padding-left:8px;padding-right:8px}.nav__foot a svg{width:14px;height:14px;color:var(--text-faint);flex:none}.nav__foot a.active svg{color:var(--text)}.nav__group{text-transform:uppercase;letter-spacing:.08em;color:var(--text-faint);justify-content:space-between;align-items:center;margin:12px 8px 4px;font-size:11px;display:flex}.nav__group button{padding:0 6px;font-size:11px;line-height:18px}.nav a .badge{margin-left:auto;padding:0 6px;font-size:10px;line-height:16px}.shell__menu{z-index:60;border-radius:8px;justify-content:center;align-items:center;width:36px;height:36px;display:none;position:fixed;top:10px;left:10px}.shell__scrim{z-index:49;background:#00000059;display:none;position:fixed;inset:0}.nav a{color:var(--text-muted);border-radius:6px;align-items:center;gap:8px;padding:5px 8px;text-decoration:none;display:flex}.nav a:hover{background:var(--bg-hover);color:var(--text)}.nav a.active{background:var(--accent-soft);color:var(--text)}.nav a .count{color:var(--text-faint);font-size:11px;font-family:var(--mono);margin-left:auto}.nav__group--framework{color:var(--accent)}.nav a.nav__framework{border-left:2px solid color-mix(in srgb, var(--accent) 45%, transparent);border-radius:0 6px 6px 0;margin-left:4px;padding-left:10px}.field__hint{color:var(--text-faint);grid-column:2;font-size:11px}.sidebar__foot{padding:4px 12px 10px}.sidebar__acting{color:var(--text-faint);grid-template-columns:max-content minmax(0,1fr);align-items:center;gap:6px;margin-top:8px;font-size:11px;display:grid}.sidebar__acting .select{min-width:0}.sidebar__acting--top{margin:0 12px 10px}.sidebar__acting>span{white-space:nowrap}.sidebar__acting .select{width:100%}.sidebar__acting .select__btn{padding:3px 6px;font-size:12px}.sidebar__version{color:var(--text-faint);font-size:11px;font-family:var(--mono);justify-content:space-between;margin-top:0;display:flex}.main{flex-direction:column;min-width:0;min-height:0;display:flex;position:relative;overflow:hidden}.page{flex:1;padding:22px 28px 60px;overflow:auto}.page--narrow{max-width:900px}.page--read{max-width:78ch;margin:0 auto;padding-top:32px}.page--doc{width:100%;max-width:1100px;margin:0 auto;padding-top:28px}.doc{grid-template-columns:minmax(0,1fr);align-items:start;gap:32px;display:grid}.doc--rail{grid-template-columns:minmax(0,1fr) 220px}.doc__rail{min-width:0;position:sticky;top:0}.doc__rail .toc{margin-top:0}.source{font-family:var(--mono);white-space:pre-wrap;word-break:break-word;color:var(--text);background:var(--bg-sunken);border:1px solid var(--border);border-radius:8px;margin:0;padding:14px 16px;font-size:13px;line-height:1.55}.page--doc .md{font-size:15px}.page__back{color:var(--text-muted);align-items:center;gap:4px;margin-bottom:6px;font-size:12px;display:inline-flex}.page__back:hover{color:var(--text);text-decoration:none}.page__head{align-items:flex-start;gap:14px;margin-bottom:14px;display:flex}.page__head h1{letter-spacing:-.01em;margin:0;font-size:22px;font-weight:600}.page__head .grow{flex:1;min-width:0}.page__head p{color:var(--text-muted);max-width:70ch;margin:4px 0 0}.toolbar{flex-wrap:wrap;align-items:center;gap:8px;display:flex}.toolbar .grow{flex:1}.muted{color:var(--text-muted)}.faint{color:var(--text-faint)}.mono{font-family:var(--mono);font-size:12px}.empty{color:var(--text-faint);text-align:center;padding:48px 0}.badge{background:var(--bg-raised);border:1px solid var(--border);color:var(--text-muted);white-space:nowrap;border-radius:999px;align-items:center;gap:4px;padding:1px 8px;font-size:11px;display:inline-flex}.badge.error{color:var(--error);border-color:color-mix(in srgb, var(--error) 50%, transparent)}.badge.warn{color:var(--warn);border-color:color-mix(in srgb, var(--warn) 50%, transparent)}.badge.ok{color:var(--ok);border-color:color-mix(in srgb, var(--ok) 50%, transparent)}.badge.accent{color:var(--accent);border-color:color-mix(in srgb, var(--accent) 50%, transparent)}.swatch{vertical-align:-1px;border-radius:3px;width:10px;height:10px;margin-right:5px;display:inline-block}.findings{margin:10px 0 16px;padding:0;font-size:13px;list-style:none}.findings li{border-left:3px solid var(--warn);background:var(--bg-raised);border-radius:0 6px 6px 0;margin-bottom:4px;padding:5px 10px}.findings li.error{border-left-color:var(--error)}.findings li code{color:var(--text-faint);margin-right:6px}.toast{z-index:60;background:var(--text);color:var(--bg);white-space:pre-wrap;max-width:460px;box-shadow:var(--shadow);border-radius:9px;padding:10px 16px;font-size:13px;position:fixed;bottom:20px;right:20px}.toast.error{background:var(--error);color:#fff}.form{grid-template-columns:130px 1fr;align-items:center;gap:10px 14px;margin:14px 0;display:grid}.form label{color:var(--text-muted);font-size:13px}.form .full{grid-column:1/-1}.actions{justify-content:flex-end;gap:8px;margin-top:16px;display:flex}.split{grid-template-columns:1fr 1fr;gap:12px;display:grid}.md{font-size:15px;line-height:1.6}.md>:first-child{margin-top:0}.md h1{letter-spacing:-.015em;margin:0 0 12px;font-size:24px}.md h2{border-bottom:1px solid var(--border);margin:28px 0 8px;padding-bottom:5px;font-size:18px}.md h3{margin:20px 0 6px;font-size:15px}.md p,.md ul,.md ol{margin:0 0 12px}.md li{margin:2px 0}.md table{border-collapse:collapse;margin:0 0 12px;font-size:14px}.md th,.md td{border:1px solid var(--border);text-align:left;vertical-align:top;padding:5px 9px}.md th{background:var(--bg-raised)}.md blockquote{border-left:3px solid var(--accent);color:var(--text-muted);margin:0 0 12px;padding:2px 14px}.md em:only-child{color:var(--text-faint)}.md img{max-width:100%}.md hr{border:0;border-top:1px solid var(--border);margin:20px 0}.md input[type=checkbox]{width:auto;margin-right:6px}.table-wrap{border:1px solid var(--border);border-radius:var(--radius);background:var(--bg-raised);overflow:auto}table.grid{border-collapse:separate;border-spacing:0;width:100%;font-size:13px}table.grid th{z-index:1;background:var(--bg-raised);text-align:left;color:var(--text-muted);border-bottom:1px solid var(--border);white-space:nowrap;cursor:pointer;-webkit-user-select:none;user-select:none;padding:8px 12px;font-weight:500;position:sticky;top:0}table.grid th:hover{color:var(--text)}table.grid th .dir{color:var(--accent);margin-left:4px;font-size:11px}table.grid td{border-bottom:1px solid var(--border);vertical-align:top;text-overflow:ellipsis;white-space:nowrap;max-width:380px;padding:7px 12px;overflow:hidden}table.grid tr:last-child td{border-bottom:0}table.grid tbody tr{cursor:pointer}table.grid tbody tr:hover td{background:var(--bg-hover)}table.grid tbody tr.selected td{background:var(--accent-soft)}table.grid td.title{color:var(--text);white-space:normal;min-width:200px;font-weight:500}table.grid td.title .id{font-family:var(--mono);color:var(--text-faint);font-size:11px;font-weight:400;display:block}table.grid td.summary{color:var(--text-muted);white-space:normal;min-width:240px;max-width:460px}table.grid td .chip{background:var(--bg-sunken);border:1px solid var(--border);color:var(--text-muted);border-radius:999px;margin:1px 3px 1px 0;padding:0 7px;font-size:11px;display:inline-block}table.grid td .value-swatch{vertical-align:0;border-radius:50%;width:8px;height:8px;margin-right:6px;display:inline-block}table.grid td.flags .dot{background:var(--warn);border-radius:50%;width:7px;height:7px;display:inline-block}table.grid td.flags .dot.error{background:var(--error)}.popover{z-index:20;background:var(--bg-raised);border:1px solid var(--border);box-shadow:var(--shadow);border-radius:9px;min-width:200px;padding:8px;position:absolute;top:calc(100% + 6px);right:0}.popover label{cursor:pointer;border-radius:5px;align-items:center;gap:8px;padding:4px 6px;font-size:13px;display:flex}.popover label:hover{background:var(--bg-hover)}.popover input[type=checkbox]{width:auto}.relative{position:relative}.popover--left{left:0;right:auto}button.on-filter{border-color:var(--accent);color:var(--text)}button svg{vertical-align:-2px}table.grid tr.group-row td{background:var(--bg-sunken);color:var(--text-muted);cursor:pointer;padding:5px 12px;font-size:12px}table.grid tr.group-row td svg{margin-right:6px}table.grid tr.group-row td .mono{color:var(--text);margin-right:8px}table.grid tr.nested td.title{padding-left:32px}.palette__section{text-transform:uppercase;letter-spacing:.08em;color:var(--text-faint);padding:8px 12px 2px;font-size:10px}.reader__fields{gap:10px;margin-bottom:14px;display:grid}.reader__fields label{color:var(--text-muted);grid-template-columns:80px 1fr;align-items:start;gap:10px;font-size:13px;display:grid}.reader__fields input,.reader__fields textarea{font-size:15px}.settings__h{text-transform:uppercase;letter-spacing:.06em;color:var(--text-faint);align-items:center;gap:6px;margin:22px 0 8px;font-size:12px;display:flex}.settings__h:first-child{margin-top:0}.prop__value .list .chip button svg{width:11px;height:11px}.prop--edit .prop__remove{color:var(--text-faint);justify-content:center;align-items:center;display:inline-flex}.prop--edit .prop__remove svg,.mini td.x button svg{width:13px;height:13px}.backdrop{z-index:40;background:#0000008c;justify-content:center;align-items:flex-start;padding:40px 20px;display:flex;position:fixed;inset:0;overflow:auto}.backdrop.center{align-items:center}.modal{background:var(--bg);border:1px solid var(--border);box-shadow:var(--shadow);border-radius:14px;flex-direction:column;width:100%;max-width:980px;max-height:calc(100vh - 80px);display:flex;overflow:hidden}.modal--sm{max-width:560px}.modal--lg{max-width:1280px}.modal--xl{max-width:1200px;height:calc(100vh - 80px)}.modal__head{border-bottom:1px solid var(--border);align-items:center;gap:10px;padding:12px 18px;display:flex}.modal__head h2{white-space:nowrap;text-overflow:ellipsis;flex:1;min-width:0;margin:0;font-size:16px;font-weight:600;overflow:hidden}.modal__body{flex:1;min-height:0;overflow:auto}.modal__body:has(>.reader){flex-direction:column;display:flex;overflow:hidden}.modal__body>.reader{flex:1;min-height:0}.modal__body>.reader .reader__props,.modal__body>.reader .reader__content{min-height:0;overflow:auto}.modal__foot{border-top:1px solid var(--border);justify-content:flex-end;gap:8px;padding:12px 18px;display:flex}.reader{grid-template-columns:340px 1fr;min-height:100%;display:grid}.reader__props{border-right:1px solid var(--border);background:var(--bg-sunken);padding:16px}.reader__content{min-width:0;padding:22px 28px 40px}.reader--stack{grid-template-columns:1fr}.reader--stack .reader__props{border-right:0;border-bottom:1px solid var(--border)}.reader__meta{flex-wrap:wrap;gap:6px;margin-bottom:12px;display:flex}.reader__summary{color:var(--text-muted);margin:0 0 18px;font-size:15px}.editor{width:100%;min-height:60vh;font-family:var(--mono);white-space:pre;resize:vertical;tab-size:2;font-size:13px;line-height:1.5}.props{flex-direction:column;gap:2px;display:flex}.prop{border-radius:6px;grid-template-columns:18px 112px 1fr;align-items:start;gap:6px;min-height:28px;padding:3px 4px;font-size:13px;display:grid}.prop:hover{background:var(--bg-hover)}.prop__icon{color:var(--text-faint);justify-content:center;align-items:center;height:22px;display:flex}.prop__icon svg{width:14px;height:14px}.prop__name{color:var(--text-muted);white-space:nowrap;text-overflow:ellipsis;line-height:22px;font-family:var(--mono);font-size:12px;overflow:hidden}.prop__name.unknown{color:var(--warn)}.prop__value{word-break:break-word;min-width:0;line-height:22px}.prop__value input,.prop__value select,.prop__value .select__btn{background:0 0;border-color:#0000;border-radius:5px;padding:1px 6px}.prop__value input:hover,.prop__value select:hover{border-color:var(--border)}.prop__value input:focus,.prop__value select:focus{border-color:var(--accent);background:var(--bg)}.prop__value input[type=checkbox]{width:auto;margin:4px}.prop__value .list{flex-wrap:wrap;align-items:center;gap:4px;display:flex}.prop__value .list .chip{background:var(--bg-raised);border:1px solid var(--border);white-space:nowrap;text-overflow:ellipsis;white-space:nowrap;border-radius:999px;align-items:center;gap:4px;max-width:100%;padding:0 8px;font-size:12px;display:inline-flex;overflow:hidden}.prop__value .list .chip:has(button){padding-right:3px}.prop__value .list .chip button{color:var(--text-faint);background:0 0;border:0;padding:0 4px;font-size:13px;line-height:18px}.prop__value .list .chip button:hover{color:var(--error)}.prop__value .list input{flex:1;width:120px;min-width:80px}.prop__value .link{color:var(--accent)}.prop__remove{grid-column:3;display:none}.prop--edit{grid-template-columns:18px 112px 1fr 22px}.prop--edit .prop__remove{color:var(--text-faint);background:0 0;border:0;grid-column:auto;height:22px;padding:0;display:block}.prop--edit .prop__remove:hover{color:var(--error)}.prop--add{color:var(--text-faint);cursor:pointer;border-radius:6px;align-items:center;gap:6px;padding:5px 8px;font-size:13px;display:flex}.prop--add:hover{background:var(--bg-hover);color:var(--text)}.prop--add select,.prop--add .select__btn{padding:1px 6px}.prop__hint{color:var(--text-faint);margin:0 4px 6px;font-size:11px}.prop--hot .prop__value{cursor:text;border-radius:5px}.prop--hot .prop__value:hover{background:color-mix(in srgb, var(--accent) 12%, transparent);box-shadow:0 0 0 3px color-mix(in srgb, var(--accent) 12%, transparent)}.prop--inline{background:var(--bg);box-shadow:0 0 0 1px var(--accent)}.prop--inline .prop__value input,.prop--inline .prop__value select,.prop--inline .prop__value .select__btn{background:var(--bg);border-color:var(--border)}.toc{flex-direction:column;gap:1px;margin:14px 0;display:flex}.toc a{color:var(--text-muted);white-space:nowrap;text-overflow:ellipsis;border-radius:4px;padding:2px 6px;font-size:12px;text-decoration:none;overflow:hidden}.toc a:hover{background:var(--bg-hover);color:var(--text)}.toc a.toc__3{padding-left:18px;font-size:11px}.history{margin-top:14px;font-size:12px}.history__h{text-transform:uppercase;letter-spacing:.08em;color:var(--text-faint);justify-content:space-between;align-items:center;margin-bottom:4px;padding:0 6px;font-size:10px;display:flex}.history__row{border-radius:5px;grid-template-columns:56px 1fr auto auto;align-items:center;gap:8px;padding:3px 6px;display:grid}.history__row:hover{background:var(--bg-hover)}.history__row code{color:var(--text-faint)}.history__who{white-space:nowrap;text-overflow:ellipsis;overflow:hidden}table.grid td.flags{text-align:right;white-space:nowrap;width:64px}table.grid td.flags .row-more{opacity:0;vertical-align:middle;margin-left:4px}table.grid tbody tr:hover td.flags .row-more,table.grid tbody tr.selected td.flags .row-more{opacity:1}.modal .form select,.modal .form input{width:100%;min-width:0;max-width:100%}.modal .form{min-width:0}.palette{background:var(--bg);border:1px solid var(--border);width:100%;max-width:640px;box-shadow:var(--shadow);border-radius:14px;margin-top:8vh;overflow:hidden}.palette input{border:0;border-bottom:1px solid var(--border);background:0 0;border-radius:0;padding:14px 18px;font-size:16px}.palette__list{max-height:60vh;padding:6px;overflow:auto}.palette__hit{cursor:pointer;border-radius:8px;grid-template-columns:1fr auto;gap:2px 10px;padding:8px 12px;display:grid}.palette__hit.active,.palette__hit:hover{background:var(--bg-hover)}.palette__hit .t{font-weight:500}.palette__hit .s{color:var(--text-muted);white-space:nowrap;text-overflow:ellipsis;grid-column:1/-1;font-size:12px;overflow:hidden}.palette__hit .s mark{background:var(--accent-soft);color:var(--accent-strong);border-radius:3px;padding:0 2px}.palette__hit .w{color:var(--text-faint);font-size:11px;font-family:var(--mono);white-space:nowrap}.palette__foot{border-top:1px solid var(--border);color:var(--text-faint);gap:14px;padding:8px 14px;font-size:11px;display:flex}.palette__empty{color:var(--text-faint);text-align:center;padding:24px}.card{border:1px solid var(--border);background:var(--bg-raised);border-radius:10px;margin-bottom:10px;padding:12px 14px}.card__head{align-items:center;gap:8px;margin-bottom:8px;display:flex}.tpl-head{gap:6px;margin-bottom:6px;display:grid}.tpl-head textarea{field-sizing:content;min-height:96px;max-height:50vh;font-size:13px;line-height:1.5}.tpl-head label{color:var(--text-muted);font-size:12px}.tpl-sec{border-bottom:1px solid var(--border);grid-template-columns:68px minmax(0,1fr) auto;align-items:center;gap:8px;padding:10px 0;display:grid}.tpl-sec textarea{field-sizing:content;grid-column:1/-1;min-height:150px;max-height:60vh;font-size:13px;line-height:1.5}.tpl-sec__tools{gap:2px;display:flex}.card__head strong{flex:1}.field{grid-template-columns:120px 1fr;align-items:center;gap:6px 12px;margin:4px 0;font-size:13px;display:grid}.field>span{color:var(--text-muted)}.field input,.field select,.field textarea{font-size:13px}.mini{border-collapse:collapse;width:100%;font-size:13px}.mini th{text-align:left;color:var(--text-faint);padding:3px 6px;font-weight:500}.mini td{vertical-align:middle;padding:3px 6px}.mini input,.mini select,.mini .select__btn{padding:3px 7px;font-size:13px}.mini input[type=color]{width:30px;height:26px;padding:0 2px}.mini input[type=checkbox]{width:auto}.mini td.x{width:28px}.rowbtn{gap:6px;margin-top:6px;display:flex}.dirty{color:var(--warn);font-size:12px}.cv{background:var(--bg);background-image:radial-gradient(color-mix(in srgb, var(--text) 12%, transparent) 1px, transparent 1px);-webkit-user-select:none;user-select:none;touch-action:none;background-size:24px 24px;position:absolute;inset:0;overflow:hidden}.cv[data-tool=select]{cursor:default}.cv[data-tool=hand]{cursor:grab}.cv[data-tool=hand].dragging,.cv.panning{cursor:grabbing}.cv[data-tool=sketch],.cv[data-tool=sticky],.cv[data-tool=text],.cv[data-tool=blueprint],.cv[data-tool=frame],.cv[data-tool=connect]{cursor:crosshair}.cv[data-tool=comment]{cursor:cell}.cv:not([data-tool=select]) :is(.node,.text-el,.frame,.frame__title,.node [data-field]){cursor:inherit}.cv__world{transform-origin:0 0;will-change:transform;position:absolute;top:0;left:0}.cv__svg{pointer-events:none;position:absolute;top:0;left:0;overflow:visible}.cv__svg path.edge{fill:none;stroke:var(--text-faint);stroke-width:1.6px;pointer-events:stroke;cursor:pointer}.cv__svg path.hit{fill:none;stroke:#0000;stroke-width:24px;pointer-events:stroke;cursor:pointer}.cv__svg rect.labelhit{fill:#0000;pointer-events:all;cursor:grab}.cv__svg path.edge.selected{stroke:var(--accent);stroke-width:2.2px}.cv__svg path.temp{fill:none;stroke:var(--accent);stroke-width:1.6px;stroke-dasharray:6 4}.cv__svg text{fill:var(--text-muted);font-size:11px;font-family:var(--font);pointer-events:none;paint-order:stroke;stroke:var(--bg);stroke-width:3px;stroke-linejoin:round}.cv__svg circle.bend{fill:var(--bg);stroke:var(--accent);stroke-width:2px;pointer-events:all;cursor:move}.cv__svg circle.endpoint{fill:var(--accent);stroke:var(--bg);stroke-width:2px;pointer-events:all;cursor:crosshair}.cv__svg rect.marquee{fill:color-mix(in srgb, var(--accent) 12%, transparent);stroke:var(--accent);stroke-width:1px;vector-effect:non-scaling-stroke}.cv__svg rect.drawing{fill:color-mix(in srgb, var(--accent) 8%, transparent);stroke:var(--accent);stroke-width:1px;stroke-dasharray:6 4;vector-effect:non-scaling-stroke}.cv__svg rect.group-box{fill:none;stroke:var(--accent);stroke-width:1px;stroke-dasharray:4 3;vector-effect:non-scaling-stroke;pointer-events:none}.cv__svg circle.snap{fill:color-mix(in srgb, var(--accent) 25%, transparent);stroke:var(--accent);stroke-width:2px;pointer-events:none}.cv__svg g.snap rect.group-box{stroke-dasharray:none;stroke-width:1.5px}.frame{border:1.5px solid var(--border-strong);background:color-mix(in srgb, var(--bg-raised) 45%, transparent);cursor:move;--frame-tint:transparent;border-radius:12px;position:absolute}.frame:before{content:"";background:var(--frame-tint);pointer-events:none;border-radius:11px;position:absolute;inset:0}.frame.selected{border-color:var(--accent)}.frame.locked{cursor:default}.frame.frame-sand{--frame-tint:#e08a6317}.frame.frame-sky{--frame-tint:#2f6fd01a}.frame.frame-mint{--frame-tint:#1f7a5a1a}.frame.frame-rose{--frame-tint:#b23a2a17}.frame.frame-lilac{--frame-tint:#785ac81a}.frame__title{background:var(--bg);border:1px solid var(--border);color:var(--text-muted);letter-spacing:.04em;text-transform:uppercase;white-space:nowrap;cursor:text;text-overflow:ellipsis;border-radius:6px;max-width:calc(100% - 20px);padding:2px 8px;font-size:11px;font-weight:600;position:absolute;top:-13px;left:10px;overflow:hidden}.frame.selected .frame__title{color:var(--text);border-color:var(--accent)}.frame__grip{background:var(--bg);border:2px solid var(--accent);border-radius:2px;width:10px;height:10px;display:none;position:absolute}.frame.selected:not(.locked) .frame__grip{display:block}.frame__grip.nw{cursor:nwse-resize;top:-6px;left:-6px}.frame__grip.ne{cursor:nesw-resize;top:-6px;right:-6px}.frame__grip.sw{cursor:nesw-resize;bottom:-6px;left:-6px}.frame__grip.se{cursor:nwse-resize;bottom:-6px;right:-6px}.frame__grip.n,.frame__grip.s{border-radius:3px;width:24px;height:6px;margin-left:-12px;left:50%}.frame__grip.n{cursor:ns-resize;top:-4px}.frame__grip.s{cursor:ns-resize;bottom:-4px}.frame__grip.e,.frame__grip.w{border-radius:3px;width:6px;height:24px;margin-top:-12px;top:50%}.frame__grip.e{cursor:ew-resize;right:-4px}.frame__grip.w{cursor:ew-resize;left:-4px}.frame__handle{background:var(--accent);border:2px solid var(--bg);cursor:crosshair;opacity:0;z-index:2;border-radius:50%;width:12px;height:12px;transition:opacity .12s;position:absolute}.frame__handle--top{top:-7px;left:25%}.frame__handle--bottom{bottom:-7px;left:75%}.frame__handle--left{top:75%;left:-7px}.frame__handle--right{top:25%;right:-7px}.frame:hover .frame__handle,.frame.selected .frame__handle{opacity:1}.frame.locked .frame__handle{display:none}.frame.drop-border{border-color:var(--accent);box-shadow:0 0 0 4px color-mix(in srgb, var(--accent) 22%, transparent);border-width:3px}.node{border:1px solid var(--border-strong);background:var(--bg-raised);cursor:move;--node-color:var(--border-strong);border-radius:9px;flex-direction:column;width:220px;height:112px;padding:9px 13px 28px;font-size:13px;line-height:1.35;display:flex;position:absolute;overflow:visible;box-shadow:0 1px 2px #00000040}.node.selected{outline:2px solid var(--accent);outline-offset:1px}.node.locked{cursor:default}.node.pill{text-align:center;border-radius:56px;padding-left:22px;padding-right:22px}.node.fill-solid{background:var(--node-fill,var(--bg-raised))}.node.fill-tint{background:color-mix(in srgb, var(--node-fill,var(--node-color)) 18%, transparent)}.node.fill-none{box-shadow:none;background:0 0}.node.fill-solid.ink-dark{color:#191b1f}.node.fill-solid .node__sum{color:inherit;opacity:.74}.node.fill-solid .node__tags span{color:inherit;opacity:.8;border-color:currentColor}.node.fill-solid .node__kind{color:inherit;opacity:.8}.node.ink-light{color:#f4f1ec}.node.ink-light .node__sum{color:#f4f1ecb8}.node.ink-light .node__tags span{color:#f4f1eccc;border-color:#f4f1ec66}.node.parallelogram{transform:skew(-12deg)}.node.parallelogram>*{transform:skew(12deg)}.node.missing{border-style:dashed;border-color:var(--error)}.node.sketch{border-style:dashed}.node.annotation{background:var(--ann,var(--text));width:200px;height:auto;min-height:40px;color:var(--bg);white-space:pre-wrap;border:1px solid #0000;border-radius:8px;padding:8px 34px 8px 12px;font-size:12px;line-height:1.4;display:block;box-shadow:0 2px 6px #00000040}.node.annotation.ink-dark{color:#191b1f}.node.annotation .node__lbl{white-space:pre-wrap;text-overflow:clip;font-weight:500;overflow:visible}.node.annotation.pending{border-color:var(--accent);border-style:dashed}.node.annotation .node__more,.node.annotation .node__lock{color:inherit;opacity:.75;background:color-mix(in srgb, currentColor 14%, transparent)}.node.annotation .node__more:hover,.node.annotation .node__lock:hover{opacity:1}.node.size-small{width:180px;height:84px;padding:7px 11px 8px}.node.size-small .node__sum{-webkit-line-clamp:2}.node.size-small .node__tags{display:none}.node.size-large{width:280px;height:148px;padding:11px 15px 28px}.node.size-large .node__sum{-webkit-line-clamp:5}.node.size-large .node__lbl{font-size:15px}.node.attached,.text-el.attached{outline:2px solid var(--accent);outline-offset:3px;box-shadow:0 0 0 6px color-mix(in srgb, var(--accent) 16%, transparent), 0 1px 2px #00000040}.frame.hover{border-color:var(--accent-dim)}.frame.drop{border-color:var(--accent);background:color-mix(in srgb, var(--accent) 10%, transparent);border-style:dashed;border-width:2.5px}.frame.drop .frame__title{color:var(--accent);border-color:var(--accent)}.cv__droplabel{z-index:9;background:var(--accent);color:#fff;pointer-events:none;white-space:nowrap;border-radius:999px;padding:3px 9px;font-size:11px;font-weight:600;position:absolute;transform:translate(14px,14px);box-shadow:0 2px 8px #00000040}.node.hot [data-field],.text-el.hot,.frame__title.hot{cursor:text;border-radius:4px;transition:background .1s}.node.hot [data-field]:hover,.frame__title.hot:hover{background:color-mix(in srgb, var(--accent) 14%, transparent);box-shadow:0 0 0 3px color-mix(in srgb, var(--accent) 14%, transparent)}.node.hot .node__sum{min-height:18px}.node__ph{color:var(--text-faint);font-style:italic;font-weight:400}.node__kind{vertical-align:-2px;color:var(--text-muted);margin-right:5px;display:inline-block}.node__kind svg{display:block}.node.ink-light .node__kind{color:inherit;opacity:.8}.node.sticky{color:#1f1d1a;white-space:pre-wrap;word-break:break-word;border:0;border-radius:4px;width:176px;height:176px;padding:26px 14px 14px;font-size:14px;line-height:1.4;overflow:visible;box-shadow:2px 3px 8px #00000038}.node.sticky .node__lbl{white-space:pre-wrap;-webkit-line-clamp:unset;max-height:100%;font-weight:500;display:block;overflow:hidden}.sticky-yellow{background:#f6e27a}.sticky-pink{background:#f5b6c8}.sticky-blue{background:#a9d4f5}.sticky-green{background:#b8e6b0}.sticky-purple{background:#d3c1f2}.sticky-orange{background:#f7c48b}.node__bar{background:var(--node-color);border-radius:3px;width:3px;position:absolute;top:8px;bottom:8px;left:0}.node.pill .node__bar,.node.parallelogram .node__bar{display:none}.node.pill.highlighted,.node.parallelogram.highlighted{border-left-width:5px}.node.parallelogram.highlighted{padding-left:16px}.node__lbl{white-space:nowrap;text-overflow:ellipsis;font-weight:600;overflow:hidden}.node__lbl a{color:inherit}.node__sum{color:var(--text-muted);-webkit-line-clamp:3;-webkit-box-orient:vertical;flex:1;min-height:0;margin-top:2px;font-size:12px;display:-webkit-box;overflow:hidden}.node.sticky{display:block}.node__tags{white-space:nowrap;gap:4px;display:flex;position:absolute;bottom:8px;left:13px;right:13px;overflow:hidden}.node__tags span{border:1px solid var(--border);color:var(--text-muted);border-radius:999px;flex-shrink:0;padding:0 6px;font-size:10px}.node__grip{background:var(--bg);border:2px solid var(--accent);z-index:3;border-radius:2px;width:9px;height:9px;display:none;position:absolute}.node.selected:not(.locked) .node__grip,.text-el.selected:not(.locked) .node__grip{display:block}.node__grip.nw{cursor:nwse-resize;top:-5px;left:-5px}.node__grip.ne{cursor:nesw-resize;top:-5px;right:-5px}.node__grip.sw{cursor:nesw-resize;bottom:-5px;left:-5px}.node__grip.se{cursor:nwse-resize;bottom:-5px;right:-5px}.node.boxed .node__sum{-webkit-line-clamp:unset;flex:1;min-height:0;display:block;overflow:auto}.node.boxed.sticky .node__lbl,.node.boxed.annotation .node__lbl{max-height:100%;overflow:auto}.text-el.boxed{width:auto;max-width:none;overflow:visible}.text-el.boxed .text-el__body{width:100%;height:100%;overflow:auto}.node__handle{background:var(--accent);border:2px solid var(--bg);cursor:crosshair;opacity:0;z-index:2;border-radius:50%;width:12px;height:12px;transition:opacity .12s;position:absolute}.node__handle--top{margin-left:-6px;top:-7px;left:50%}.node__handle--bottom{margin-left:-6px;bottom:-7px;left:50%}.node__handle--left{margin-top:-6px;top:50%;left:-7px}.node__handle--right{margin-top:-6px;top:50%;right:-7px}.node:hover .node__handle,.node.selected .node__handle,.text-el:hover .node__handle,.text-el.selected .node__handle{opacity:1}.node.locked .node__handle,.text-el.locked .node__handle{display:none}.node__lock{width:18px;height:18px;color:var(--text-faint);background:color-mix(in srgb, var(--bg) 70%, transparent);cursor:pointer;border-radius:4px;justify-content:center;align-items:center;display:flex;position:absolute;top:6px;right:7px}.node__lock:hover{color:var(--text);background:var(--bg-hover)}.node__open{width:18px;height:18px;color:var(--text-faint);background:color-mix(in srgb, var(--bg) 70%, transparent);cursor:pointer;border-radius:4px;justify-content:center;align-items:center;display:none;position:absolute;top:6px;right:27px}.node__open:hover{color:var(--text)}.node:hover .node__open{display:flex}.node__more{width:18px;height:18px;color:var(--text-faint);background:color-mix(in srgb, var(--bg) 70%, transparent);cursor:pointer;border-radius:4px;justify-content:center;align-items:center;display:none;position:absolute;top:6px;right:7px}.node__more svg{width:12px;height:12px}.node__more:hover{color:var(--text);background:var(--bg-hover)}.node:hover .node__more,.node.selected .node__more{display:flex}.node.locked .node__more{right:27px}.node.sticky .node__more,.node.annotation .node__more{top:6px;right:6px}.node.sticky.locked .node__more{right:26px}.frame__title .lock{cursor:pointer}.node__lock svg{width:11px;height:11px}.node.hot .node__lbl{padding-right:20px}.node.sticky .node__lock{color:#00000080;background:#ffffff59}.frame__title .lock{vertical-align:-2px;margin-left:6px;display:inline-flex}.frame__title .lock svg{width:10px;height:10px}.text-el{white-space:pre-wrap;word-break:break-word;width:max-content;min-width:40px;max-width:360px;color:var(--text);cursor:move;border:1px solid #0000;border-radius:6px;padding:4px 6px;line-height:1.3;position:absolute}.text-el:hover{border-color:var(--border)}.text-el.selected{outline:2px solid var(--accent);outline-offset:1px}.text-el.locked{cursor:default}.text-small{color:var(--text-muted);font-size:14px}.text-medium{font-size:20px;font-weight:500}.text-large{letter-spacing:-.01em;font-size:32px;font-weight:600}.ghost{border:1.5px dashed var(--accent);background:color-mix(in srgb, var(--accent) 8%, transparent);pointer-events:none;color:var(--accent);border-radius:9px;justify-content:center;align-items:center;font-size:12px;display:flex;position:absolute}.ghost--sticky{border-radius:4px}.ghost--text{justify-content:flex-start;padding-left:6px}.cv__edit{z-index:8;position:absolute}.cv__edit textarea,.cv__edit input{width:100%;height:100%;font:inherit;border:2px solid var(--accent);background:var(--bg-raised);color:var(--text);resize:none;border-radius:9px;outline:none;padding:9px 13px;font-size:13px;line-height:1.35}.cv__edit.sticky{border-radius:4px}.cv__edit.sticky textarea{color:#1f1d1a;background:inherit;border-radius:4px;padding:14px;font-size:14px;line-height:1.4}.cv__edit.text textarea{background:var(--bg);border-radius:6px;padding:4px 6px;line-height:1.3}.cv__edit.text.text-small textarea{font-size:14px}.cv__edit.text.text-medium textarea{font-size:20px;font-weight:500}.cv__edit.text.text-large textarea{font-size:32px;font-weight:600}.cv__edit.frame input{text-transform:uppercase;letter-spacing:.04em;border-radius:6px;width:auto;min-width:120px;height:auto;padding:2px 8px;font-size:11px;font-weight:600}.cv__edit.field textarea{background:var(--bg);border-width:1.5px;border-radius:5px;padding:2px 4px}.cv__edit.field-label textarea{white-space:nowrap;font-weight:600;overflow:hidden}.cv__edit.field-summary textarea{color:var(--text-muted);font-size:12px}.pin{background:var(--accent);color:#fff;border:2px solid var(--bg);cursor:pointer;z-index:3;border-radius:14px 14px 14px 3px;justify-content:center;align-items:center;width:28px;height:28px;margin:-28px 0 0 -2px;font-size:10px;font-weight:700;display:flex;position:absolute;box-shadow:0 2px 6px #0000004d}.pin:hover,.pin.open{transform:scale(1.12)}.pin.resolved{background:var(--text-faint);opacity:.55}.pin.resolved:hover,.pin.resolved.open{opacity:.9}.thread--resolved .thread__list{opacity:.7}.thread{z-index:9;background:var(--bg);border:1px solid var(--border);width:360px;box-shadow:var(--shadow);border-radius:12px;padding:10px 12px;font-size:13px;position:absolute}.thread__head{align-items:center;gap:4px;margin-bottom:8px;display:flex}.thread__head strong{text-transform:uppercase;letter-spacing:.06em;color:var(--text-faint);flex:1;font-size:12px}.thread__list{max-height:260px;margin-bottom:8px;overflow:hidden auto}.thread__row{align-items:flex-start;gap:8px;margin-bottom:8px;display:flex}.thread__row:last-child{margin-bottom:0}.thread__row textarea{resize:none;width:100%;padding:6px 9px}.thread__field{flex:1;min-width:0;position:relative}.thread__suggest{z-index:2;background:var(--bg-raised);border:1px solid var(--border);box-shadow:var(--shadow);border-radius:8px;padding:4px;position:absolute;top:calc(100% + 4px);left:0;right:0}.thread__suggest button{text-align:left;background:0 0;border:0;border-radius:5px;gap:8px;width:100%;padding:5px 8px;font-size:12px;display:flex}.thread__suggest button:hover{background:var(--bg-hover)}.mention{color:var(--accent);font-weight:600}.thread__avatar{background:var(--accent-soft);width:24px;height:24px;color:var(--accent);border-radius:50%;flex-shrink:0;justify-content:center;align-items:center;font-size:10px;font-weight:700;display:flex}.thread__msg{white-space:pre-wrap;word-break:break-word;flex:1;min-width:0}.thread__meta{align-items:baseline;gap:8px;min-width:0;margin-bottom:1px;font-size:12px;display:flex}.thread__meta b{white-space:nowrap;text-overflow:ellipsis;overflow:hidden}.thread__tools{opacity:0;gap:2px;margin-left:auto;display:inline-flex}.thread__row:hover .thread__tools{opacity:1}.thread__tools button.icon{width:22px;height:22px}.thread__tools button.icon svg{width:12px;height:12px}.thread__avatar[title]{cursor:help}.thread__actions{align-items:center;gap:6px;margin-top:6px;font-size:11px;display:flex}.thread__actions .faint{flex:1}.thread__card{cursor:pointer;border:1px solid #0000;border-radius:8px;padding:8px 8px 6px}.thread__card:hover{background:var(--bg-hover);border-color:var(--border)}.thread__card.resolved{opacity:.65}.thread__text{-webkit-line-clamp:3;-webkit-box-orient:vertical;display:-webkit-box;overflow:hidden}.cv__toolbar{z-index:6;background:var(--bg-raised);border:1px solid var(--border);box-shadow:var(--shadow);border-radius:12px;align-items:center;gap:2px;padding:4px;display:flex;position:absolute;bottom:16px;left:50%;transform:translate(-50%)}.cv__toolbar button{width:40px;height:38px;color:var(--text-muted);background:0 0;border:0;border-radius:8px;justify-content:center;align-items:center;padding:0;display:flex;position:relative}.cv__toolbar button:hover{background:var(--bg-hover);color:var(--text)}.cv__toolbar button.on{background:var(--accent);color:#fff}.cv__toolbar button.temp{background:var(--accent-soft);color:var(--text)}.cv__toolbar button.locked:before{content:"";width:6px;height:6px;box-shadow:0 0 0 1.5px var(--accent);background:#fff;border-radius:50%;position:absolute;top:4px;left:4px}.cv__toolbar button.locked:not(.on):before{background:var(--accent);box-shadow:none}.cv__toolbar button kbd{color:inherit;background:color-mix(in srgb, currentColor 14%, transparent);opacity:.9;border:0;border-radius:3px;padding:1px 3px;font-size:9.5px;font-weight:600;line-height:1;position:absolute;bottom:2px;right:3px}.cv__toolbar button[data-tip]:hover:after{white-space:pre-line;text-align:center;width:max-content;max-width:260px}.cv__toolbar-sep{background:var(--border);width:1px;height:22px;margin:0 4px}.cv__top{z-index:5;flex-wrap:wrap;align-items:center;gap:8px;display:flex;position:absolute;top:12px}.cv__top--right{right:14px}.cv__top .group{background:var(--bg-raised);border:1px solid var(--border);border-radius:9px;align-items:center;gap:2px;padding:3px;display:flex}.cv__top .group button{color:var(--text-muted);background:0 0;border:0;border-radius:6px;align-items:center;gap:5px;min-height:28px;padding:4px 10px;display:inline-flex}.cv__top .group button.on{background:var(--accent-soft);color:var(--text)}.cv__top .group button:hover:not(:disabled){background:var(--bg-hover);color:var(--text)}.cv__top .group button:disabled{opacity:.4}.cv__top .group .count{background:var(--accent);color:#fff;border-radius:999px;padding:0 5px;font-size:10px;line-height:15px}.cv__pages{z-index:6;background:var(--bg-raised);border:1px solid var(--border);border-radius:10px;width:220px;font-size:13px;position:absolute;top:12px;left:14px;box-shadow:0 4px 16px #0000001f}.cv__pages-head{align-items:center;gap:4px;padding:6px 6px 6px 4px;display:flex;position:relative}.cv__pages-title{white-space:nowrap;text-overflow:ellipsis;cursor:text;border-radius:5px;flex:1;min-width:0;padding:2px 4px;font-weight:600;overflow:hidden}.cv__pages-title.editing{padding:2px 6px;font-weight:600}.cv__pages-list{border-top:1px solid var(--border);max-height:40vh;padding:4px 6px 6px;overflow:hidden auto}.cv__pages-label{text-transform:uppercase;letter-spacing:.08em;color:var(--text-faint);justify-content:space-between;align-items:center;padding:2px 4px 2px 8px;font-size:10px;display:flex}.cv__page{cursor:pointer;color:var(--text-muted);border-radius:6px;align-items:center;gap:6px;padding:4px 4px 4px 8px;display:flex;position:relative}.cv__page:hover{background:var(--bg-hover);color:var(--text)}.cv__page.on{background:var(--accent-soft);color:var(--text)}.cv__page-title{white-space:nowrap;text-overflow:ellipsis;flex:1;min-width:0;overflow:hidden}.cv__page-title.editing{padding:1px 6px}.cv__page-more{opacity:0}.cv__page:hover .cv__page-more,.cv__page.on .cv__page-more{opacity:1}.cv__br{z-index:5;align-items:center;gap:6px;display:flex;position:absolute;bottom:16px;right:14px}.cv__zoom{background:var(--bg-raised);border:1px solid var(--border);border-radius:9px;gap:2px;padding:3px;display:flex}.cv__zoom button{color:var(--text-muted);background:0 0;border:0;border-radius:6px;min-width:34px;padding:4px 9px}.cv__zoom button:hover{background:var(--bg-hover);color:var(--text)}.cv__corner{z-index:5;align-items:flex-end;gap:6px;display:flex;position:absolute;bottom:16px;left:14px}.cv__help{width:32px;height:32px;color:var(--text-muted);border-radius:9px;justify-content:center;align-items:center;padding:0;font-size:12px;display:inline-flex}.cv__help.on{background:var(--accent-soft);color:var(--text);border-color:var(--accent)}.cv__legend-wrap{flex-direction:column;align-items:flex-start;gap:6px;display:flex}.cv__legend{color:var(--text-muted);background:var(--bg-raised);border:1px solid var(--border);max-width:320px;box-shadow:var(--shadow);border-radius:9px;flex-wrap:wrap;gap:6px 12px;padding:8px 12px;font-size:12px;display:flex}.cv__prefs{z-index:7;background:var(--bg-raised);border:1px solid var(--border);width:340px;box-shadow:var(--shadow);border-radius:10px;padding:10px 12px;position:absolute;bottom:56px;right:14px}.cv__prefs-foot{border-top:1px solid var(--border);justify-content:flex-end;align-items:center;gap:8px;margin-top:8px;padding-top:8px;font-size:12px;display:flex}.cv__pop{z-index:9;background:var(--bg-raised);border:1px solid var(--border);width:360px;max-height:calc(100% - 16px);box-shadow:var(--shadow);border-radius:12px;flex-direction:column;font-size:13px;display:flex;position:absolute}.cv__pop-head{border-bottom:1px solid var(--border);align-items:center;gap:8px;padding:8px 8px 8px 12px;display:flex}.cv__pop-head strong{white-space:nowrap;text-overflow:ellipsis;flex:1;min-width:0;overflow:hidden}.cv__pop-body{padding:4px 12px 10px;overflow:auto}.cv__pop-sec{border-bottom:1px solid var(--border);padding:8px 0}.cv__pop-sec:last-child{border-bottom:0}.cv__pop-sec-h{text-transform:uppercase;letter-spacing:.08em;color:var(--text-faint);justify-content:space-between;align-items:center;gap:8px;margin-bottom:6px;font-size:10px;display:flex}.cv__pop-grid{grid-template-columns:112px 1fr;align-items:center;gap:6px 10px;display:grid}.cv__pop-grid label{color:var(--text-muted);white-space:nowrap;text-overflow:ellipsis;font-size:12px;overflow:hidden}.cv__pop-grid input,.cv__pop-grid select,.cv__pop-grid textarea{padding:4px 8px;font-size:13px}.cv__pop-grid select,.cv__pop-grid .select{width:100%}.cv__pop-foot{align-items:center;gap:6px;margin-top:8px;display:flex}.cv__pop .swatches{flex-wrap:wrap}.seg{border:1px solid var(--border);border-radius:7px;width:max-content;display:inline-flex;overflow:hidden}.cv__pop-grid .seg{justify-self:start}.seg button{text-align:center;min-width:34px;color:var(--text-muted);background:0 0;border:0;border-radius:0;flex:none;padding:3px 10px;font-size:12px}.seg button+button{border-left:1px solid var(--border)}.seg button.on{background:var(--accent-soft);color:var(--text)}.cv__selbar{z-index:8;background:var(--bg-raised);border:1px solid var(--border);box-shadow:var(--shadow);white-space:nowrap;border-radius:10px;align-items:center;gap:2px;padding:3px 4px;font-size:12px;display:flex;position:absolute;transform:translate(-50%,-100%)}.cv__selbar button.icon{border-color:#0000;width:28px;height:28px}.cv__selbar button.icon.on{background:var(--accent-soft);color:var(--text)}.cv__selbar button.small{border-color:#0000}.cv__selbar .seg{margin:0 2px}.cv__selbar .seg button{min-width:28px;padding:3px 8px}.cv__selbar .swatches{gap:4px;margin:0 4px}.cv__selbar .swatch-btn{border-radius:5px;width:18px;height:18px}.cv__selbar-sep{background:var(--border);width:1px;height:18px;margin:0 4px}.cv__selbar-style{border:1px solid #0000;border-radius:7px;align-items:center;gap:6px;padding:3px 8px;display:inline-flex}.cv__selbar-style .swatch{border:1.5px solid var(--border-strong);width:12px;height:12px;margin:0}.cv__chev{transition:transform .12s;display:inline-flex}.cv__chev.open{transform:rotate(180deg)}.cv__stylepop--anchored{white-space:normal;top:-8px;left:0;transform:translateY(-100%)}.cv__stylepop{z-index:9;background:var(--bg-raised);border:1px solid var(--border);width:400px;box-shadow:var(--shadow);border-radius:12px;padding:8px 12px 10px;font-size:13px;position:absolute}.cv__stylepop .cv__pop-grid{grid-template-columns:108px 1fr}.cv__stylepop .cv__pop-grid select,.cv__stylepop .cv__pop-grid .select{width:auto;max-width:100%}.cv__stylepop .cv__pop-grid input[type=number]{padding:3px 6px}.cv__stylepop input[type=range]{background:0 0;border:0;width:100%;padding:0}.colors{flex-wrap:nowrap;align-items:center;gap:3px;display:flex}.colors__swatch{border:2px solid #0000;border-radius:50%;flex:none;width:16px;height:16px;padding:0;box-shadow:inset 0 0 0 1px #0000001f}.colors__swatch:hover{z-index:5;transform:scale(1.15)}.colors__swatch.on{border-color:var(--text)}.colors__pick{border:1px dashed var(--border-strong);cursor:pointer;border-radius:6px;flex:none;justify-content:center;align-items:center;width:20px;height:20px;margin-left:2px;display:inline-flex;position:relative}.colors__pick .swatch{border-radius:50%;width:11px;height:11px;margin:0}.colors__pick input{opacity:0;cursor:pointer;width:100%;height:100%;position:absolute;inset:0}.colors>button.quiet.small{white-space:nowrap;padding:1px 5px}.cv__svg path.navrange{fill:color-mix(in srgb, var(--accent) 10%, transparent);stroke:var(--accent);stroke-width:1px;stroke-dasharray:5 4;vector-effect:non-scaling-stroke;pointer-events:none}.cap-picker{display:inline-block;position:relative}.cap-picker>button{align-items:center;gap:4px;padding:2px 6px;display:inline-flex}.cap-picker svg{width:34px;height:16px}.cap-menu{z-index:12;background:var(--bg-raised);border:1px solid var(--border);box-shadow:var(--shadow);border-radius:9px;grid-template-columns:repeat(4,1fr);gap:2px;padding:4px;display:grid;position:absolute;top:calc(100% + 4px);left:0}.cap-menu button{border-color:#0000;justify-content:center;align-items:center;width:44px;height:30px;padding:0;display:inline-flex}.cap-menu button.on{background:var(--accent-soft);border-color:var(--accent)}.cv__svg path.cap{pointer-events:none}.cv__edit.edge input{text-align:center;border-radius:6px;width:auto;min-width:100px;height:auto;padding:2px 8px;font-size:11px}a.btn{background:var(--bg-raised);border:1px solid var(--border);color:var(--text);border-radius:7px;align-items:center;gap:6px;padding:5px 11px;font-size:13px;line-height:1.3;text-decoration:none;display:inline-flex}a.btn:hover{border-color:var(--border-strong);background:var(--bg-hover);text-decoration:none}.cv__prefs-head{justify-content:space-between;align-items:center;margin-bottom:6px;display:flex}.cv__prefs-head strong{text-transform:uppercase;letter-spacing:.06em;color:var(--text-faint);font-size:12px}.cv__pref{cursor:pointer;border-radius:6px;align-items:flex-start;gap:10px;padding:6px 4px;display:flex}.cv__pref:hover{background:var(--bg-hover)}.cv__pref input{width:auto;margin-top:3px}.cv__pref span{flex-direction:column;gap:2px;font-size:13px;display:flex}.cv__pref small{color:var(--text-faint);font-size:11px;line-height:1.35}.cv__panel{z-index:6;background:var(--bg);border-left:1px solid var(--border);width:380px;max-width:100%;box-shadow:var(--shadow);flex-direction:column;display:flex;position:absolute;top:0;bottom:0;right:0}.cv__panel .head{border-bottom:1px solid var(--border);align-items:center;gap:8px;padding:10px 14px;display:flex}.cv__panel .head strong{white-space:nowrap;text-overflow:ellipsis;flex:1;min-width:0;overflow:hidden}.cv__panel .body{flex:1;padding:14px;overflow:auto}.cv__panel--comments{width:320px}.cv__toggle{color:var(--text-muted);align-items:center;gap:8px;margin:8px 0;font-size:13px;display:flex}.cv__toggle input{width:auto}.swatches{gap:6px;display:flex}.swatch-btn{border:2px solid #0000;border-radius:6px;width:22px;height:22px;padding:0}.swatch-btn.on{border-color:var(--text)}.swatch-btn.frame-none{background:var(--bg-sunken);border-color:var(--border)}.swatch-btn.frame-sand{background:#e0a986}.swatch-btn.frame-sky{background:#8fb7ea}.swatch-btn.frame-mint{background:#8fd0b4}.swatch-btn.frame-rose{background:#e2968a}.swatch-btn.frame-lilac{background:#bfaaf0}.cv__hint{z-index:5;color:var(--text-faint);pointer-events:none;background:color-mix(in srgb, var(--bg) 85%, transparent);white-space:nowrap;border-radius:6px;padding:2px 8px;font-size:11px;position:absolute;bottom:66px;left:50%;transform:translate(-50%)}.cv__menu{z-index:20;white-space:nowrap;background:var(--bg-raised);border:1px solid var(--border);min-width:260px;box-shadow:var(--shadow);border-radius:9px;padding:4px;position:absolute}.cv__menu button{text-align:left;background:0 0;border:0;border-radius:6px;align-items:center;gap:12px;width:100%;padding:6px 10px;font-size:13px;display:flex}.cv__menu button span{flex:1;padding-right:16px}.cv__menu button:hover:not(:disabled){background:var(--bg-hover)}.cv__menu button .keys kbd{min-width:18px;color:var(--text-muted);background:0 0;padding:0 4px;font-size:11px}.cv__menu button:disabled{opacity:.4}.cv__menu i{background:var(--border);height:1px;margin:4px 6px;display:block}.cv__sheet-h{text-transform:uppercase;letter-spacing:.08em;color:var(--text-faint);margin:14px 0 6px;font-size:11px}@media (width<=1000px){.shell{grid-template-columns:1fr}.sidebar{z-index:50;width:280px;box-shadow:var(--shadow);transition:transform .16s;position:fixed;top:0;bottom:0;left:0;transform:translate(-100%)}.sidebar.open{transform:none}.shell__menu{display:flex}.shell.drawer-open .shell__scrim{display:block}.page__head{padding-left:44px}.cv__pages{left:54px}}@media (width<=800px){.reader{grid-template-columns:1fr}.doc--rail{grid-template-columns:minmax(0,1fr)}.doc__rail{position:static}.reader__props{border-right:0;border-bottom:1px solid var(--border)}}
|