@conduction/docusaurus-preset 3.28.0 → 3.32.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.
Files changed (33) hide show
  1. package/MISSING_COMPONENTS.md +6 -2
  2. package/package.json +4 -4
  3. package/src/components/AppMock/AppMock.jsx +16 -0
  4. package/src/components/AppMock/variants/AppVersionsMock.jsx +83 -0
  5. package/src/components/AppMock/variants/DoriathMock.jsx +79 -0
  6. package/src/components/AppMock/variants/HermiqMock.jsx +71 -0
  7. package/src/components/AppMock/variants/HrmqMock.jsx +77 -0
  8. package/src/components/AppMock/variants/PlanixMock.jsx +80 -0
  9. package/src/components/AppMock/variants/PortaliqMock.jsx +63 -0
  10. package/src/components/AppMock/variants/ScholiqMock.jsx +74 -0
  11. package/src/components/AppMock/variants/ShillinqMock.jsx +90 -0
  12. package/src/components/BuildMock/BuildMock.jsx +101 -0
  13. package/src/components/BuildMock/BuildMock.module.css +290 -0
  14. package/src/components/CookieCli/CookieCli.jsx +197 -24
  15. package/src/components/CookieCli/CookieCli.module.css +139 -1
  16. package/src/components/CookieCli/shell.js +161 -0
  17. package/src/components/CookieCli/spaceInvaders.js +359 -0
  18. package/src/components/CookieCli/spaceInvaders.test.js +112 -0
  19. package/src/components/DetailHero/DetailHero.jsx +68 -16
  20. package/src/components/DetailHero/DetailHero.module.css +31 -1
  21. package/src/components/FlowMock/FlowMock.jsx +151 -0
  22. package/src/components/FlowMock/FlowMock.module.css +164 -0
  23. package/src/components/KanbanMock/KanbanMock.jsx +119 -0
  24. package/src/components/KanbanMock/KanbanMock.module.css +233 -0
  25. package/src/components/LeafMock/LeafMock.jsx +173 -0
  26. package/src/components/LeafMock/LeafMock.module.css +237 -0
  27. package/src/components/RotatingCards/RotatingCards.module.css +5 -2
  28. package/src/components/Showcase/Showcase.module.css +5 -2
  29. package/src/components/WidgetShelf/WidgetShelf.jsx +52 -13
  30. package/src/components/WidgetShelf/WidgetShelf.module.css +84 -5
  31. package/src/components/index.js +4 -0
  32. package/src/components/primitives/SectionHead.module.css +6 -0
  33. package/src/data/app-glyphs.json +4 -0
@@ -0,0 +1,90 @@
1
+ /**
2
+ * Shillinq abstract — bookkeeping ledger.
3
+ *
4
+ * Inferred from the app role (invoices, VAT, bank reconciliation):
5
+ * a VAT/summary KPI strip over an invoice table — document icon,
6
+ * description, two amount columns (net / VAT), and a reconciliation
7
+ * tick column where a mint hex = matched against the bank and a
8
+ * muted pip = still open. Tone: terracotta — documents, human work.
9
+ */
10
+
11
+ import React from 'react';
12
+ import styles from '../AppMock.module.css';
13
+
14
+ const INVOICES = [
15
+ {amount: 26, vat: 16, matched: true},
16
+ {amount: 20, vat: 12, matched: true},
17
+ {amount: 30, vat: 18, matched: false},
18
+ {amount: 22, vat: 14, matched: true},
19
+ {amount: 18, vat: 10, matched: false},
20
+ ];
21
+
22
+ export default function ShillinqMock() {
23
+ return (
24
+ <>
25
+ <div className={styles.topbar}>
26
+ <div className={styles.logo}></div>
27
+ {Array.from({length: 14}).map((_, i) => <div key={i} className={styles.icon}></div>)}
28
+ <div className={styles.spacer}></div>
29
+ <div className={styles.bell}></div>
30
+ <div className={styles.avatar}></div>
31
+ </div>
32
+ <div className={[styles.body, styles.decidesk].filter(Boolean).join(' ')}>
33
+ <div className={styles.nav}>
34
+ <div className={styles.navHead}><div className={styles.h}></div><div className={styles.l}></div></div>
35
+ {[true, false, false, false, false].map((active, i) => (
36
+ <div key={i} className={[styles.item, active && styles.active].filter(Boolean).join(' ')}>
37
+ <div className={styles.ico}></div>
38
+ <div className={styles.l}></div>
39
+ </div>
40
+ ))}
41
+ </div>
42
+ <div className={styles.col}>
43
+ <div className={styles.head}>
44
+ <div className={styles.row + ' ' + styles.head} style={{width: '30%'}}></div>
45
+ <div className={styles.actions}>
46
+ <div className={styles.btn + ' ' + styles.ghost}></div>
47
+ <div className={styles.btn}></div>
48
+ </div>
49
+ </div>
50
+ {/* VAT / summary strip */}
51
+ <div className={styles.kpiRow}>
52
+ <div className={styles.kpi}>
53
+ <div className={styles.ico} style={{background: 'var(--c-terracotta-500)'}}></div>
54
+ <div className={styles.meta}><div className={styles.num}></div><div className={styles.label}></div></div>
55
+ </div>
56
+ <div className={styles.kpi}>
57
+ <div className={styles.ico} style={{background: 'var(--c-terracotta-300)'}}></div>
58
+ <div className={styles.meta}><div className={styles.num}></div><div className={styles.label}></div></div>
59
+ </div>
60
+ <div className={styles.kpi}>
61
+ <div className={styles.ico}></div>
62
+ <div className={styles.meta}><div className={styles.num}></div><div className={styles.label}></div></div>
63
+ </div>
64
+ </div>
65
+ {/* Invoice table: doc · description · net · VAT · reconciled */}
66
+ <div className={styles.panel} style={{flex: 1}}>
67
+ <div className={styles.head}><div className={styles.title}></div></div>
68
+ <div className={styles.stack}>
69
+ {INVOICES.map(({amount, vat, matched}, i) => (
70
+ <div key={i} className={styles.item}>
71
+ <div style={{width: 11, height: 13, clipPath: 'var(--hex-pointy-top)', background: 'var(--c-terracotta-300)', flexShrink: 0}}></div>
72
+ <div className={styles.lines}><div className={styles.l1}></div></div>
73
+ <div style={{width: amount, height: 4, background: 'var(--c-cobalt-700)', borderRadius: 1, flexShrink: 0}}></div>
74
+ <div style={{width: vat, height: 4, background: 'var(--c-cobalt-300)', borderRadius: 1, flexShrink: 0}}></div>
75
+ {/* Bank-reconciliation tick: mint hex = matched */}
76
+ <div style={{width: 9, height: 10, clipPath: 'var(--hex-pointy-top)', background: matched ? 'var(--c-mint-500)' : 'var(--c-cobalt-200)', flexShrink: 0}}></div>
77
+ </div>
78
+ ))}
79
+ </div>
80
+ {/* Totals line */}
81
+ <div style={{display: 'flex', justifyContent: 'flex-end', gap: 6, paddingTop: 4, borderTop: '1px solid var(--c-cobalt-100)'}}>
82
+ <div style={{width: 32, height: 6, background: 'var(--c-cobalt-900)', borderRadius: 1}}></div>
83
+ <div style={{width: 20, height: 6, background: 'var(--c-cobalt-400)', borderRadius: 1}}></div>
84
+ </div>
85
+ </div>
86
+ </div>
87
+ </div>
88
+ </>
89
+ );
90
+ }
@@ -0,0 +1,101 @@
1
+ /**
2
+ * <BuildMock />
3
+ *
4
+ * Token-built abstract of the OpenBuild "make it yours" moment: the
5
+ * orange edit button gets pressed, a small component palette opens, a
6
+ * widget is picked and dragged onto the page, and it snaps into the
7
+ * empty layout slot. Loops every ~8 seconds. Used on every app's
8
+ * Make-it-yours card.
9
+ *
10
+ * Same abstraction level as <AppMock>: greeked content, tokens only.
11
+ * The orange FAB is this component's single orange accent (it *is*
12
+ * the OpenBuild edit button).
13
+ *
14
+ * `prefers-reduced-motion: reduce` (and `running={false}`) renders
15
+ * the static end state: palette closed, cursor gone, the dragged
16
+ * component already snapped into the layout.
17
+ *
18
+ * Usage:
19
+ *
20
+ * <BuildMock />
21
+ * <BuildMock size="sm" caption />
22
+ * <BuildMock running={false} />
23
+ *
24
+ * Props:
25
+ * - size: 'sm' | 'md' (default) — frame width, as AppMock
26
+ * - caption: string | true — small label below the frame;
27
+ * `true` renders the default "Make it yours"
28
+ * - running: boolean (default true) — false freezes to the end state
29
+ * - className: string
30
+ */
31
+
32
+ import React from 'react';
33
+ import styles from './BuildMock.module.css';
34
+
35
+ function MiniTile({wide}) {
36
+ return (
37
+ <span className={styles.miniTile}>
38
+ <span className={styles.miniBar} style={{width: wide ? '70%' : '50%'}} />
39
+ <span className={styles.miniLine} />
40
+ <span className={styles.miniLine} style={{width: '60%'}} />
41
+ </span>
42
+ );
43
+ }
44
+
45
+ export default function BuildMock({size = 'md', caption, running = true, className}) {
46
+ return (
47
+ <div className={styles.bm}>
48
+ <figure className={[styles.figure, className].filter(Boolean).join(' ')}>
49
+ <div
50
+ className={[styles.frame, styles[`size-${size}`], !running && styles.static].filter(Boolean).join(' ')}
51
+ role="img"
52
+ aria-label="Abstract page editor: the edit button opens a component palette and a widget is dragged into the page layout."
53
+ >
54
+ <div className={styles.page}>
55
+ <div className={styles.pageHead}>
56
+ <span className={styles.headGreek} />
57
+ </div>
58
+ <div className={styles.pageGrid}>
59
+ <div className={styles.tile}><MiniTile wide /></div>
60
+ <div className={styles.tile}><MiniTile /></div>
61
+ <div className={styles.slot}>
62
+ {/* The component the drag delivers. Fades in when the
63
+ ghost lands; permanently visible in the static /
64
+ reduced-motion end state. */}
65
+ <div className={styles.snapTile}><MiniTile wide /></div>
66
+ </div>
67
+ <div className={styles.tile}><MiniTile /></div>
68
+ </div>
69
+ </div>
70
+
71
+ {/* Component palette, opened by the FAB press. */}
72
+ <div className={styles.palette}>
73
+ <span className={styles.paletteTile} />
74
+ <span className={[styles.paletteTile, styles.paletteTileActive].join(' ')} />
75
+ <span className={styles.paletteTile} />
76
+ </div>
77
+
78
+ {/* The OpenBuild edit button — the one orange accent. */}
79
+ <div className={styles.fab}>
80
+ <svg viewBox="0 0 24 24" aria-hidden="true">
81
+ <path d="M12 20h9M16.5 3.5a2.1 2.1 0 0 1 3 3L7 19l-4 1 1-4L16.5 3.5z" />
82
+ </svg>
83
+ </div>
84
+
85
+ {/* The dragged component ghost. */}
86
+ <div className={styles.ghost}><MiniTile wide /></div>
87
+
88
+ {/* The cursor driving the loop. */}
89
+ <svg className={styles.cursor} viewBox="0 0 24 24" aria-hidden="true">
90
+ <path d="M3 3l7.07 16.97 2.51-7.39 7.39-2.51L3 3z" />
91
+ </svg>
92
+ </div>
93
+ {caption && (
94
+ <figcaption className={styles.caption}>
95
+ {caption === true ? 'Make it yours' : caption}
96
+ </figcaption>
97
+ )}
98
+ </figure>
99
+ </div>
100
+ );
101
+ }
@@ -0,0 +1,290 @@
1
+ /**
2
+ * <BuildMock /> styles. Scoped under `.bm` (display: contents), the
3
+ * AppMock `.am` convention, so specimen pages can reuse the file as a
4
+ * plain global stylesheet.
5
+ *
6
+ * One shared timeline (--bm-dur, default 8s) drives five animations:
7
+ * the cursor path, the FAB press, the palette open/close, the dragged
8
+ * ghost, and the snap-in of the placed component. Percentages line up
9
+ * across the keyframe sets:
10
+ *
11
+ * 0–14% cursor travels to the FAB, presses it
12
+ * 16–22% palette opens, cursor moves to the middle palette tile
13
+ * 30–58% ghost is dragged from the palette to the empty slot
14
+ * 58–62% snap: ghost settles, placed component fades in
15
+ * 62–88% hold the result
16
+ * 88–100% everything resets for the next loop
17
+ *
18
+ * prefers-reduced-motion (and the .static class from running={false})
19
+ * freezes the mock at the end state: component placed, palette closed,
20
+ * no cursor. Tokens only; the orange FAB is the single orange accent.
21
+ */
22
+
23
+ .bm { display: contents; }
24
+
25
+ .bm .figure {
26
+ margin: 0;
27
+ display: inline-flex;
28
+ flex-direction: column;
29
+ gap: var(--space-2);
30
+ width: 100%;
31
+ max-width: 100%;
32
+ }
33
+
34
+ .bm .frame {
35
+ --bm-dur: 8s;
36
+ width: 100%;
37
+ max-width: 720px;
38
+ aspect-ratio: 16 / 10;
39
+ background: white;
40
+ border: 1px solid var(--c-cobalt-100);
41
+ border-radius: var(--radius-lg);
42
+ box-shadow: var(--shadow-3);
43
+ overflow: hidden;
44
+ position: relative;
45
+ font-family: var(--conduction-typography-font-family-body);
46
+ }
47
+ .bm .size-sm { max-width: 480px; }
48
+ .bm .size-md { max-width: 720px; }
49
+
50
+ .bm .caption {
51
+ font-family: var(--conduction-typography-font-family-code);
52
+ font-size: 11px;
53
+ letter-spacing: 0.06em;
54
+ color: var(--c-cobalt-400);
55
+ text-transform: uppercase;
56
+ text-align: center;
57
+ }
58
+
59
+ /* ---- Page skeleton ---- */
60
+
61
+ .bm .page {
62
+ position: absolute;
63
+ inset: 0;
64
+ padding: 7% 8%;
65
+ display: flex;
66
+ flex-direction: column;
67
+ gap: 5%;
68
+ }
69
+ .bm .pageHead { flex-shrink: 0; }
70
+ .bm .headGreek {
71
+ display: block;
72
+ width: 34%;
73
+ height: 8px;
74
+ border-radius: 2px;
75
+ background: var(--c-cobalt-700);
76
+ }
77
+ .bm .pageGrid {
78
+ flex: 1;
79
+ display: grid;
80
+ grid-template-columns: 1fr 1fr;
81
+ grid-template-rows: 1fr 1fr;
82
+ gap: 5%;
83
+ /* Leave the right quarter free for the palette + FAB. */
84
+ margin-right: 22%;
85
+ }
86
+
87
+ .bm .tile,
88
+ .bm .slot {
89
+ border-radius: var(--radius-md);
90
+ padding: 8px 10px;
91
+ }
92
+ .bm .tile {
93
+ background: var(--c-cobalt-50);
94
+ border: 1px solid var(--c-cobalt-100);
95
+ }
96
+ .bm .slot {
97
+ border: 2px dashed var(--c-cobalt-200);
98
+ animation: bmSlotHint var(--bm-dur) linear infinite;
99
+ }
100
+
101
+ .bm .miniTile {
102
+ display: flex;
103
+ flex-direction: column;
104
+ gap: 5px;
105
+ width: 100%;
106
+ }
107
+ .bm .miniBar { display: block; height: 5px; border-radius: 1.5px; background: var(--c-cobalt-700); }
108
+ .bm .miniLine { display: block; height: 3px; border-radius: 1px; background: var(--c-cobalt-200); width: 80%; }
109
+
110
+ /* The delivered component inside the slot. */
111
+ .bm .snapTile {
112
+ opacity: 0;
113
+ animation: bmSnapIn var(--bm-dur) linear infinite;
114
+ }
115
+
116
+ /* ---- Palette ---- */
117
+
118
+ .bm .palette {
119
+ position: absolute;
120
+ right: 4%;
121
+ top: 22%;
122
+ width: 13%;
123
+ display: flex;
124
+ flex-direction: column;
125
+ gap: 8px;
126
+ background: white;
127
+ border: 1px solid var(--c-cobalt-100);
128
+ border-radius: var(--radius-md);
129
+ box-shadow: var(--shadow-3);
130
+ padding: 8px;
131
+ opacity: 0;
132
+ transform: translateX(10px);
133
+ animation: bmPalette var(--bm-dur) linear infinite;
134
+ }
135
+ .bm .paletteTile {
136
+ display: block;
137
+ height: 18px;
138
+ border-radius: 3px;
139
+ background: var(--c-cobalt-50);
140
+ border: 1px solid var(--c-cobalt-100);
141
+ }
142
+ .bm .paletteTileActive { animation: bmPaletteTile var(--bm-dur) linear infinite; }
143
+
144
+ /* ---- FAB (the one orange accent) ---- */
145
+
146
+ .bm .fab {
147
+ position: absolute;
148
+ right: 5%;
149
+ bottom: 7%;
150
+ width: 34px;
151
+ height: 34px;
152
+ border-radius: 50%;
153
+ background: var(--c-orange-knvb);
154
+ display: flex;
155
+ align-items: center;
156
+ justify-content: center;
157
+ box-shadow: var(--shadow-2);
158
+ animation: bmFabPress var(--bm-dur) linear infinite;
159
+ }
160
+ .bm .fab svg {
161
+ width: 15px;
162
+ height: 15px;
163
+ fill: none;
164
+ stroke: white;
165
+ stroke-width: 2;
166
+ stroke-linecap: round;
167
+ stroke-linejoin: round;
168
+ }
169
+
170
+ /* ---- Dragged ghost ---- */
171
+
172
+ .bm .ghost {
173
+ position: absolute;
174
+ width: 22%;
175
+ left: 76%;
176
+ top: 30%;
177
+ background: white;
178
+ border: 1px solid var(--c-lavender-500);
179
+ border-radius: var(--radius-md);
180
+ box-shadow: var(--shadow-3);
181
+ padding: 8px 10px;
182
+ opacity: 0;
183
+ animation: bmGhost var(--bm-dur) linear infinite;
184
+ }
185
+
186
+ /* ---- Cursor ---- */
187
+
188
+ .bm .cursor {
189
+ position: absolute;
190
+ width: 16px;
191
+ height: 16px;
192
+ left: 55%;
193
+ top: 42%;
194
+ fill: var(--c-cobalt-900);
195
+ stroke: white;
196
+ stroke-width: 1;
197
+ filter: drop-shadow(0 1px 2px rgba(10, 23, 47, 0.35));
198
+ animation: bmCursor var(--bm-dur) linear infinite;
199
+ z-index: 2;
200
+ }
201
+
202
+ /* ---- Timeline keyframes ---- */
203
+
204
+ @keyframes bmCursor {
205
+ 0% { left: 55%; top: 42%; }
206
+ 12% { left: 88%; top: 82%; } /* over the FAB */
207
+ 16% { left: 88%; top: 82%; } /* press */
208
+ 24% { left: 82%; top: 36%; } /* over the middle palette tile */
209
+ 30% { left: 82%; top: 36%; } /* grab */
210
+ 58% { left: 26%; top: 66%; } /* drag to the slot */
211
+ 64% { left: 26%; top: 66%; } /* release */
212
+ 82% { left: 55%; top: 42%; }
213
+ 100% { left: 55%; top: 42%; }
214
+ }
215
+
216
+ @keyframes bmFabPress {
217
+ 0%, 11% { transform: scale(1); }
218
+ 13% { transform: scale(0.85); }
219
+ 16%, 100% { transform: scale(1); }
220
+ }
221
+
222
+ @keyframes bmPalette {
223
+ 0%, 15% { opacity: 0; transform: translateX(10px); }
224
+ 18%, 72% { opacity: 1; transform: translateX(0); }
225
+ 78%, 100% { opacity: 0; transform: translateX(10px); }
226
+ }
227
+
228
+ @keyframes bmPaletteTile {
229
+ 0%, 22% { background: var(--c-cobalt-50); border-color: var(--c-cobalt-100); }
230
+ 26%, 34% { background: var(--c-cobalt-100); border-color: var(--c-lavender-500); }
231
+ 38%, 100% { background: var(--c-cobalt-50); border-color: var(--c-cobalt-100); }
232
+ }
233
+
234
+ @keyframes bmGhost {
235
+ 0%, 29% { opacity: 0; left: 76%; top: 30%; transform: scale(1); }
236
+ 31% { opacity: 1; left: 76%; top: 30%; transform: scale(1.02); }
237
+ 58% { opacity: 1; left: 12%; top: 58%; transform: scale(1.02); }
238
+ 61% { opacity: 1; left: 12%; top: 60%; transform: scale(1); }
239
+ 63% { opacity: 0; left: 12%; top: 60%; transform: scale(1); }
240
+ 100% { opacity: 0; left: 12%; top: 60%; transform: scale(1); }
241
+ }
242
+
243
+ @keyframes bmSnapIn {
244
+ 0%, 60% { opacity: 0; }
245
+ 63%, 88% { opacity: 1; }
246
+ 94%, 100% { opacity: 0; }
247
+ }
248
+
249
+ @keyframes bmSlotHint {
250
+ 0%, 38% { border-color: var(--c-cobalt-200); }
251
+ 44%, 58% { border-color: var(--c-lavender-500); }
252
+ 63%, 100% { border-color: var(--c-cobalt-200); }
253
+ }
254
+
255
+ /* ---- Static end state (running={false} and reduced motion) ----
256
+ * Component placed, palette closed, no cursor, no ghost. */
257
+
258
+ .bm .static .snapTile,
259
+ .bm .static .slot,
260
+ .bm .static .fab,
261
+ .bm .static .palette,
262
+ .bm .static .paletteTile,
263
+ .bm .static .ghost,
264
+ .bm .static .cursor { animation: none; }
265
+ .bm .static .snapTile { opacity: 1; }
266
+ .bm .static .slot {
267
+ border-style: solid;
268
+ border-color: var(--c-cobalt-100);
269
+ border-width: 1px;
270
+ background: var(--c-cobalt-50);
271
+ }
272
+ .bm .static .palette, .bm .static .ghost, .bm .static .cursor { opacity: 0; visibility: hidden; }
273
+
274
+ @media (prefers-reduced-motion: reduce) {
275
+ .bm .snapTile,
276
+ .bm .slot,
277
+ .bm .fab,
278
+ .bm .palette,
279
+ .bm .paletteTile,
280
+ .bm .ghost,
281
+ .bm .cursor { animation: none; }
282
+ .bm .snapTile { opacity: 1; }
283
+ .bm .slot {
284
+ border-style: solid;
285
+ border-color: var(--c-cobalt-100);
286
+ border-width: 1px;
287
+ background: var(--c-cobalt-50);
288
+ }
289
+ .bm .palette, .bm .ghost, .bm .cursor { opacity: 0; visibility: hidden; }
290
+ }