eidosmd 0.2.0 → 0.3.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/browser/dist/assets/index-Cc3cNWHY.css +1 -0
- package/browser/dist/assets/index-DQgCQRa5.js +46 -0
- package/browser/dist/index.html +2 -2
- package/dist/src/commands/check.js +9 -3
- package/dist/src/commands/configure.js +201 -0
- package/dist/src/commands/framework.js +15 -4
- package/dist/src/commands/init.js +4 -0
- package/dist/src/commands/property.js +125 -0
- package/dist/src/commands/setup.js +24 -12
- package/dist/src/commands/version.js +2 -2
- package/dist/src/core/canvas.js +59 -49
- package/dist/src/core/check.js +101 -26
- package/dist/src/core/edits.js +1381 -0
- package/dist/src/core/framework-markdown.js +9 -3
- package/dist/src/core/framework-model.js +43 -8
- package/dist/src/core/framework-structured.js +104 -28
- package/dist/src/core/frontmatter.js +61 -1
- package/dist/src/core/git.js +28 -3
- package/dist/src/core/links.js +87 -0
- package/dist/src/core/markdown.js +16 -9
- package/dist/src/core/migrate.js +91 -15
- package/dist/src/core/regions.js +117 -0
- package/dist/src/core/scaffold.js +15 -9
- package/dist/src/core/seed.js +56 -31
- package/dist/src/core/server.js +204 -31
- package/dist/src/core/settings.js +63 -12
- package/dist/src/core/store.js +73 -17
- package/dist/src/core/versions.js +10 -5
- package/dist/src/program.js +296 -11
- package/instructions/authoring.md +4 -2
- package/instructions/configuring.md +27 -11
- package/instructions/overview.md +6 -4
- package/instructions/validating.md +6 -4
- package/package.json +1 -1
- package/standard/EIDOS.md +135 -193
- package/standard/seeds/README.md +12 -16
- package/standard/seeds/book/Framework.yaml +30 -50
- package/standard/seeds/book/README.md +2 -1
- package/standard/seeds/book/_gitignore +7 -1
- package/standard/seeds/research/Framework.yaml +30 -50
- package/standard/seeds/research/README.md +2 -1
- package/standard/seeds/research/_gitignore +7 -1
- package/standard/seeds/software/Framework.yaml +31 -51
- package/standard/seeds/software/README.md +2 -1
- package/standard/seeds/software/_gitignore +7 -1
- package/browser/dist/assets/index-C2NMN_D4.css +0 -1
- package/browser/dist/assets/index-C65k1ihb.js +0 -46
|
@@ -1,40 +1,31 @@
|
|
|
1
|
-
# The framework document: the structure this root is written in
|
|
2
|
-
#
|
|
3
|
-
# table, the Vocabulary, and, once blueprints exist, the generated index. The visible
|
|
4
|
-
# README.md at the root is the friendly door to it; keep it current with the `eidos` CLI.
|
|
1
|
+
# The framework document: the structure this root is written in. See EIDOS.md for what each key means;
|
|
2
|
+
# the `eidos` CLI edits this file. Every path is relative to this folder.
|
|
5
3
|
|
|
6
|
-
|
|
7
|
-
eidos_version: 5.0.0
|
|
4
|
+
eidos_version: 5.3.0
|
|
8
5
|
|
|
9
|
-
#
|
|
10
|
-
# governs the whole root and changing it later means renaming files, so it is settled at install.
|
|
6
|
+
# kebab-case | TitleCase | Title Case. Settled at install; changing it later means renaming files.
|
|
11
7
|
naming: kebab-case
|
|
12
8
|
|
|
13
|
-
#
|
|
14
|
-
# book, a Style Sheet, a Bibliography), each a title, a path from this folder, and a one-line
|
|
15
|
-
# description. The framing docs live in the framing collection, not here. The `eidos` CLI refreshes
|
|
16
|
-
# this list.
|
|
9
|
+
# Every file at the root, one entry each.
|
|
17
10
|
top_level:
|
|
18
11
|
- title: README
|
|
19
12
|
path: ../README.md
|
|
20
13
|
description: "the root's front door: what this book is, and pointers in."
|
|
21
14
|
|
|
22
|
-
#
|
|
23
|
-
|
|
24
|
-
#
|
|
25
|
-
# <unit>.<variant>.md under templates/, the unit being the word for one of its blueprints) and its grouping.
|
|
26
|
-
collections:
|
|
27
|
-
# This framework's framing collection: the docs that set what every other blueprint is judged
|
|
28
|
-
# against. Each frame follows the variant of its kind, and one left unwritten is a gap to surface,
|
|
15
|
+
# Every folder at the root, one entry each, with its type: collection | assets | other.
|
|
16
|
+
folders:
|
|
17
|
+
# The framing docs: what every other blueprint is judged against. One left unwritten is a gap to surface,
|
|
29
18
|
# not a failure.
|
|
30
19
|
- name: Frames
|
|
31
|
-
|
|
20
|
+
type: collection
|
|
21
|
+
description: "What every chapter is judged against: what the book argues, who it is for, how it sounds, and where it sits."
|
|
32
22
|
variants:
|
|
33
23
|
- { name: premise, template: templates/frame.premise.md, description: "what the book says, and why it has to exist", default: true }
|
|
34
24
|
- { name: reader, template: templates/frame.reader.md, description: "who it is for, and what changes for them" }
|
|
35
25
|
- { name: voice, template: templates/frame.voice.md, description: "person, tense, register, and the rules the prose keeps" }
|
|
36
26
|
- { name: market, template: templates/frame.market.md, description: "shelf, comparables, and how it reaches readers" }
|
|
37
27
|
- name: Chapters
|
|
28
|
+
type: collection
|
|
38
29
|
description: "The book's units, one per chapter, grouped by part."
|
|
39
30
|
variants:
|
|
40
31
|
- { name: full, template: templates/chapter.full.md, description: "the complete chapter template", default: true }
|
|
@@ -42,40 +33,29 @@ collections:
|
|
|
42
33
|
grouping:
|
|
43
34
|
label: Parts
|
|
44
35
|
property: part
|
|
45
|
-
#
|
|
46
|
-
|
|
36
|
+
groups: [] # one entry per part, a name and a description, as they accrue
|
|
37
|
+
- name: assets
|
|
38
|
+
type: assets
|
|
39
|
+
description: "Images, diagrams, and documents the blueprints link to."
|
|
47
40
|
|
|
48
|
-
# The property contract
|
|
49
|
-
#
|
|
50
|
-
# a tools.<tool> block for any tool that declares properties of its own (none ship with a seed). Every
|
|
51
|
-
# custom property declares which collections it applies to, `all` or a list, so a property never lands
|
|
52
|
-
# where it makes no sense (part is Chapters-only). A type comes from the Obsidian set (Text, List,
|
|
53
|
-
# Number, Checkbox, Date, Date & time), so frontmatter renders natively in a vault. The `eidos` CLI
|
|
54
|
-
# edits the custom block.
|
|
41
|
+
# The property contract, one block per owner. A property applies to `all` collections or a list; a required
|
|
42
|
+
# one is generated into every new blueprint and surfaced when missing; `options` closes the value to a set.
|
|
55
43
|
properties:
|
|
56
|
-
#
|
|
57
|
-
# version change, so don't hand-edit it. variant absent = the collection's default; a missing summary
|
|
58
|
-
# is flagged by the index.
|
|
44
|
+
# The standard's. migrate rewrites this block; don't hand-edit it.
|
|
59
45
|
core:
|
|
60
|
-
- { name: id, type: Text, meaning: "Stable, unique identity, in any form
|
|
61
|
-
- { name: title, type: Text, meaning: "Human-readable name." }
|
|
62
|
-
- { name: summary, type: Text, meaning: "One
|
|
63
|
-
- { name: variant, type: Text, meaning: "Which
|
|
64
|
-
# Yours
|
|
65
|
-
# them, Eidos doesn't depend on them. Absence where a property applies is a soft gap a check notes,
|
|
66
|
-
# never refuses.
|
|
46
|
+
- { name: id, type: Text, required: true, meaning: "Stable, unique identity, in any form. Assigned once, never changed." }
|
|
47
|
+
- { name: title, type: Text, required: true, meaning: "Human-readable name." }
|
|
48
|
+
- { name: summary, type: Text, meaning: "One line: what this blueprint is. Feeds the index; absent, the index flags it." }
|
|
49
|
+
- { name: variant, type: Text, meaning: "Which variant this blueprint follows. Absent = the collection's default." }
|
|
50
|
+
# Yours. The seed ships defaults; keep, scope, or drop any of them. Only the grouping is required.
|
|
67
51
|
custom:
|
|
68
|
-
- { name: status, type: Text, applies_to: all,
|
|
69
|
-
- { name: date_created, type: Date, applies_to: all, meaning: "YYYY-MM-DD.
|
|
70
|
-
- { name: date_modified, type: Date, applies_to: all, meaning: "YYYY-MM-DD. The
|
|
52
|
+
- { name: status, type: Text, applies_to: all, options: [Draft, Outlined, Drafted, Revised, Final, Cut], meaning: "Lifecycle stage." }
|
|
53
|
+
- { name: date_created, type: Date, applies_to: all, meaning: "YYYY-MM-DD. Set once." }
|
|
54
|
+
- { name: date_modified, type: Date, applies_to: all, meaning: "YYYY-MM-DD. The last change." }
|
|
71
55
|
- { name: tags, type: List, applies_to: all, meaning: "Free tags." }
|
|
72
|
-
- { name: part, type: Text, applies_to: [Chapters], meaning: "The
|
|
73
|
-
- { name: depends_on, type: List, applies_to: [Chapters], meaning: "Chapters a reader must have read first, each a markdown link.
|
|
56
|
+
- { name: part, type: Text, required: true, applies_to: [Chapters], meaning: "The group: matches the blueprint's sub-folder. An unknown value warns." }
|
|
57
|
+
- { name: depends_on, type: List, applies_to: [Chapters], meaning: "Chapters a reader must have read first, each a markdown link." }
|
|
74
58
|
|
|
75
|
-
# The
|
|
76
|
-
#
|
|
77
|
-
# thing); `see` points at the blueprint that defines the term in full. Eidos declares none of these; the
|
|
78
|
-
# list starts empty and grows an entry when a word begins to carry a distinction worth keeping.
|
|
79
|
-
# The `eidos` CLI edits it and presses for all three of term, means, and not.
|
|
59
|
+
# The root's own terms: term, means, not (the near-misses and why), and see (the blueprint that defines it).
|
|
60
|
+
# Starts empty; Eidos declares none.
|
|
80
61
|
vocabulary: []
|
|
81
|
-
|
|
@@ -9,12 +9,13 @@
|
|
|
9
9
|
|
|
10
10
|
- **[Frames](Frames/)** — what the book argues, who reads it, how it sounds, where it sits.
|
|
11
11
|
- **[Chapters](Chapters/)** — one file per chapter, grouped by part.
|
|
12
|
+
- **[assets](assets/)** — images, diagrams, and documents the blueprints link to.
|
|
12
13
|
|
|
13
14
|
## Top-level documents
|
|
14
15
|
|
|
15
16
|
_Your own one-of-a-kind docs: an Outline of the whole book, a Style Sheet (spellings, names, hyphenation), a Bibliography. Add them here as you write them._
|
|
16
17
|
|
|
17
|
-
The full index — every
|
|
18
|
+
The full index — every folder, its variants, and the Properties table — is in
|
|
18
19
|
[`.eidos/Framework.yaml`](.eidos/Framework.yaml).
|
|
19
20
|
|
|
20
21
|
## How to use it
|
|
@@ -1,4 +1,10 @@
|
|
|
1
1
|
# Eidos: me.md is personal and never shared.
|
|
2
2
|
# Each person who works on this definition keeps their own me.md (here in .eidos/); the agent reads
|
|
3
|
-
# it to know who they are. It is the one
|
|
3
|
+
# it to know who they are. It is the one file of the standard's own that is not checked in.
|
|
4
4
|
me.md
|
|
5
|
+
|
|
6
|
+
# Eidos: a tool's local.yaml is personal and never shared.
|
|
7
|
+
# A tool that keeps a folder under plugins/ may keep its personal settings there, one machine's (a
|
|
8
|
+
# viewer command, an editor, a key path); everything else in its folder is the root's. This one
|
|
9
|
+
# line covers every tool, so no tool writes a .gitignore of its own.
|
|
10
|
+
plugins/*/local.yaml
|
|
@@ -1,40 +1,31 @@
|
|
|
1
|
-
# The framework document: the structure this root is written in
|
|
2
|
-
#
|
|
3
|
-
# table, the Vocabulary, and, once blueprints exist, the generated index. The visible
|
|
4
|
-
# README.md at the root is the friendly door to it; keep it current with the `eidos` CLI.
|
|
1
|
+
# The framework document: the structure this root is written in. See EIDOS.md for what each key means;
|
|
2
|
+
# the `eidos` CLI edits this file. Every path is relative to this folder.
|
|
5
3
|
|
|
6
|
-
|
|
7
|
-
eidos_version: 5.0.0
|
|
4
|
+
eidos_version: 5.3.0
|
|
8
5
|
|
|
9
|
-
#
|
|
10
|
-
# governs the whole root and changing it later means renaming files, so it is settled at install.
|
|
6
|
+
# kebab-case | TitleCase | Title Case. Settled at install; changing it later means renaming files.
|
|
11
7
|
naming: kebab-case
|
|
12
8
|
|
|
13
|
-
#
|
|
14
|
-
# Management Plan, a Bibliography), each a title, a path from this folder, and a one-line
|
|
15
|
-
# description. The framing docs live in the framing collection, not here. The `eidos` CLI refreshes
|
|
16
|
-
# this list.
|
|
9
|
+
# Every file at the root, one entry each.
|
|
17
10
|
top_level:
|
|
18
11
|
- title: README
|
|
19
12
|
path: ../README.md
|
|
20
13
|
description: "the root's front door: what this programme asks, and pointers in."
|
|
21
14
|
|
|
22
|
-
#
|
|
23
|
-
|
|
24
|
-
#
|
|
25
|
-
# <unit>.<variant>.md under templates/, the unit being the word for one of its blueprints) and its grouping.
|
|
26
|
-
collections:
|
|
27
|
-
# This framework's framing collection: the docs that set what every other blueprint is judged
|
|
28
|
-
# against. Each frame follows the variant of its kind, and one left unwritten is a gap to surface,
|
|
15
|
+
# Every folder at the root, one entry each, with its type: collection | assets | other.
|
|
16
|
+
folders:
|
|
17
|
+
# The framing docs: what every other blueprint is judged against. One left unwritten is a gap to surface,
|
|
29
18
|
# not a failure.
|
|
30
19
|
- name: Frames
|
|
31
|
-
|
|
20
|
+
type: collection
|
|
21
|
+
description: "What every investigation is judged against: what is asked, what is known, what would count as knowing, and who is affected."
|
|
32
22
|
variants:
|
|
33
23
|
- { name: question, template: templates/frame.question.md, description: "what the programme asks, and why it matters", default: true }
|
|
34
24
|
- { name: "prior work", template: templates/frame.prior-work.md, description: "what is already known, and where this sits" }
|
|
35
25
|
- { name: method, template: templates/frame.method.md, description: "how anyone would know, and the standard of evidence" }
|
|
36
26
|
- { name: ethics, template: templates/frame.ethics.md, description: "who is affected, what they consented to, what could go wrong" }
|
|
37
27
|
- name: Investigations
|
|
28
|
+
type: collection
|
|
38
29
|
description: "The programme's units, one per line of inquiry, grouped by strand."
|
|
39
30
|
variants:
|
|
40
31
|
- { name: full, template: templates/investigation.full.md, description: "the complete investigation template", default: true }
|
|
@@ -42,40 +33,29 @@ collections:
|
|
|
42
33
|
grouping:
|
|
43
34
|
label: Strands
|
|
44
35
|
property: strand
|
|
45
|
-
#
|
|
46
|
-
|
|
36
|
+
groups: [] # one entry per strand, a name and a description, as they accrue
|
|
37
|
+
- name: assets
|
|
38
|
+
type: assets
|
|
39
|
+
description: "Images, diagrams, and documents the blueprints link to."
|
|
47
40
|
|
|
48
|
-
# The property contract
|
|
49
|
-
#
|
|
50
|
-
# a tools.<tool> block for any tool that declares properties of its own (none ship with a seed). Every
|
|
51
|
-
# custom property declares which collections it applies to, `all` or a list, so a property never lands
|
|
52
|
-
# where it makes no sense (strand is Investigations-only). A type comes from the Obsidian set (Text, List,
|
|
53
|
-
# Number, Checkbox, Date, Date & time), so frontmatter renders natively in a vault. The `eidos` CLI
|
|
54
|
-
# edits the custom block.
|
|
41
|
+
# The property contract, one block per owner. A property applies to `all` collections or a list; a required
|
|
42
|
+
# one is generated into every new blueprint and surfaced when missing; `options` closes the value to a set.
|
|
55
43
|
properties:
|
|
56
|
-
#
|
|
57
|
-
# version change, so don't hand-edit it. variant absent = the collection's default; a missing summary
|
|
58
|
-
# is flagged by the index.
|
|
44
|
+
# The standard's. migrate rewrites this block; don't hand-edit it.
|
|
59
45
|
core:
|
|
60
|
-
- { name: id, type: Text, meaning: "Stable, unique identity, in any form
|
|
61
|
-
- { name: title, type: Text, meaning: "Human-readable name." }
|
|
62
|
-
- { name: summary, type: Text, meaning: "One
|
|
63
|
-
- { name: variant, type: Text, meaning: "Which
|
|
64
|
-
# Yours
|
|
65
|
-
# them, Eidos doesn't depend on them. Absence where a property applies is a soft gap a check notes,
|
|
66
|
-
# never refuses.
|
|
46
|
+
- { name: id, type: Text, required: true, meaning: "Stable, unique identity, in any form. Assigned once, never changed." }
|
|
47
|
+
- { name: title, type: Text, required: true, meaning: "Human-readable name." }
|
|
48
|
+
- { name: summary, type: Text, meaning: "One line: what this blueprint is. Feeds the index; absent, the index flags it." }
|
|
49
|
+
- { name: variant, type: Text, meaning: "Which variant this blueprint follows. Absent = the collection's default." }
|
|
50
|
+
# Yours. The seed ships defaults; keep, scope, or drop any of them. Only the grouping is required.
|
|
67
51
|
custom:
|
|
68
|
-
- { name: status, type: Text, applies_to: all,
|
|
69
|
-
- { name: date_created, type: Date, applies_to: all, meaning: "YYYY-MM-DD.
|
|
70
|
-
- { name: date_modified, type: Date, applies_to: all, meaning: "YYYY-MM-DD. The
|
|
52
|
+
- { name: status, type: Text, applies_to: all, options: [Draft, Open, Running, Answered, Inconclusive, Abandoned], meaning: "Lifecycle stage." }
|
|
53
|
+
- { name: date_created, type: Date, applies_to: all, meaning: "YYYY-MM-DD. Set once." }
|
|
54
|
+
- { name: date_modified, type: Date, applies_to: all, meaning: "YYYY-MM-DD. The last change." }
|
|
71
55
|
- { name: tags, type: List, applies_to: all, meaning: "Free tags." }
|
|
72
|
-
- { name: strand, type: Text, applies_to: [Investigations], meaning: "The
|
|
73
|
-
- { name: depends_on, type: List, applies_to: [Investigations], meaning: "Investigations, data, or approvals this one needs first, each a markdown link.
|
|
56
|
+
- { name: strand, type: Text, required: true, applies_to: [Investigations], meaning: "The group: matches the blueprint's sub-folder. An unknown value warns." }
|
|
57
|
+
- { name: depends_on, type: List, applies_to: [Investigations], meaning: "Investigations, data, or approvals this one needs first, each a markdown link." }
|
|
74
58
|
|
|
75
|
-
# The
|
|
76
|
-
#
|
|
77
|
-
# thing); `see` points at the blueprint that defines the term in full. Eidos declares none of these; the
|
|
78
|
-
# list starts empty and grows an entry when a word begins to carry a distinction worth keeping.
|
|
79
|
-
# The `eidos` CLI edits it and presses for all three of term, means, and not.
|
|
59
|
+
# The root's own terms: term, means, not (the near-misses and why), and see (the blueprint that defines it).
|
|
60
|
+
# Starts empty; Eidos declares none.
|
|
80
61
|
vocabulary: []
|
|
81
|
-
|
|
@@ -9,12 +9,13 @@
|
|
|
9
9
|
|
|
10
10
|
- **[Frames](Frames/)** — the question, the prior work, the method, the ethics.
|
|
11
11
|
- **[Investigations](Investigations/)** — one file per line of inquiry, grouped by strand.
|
|
12
|
+
- **[assets](assets/)** — images, diagrams, and documents the blueprints link to.
|
|
12
13
|
|
|
13
14
|
## Top-level documents
|
|
14
15
|
|
|
15
16
|
_Your own one-of-a-kind docs: a Pre-registration, a Data Management Plan, a Bibliography. Add them here as you write them._
|
|
16
17
|
|
|
17
|
-
The full index — every
|
|
18
|
+
The full index — every folder, its variants, and the Properties table — is in
|
|
18
19
|
[`.eidos/Framework.yaml`](.eidos/Framework.yaml).
|
|
19
20
|
|
|
20
21
|
## How to use it
|
|
@@ -1,4 +1,10 @@
|
|
|
1
1
|
# Eidos: me.md is personal and never shared.
|
|
2
2
|
# Each person who works on this definition keeps their own me.md (here in .eidos/); the agent reads
|
|
3
|
-
# it to know who they are. It is the one
|
|
3
|
+
# it to know who they are. It is the one file of the standard's own that is not checked in.
|
|
4
4
|
me.md
|
|
5
|
+
|
|
6
|
+
# Eidos: a tool's local.yaml is personal and never shared.
|
|
7
|
+
# A tool that keeps a folder under plugins/ may keep its personal settings there, one machine's (a
|
|
8
|
+
# viewer command, an editor, a key path); everything else in its folder is the root's. This one
|
|
9
|
+
# line covers every tool, so no tool writes a .gitignore of its own.
|
|
10
|
+
plugins/*/local.yaml
|
|
@@ -1,40 +1,31 @@
|
|
|
1
|
-
# The framework document: the structure this root is written in
|
|
2
|
-
#
|
|
3
|
-
# table, the Vocabulary, and, once blueprints exist, the generated index. The visible
|
|
4
|
-
# README.md at the root is the friendly door to it; keep it current with the `eidos` CLI.
|
|
1
|
+
# The framework document: the structure this root is written in. See EIDOS.md for what each key means;
|
|
2
|
+
# the `eidos` CLI edits this file. Every path is relative to this folder.
|
|
5
3
|
|
|
6
|
-
|
|
7
|
-
eidos_version: 5.0.0
|
|
4
|
+
eidos_version: 5.3.0
|
|
8
5
|
|
|
9
|
-
#
|
|
10
|
-
# governs the whole root and changing it later means renaming files, so it is settled at install.
|
|
6
|
+
# kebab-case | TitleCase | Title Case. Settled at install; changing it later means renaming files.
|
|
11
7
|
naming: kebab-case
|
|
12
8
|
|
|
13
|
-
#
|
|
14
|
-
# Principles, the generated Blueprint Map), each a title, a path from this folder, and a one-line
|
|
15
|
-
# description. The framing docs live in the framing collection, not here. The `eidos` CLI refreshes
|
|
16
|
-
# this list.
|
|
9
|
+
# Every file at the root, one entry each.
|
|
17
10
|
top_level:
|
|
18
11
|
- title: README
|
|
19
12
|
path: ../README.md
|
|
20
13
|
description: "the root's front door: what this is, and pointers in."
|
|
21
14
|
|
|
22
|
-
#
|
|
23
|
-
|
|
24
|
-
#
|
|
25
|
-
# <unit>.<variant>.md under templates/, the unit being the word for one of its blueprints) and its grouping.
|
|
26
|
-
collections:
|
|
27
|
-
# This framework's framing collection: the docs that set what every other blueprint is judged
|
|
28
|
-
# against. Each frame follows the variant of its kind, and one left unwritten is a gap to surface,
|
|
15
|
+
# Every folder at the root, one entry each, with its type: collection | assets | other.
|
|
16
|
+
folders:
|
|
17
|
+
# The framing docs: what every other blueprint is judged against. One left unwritten is a gap to surface,
|
|
29
18
|
# not a failure.
|
|
30
19
|
- name: Frames
|
|
31
|
-
|
|
20
|
+
type: collection
|
|
21
|
+
description: "What every other blueprint is judged against: the product's architecture, audience, criteria, and market."
|
|
32
22
|
variants:
|
|
33
23
|
- { name: architecture, template: templates/frame.architecture.md, description: "the product as a built system", default: true }
|
|
34
24
|
- { name: audience, template: templates/frame.audience.md, description: "who it serves, and how each kind differs" }
|
|
35
25
|
- { name: criteria, template: templates/frame.criteria.md, description: "budget, scope objectives, timeline" }
|
|
36
26
|
- { name: market, template: templates/frame.market.md, description: "landscape, positioning, and how it earns" }
|
|
37
27
|
- name: Specs
|
|
28
|
+
type: collection
|
|
38
29
|
description: "The product's units, one per blueprint, grouped by domain."
|
|
39
30
|
variants:
|
|
40
31
|
- { name: full, template: templates/spec.full.md, description: "the complete spec template", default: true }
|
|
@@ -42,41 +33,30 @@ collections:
|
|
|
42
33
|
grouping:
|
|
43
34
|
label: Domains
|
|
44
35
|
property: domain
|
|
45
|
-
#
|
|
46
|
-
|
|
36
|
+
groups: [] # one entry per domain, a name and a description, as they accrue
|
|
37
|
+
- name: assets
|
|
38
|
+
type: assets
|
|
39
|
+
description: "Images, diagrams, and documents the blueprints link to."
|
|
47
40
|
|
|
48
|
-
# The property contract
|
|
49
|
-
#
|
|
50
|
-
# a tools.<tool> block for any tool that declares properties of its own (none ship with a seed). Every
|
|
51
|
-
# custom property declares which collections it applies to, `all` or a list, so a property never lands
|
|
52
|
-
# where it makes no sense (domain is Specs-only). A type comes from the Obsidian set (Text, List,
|
|
53
|
-
# Number, Checkbox, Date, Date & time), so frontmatter renders natively in a vault. The `eidos` CLI
|
|
54
|
-
# edits the custom block.
|
|
41
|
+
# The property contract, one block per owner. A property applies to `all` collections or a list; a required
|
|
42
|
+
# one is generated into every new blueprint and surfaced when missing; `options` closes the value to a set.
|
|
55
43
|
properties:
|
|
56
|
-
#
|
|
57
|
-
# version change, so don't hand-edit it. variant absent = the collection's default; a missing summary
|
|
58
|
-
# is flagged by the index.
|
|
44
|
+
# The standard's. migrate rewrites this block; don't hand-edit it.
|
|
59
45
|
core:
|
|
60
|
-
- { name: id, type: Text, meaning: "Stable, unique identity, in any form
|
|
61
|
-
- { name: title, type: Text, meaning: "Human-readable name." }
|
|
62
|
-
- { name: summary, type: Text, meaning: "One
|
|
63
|
-
- { name: variant, type: Text, meaning: "Which
|
|
64
|
-
# Yours
|
|
65
|
-
# them, Eidos doesn't depend on them. Absence where a property applies is a soft gap a check notes,
|
|
66
|
-
# never refuses.
|
|
46
|
+
- { name: id, type: Text, required: true, meaning: "Stable, unique identity, in any form. Assigned once, never changed." }
|
|
47
|
+
- { name: title, type: Text, required: true, meaning: "Human-readable name." }
|
|
48
|
+
- { name: summary, type: Text, meaning: "One line: what this blueprint is. Feeds the index; absent, the index flags it." }
|
|
49
|
+
- { name: variant, type: Text, meaning: "Which variant this blueprint follows. Absent = the collection's default." }
|
|
50
|
+
# Yours. The seed ships defaults; keep, scope, or drop any of them. Only the grouping is required.
|
|
67
51
|
custom:
|
|
68
|
-
- { name: status, type: Text, applies_to: all,
|
|
69
|
-
- { name: date_created, type: Date, applies_to: all, meaning: "YYYY-MM-DD.
|
|
70
|
-
- { name: date_modified, type: Date, applies_to: all, meaning: "YYYY-MM-DD. The
|
|
52
|
+
- { name: status, type: Text, applies_to: all, options: [Draft, Intake, In Progress, Done, Archived, Deprecated], meaning: "Lifecycle stage." }
|
|
53
|
+
- { name: date_created, type: Date, applies_to: all, meaning: "YYYY-MM-DD. Set once." }
|
|
54
|
+
- { name: date_modified, type: Date, applies_to: all, meaning: "YYYY-MM-DD. The last change." }
|
|
71
55
|
- { name: tags, type: List, applies_to: all, meaning: "Free tags." }
|
|
72
|
-
- { name: domain, type: Text, applies_to: [Specs], meaning: "The
|
|
73
|
-
- { name: depends_on, type: List, applies_to: [Specs], meaning: "Blueprints this one needs, each a markdown link.
|
|
74
|
-
- { name: type, type: Text, applies_to: [Specs], meaning: "
|
|
56
|
+
- { name: domain, type: Text, required: true, applies_to: [Specs], meaning: "The group: matches the blueprint's sub-folder. An unknown value warns." }
|
|
57
|
+
- { name: depends_on, type: List, applies_to: [Specs], meaning: "Blueprints this one needs, each a markdown link." }
|
|
58
|
+
- { name: type, type: Text, applies_to: [Specs], meaning: "Soft category label: drives views and filtering, never structure. e.g. feature, capability, integration." }
|
|
75
59
|
|
|
76
|
-
# The
|
|
77
|
-
#
|
|
78
|
-
# thing); `see` points at the blueprint that defines the term in full. Eidos declares none of these; the
|
|
79
|
-
# list starts empty and grows an entry when a word begins to carry a distinction worth keeping.
|
|
80
|
-
# The `eidos` CLI edits it and presses for all three of term, means, and not.
|
|
60
|
+
# The root's own terms: term, means, not (the near-misses and why), and see (the blueprint that defines it).
|
|
61
|
+
# Starts empty; Eidos declares none.
|
|
81
62
|
vocabulary: []
|
|
82
|
-
|
|
@@ -14,10 +14,11 @@ _One or two sentences: what {{Product}} is, and for whom._
|
|
|
14
14
|
|
|
15
15
|
_Your own one-of-a-kind docs: a Vision, a set of Design Principles, the generated Blueprint Map. Add them here as you write them._
|
|
16
16
|
|
|
17
|
-
##
|
|
17
|
+
## Folders
|
|
18
18
|
|
|
19
19
|
- **[Frames](Frames/)** — the framing docs: Architecture, Audience, Criteria, Market.
|
|
20
20
|
- **[Specs](Specs/)** — the product's units, grouped by domain.
|
|
21
|
+
- **[assets](assets/)** — images, diagrams, and documents the blueprints link to.
|
|
21
22
|
|
|
22
23
|
---
|
|
23
24
|
|
|
@@ -1,4 +1,10 @@
|
|
|
1
1
|
# Eidos: me.md is personal and never shared.
|
|
2
2
|
# Each person who works on this definition keeps their own me.md (here in .eidos/); the agent reads
|
|
3
|
-
# it to know who they are. It is the one
|
|
3
|
+
# it to know who they are. It is the one file of the standard's own that is not checked in.
|
|
4
4
|
me.md
|
|
5
|
+
|
|
6
|
+
# Eidos: a tool's local.yaml is personal and never shared.
|
|
7
|
+
# A tool that keeps a folder under plugins/ may keep its personal settings there, one machine's (a
|
|
8
|
+
# viewer command, an editor, a key path); everything else in its folder is the root's. This one
|
|
9
|
+
# line covers every tool, so no tool writes a .gitignore of its own.
|
|
10
|
+
plugins/*/local.yaml
|
|
@@ -1 +0,0 @@
|
|
|
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)}}
|