@conduction/docusaurus-preset 3.34.0 → 3.36.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 (55) hide show
  1. package/ANIMATION_ROADMAP.md +129 -0
  2. package/MISSING_COMPONENTS.md +13 -4
  3. package/package.json +3 -2
  4. package/src/components/AppMock/AppMock.jsx +14 -14
  5. package/src/components/AppMock/AppMock.module.css +1270 -7
  6. package/src/components/AppMock/__tests__/AppMock.render.test.js +148 -0
  7. package/src/components/AppMock/variants/AppVersionsMock.jsx +1 -1
  8. package/src/components/AppMock/variants/DeciDeskMock.jsx +47 -6
  9. package/src/components/AppMock/variants/DocuDeskMock.jsx +40 -10
  10. package/src/components/AppMock/variants/DoriathMock.jsx +29 -14
  11. package/src/components/AppMock/variants/HermiqMock.jsx +35 -15
  12. package/src/components/AppMock/variants/HrmqMock.jsx +46 -28
  13. package/src/components/AppMock/variants/LarpingAppMock.jsx +14 -4
  14. package/src/components/AppMock/variants/LaunchPadWidgetsMock.jsx +3 -3
  15. package/src/components/AppMock/variants/NLDesignMock.jsx +1 -1
  16. package/src/components/AppMock/variants/OpenBuildMock.jsx +21 -6
  17. package/src/components/AppMock/variants/OpenCatalogiMock.jsx +23 -4
  18. package/src/components/AppMock/variants/OpenConnectorMock.jsx +26 -4
  19. package/src/components/AppMock/variants/OpenRegisterMock.jsx +13 -2
  20. package/src/components/AppMock/variants/PlanixMock.jsx +1 -1
  21. package/src/components/AppMock/variants/ProcestMock.jsx +36 -9
  22. package/src/components/AppMock/variants/ScholiqMock.jsx +1 -1
  23. package/src/components/AppMock/variants/ShillinqMock.jsx +33 -17
  24. package/src/components/AppMock/variants/SoftwareCatalogMock.jsx +16 -6
  25. package/src/components/AppMock/variants/ZaakAfhandelAppMock.jsx +19 -4
  26. package/src/components/BuildMock/BuildMock.jsx +3 -3
  27. package/src/components/FeaturesPage/FeaturesPage.jsx +3 -3
  28. package/src/components/IntegrationIcon/registry.js +3 -3
  29. package/src/components/LeafCard/LeafCard.jsx +2 -2
  30. package/src/components/NextSteps/NextSteps.jsx +1 -1
  31. package/src/components/PartnerDirectory/PartnerDirectory.jsx +1 -1
  32. package/src/components/Pipeline/Pipeline.jsx +2 -2
  33. package/src/components/PlatformOverview/PlatformOverview.module.css +1 -1
  34. package/src/components/SidebarMock/SidebarMock.jsx +38 -11
  35. package/src/components/SidebarMock/SidebarMock.module.css +1 -1
  36. package/src/components/SidebarMock/__tests__/SidebarMock.render.test.js +115 -0
  37. package/src/components/SidebarMock/variants/DeciDeskDecision.jsx +1 -1
  38. package/src/components/SidebarMock/variants/DocuDeskPiiMap.jsx +1 -1
  39. package/src/components/SidebarMock/variants/DocuDeskSignatures.jsx +1 -1
  40. package/src/components/SidebarMock/variants/OpenConnectorRunDetail.jsx +1 -1
  41. package/src/components/SidebarMock/variants/ProcestTimeline.jsx +1 -1
  42. package/src/components/SidebarMock/variants/ProcestXWiki.jsx +2 -2
  43. package/src/components/SolutionCard/SolutionCard.jsx +1 -1
  44. package/src/components/WidgetMock/WidgetMock.jsx +37 -16
  45. package/src/components/WidgetMock/__tests__/WidgetMock.render.test.js +125 -0
  46. package/src/components/WidgetMock/variants/DeciDeskActions.jsx +1 -1
  47. package/src/components/WidgetMock/variants/DocuDeskAnonymise.jsx +7 -2
  48. package/src/components/WidgetMock/variants/DocuDeskPendingSign.jsx +1 -1
  49. package/src/components/WidgetMock/variants/OpenConnectorRuns.jsx +1 -1
  50. package/src/components/WidgetMock/variants/ProcestDueToday.jsx +1 -1
  51. package/src/components/WidgetMock/variants/ProcestWerkvoorraad.jsx +1 -1
  52. package/src/components/WidgetShelf/WidgetShelf.jsx +1 -1
  53. package/src/data/apps-registry.js +15 -15
  54. package/src/diagrams/cn-pair.js +1 -1
  55. package/src/theme/brand.jsx +2 -2
@@ -1,11 +1,17 @@
1
1
  /**
2
- * LarpingApp abstract — character + scene workshop.
2
+ * Larpinq abstract — character + scene workshop.
3
3
  *
4
4
  * Inferred from the app role (LARP setting management, character sheets,
5
5
  * scenes, NPCs, factions): centre shows a character grid (3×2 cards
6
6
  * with hex avatars in different family tones) plus a scene timeline
7
7
  * across the top so a session organiser can move stages forward. Left
8
8
  * nav for characters / scenes / NPCs / factions / rules / archive.
9
+ *
10
+ * Animation (wave 4, the XP ripple): the second character card lifts,
11
+ * an XP hex token rises from it to the scene timeline's active stage,
12
+ * the stage hex pulses as it absorbs the token, and every character
13
+ * card's text rows grow in a stagger — the whole party levelling from
14
+ * the played scene. Base styles are the settled (post-XP) end state.
9
15
  */
10
16
 
11
17
  import React from 'react';
@@ -22,7 +28,7 @@ export default function LarpingAppMock() {
22
28
  <div className={styles.bell}></div>
23
29
  <div className={styles.avatar}></div>
24
30
  </div>
25
- <div className={[styles.body, styles.opencatalogi].filter(Boolean).join(' ')}>
31
+ <div className={[styles.body, styles.opencatalogi, styles.larping].filter(Boolean).join(' ')}>
26
32
  <div className={styles.nav}>
27
33
  <div className={styles.navHead}><div className={styles.h}></div><div className={styles.l}></div></div>
28
34
  {[true, false, false, false, false, false].map((active, i) => (
@@ -58,10 +64,11 @@ export default function LarpingAppMock() {
58
64
  </div>
59
65
  </div>
60
66
  </div>
61
- {/* Character grid */}
67
+ {/* Character grid. Card 2 (.xpSource) lifts and releases the
68
+ XP token that travels up to the timeline's active stage. */}
62
69
  <div className={styles.grid}>
63
70
  {charTones.map((cls, i) => (
64
- <div key={i} className={[styles.card, cls && styles[cls]].filter(Boolean).join(' ')}>
71
+ <div key={i} className={[styles.card, cls && styles[cls], i === 1 && styles.xpSource].filter(Boolean).join(' ')}>
65
72
  <div className={styles.ico}></div>
66
73
  <div className={styles.row + ' ' + styles.head}></div>
67
74
  <div className={styles.row + ' ' + styles.short}></div>
@@ -71,6 +78,9 @@ export default function LarpingAppMock() {
71
78
  </div>
72
79
  ))}
73
80
  </div>
81
+ {/* XP token — travels from the lifted card to the timeline.
82
+ Hidden at rest and in static frames. */}
83
+ <div className={styles.xpToken}></div>
74
84
  </div>
75
85
  </div>
76
86
  </>
@@ -4,8 +4,8 @@
4
4
  * Demonstrates the cross-app widget angle: any Conduction app that
5
5
  * registers a Nextcloud dashboard widget shows up here. The mock
6
6
  * pictures the canonical mix:
7
- * - DocuDesk → upload-to-anonymise dropzone widget
8
- * - Procest → werkvoorraad (case queue) widget
7
+ * - Filinq → upload-to-anonymise dropzone widget
8
+ * - Dossiq → werkvoorraad (case queue) widget
9
9
  * - Mail → Important mail (avatar list)
10
10
  * - Calendar → upcoming-events mini grid
11
11
  * - Jira → external-app status board
@@ -37,7 +37,7 @@ export default function LaunchPadWidgetsMock() {
37
37
  </div>
38
38
  <div className={[styles.body, styles.launchpad, styles.lpWidgets].filter(Boolean).join(' ')}>
39
39
  <div className={styles.grid}>
40
- {/* Column 1: Procest werkvoorraad + DocuDesk upload */}
40
+ {/* Column 1: Dossiq werkvoorraad + Filinq upload */}
41
41
  <div className={styles.col}>
42
42
  <div className={[styles.w, styles['w-werkvoorraad']].join(' ')} style={ARRIVE(0)}>
43
43
  <div className={styles.wHead}>
@@ -1,5 +1,5 @@
1
1
  /**
2
- * NLDesign abstract — theme settings panel.
2
+ * Thematiq abstract — theme settings panel.
3
3
  *
4
4
  * Inferred from the app role (NL Design System theme for Nextcloud):
5
5
  * centre shows a settings layout with a colour-swatch row, a type
@@ -1,5 +1,5 @@
1
1
  /**
2
- * OpenBuild abstract — three-pane citizen-developer app builder: left
2
+ * Buildiq abstract — three-pane citizen-developer app builder: left
3
3
  * builder nav + centre dashboard + right manifest/detail rail.
4
4
  * Reference: live screenshot at http://localhost:8080/apps/openbuild/.
5
5
  *
@@ -7,6 +7,12 @@
7
7
  * Published / Templates / Versions) over two panels — a virtual-app card
8
8
  * list ("Virtual apps") and a template-catalogue list ("Templates").
9
9
  * Right rail abstracts the per-app manifest/schema editor.
10
+ *
11
+ * Animation (wave 4): the top template row highlights, a ghost chip
12
+ * travels from the template catalogue into the virtual-apps list, the
13
+ * new app row lands there, the first KPI widens, and the published
14
+ * KPI's hex pulses mint — template to running app in one loop. Base
15
+ * styles are the published end state.
10
16
  */
11
17
 
12
18
  import React from 'react';
@@ -40,11 +46,11 @@ export default function OpenBuildMock({ sidebar = null }) {
40
46
  <div className={styles.col}>
41
47
  {/* KPI strip: Virtual apps / Published / Templates / Versions */}
42
48
  <div className={styles.kpiRow}>
43
- <div className={styles.kpi}>
49
+ <div className={[styles.kpi, styles.kpiGrow].join(' ')}>
44
50
  <div className={styles.ico}></div>
45
51
  <div className={styles.meta}><div className={styles.num}></div><div className={styles.label}></div></div>
46
52
  </div>
47
- <div className={[styles.kpi, styles.forest].join(' ')}>
53
+ <div className={[styles.kpi, styles.forest, styles.publishedKpi].join(' ')}>
48
54
  <div className={styles.ico}></div>
49
55
  <div className={styles.meta}><div className={styles.num}></div><div className={styles.label}></div></div>
50
56
  </div>
@@ -57,12 +63,18 @@ export default function OpenBuildMock({ sidebar = null }) {
57
63
  <div className={styles.meta}><div className={styles.num}></div><div className={styles.label}></div></div>
58
64
  </div>
59
65
  </div>
60
- {/* Virtual-app card list + template catalogue */}
66
+ {/* Virtual-app card list + template catalogue. The ghost
67
+ chip travels template row → apps list; the new app row
68
+ (.newApp) lands at the top of the virtual-apps stack. */}
61
69
  <div className={styles.panelRow}>
62
70
  <div className={styles.panel}>
63
71
  <div className={styles.head}><div className={styles.title}></div></div>
64
72
  <div className={styles.stack}>
65
- {['b','d','a','c'].map((cls, i) => (
73
+ <div className={[styles.item, styles.newApp].join(' ')}>
74
+ <div className={[styles.av, styles.b].join(' ')}></div>
75
+ <div className={styles.lines}><div className={styles.l1}></div><div className={styles.l2}></div></div>
76
+ </div>
77
+ {['d','a','c'].map((cls, i) => (
66
78
  <div key={i} className={styles.item}>
67
79
  <div className={[styles.av, styles[cls]].join(' ')}></div>
68
80
  <div className={styles.lines}><div className={styles.l1}></div><div className={styles.l2}></div></div>
@@ -74,13 +86,16 @@ export default function OpenBuildMock({ sidebar = null }) {
74
86
  <div className={styles.head}><div className={styles.title}></div></div>
75
87
  <div className={styles.stack}>
76
88
  {[0,1,2,3].map(i => (
77
- <div key={i} className={styles.item}>
89
+ <div key={i} className={[styles.item, i === 0 && styles.tplSource].filter(Boolean).join(' ')}>
78
90
  <div className={styles.lines}><div className={styles.l1}></div></div>
79
91
  </div>
80
92
  ))}
81
93
  </div>
82
94
  </div>
83
95
  </div>
96
+ {/* Ghost chip — travels from the template catalogue into the
97
+ virtual-apps list. Hidden at rest and in static frames. */}
98
+ <div className={styles.buildGhost}></div>
84
99
  </div>
85
100
  {/* Right rail: per-app manifest / schema editor. When AppMock passes
86
101
  a `sidebar` prop it renders there instead of this placeholder. */}
@@ -5,13 +5,28 @@
5
5
  * search across registers"): centre is a 3×2 grid of catalogue cards,
6
6
  * each with a hex glyph in a different family colour to signal the
7
7
  * categorical mix. Left nav for catalogues / publications / sources.
8
+ *
9
+ * Animation (wave 2): a query types into the search bar, the grid
10
+ * dims, the three matching cards snap back to full strength, and
11
+ * their status pills tick mint. Base styles are the filtered end
12
+ * state (non-matches dimmed); keyframes replay the unfiltered
13
+ * before-state and the search.
8
14
  */
9
15
 
10
16
  import React from 'react';
11
17
  import styles from '../AppMock.module.css';
12
18
 
19
+ /* Cards 1, 3 and 5 (indices 0/2/4) match the query; the others dim. */
20
+ const CARDS = [
21
+ {tone: '', match: true},
22
+ {tone: 'b', match: false},
23
+ {tone: 'c', match: true},
24
+ {tone: 'd', match: false},
25
+ {tone: 'e', match: true},
26
+ {tone: '', match: false},
27
+ ];
28
+
13
29
  export default function OpenCatalogiMock() {
14
- const cards = ['', 'b', 'c', 'd', 'e', ''];
15
30
  return (
16
31
  <>
17
32
  <div className={styles.topbar}>
@@ -36,14 +51,18 @@ export default function OpenCatalogiMock() {
36
51
  <div className={styles.col}>
37
52
  <div className={styles.head}>
38
53
  <div className={styles.row + ' ' + styles.head} style={{width: 30}}></div>
54
+ {/* Federated search bar — the query types in, the grid filters */}
55
+ <div className={styles.search}>
56
+ <div className={styles.sIco}></div>
57
+ <div className={styles.q}></div>
58
+ </div>
39
59
  <div className={styles.actions}>
40
- <div className={styles.btn + ' ' + styles.ghost}></div>
41
60
  <div className={styles.btn}></div>
42
61
  </div>
43
62
  </div>
44
63
  <div className={styles.grid}>
45
- {cards.map((cls, i) => (
46
- <div key={i} className={[styles.card, cls && styles[cls]].filter(Boolean).join(' ')}>
64
+ {CARDS.map(({tone, match}, i) => (
65
+ <div key={i} className={[styles.card, tone && styles[tone], match ? styles.match : styles.dim].filter(Boolean).join(' ')}>
47
66
  <div className={styles.ico}></div>
48
67
  <div className={styles.row + ' ' + styles.head}></div>
49
68
  <div className={styles.row}></div>
@@ -1,11 +1,16 @@
1
1
  /**
2
- * OpenConnector abstract — source-connector-target pipeline view.
2
+ * Integriq abstract — source-connector-target pipeline view.
3
3
  *
4
4
  * Inferred from the app's role ("integration plane between Conduction
5
5
  * apps and external APIs"): the centre stage shows a single canonical
6
6
  * pipeline (lavender source → cobalt connector → forest target), with
7
7
  * a status table below for recent runs. Left nav for sources, jobs,
8
8
  * mappings, sync logs, schedules.
9
+ *
10
+ * Animation (wave 2): a lavender record dot travels source →
11
+ * connector, re-emerges forest on the far side → target (the mapping
12
+ * made visible), then a new run row inserts at the top of the runs
13
+ * table and ticks mint. Base styles are the completed end state.
9
14
  */
10
15
 
11
16
  import React from 'react';
@@ -45,12 +50,18 @@ export default function OpenConnectorMock() {
45
50
  <div className={styles.ico}></div>
46
51
  <div className={styles.row + ' ' + styles.short}></div>
47
52
  </div>
48
- <div className={styles.arrow}></div>
53
+ <div className={styles.arrow}>
54
+ {/* Record dot, lavender leg: source → connector */}
55
+ <div className={styles.travelDotA}></div>
56
+ </div>
49
57
  <div className={styles.conn}>
50
58
  <div className={styles.ico}></div>
51
59
  <div className={styles.label}></div>
52
60
  </div>
53
- <div className={styles.arrow}></div>
61
+ <div className={styles.arrow}>
62
+ {/* Record dot, forest leg: connector → target */}
63
+ <div className={styles.travelDotB}></div>
64
+ </div>
54
65
  <div className={styles.target}>
55
66
  <div className={styles.ico}></div>
56
67
  <div className={styles.row + ' ' + styles.short}></div>
@@ -64,7 +75,18 @@ export default function OpenConnectorMock() {
64
75
  </div>
65
76
  </div>
66
77
  <div className={styles.stack}>
67
- {['a','d','b','c'].map((cls, i) => (
78
+ {/* The freshly-inserted run row: slides in when the dot
79
+ lands, its trailing pip ticks mint. Present (mint)
80
+ in the static end state. */}
81
+ <div className={[styles.item, styles.newRun].join(' ')}>
82
+ <div className={[styles.av, styles.d].join(' ')}></div>
83
+ <div className={styles.lines}>
84
+ <div className={styles.l1}></div>
85
+ <div className={styles.l2}></div>
86
+ </div>
87
+ <div className={styles.runTick}></div>
88
+ </div>
89
+ {['a','d','b'].map((cls, i) => (
68
90
  <div key={i} className={styles.item}>
69
91
  <div className={[styles.av, styles[cls]].join(' ')}></div>
70
92
  <div className={styles.lines}>
@@ -5,6 +5,11 @@
5
5
  * Centre is the canonical "Dashboard" view: KPI strip top, two
6
6
  * side-by-side tables ("Popular Search Terms" / "Objects by Register"),
7
7
  * second row of two more. Right rail shows Filter Statistics + Totals.
8
+ *
9
+ * Animation (wave 2): a new object row lands in the "Objects by
10
+ * Register" table, the first KPI's number widens to absorb the count,
11
+ * and the right-rail statistics rows repaint in a stagger — the
12
+ * dashboard reacting to a write. Base styles are the landed end state.
8
13
  */
9
14
 
10
15
  import React from 'react';
@@ -38,7 +43,7 @@ export default function OpenRegisterMock({ sidebar = null }) {
38
43
  <div className={styles.col}>
39
44
  {/* KPI strip */}
40
45
  <div className={styles.kpiRow}>
41
- <div className={styles.kpi}>
46
+ <div className={[styles.kpi, styles.kpiGrow].join(' ')}>
42
47
  <div className={styles.ico}></div>
43
48
  <div className={styles.meta}><div className={styles.num}></div><div className={styles.label}></div></div>
44
49
  </div>
@@ -70,7 +75,13 @@ export default function OpenRegisterMock({ sidebar = null }) {
70
75
  <div className={styles.panel}>
71
76
  <div className={styles.head}><div className={styles.title}></div></div>
72
77
  <div className={styles.stack}>
73
- {['b','d','c','a'].map((cls, i) => (
78
+ {/* The freshly-written object row: lands with a slide
79
+ when the loop fires. Present in static frames. */}
80
+ <div className={[styles.item, styles.newObj].join(' ')}>
81
+ <div className={[styles.av, styles.d].join(' ')}></div>
82
+ <div className={styles.lines}><div className={styles.l1}></div></div>
83
+ </div>
84
+ {['b','d','c'].map((cls, i) => (
74
85
  <div key={i} className={styles.item}>
75
86
  <div className={[styles.av, styles[cls]].join(' ')}></div>
76
87
  <div className={styles.lines}><div className={styles.l1}></div></div>
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Planix abstract — planning board.
2
+ * Planiq abstract — planning board.
3
3
  *
4
4
  * Inferred from the app role (scheduling people and work over time):
5
5
  * a week grid of five day columns with placed planning blocks at
@@ -1,11 +1,17 @@
1
1
  /**
2
- * Procest abstract — case management with process timeline.
2
+ * Dossiq abstract — case management with process timeline.
3
3
  *
4
4
  * Inferred from app role (ZGW case-management for VTH and citizen
5
5
  * processes): centre shows a canonical case detail with the timeline
6
- * of stages running across the top (one done, one active, three to-do)
6
+ * of stages running across the top (two done, one active, two to-do)
7
7
  * plus a list of recent cases below. Left nav for cases, types,
8
8
  * roles, decisions, archive.
9
+ *
10
+ * Animation (wave 2): the case advances one stage — ghost hexes
11
+ * overlaid on steps 2 and 3 replay the before-state (step 2 still
12
+ * orange-active, step 3 still to-do) and fade away to reveal the
13
+ * advanced base state; the advanced case's list row re-sorts to the
14
+ * top. Base styles are the advanced end state throughout.
9
15
  */
10
16
 
11
17
  import React from 'react';
@@ -41,17 +47,21 @@ export default function ProcestMock({ sidebar = null }) {
41
47
  <div className={styles.btn}></div>
42
48
  </div>
43
49
  </div>
50
+ {/* Base = advanced state: done, done, now, todo, todo.
51
+ Ghost hexes on steps 2+3 replay the before-state. */}
44
52
  <div className={styles.timeline}>
45
53
  <div className={styles.step}>
46
54
  <div className={styles.h}></div>
47
55
  <div className={styles.label}></div>
48
56
  </div>
49
- <div className={[styles.step, styles.now].join(' ')}>
57
+ <div className={[styles.step, styles.advanceFrom].join(' ')}>
50
58
  <div className={styles.h}></div>
59
+ <div className={[styles.ghost, styles.ghostNow].join(' ')}></div>
51
60
  <div className={styles.label}></div>
52
61
  </div>
53
- <div className={[styles.step, styles.todo].join(' ')}>
62
+ <div className={[styles.step, styles.now, styles.advanceTo].join(' ')}>
54
63
  <div className={styles.h}></div>
64
+ <div className={[styles.ghost, styles.ghostTodo].join(' ')}></div>
55
65
  <div className={styles.label}></div>
56
66
  </div>
57
67
  <div className={[styles.step, styles.todo].join(' ')}>
@@ -66,16 +76,33 @@ export default function ProcestMock({ sidebar = null }) {
66
76
  <div className={styles.panel}>
67
77
  <div className={styles.head}><div className={styles.title}></div></div>
68
78
  <div className={styles.stack}>
69
- {['a','b','d','c','a'].map((cls, i) => (
79
+ {/* DOM order = end state: the advanced case (status pill,
80
+ .sortUp) sits on top; the row it overtook (.sortDown)
81
+ is second. The keyframes replay the pre-sort order. */}
82
+ <div className={[styles.item, styles.sortUp].join(' ')}>
83
+ <div className={[styles.av, styles.b].join(' ')}></div>
84
+ <div className={styles.lines}>
85
+ <div className={styles.l1}></div>
86
+ <div className={styles.l2}></div>
87
+ </div>
88
+ <div className={styles.statusPill}>
89
+ <div className={styles.h}></div><div className={styles.t}></div>
90
+ </div>
91
+ </div>
92
+ <div className={[styles.item, styles.sortDown].join(' ')}>
93
+ <div className={[styles.av, styles.a].filter(Boolean).join(' ')}></div>
94
+ <div className={styles.lines}>
95
+ <div className={styles.l1}></div>
96
+ <div className={styles.l2}></div>
97
+ </div>
98
+ </div>
99
+ {['d','c','a'].map((cls, i) => (
70
100
  <div key={i} className={styles.item}>
71
101
  <div className={[styles.av, styles[cls]].join(' ')}></div>
72
102
  <div className={styles.lines}>
73
103
  <div className={styles.l1}></div>
74
104
  <div className={styles.l2}></div>
75
105
  </div>
76
- <div className={[styles.statusPill, i === 1 && styles.beta].filter(Boolean).join(' ')}>
77
- <div className={styles.h}></div><div className={styles.t}></div>
78
- </div>
79
106
  </div>
80
107
  ))}
81
108
  </div>
@@ -83,7 +110,7 @@ export default function ProcestMock({ sidebar = null }) {
83
110
  </div>
84
111
  {/* Optional sidebar (typically a <SidebarMock kind="..." />)
85
112
  renders here as a flex sibling of .col, taking the .detail
86
- slot. Procest's case detail view doesn't ship a default
113
+ slot. Dossiq's case detail view doesn't ship a default
87
114
  detail rail, so without the prop nothing extra renders. */}
88
115
  {sidebar}
89
116
  </div>
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Scholiq abstract — learning environment.
2
+ * Learniq abstract — learning environment.
3
3
  *
4
4
  * Inferred from the app role (courses, lessons, credentials): centre
5
5
  * shows a course-card grid, each card carrying a progress bar, with a
@@ -6,15 +6,23 @@
6
6
  * description, two amount columns (net / VAT), and a reconciliation
7
7
  * tick column where a mint hex = matched against the bank and a
8
8
  * muted pip = still open. Tone: terracotta — documents, human work.
9
+ *
10
+ * Animation (wave 2): a bank statement line slides down onto invoice
11
+ * row 3, both tick mint (reconciled), the totals line and the first
12
+ * KPI grow to absorb the match. Base styles are the reconciled end
13
+ * state; keyframes replay the unmatched before-state and the slide.
9
14
  */
10
15
 
11
16
  import React from 'react';
12
17
  import styles from '../AppMock.module.css';
13
18
 
19
+ /* Row 3 (index 2) is the row the bank line reconciles: its tick is
20
+ mint in the base (end) state and the amShqTick keyframe replays
21
+ the open cobalt-200 before-state. Row 5 stays open. */
14
22
  const INVOICES = [
15
23
  {amount: 26, vat: 16, matched: true},
16
24
  {amount: 20, vat: 12, matched: true},
17
- {amount: 30, vat: 18, matched: false},
25
+ {amount: 30, vat: 18, matched: true, reconciling: true},
18
26
  {amount: 22, vat: 14, matched: true},
19
27
  {amount: 18, vat: 10, matched: false},
20
28
  ];
@@ -29,7 +37,7 @@ export default function ShillinqMock() {
29
37
  <div className={styles.bell}></div>
30
38
  <div className={styles.avatar}></div>
31
39
  </div>
32
- <div className={[styles.body, styles.decidesk].filter(Boolean).join(' ')}>
40
+ <div className={[styles.body, styles.decidesk, styles.shillinq].filter(Boolean).join(' ')}>
33
41
  <div className={styles.nav}>
34
42
  <div className={styles.navHead}><div className={styles.h}></div><div className={styles.l}></div></div>
35
43
  {[true, false, false, false, false].map((active, i) => (
@@ -47,14 +55,15 @@ export default function ShillinqMock() {
47
55
  <div className={styles.btn}></div>
48
56
  </div>
49
57
  </div>
50
- {/* VAT / summary strip */}
58
+ {/* VAT / summary strip. The first KPI's number widens when
59
+ the reconciliation lands. */}
51
60
  <div className={styles.kpiRow}>
52
- <div className={styles.kpi}>
53
- <div className={styles.ico} style={{background: 'var(--c-terracotta-500)'}}></div>
61
+ <div className={[styles.kpi, styles.kpiGrow].join(' ')}>
62
+ <div className={[styles.ico, styles.terra].join(' ')}></div>
54
63
  <div className={styles.meta}><div className={styles.num}></div><div className={styles.label}></div></div>
55
64
  </div>
56
65
  <div className={styles.kpi}>
57
- <div className={styles.ico} style={{background: 'var(--c-terracotta-300)'}}></div>
66
+ <div className={[styles.ico, styles.terraSoft].join(' ')}></div>
58
67
  <div className={styles.meta}><div className={styles.num}></div><div className={styles.label}></div></div>
59
68
  </div>
60
69
  <div className={styles.kpi}>
@@ -63,24 +72,31 @@ export default function ShillinqMock() {
63
72
  </div>
64
73
  </div>
65
74
  {/* Invoice table: doc · description · net · VAT · reconciled */}
66
- <div className={styles.panel} style={{flex: 1}}>
75
+ <div className={[styles.panel, styles.ledger].join(' ')}>
67
76
  <div className={styles.head}><div className={styles.title}></div></div>
77
+ {/* Bank statement line — slides onto row 3 and dissolves
78
+ into the mint tick. Hidden at rest and in static frames. */}
79
+ <div className={styles.bankLine}>
80
+ <div className={styles.bIco}></div>
81
+ <div className={styles.bBar}></div>
82
+ <div className={styles.bAmt}></div>
83
+ </div>
68
84
  <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>
85
+ {INVOICES.map(({amount, vat, matched, reconciling}, i) => (
86
+ <div key={i} className={[styles.item, styles.inv, reconciling && styles.reconciling].filter(Boolean).join(' ')}>
87
+ <div className={styles.doc}></div>
72
88
  <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>
89
+ <div className={styles.net} style={{width: amount}}></div>
90
+ <div className={styles.vat} style={{width: vat}}></div>
75
91
  {/* 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>
92
+ <div className={[styles.tick, !matched && styles.open].filter(Boolean).join(' ')}></div>
77
93
  </div>
78
94
  ))}
79
95
  </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>
96
+ {/* Totals line — grows when the match lands */}
97
+ <div className={styles.totals}>
98
+ <div className={styles.totNet}></div>
99
+ <div className={styles.totVat}></div>
84
100
  </div>
85
101
  </div>
86
102
  </div>
@@ -1,11 +1,18 @@
1
1
  /**
2
- * SoftwareCatalog abstract — IT-asset inventory list.
2
+ * Stackiq abstract — IT-asset inventory list.
3
3
  *
4
4
  * Inferred from the app role (software inventory, licences, contracts,
5
5
  * dependencies): centre shows a tabular app list with status pips
6
6
  * (mint = stable, orange = update available, red = end-of-life) plus
7
7
  * a graph card on top showing licence-renewal timeline. Left nav for
8
8
  * apps / licences / contracts / dependencies / discovery / archive.
9
+ *
10
+ * Animation (wave 4, the CVE scan): a scan band sweeps down the app
11
+ * list, row 4's pip flips to red as the sweep crosses it (a CVE
12
+ * found), and the matching chart bar surges in vermillion. The chart
13
+ * keeps its single KNVB-orange accent bar; the CVE reading is
14
+ * red-family throughout so the component stays at one orange.
15
+ * Base styles are the post-scan end state (red pip, tall CVE bar).
9
16
  */
10
17
 
11
18
  import React from 'react';
@@ -21,7 +28,7 @@ export default function SoftwareCatalogMock() {
21
28
  <div className={styles.bell}></div>
22
29
  <div className={styles.avatar}></div>
23
30
  </div>
24
- <div className={[styles.body, styles.openregister].filter(Boolean).join(' ')}>
31
+ <div className={[styles.body, styles.openregister, styles.swc].filter(Boolean).join(' ')}>
25
32
  <div className={styles.nav}>
26
33
  <div className={styles.navHead}><div className={styles.h}></div><div className={styles.l}></div></div>
27
34
  {[true, false, false, false, false, false].map((active, i) => (
@@ -40,7 +47,8 @@ export default function SoftwareCatalogMock() {
40
47
  <div className={styles.bars}>
41
48
  <div className={styles.bar} style={{height: '30%'}}></div>
42
49
  <div className={styles.bar} style={{height: '50%'}}></div>
43
- <div className={styles.bar} style={{height: '40%'}}></div>
50
+ {/* CVE bar surges (vermillion, red family) post-scan */}
51
+ <div className={[styles.bar, styles.cve].join(' ')} style={{height: '64%'}}></div>
44
52
  <div className={styles.bar} style={{height: '70%'}}></div>
45
53
  <div className={[styles.bar, styles.accent].join(' ')} style={{height: '88%'}}></div>
46
54
  <div className={styles.bar} style={{height: '60%'}}></div>
@@ -49,16 +57,18 @@ export default function SoftwareCatalogMock() {
49
57
  </div>
50
58
  <div className={styles.axis}></div>
51
59
  </div>
52
- {/* App list with status pips */}
53
- <div className={[styles.w, styles['w-jira']].join(' ')}>
60
+ {/* App list with status pips. The scan band sweeps this
61
+ panel; row 4 (.blocked, .cveHit) flips red as it passes. */}
62
+ <div className={[styles.w, styles['w-jira'], styles.scanPanel].join(' ')}>
54
63
  <div className={styles.wHead}>
55
64
  <div className={styles.h}></div><div className={styles.t}></div>
56
65
  </div>
66
+ <div className={styles.scanBand}></div>
57
67
  <div className={styles.list}>
58
68
  <div className={styles.item}><div className={styles.id}></div><div className={styles.l}></div><div className={styles.pip}></div></div>
59
69
  <div className={[styles.item, styles.review].join(' ')}><div className={styles.id}></div><div className={styles.l}></div><div className={styles.pip}></div></div>
60
70
  <div className={styles.item}><div className={styles.id}></div><div className={styles.l}></div><div className={styles.pip}></div></div>
61
- <div className={[styles.item, styles.blocked].join(' ')}><div className={styles.id}></div><div className={styles.l}></div><div className={styles.pip}></div></div>
71
+ <div className={[styles.item, styles.blocked, styles.cveHit].join(' ')}><div className={styles.id}></div><div className={styles.l}></div><div className={styles.pip}></div></div>
62
72
  <div className={styles.item}><div className={styles.id}></div><div className={styles.l}></div><div className={styles.pip}></div></div>
63
73
  <div className={styles.item}><div className={styles.id}></div><div className={styles.l}></div><div className={styles.pip}></div></div>
64
74
  <div className={[styles.item, styles.todo].join(' ')}><div className={styles.id}></div><div className={styles.l}></div><div className={styles.pip}></div></div>
@@ -6,6 +6,13 @@
6
6
  * (werkvoorraad widget) with stage pips, plus a citizen-side timeline
7
7
  * of recent submissions. Left nav for queue / archive / public portal /
8
8
  * audit / settings.
9
+ *
10
+ * Animation (wave 4): a citizen submission travels up from the
11
+ * submissions list into the werkvoorraad — the ghost row rises, and
12
+ * the new case row at the top of the queue gains its stage hex and
13
+ * assignee avatar as it lands. The late row's red stage pip pulses
14
+ * once per loop as the SLA reminder. Base styles are the assigned
15
+ * end state (new case present, fully dressed).
9
16
  */
10
17
 
11
18
  import React from 'react';
@@ -21,7 +28,7 @@ export default function ZaakAfhandelAppMock() {
21
28
  <div className={styles.bell}></div>
22
29
  <div className={styles.avatar}></div>
23
30
  </div>
24
- <div className={[styles.body, styles.procest].filter(Boolean).join(' ')}>
31
+ <div className={[styles.body, styles.procest, styles.zaak].filter(Boolean).join(' ')}>
25
32
  <div className={styles.nav}>
26
33
  <div className={styles.navHead}><div className={styles.h}></div><div className={styles.l}></div></div>
27
34
  {[true, false, false, false, false].map((active, i) => (
@@ -39,26 +46,34 @@ export default function ZaakAfhandelAppMock() {
39
46
  <div className={styles.btn}></div>
40
47
  </div>
41
48
  </div>
42
- {/* Case-worker werkvoorraad */}
49
+ {/* Case-worker werkvoorraad. The first row (.zkNew) is the
50
+ citizen submission after landing: its stage hex and
51
+ assignee avatar dress it as it arrives. */}
43
52
  <div className={[styles.w, styles['w-werkvoorraad']].join(' ')}>
44
53
  <div className={styles.wHead}>
45
54
  <div className={styles.h}></div><div className={styles.t}></div>
46
55
  </div>
47
56
  <div className={styles.list}>
57
+ <div className={[styles.item, styles.zkNew].join(' ')}><div className={styles.stage}></div><div className={styles.l1}></div><div className={[styles.av, styles.b].join(' ')}></div></div>
48
58
  <div className={[styles.item, styles.now].join(' ')}><div className={styles.stage}></div><div className={styles.l1}></div><div className={styles.av}></div></div>
49
59
  <div className={styles.item}><div className={styles.stage}></div><div className={styles.l1}></div><div className={[styles.av, styles.b].join(' ')}></div></div>
50
60
  <div className={[styles.item, styles.late].join(' ')}><div className={styles.stage}></div><div className={styles.l1}></div><div className={[styles.av, styles.c].join(' ')}></div></div>
51
61
  <div className={styles.item}><div className={styles.stage}></div><div className={styles.l1}></div><div className={styles.av}></div></div>
52
- <div className={styles.item}><div className={styles.stage}></div><div className={styles.l1}></div><div className={[styles.av, styles.b].join(' ')}></div></div>
53
62
  </div>
54
63
  </div>
64
+ {/* Travelling submission ghost — rises from the submissions
65
+ list into the werkvoorraad. Hidden at rest + static. */}
66
+ <div className={styles.zkGhost}>
67
+ <div className={styles.src}></div>
68
+ <div className={styles.gBar}></div>
69
+ </div>
55
70
  {/* Citizen-side recent submissions list */}
56
71
  <div className={[styles.w, styles['w-rss']].join(' ')}>
57
72
  <div className={styles.wHead}>
58
73
  <div className={styles.h}></div><div className={styles.t}></div>
59
74
  </div>
60
75
  <div className={styles.list}>
61
- <div className={styles.item}><div className={styles.src}></div><div className={styles.title}></div><div className={styles.when}></div></div>
76
+ <div className={[styles.item, styles.zkSent].join(' ')}><div className={styles.src}></div><div className={styles.title}></div><div className={styles.when}></div></div>
62
77
  <div className={styles.item}><div className={styles.src}></div><div className={styles.title}></div><div className={styles.when}></div></div>
63
78
  <div className={styles.item}><div className={styles.src}></div><div className={styles.title}></div><div className={styles.when}></div></div>
64
79
  <div className={styles.item}><div className={styles.src}></div><div className={styles.title}></div><div className={styles.when}></div></div>