@liggi/figkit 0.0.0-stage → 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/GUIDE.md +303 -0
- package/LICENSE +21 -0
- package/README.md +98 -2
- package/THIRD_PARTY_NOTICES.md +632 -0
- package/bin/fig.mjs +124 -0
- package/dist/viz.iife.js +59 -0
- package/examples/assets/settings-page.html +14 -0
- package/examples/assets/settings-page.png +0 -0
- package/examples/boundary.html +25 -0
- package/examples/charts/bars.json +8 -0
- package/examples/charts/before-after.json +16 -0
- package/examples/charts/dumbbell.json +9 -0
- package/examples/charts/entities.json +17 -0
- package/examples/charts/series.json +46 -0
- package/examples/charts/split.json +10 -0
- package/examples/consolidate.html +33 -0
- package/examples/custom-bar.html +25 -0
- package/examples/flow.html +50 -0
- package/examples/grouping.html +33 -0
- package/examples/line-chart.html +25 -0
- package/examples/screenshot-notes.html +16 -0
- package/examples/sides.html +35 -0
- package/examples/split.html +13 -0
- package/examples/timeline.html +33 -0
- package/package.json +55 -4
- package/runtime/fig.css +188 -0
- package/runtime/fig.js +704 -0
- package/viz/build.mjs +27 -0
- package/viz/draw.js +315 -0
- package/viz/index.js +2 -0
- package/viz/spec.js +177 -0
package/runtime/fig.css
ADDED
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
/* figkit theme and primitives. Authors write HTML inside <main class="fig">; everything here is optional vocabulary. */
|
|
2
|
+
|
|
3
|
+
*, *::before, *::after { box-sizing: border-box; }
|
|
4
|
+
html, body { margin: 0; padding: 0; background: transparent; }
|
|
5
|
+
|
|
6
|
+
.fig {
|
|
7
|
+
/* ink theme (dark): the default, for a dark chat */
|
|
8
|
+
--paper: #2d3142; --panel: #252938; --ink: #f5f5f5; --muted: #c3c6cf; --soft: #949eb2; --line: #8d95ad; --hair: rgba(245,245,245,.16);
|
|
9
|
+
--accent: #f08a59; --second: #739fdf; --good: #6fc392; --bad: #ef6b73;
|
|
10
|
+
--on-fill: #1d2030;
|
|
11
|
+
--sans: 'Geist Sans', 'Geist', system-ui, sans-serif;
|
|
12
|
+
--serif: 'Newsreader', Georgia, serif;
|
|
13
|
+
--mono: 'Geist Mono', ui-monospace, monospace;
|
|
14
|
+
/* glance density: one point, reads inline on a phone */
|
|
15
|
+
--w: 960px; --pad: 44px; --gap: 16px; --gap-arrow: 64px;
|
|
16
|
+
--title: 50px; --read: 22px; --h: 22px; --body: 18px; --small: 16px; --num: 46px;
|
|
17
|
+
|
|
18
|
+
position: relative; width: var(--w); padding: var(--pad); background: var(--paper); color: var(--ink);
|
|
19
|
+
font-family: var(--sans); font-size: var(--body); line-height: 1.35; -webkit-font-smoothing: antialiased;
|
|
20
|
+
display: flex; flex-direction: column; gap: 28px;
|
|
21
|
+
}
|
|
22
|
+
.fig.detail {
|
|
23
|
+
/* detail density: a map to open full screen and read */
|
|
24
|
+
--w: 1360px; --pad: 48px; --gap: 16px; --gap-arrow: 60px;
|
|
25
|
+
--title: 50px; --read: 20px; --h: 19px; --body: 16px; --small: 14px;
|
|
26
|
+
}
|
|
27
|
+
.fig.paper {
|
|
28
|
+
/* light theme: docs, Slack, Notion */
|
|
29
|
+
--paper: #faf8f3; --panel: #ffffff; --ink: #1d2130; --muted: #4c5262; --soft: #7a8092; --line: #8a90a0; --hair: rgba(29,33,48,.16);
|
|
30
|
+
--accent: #cf5a23; --second: #2f6bc4; --good: #2f8f5b; --bad: #c9414a; --on-fill: #ffffff;
|
|
31
|
+
}
|
|
32
|
+
.fig[style*="--w"] { width: var(--w); }
|
|
33
|
+
.fig.chart {
|
|
34
|
+
/* a chart from a spec: narrower, so it reads inline on a phone; the chart, not the title, is the largest thing */
|
|
35
|
+
--w: 720px; --title: 36px; --read: 22px; --body: 22px; --small: 21px;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
.fig.phone {
|
|
39
|
+
/* the phone layout of a figure with sides: narrow, so its text stays readable inline; sides stack */
|
|
40
|
+
--w: 560px; --pad: 30px; --title: 40px;
|
|
41
|
+
}
|
|
42
|
+
.fig.phone .sides { display: flex; flex-direction: column; row-gap: 56px; }
|
|
43
|
+
.fig.phone .sides > * { flex: 0 0 auto; width: 100%; }
|
|
44
|
+
|
|
45
|
+
/* ---------- header and footer ---------- */
|
|
46
|
+
.fig > header { display: flex; flex-direction: column; gap: 10px; }
|
|
47
|
+
.fig h1 { font-family: var(--serif); font-weight: 400; font-size: var(--title); line-height: 1.06; letter-spacing: -.02em; margin: 0; text-wrap: balance; }
|
|
48
|
+
.fig h1 em { color: var(--accent); }
|
|
49
|
+
.fig .read { font-size: var(--read); color: var(--muted); margin: 0; text-wrap: pretty; }
|
|
50
|
+
.fig > footer { font-size: var(--small); color: var(--soft); border-top: 1px solid var(--hair); padding-top: 14px; }
|
|
51
|
+
.fig > footer p { margin: 0 0 4px; }
|
|
52
|
+
.fig .takeaway { font-family: var(--serif); font-size: calc(var(--read) * 1.3); color: var(--ink); margin: 0; }
|
|
53
|
+
|
|
54
|
+
/* ---------- text ---------- */
|
|
55
|
+
.fig h2 { font-size: var(--h); font-weight: 600; margin: 0; }
|
|
56
|
+
.fig h3 { font-size: var(--h); font-weight: 600; margin: 0; line-height: 1.2; }
|
|
57
|
+
.fig p { margin: 0; }
|
|
58
|
+
.fig .note { font-size: var(--small); color: var(--muted); max-width: 34ch; }
|
|
59
|
+
.fig .num { font-family: var(--serif); font-size: var(--num); line-height: 1; letter-spacing: -.01em; }
|
|
60
|
+
.fig .tag { font-family: var(--mono); font-size: var(--small); font-weight: 400; color: var(--soft); }
|
|
61
|
+
.fig code { font-family: var(--mono); font-size: .92em; }
|
|
62
|
+
.fig .t-accent { color: var(--accent); } .fig .t-second { color: var(--second); }
|
|
63
|
+
.fig .t-good { color: var(--good); } .fig .t-bad { color: var(--bad); }
|
|
64
|
+
.fig .t-muted { color: var(--muted); } .fig .t-soft { color: var(--soft); }
|
|
65
|
+
.fig b, .fig strong { font-weight: 600; }
|
|
66
|
+
|
|
67
|
+
/* ---------- layout ---------- */
|
|
68
|
+
.fig .row { display: flex; flex-direction: row; gap: var(--gap); align-items: stretch; }
|
|
69
|
+
.fig .col { display: flex; flex-direction: column; gap: var(--gap); }
|
|
70
|
+
.fig .grid { display: grid; grid-template-columns: repeat(var(--cols, 3), minmax(0, 1fr)); gap: var(--gap); }
|
|
71
|
+
.fig .arrows { gap: var(--gap-arrow); } /* a row or column whose children are joined by arrows */
|
|
72
|
+
.fig .wide { gap: calc(var(--gap-arrow) * 1.6); }
|
|
73
|
+
.fig .tight { gap: 8px; }
|
|
74
|
+
.fig .grow { flex: 1 1 0; min-width: 0; }
|
|
75
|
+
.fig .fit { flex: 0 0 auto; }
|
|
76
|
+
.fig .middle { align-items: center; } .fig .top { align-items: flex-start; } .fig .bottom { align-items: flex-end; }
|
|
77
|
+
.fig .center { justify-content: center; } .fig .between { justify-content: space-between; }
|
|
78
|
+
.fig .tc { text-align: center; } .fig .tr { text-align: right; }
|
|
79
|
+
|
|
80
|
+
/* ---------- nodes ---------- */
|
|
81
|
+
.fig .node {
|
|
82
|
+
--tone: var(--line);
|
|
83
|
+
background: var(--panel); border: 1.5px solid var(--tone); border-radius: 10px; padding: 14px 18px;
|
|
84
|
+
display: flex; flex-direction: column; gap: 4px; min-width: 0; position: relative;
|
|
85
|
+
}
|
|
86
|
+
.fig .node > p { color: var(--muted); font-size: var(--small); }
|
|
87
|
+
.fig .node > .num + h3 { margin-top: 6px; }
|
|
88
|
+
.fig .accent { --tone: var(--accent); } .fig .second { --tone: var(--second); }
|
|
89
|
+
.fig .good { --tone: var(--good); } .fig .bad { --tone: var(--bad); }
|
|
90
|
+
.fig .node.accent > .tag, .fig .node.second > .tag, .fig .node.good > .tag, .fig .node.bad > .tag { color: var(--tone); }
|
|
91
|
+
.fig .node.fill { background: var(--tone); border-color: var(--tone); color: var(--on-fill); }
|
|
92
|
+
.fig .node.fill > p { color: var(--on-fill); opacity: .82; }
|
|
93
|
+
.fig .node.fill:not(.accent):not(.second):not(.good):not(.bad) { --tone: var(--ink); color: var(--paper); }
|
|
94
|
+
.fig .node.fill:not(.accent):not(.second):not(.good):not(.bad) > p { color: var(--paper); }
|
|
95
|
+
.fig .node.tint { background: color-mix(in srgb, var(--tone) 18%, var(--panel)); }
|
|
96
|
+
.fig .node.quiet { background: transparent; border-color: var(--hair); }
|
|
97
|
+
.fig .node.dashed { border-style: dashed; background: transparent; }
|
|
98
|
+
.fig .node.bare { background: transparent; border-color: transparent; padding: 0; }
|
|
99
|
+
.fig .node.pill { border-radius: 999px; padding: 12px 26px; align-items: center; text-align: center; }
|
|
100
|
+
.fig .step {
|
|
101
|
+
position: absolute; top: -13px; right: -13px; width: 28px; height: 28px; border-radius: 50%;
|
|
102
|
+
background: var(--ink); color: var(--paper); font-size: 15px; font-weight: 600; display: grid; place-items: center;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/* a decision: diamond, text centred */
|
|
106
|
+
.fig .decision {
|
|
107
|
+
--tone: var(--ink); position: relative; isolation: isolate; display: grid; place-items: center; text-align: center;
|
|
108
|
+
padding: 2.9em 0; min-width: 300px; align-self: center; font-weight: 600; font-size: var(--h); line-height: 1.25;
|
|
109
|
+
}
|
|
110
|
+
.fig .decision > * { max-width: 56%; }
|
|
111
|
+
.fig .decision::before { content: ''; position: absolute; inset: 0; z-index: -2; background: var(--tone); clip-path: polygon(50% 0, 100% 50%, 50% 100%, 0 50%); }
|
|
112
|
+
.fig .decision::after { content: ''; position: absolute; inset: 0; z-index: -1; background: var(--panel); clip-path: polygon(50% 3px, calc(100% - 5px) 50%, 50% calc(100% - 3px), 5px 50%); }
|
|
113
|
+
|
|
114
|
+
/* a group: a light container with a label on its top edge */
|
|
115
|
+
.fig .group { position: relative; border: 1px dashed var(--hair); border-radius: 12px; padding: 26px 18px 18px; display: flex; flex-direction: column; gap: var(--gap); }
|
|
116
|
+
.fig .group > .label { position: absolute; top: -0.72em; left: 14px; background: var(--paper); padding: 0 8px; font-size: var(--small); font-weight: 600; color: var(--muted); }
|
|
117
|
+
.fig .lane-title { font-size: var(--small); font-weight: 600; color: var(--muted); letter-spacing: .01em; }
|
|
118
|
+
.fig hr { border: 0; border-top: 1px solid var(--hair); margin: 0; width: 100%; }
|
|
119
|
+
.fig .divide { border-left: 1px solid var(--hair); align-self: stretch; }
|
|
120
|
+
|
|
121
|
+
/* ---------- entities: records and the references between them (a spec of type "entities") ---------- */
|
|
122
|
+
.fig .entities { display: grid; column-gap: 110px; row-gap: 96px; align-items: start; }
|
|
123
|
+
.fig.phone .entities { column-gap: 72px; row-gap: 84px; }
|
|
124
|
+
.fig .record > ul { list-style: none; margin: 6px 0 0; padding: 0; display: flex; flex-direction: column; gap: 2px; }
|
|
125
|
+
.fig .record > ul li { font-size: var(--small); color: var(--muted); }
|
|
126
|
+
|
|
127
|
+
/* ---------- arrows (drawn by fig.js) ---------- */
|
|
128
|
+
fig-arrow { display: none; }
|
|
129
|
+
.fig > svg.fig-wires { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; overflow: visible; }
|
|
130
|
+
.fig .fig-wire-label {
|
|
131
|
+
position: absolute; transform: translate(-50%, -50%); background: var(--paper); padding: 1px 8px; border-radius: 4px;
|
|
132
|
+
font-size: var(--small); font-weight: 600; white-space: nowrap; line-height: 1.3;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/* ---------- split bar: parts of a whole ---------- */
|
|
136
|
+
fig-split { display: flex; flex-direction: column; gap: 10px; }
|
|
137
|
+
fig-split .fs-bar { display: flex; gap: 3px; height: 58px; }
|
|
138
|
+
fig-split .fs-seg { --tone: var(--soft); background: var(--tone); color: var(--on-fill); min-width: 4px; display: flex; align-items: center; gap: 10px; padding: 0 14px; overflow: hidden; white-space: nowrap; }
|
|
139
|
+
fig-split .fs-seg:first-child { border-radius: 8px 0 0 8px; } fig-split .fs-seg:last-child { border-radius: 0 8px 8px 0; }
|
|
140
|
+
fig-split .fs-seg.fs-out { padding: 0; }
|
|
141
|
+
fig-split .fs-seg.fs-out > * { display: none; }
|
|
142
|
+
fig-split .fs-seg b { font-family: var(--serif); font-weight: 400; font-size: calc(var(--num) * .66); }
|
|
143
|
+
fig-split .fs-seg span { font-size: var(--small); font-weight: 600; }
|
|
144
|
+
fig-split .fs-rest { font-size: var(--small); color: var(--muted); }
|
|
145
|
+
fig-split .fs-rest > span { font-weight: 600; }
|
|
146
|
+
fig-split .fs-rest b { color: var(--ink); font-family: var(--serif); font-weight: 400; font-size: 1.3em; }
|
|
147
|
+
.fig.paper fig-split .fs-seg:not(.accent):not(.second):not(.good):not(.bad) { --tone: #c9cdd6; color: var(--ink); }
|
|
148
|
+
|
|
149
|
+
/* ---------- before and after: one measure that changed ---------- */
|
|
150
|
+
fig-change { display: grid; grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr); column-gap: 28px; row-gap: 14px; align-items: center; }
|
|
151
|
+
fig-change .fc-side { display: flex; flex-direction: column; gap: 10px; }
|
|
152
|
+
fig-change .fc-when { font-size: var(--small); font-weight: 600; color: var(--muted); }
|
|
153
|
+
fig-change .fc-num { font-family: var(--serif); font-weight: 400; font-size: calc(var(--num) * 1.5); line-height: 1; letter-spacing: -.01em; color: var(--ink); }
|
|
154
|
+
fig-change .fc-bar { height: 14px; min-width: 3px; background: var(--soft); border-radius: 3px; }
|
|
155
|
+
fig-change .before .fc-num { color: var(--muted); }
|
|
156
|
+
fig-change .after .fc-num { color: var(--tone); }
|
|
157
|
+
fig-change .after .fc-bar { background: var(--tone); }
|
|
158
|
+
fig-change .fc-arrow { color: var(--soft); display: flex; }
|
|
159
|
+
|
|
160
|
+
/* ---------- bars: compare a few numbers ---------- */
|
|
161
|
+
fig-bars { display: grid; grid-template-columns: max-content minmax(0, 1fr); column-gap: 16px; row-gap: 10px; align-items: center; }
|
|
162
|
+
fig-bars .fb-label { font-size: var(--body); }
|
|
163
|
+
fig-bars .fb-track { display: flex; align-items: center; gap: 10px; min-width: 0; }
|
|
164
|
+
fig-bars .fb-bar { --tone: var(--soft); height: 26px; background: var(--tone); border-radius: 3px; min-width: 3px; flex: 0 0 auto; }
|
|
165
|
+
fig-bars .fb-val { font-family: var(--serif); font-size: 1.3em; font-weight: 400; font-variant-numeric: tabular-nums; white-space: nowrap; }
|
|
166
|
+
fig-bars .fb-val.lead { color: var(--tone); }
|
|
167
|
+
fig-bars .fb-sub { font-weight: 400; color: var(--soft); font-size: var(--small); margin-left: 6px; }
|
|
168
|
+
|
|
169
|
+
/* ---------- charts (Observable Plot via fig.plot) ---------- */
|
|
170
|
+
.fig .chart { min-width: 0; }
|
|
171
|
+
.fig .fd-key { display: flex; gap: 28px; margin: 0 0 18px; font-size: var(--small); font-weight: 600; color: var(--soft); }
|
|
172
|
+
.fig .fd-key span { display: inline-flex; align-items: center; gap: 8px; }
|
|
173
|
+
.fig .fd-key i { display: inline-block; width: 13px; height: 13px; border-radius: 50%; background: var(--soft); }
|
|
174
|
+
.fig .fd-key .fd-to i { width: 0; height: 0; border-radius: 0; background: none; border-left: 13px solid currentColor; border-top: 7.5px solid transparent; border-bottom: 7.5px solid transparent; }
|
|
175
|
+
.fig .fd-key .fd-to.back i { transform: scaleX(-1); }
|
|
176
|
+
.fig.chart > footer { border-top: 0; padding-top: 0; }
|
|
177
|
+
.fig .chart svg { display: block; overflow: visible; }
|
|
178
|
+
.fig .chart figure { margin: 0; }
|
|
179
|
+
|
|
180
|
+
/* ---------- screenshots with call-outs ---------- */
|
|
181
|
+
.fig .shot { position: relative; border-radius: 8px; overflow: hidden; border: 1px solid var(--hair); line-height: 0; }
|
|
182
|
+
.fig .shot img { width: 100%; display: block; }
|
|
183
|
+
.fig .mark { position: absolute; border: 2.5px solid var(--accent); border-radius: 6px; }
|
|
184
|
+
.fig .group.flush { margin-inline: -19px; }
|
|
185
|
+
.fig .fig .t-accent, .fig .t-accent.t-accent { color: var(--accent); }
|
|
186
|
+
.fig .t-second.t-second { color: var(--second); }
|
|
187
|
+
.fig .t-good.t-good { color: var(--good); } .fig .t-bad.t-bad { color: var(--bad); }
|
|
188
|
+
.fig .decision:not(.accent):not(.second):not(.good):not(.bad) { --tone: var(--line); }
|