@navipartner/demo-video 0.7.0 → 0.7.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -4
- package/bin/demo-video.mjs +92 -17
- package/bin/init.d.mts +2 -0
- package/bin/init.mjs +17 -6
- package/dist/{adapter-CDOXdUZI.d.ts → adapter-bOi1ZBRa.d.ts} +36 -7
- package/dist/{chunk-D7UYGNSF.js → chunk-RMBVQL2J.js} +199 -48
- package/dist/index.d.ts +119 -20
- package/dist/index.js +1 -1
- package/dist/runner/index.d.ts +1 -1
- package/dist/runner/index.js +527 -180
- package/package.json +1 -1
- package/skills/np-demo-video/SKILL.md +213 -229
- package/skills/np-demo-video/look.md +169 -79
- package/skills/np-demo-video/reference.md +81 -30
|
@@ -1,82 +1,133 @@
|
|
|
1
1
|
# The look
|
|
2
2
|
|
|
3
|
-
Every NaviPartner demo video should look and feel the same
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
3
|
+
Every NaviPartner demo video should look and feel the same. They are made
|
|
4
|
+
for serious buyers: operators and owners choosing a system for their shops,
|
|
5
|
+
restaurants and venues. They watch to understand, so a video is brisk where
|
|
6
|
+
nothing is happening and gives information the time it needs. In order of
|
|
7
|
+
importance:
|
|
8
|
+
|
|
9
|
+
1. **The product tells the story; text frames it.** Words live on their own
|
|
10
|
+
cards *between* the chapters, never over the live app. A card may hold a
|
|
11
|
+
snapshot of what its chapter achieves beside the words: the app, captured,
|
|
12
|
+
not a mock-up.
|
|
13
|
+
2. **No dead time.** Setup happens behind cards, only values that show
|
|
14
|
+
something are typed, and every beat is there so the viewer sees
|
|
15
|
+
something. Never rushed: results and cards stay up long enough to read.
|
|
16
|
+
3. **Purposeful camera.** It moves between shots, never during the action:
|
|
17
|
+
the chapter opens on the shot that holds the action and its result,
|
|
18
|
+
holds steady through the clicks, and ends on the result. It never chases
|
|
19
|
+
the cursor, and there are no hard cuts inside a chapter.
|
|
20
|
+
4. **Soft, light, branded.** A pale brand-tinted background, a floating app
|
|
21
|
+
window, big serif statements, and the brand colour used boldly.
|
|
22
|
+
5. **Believable data.** The most real-looking records the e2e mocks have.
|
|
23
|
+
Never "Test item 1" on screen when the story can type a better value.
|
|
24
|
+
|
|
25
|
+
## Two kinds of video
|
|
26
|
+
|
|
27
|
+
A story says which it is (`"kind"`, default `showcase`). The beats are the
|
|
28
|
+
same in both; the shape differs.
|
|
29
|
+
|
|
30
|
+
| | Showcase | Feature clip |
|
|
31
|
+
|---|---|---|
|
|
32
|
+
| Shows | the app's main journey, from start to the moment of value (the primary story is always one) | one feature: "see the new split-bill button" |
|
|
33
|
+
| For | the website, a sales meeting, a buyer comparing systems | release news, a LinkedIn post, a customer update |
|
|
34
|
+
| Length | 45–90 s | 15–30 s |
|
|
35
|
+
| Shape | open card, 2–4 chapters of 10–20 s, a payoff, end card | open card naming the feature, one chapter, end card |
|
|
36
|
+
| Open and end cards | up to 3.5 s | up to 2.5 s |
|
|
16
37
|
|
|
17
|
-
|
|
38
|
+
`check` keeps a feature clip to one chapter and a showcase to four, and
|
|
39
|
+
prints how long the story will run.
|
|
18
40
|
|
|
19
|
-
|
|
20
|
-
should remember.
|
|
41
|
+
### Showcase
|
|
21
42
|
|
|
22
43
|
```
|
|
23
|
-
open card
|
|
24
|
-
┌
|
|
25
|
-
│ demo 10–
|
|
26
|
-
└ payoff 3–
|
|
44
|
+
open card ≤ 3.5 s logo + what the product does for the buyer + a snapshot of the result
|
|
45
|
+
┌ chapter card ~2–4 s "Pay *by card*." + the benefit in one line, beside a snapshot of the result
|
|
46
|
+
│ demo 10–20 s the app doing exactly that, ending on the result
|
|
47
|
+
└ payoff ~3–4 s optional: the result just shown, as a fact
|
|
27
48
|
… 2–4 chapters …
|
|
28
|
-
|
|
29
|
-
|
|
49
|
+
end card ≤ 3.5 s logo + the promise, or the next step
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### Feature clip
|
|
53
|
+
|
|
54
|
+
```
|
|
55
|
+
open card ≤ 2.5 s logo + "New: …" + a snapshot of the feature
|
|
56
|
+
┌ chapter card ~2–3 s the feature's statement + what it does for the customer
|
|
57
|
+
│ demo 8–15 s straight to the feature; all setup behind the card
|
|
58
|
+
end card ≤ 2.5 s logo + where it is available
|
|
30
59
|
```
|
|
31
60
|
|
|
32
|
-
-
|
|
33
|
-
the
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
61
|
+
- **The first seconds carry brand and product.** The open card shows the
|
|
62
|
+
logo and a snapshot of the result (a showcase) or of the feature (a clip),
|
|
63
|
+
so a viewer who stops after two seconds has seen both.
|
|
64
|
+
- Setup the viewer needn't watch (a language dialog, a cookie banner,
|
|
65
|
+
opening a tab) happens behind the card before it, never on screen.
|
|
66
|
+
- Length follows the chapters: don't pad, don't cram.
|
|
38
67
|
|
|
39
|
-
##
|
|
68
|
+
## Cards
|
|
40
69
|
|
|
41
70
|
| Card | Text | Look |
|
|
42
71
|
|---|---|---|
|
|
43
|
-
| Open | eyebrow `Introducing`
|
|
44
|
-
|
|
|
45
|
-
| Payoff | the result just shown
|
|
46
|
-
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
72
|
+
| Open | eyebrow (`Introducing`, or `New` for a clip) · brand logo · one line on what it does for the buyer · a snapshot of the result | pale |
|
|
73
|
+
| Chapter | the statement and the benefit (below), beside a snapshot of the result when there is one | pale and brand colour alternate, chapter by chapter |
|
|
74
|
+
| Payoff | the result just shown; the sub-line states the fact the app showed: "64,50 kr. by card." | full-bleed brand colour |
|
|
75
|
+
| End | logo + the product's promise, or the next step: "Book a demo at navipartner.com." | pale, held still |
|
|
76
|
+
|
|
77
|
+
A **chapter card** has two lines of words, and no eyebrow: chapter numbers
|
|
78
|
+
and topic labels don't help in a film this short.
|
|
79
|
+
|
|
80
|
+
1. **Statement:** ≤ 7 words naming what the chapter shows, in its own verb,
|
|
81
|
+
sentence case, ending with a full stop, **one word or phrase in italic**
|
|
82
|
+
(the action or its result): "Pay *by card*."
|
|
83
|
+
2. **Benefit:** one sub-line, ideally ≤ 12 words, saying what it does for
|
|
84
|
+
the customer as something the chapter then shows. An outcome, not a
|
|
85
|
+
feature name, and a specific value when the app shows one: "Tap, insert
|
|
86
|
+
or phone: the terminal takes it all."
|
|
87
|
+
|
|
88
|
+
**Text and UI on one card.** A card shows a snapshot of the result beside
|
|
89
|
+
the words when there is something visual to show: the finished pass, the
|
|
90
|
+
receipt, the "Paid" screen. The words go left, the snapshot right, in the
|
|
91
|
+
same rounded window and soft shadow as the app. It is the app, captured by
|
|
92
|
+
`check`, never a mock-up. A chapter that ends on a toast or a number stays
|
|
93
|
+
text only, centred.
|
|
94
|
+
|
|
95
|
+
- **Typeface:** the brand's fonts. For NaviPartner: **Merriweather** for
|
|
96
|
+
statements (its italic is the emphasis word), **Work Sans** for eyebrows
|
|
97
|
+
and sub-lines. At 1080p: statements 116 px (92 px beside a snapshot),
|
|
98
|
+
sub-lines 40 px (36 px), the open card's eyebrow 28 px spaced capitals,
|
|
99
|
+
logo 720 px wide.
|
|
100
|
+
- **Tone:** plain, confident, present tense, for a professional audience.
|
|
101
|
+
No exclamation marks except inside a quoted customer line. No "seamless",
|
|
102
|
+
"revolutionary" or "effortless".
|
|
103
|
+
- **Truth:** every fact on a card is visible in the video (the price shown,
|
|
104
|
+
the receipt that appears), checked by an `expectText`. No invented
|
|
105
|
+
durations or customer statistics.
|
|
62
106
|
- **Never on a card:** testids, barcodes, internal names or any other code.
|
|
63
|
-
- **Reading time:** a card stays up
|
|
107
|
+
- **Reading time:** a card stays up 0.6 s plus ~0.28 s a word (an eyebrow's
|
|
108
|
+
words count half), at least 1.8 s. The open and end cards stay at most
|
|
109
|
+
3.5 s in a showcase and 2.5 s in a clip, unless the story asks for more.
|
|
64
110
|
|
|
65
111
|
## Transitions
|
|
66
112
|
|
|
67
|
-
- **Blur dissolve** everywhere.
|
|
68
|
-
~500 ms
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
blur in, so two headings never show at once.
|
|
113
|
+
- **Blur dissolve** everywhere. A card's words blur in from ~12 px to sharp
|
|
114
|
+
over ~500 ms, one after the other: statement, snapshot, sub-line. A
|
|
115
|
+
card hands over to the app by fading out (~600 ms) while the app sharpens
|
|
116
|
+
behind it.
|
|
117
|
+
- Card to card: the old words blur out first (~240 ms), then the new ones
|
|
118
|
+
blur in, so two statements never show at once.
|
|
74
119
|
- No slides, wipes, spins, or zoom-punch transitions.
|
|
75
120
|
|
|
76
121
|
## Camera
|
|
77
122
|
|
|
78
123
|
- **Wide shot:** the app floats in the middle of the frame at ~90 % width.
|
|
79
|
-
Small corner radius, soft long shadow, no browser chrome.
|
|
124
|
+
Small corner radius, soft long shadow, no browser chrome. Wide is for
|
|
125
|
+
moments that need the whole window (a new screen arriving). A desktop app
|
|
126
|
+
shown wide is too small to read on a phone, so clicks whose controls and
|
|
127
|
+
results would fit a push-in get one (`check` asks for it).
|
|
128
|
+
- **A chapter opens on its first shot.** When a chapter starts with a
|
|
129
|
+
push-in, the camera is already there when its card dissolves: no push-in
|
|
130
|
+
after every card.
|
|
80
131
|
- **Push in once per shot** on the area that holds the control *and* what it
|
|
81
132
|
changes, to scale **1.4–1.8** (never past 2: tighter loses the context and
|
|
82
133
|
softens the picture). The UI should fill the frame and read on a phone.
|
|
@@ -85,19 +136,22 @@ end card 3–5 s logo + tagline, still
|
|
|
85
136
|
- **Show the result.** When an action changes something outside the shot (a
|
|
86
137
|
row added at the top, a new screen), pull out right after it. A push-in
|
|
87
138
|
that shows a button pressed and nothing happening is the worst shot.
|
|
88
|
-
- **
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
-
|
|
139
|
+
- **End on the result.** The last shot of a chapter frames what it achieved
|
|
140
|
+
(the pass with its wallet badge, the receipt), held long enough to read,
|
|
141
|
+
then the card covers it.
|
|
142
|
+
- **Each move eases in and out** (engine: 900 ms,
|
|
143
|
+
`cubic-bezier(0.65, 0, 0.35, 1)`), then settles 150 ms before anything
|
|
144
|
+
happens.
|
|
92
145
|
|
|
93
146
|
## Cursor
|
|
94
147
|
|
|
95
|
-
- A small standard arrow, used
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
- **A beat around every click:** it rests on the control (
|
|
148
|
+
- A small standard arrow, used for the clicks and drags a person would make.
|
|
149
|
+
It glides on a gentle curve, easing in and out (400–800 ms by distance),
|
|
150
|
+
and doesn't pulse, ripple or jerk.
|
|
151
|
+
- **A beat around every click:** it rests on the control (160 ms, its hover
|
|
99
152
|
state shows), presses (110 ms, the pressed state shows), and the app's
|
|
100
|
-
reaction plays (
|
|
153
|
+
reaction plays (450 ms) before anything else happens.
|
|
154
|
+
- Typing runs at ~45 ms a character.
|
|
101
155
|
- Between actions it rests where it doesn't cover what the viewer should
|
|
102
156
|
read.
|
|
103
157
|
- If the UI animates by itself (an order total updating, a status changing),
|
|
@@ -108,10 +162,10 @@ end card 3–5 s logo + tagline, still
|
|
|
108
162
|
- **Background:** white tinted ~5–8 % with the brand's primary colour, with
|
|
109
163
|
one or two very soft radial blooms. Never a busy wallpaper, and never
|
|
110
164
|
dark mode.
|
|
111
|
-
- **Brand colour:**
|
|
112
|
-
colour. The brand's logo
|
|
113
|
-
|
|
114
|
-
|
|
165
|
+
- **Brand colour:** payoffs and every other chapter card are full-bleed
|
|
166
|
+
brand colour. The brand's logo is on the open and end cards. The app
|
|
167
|
+
itself is shown in its tenant's branding (their kiosk looks like their
|
|
168
|
+
kiosk).
|
|
115
169
|
- **Brand:** NaviPartner's (below). A pitch draft (linear.md) swaps in a
|
|
116
170
|
customer's researched logo, colours and fonts, following the same roles.
|
|
117
171
|
|
|
@@ -122,23 +176,23 @@ These values are taken from navipartner.com and the official logo
|
|
|
122
176
|
|
|
123
177
|
| Role | Value |
|
|
124
178
|
|---|---|
|
|
125
|
-
| Primary:
|
|
126
|
-
| Navy: logo wordmark,
|
|
179
|
+
| Primary: brand cards, italic emphasis word, the open card's eyebrow, background tint | `#1F5494` |
|
|
180
|
+
| Navy: logo wordmark, statements on pale cards | `#123A7E` |
|
|
127
181
|
| Light blue: the logo's "NAVI" mark, soft background bloom, sparingly | `#729FD3` |
|
|
128
|
-
| Text: sub-lines
|
|
182
|
+
| Text: sub-lines | `#232323`; muted `#707070` |
|
|
129
183
|
| Pale background base | `#F8F8F8` / `#FFFFFF` |
|
|
130
184
|
| Heading font | Merriweather 400/700, italic for the emphasis word |
|
|
131
185
|
| Body font | Work Sans 400/600/700 |
|
|
132
186
|
| Logo | official two-colour SVG: `#729FD3` mark + `#123A7E` wordmark, on pale backgrounds only. On `#1F5494`, use it all white. |
|
|
133
187
|
|
|
134
188
|
A NaviPartner pale card is `#F8F8F8` with a `#1F5494` tint at ~5 % and one
|
|
135
|
-
`#729FD3` bloom, with the
|
|
136
|
-
brand card is full-bleed `#1F5494` with the
|
|
137
|
-
the sub-line in white Work Sans at
|
|
189
|
+
`#729FD3` bloom, with the statement in navy and the italic word in primary.
|
|
190
|
+
A brand card is full-bleed `#1F5494` with the statement in white
|
|
191
|
+
Merriweather and the sub-line in white Work Sans at ~85 % opacity.
|
|
138
192
|
|
|
139
193
|
Keep the two brand layers apart. The cards and background use the video's
|
|
140
194
|
brand (NaviPartner, or the customer's). What's inside the app window is the
|
|
141
|
-
|
|
195
|
+
app's tenant branding from the adapter.
|
|
142
196
|
|
|
143
197
|
## Sound
|
|
144
198
|
|
|
@@ -152,5 +206,41 @@ the whole story.
|
|
|
152
206
|
This is used for the website and the LinkedIn feed.
|
|
153
207
|
- **Portrait kiosk apps** (food order 1080×1920) float centred in the 16:9
|
|
154
208
|
frame, and the camera pushes in the same way.
|
|
155
|
-
- 1:1 / 9:16 cuts for SoMe come later.
|
|
156
|
-
1080×1080 area
|
|
209
|
+
- 1:1 / 9:16 cuts for SoMe come later. Text-only cards keep their words
|
|
210
|
+
inside the central 1080×1080 area; a card with a snapshot will stack it
|
|
211
|
+
under the words there.
|
|
212
|
+
|
|
213
|
+
## Where these rules come from
|
|
214
|
+
|
|
215
|
+
Researched October 2026. Apple-style ads composite their UI in afterwards;
|
|
216
|
+
we film the real app, so we borrow their discipline (one message per shot,
|
|
217
|
+
the product as the hero), not their technique.
|
|
218
|
+
|
|
219
|
+
- **Showcase length and pace.** Wistia's data on 1.1 million videos: product
|
|
220
|
+
and explainer videos keep over half their viewers up to a few minutes,
|
|
221
|
+
with the steepest drop after two; put what matters early. B2B launch
|
|
222
|
+
videos run 30–60 s, explainers 60–90 s. A buyer can follow a slower video
|
|
223
|
+
that carries real information, so cut dead time, not information.
|
|
224
|
+
([Wistia](https://wistia.com/blog/optimal-video-length),
|
|
225
|
+
[Flowjam](https://www.flowjam.com/blog/b2b-saas-launch-video))
|
|
226
|
+
- **Feature clips and the first seconds.** In feeds, attention is decided in
|
|
227
|
+
the first 2–3 seconds; brand in the first 5 (Google's ABCD) or 2
|
|
228
|
+
(LinkedIn: a visible logo lifts click-through 17%), and lead with the
|
|
229
|
+
product in use, not only a logo (Meta). Short ads do best around 15–30 s.
|
|
230
|
+
([Think with Google](https://thinkwithgoogle.com/_qs/documents/8472/ABCD_Complete_V7b_HR_1.pdf),
|
|
231
|
+
[LinkedIn via Storykit](https://storykit.io/blog/linkedin-video-ads-best-practices),
|
|
232
|
+
[Meta via Cinerads](https://www.cinerads.com/blog/meta-ads-video-creative-best-practices))
|
|
233
|
+
- **Silent by design.** About 80 % of LinkedIn video and 85 % of Facebook
|
|
234
|
+
video is watched without sound, so the cards carry every claim.
|
|
235
|
+
- **What goes on a card.** One idea per scene with one supporting line; the
|
|
236
|
+
benefit a viewer grasps fastest beats the feature's name; specific numbers
|
|
237
|
+
beat vague claims; short labels hold viewers.
|
|
238
|
+
([Nemo](https://www.nemovideo.com/blog/kinetic-typography-product-ads),
|
|
239
|
+
[Arcade, 14 million demo sessions](https://www.arcade.software/post/2026-arcade-benchmarks))
|
|
240
|
+
- **Reading time.** Netflix allows at most 20 characters a second, text up
|
|
241
|
+
0.83–7 s; the BBC works to about 0.3 s a word. Our 0.6 s + 0.28 s a word
|
|
242
|
+
sits between them.
|
|
243
|
+
([Netflix](https://backlothelp.netflix.com/hc/en-us/articles/219375728))
|
|
244
|
+
- **Camera.** Screen Studio's "Focused" motion settles quickly so UI can be
|
|
245
|
+
read; that is the model: quick moves, then stillness.
|
|
246
|
+
([Screen Studio](https://screen.studio/guide/animations))
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Reference: adapter, story and
|
|
1
|
+
# Reference: adapter, story, brand and check
|
|
2
2
|
|
|
3
3
|
## Adapter (`<app>/demo/demo.config.ts`)
|
|
4
4
|
|
|
@@ -7,9 +7,10 @@ the mocks booted the app), `viewport` (default 1728×972; a portrait kiosk is
|
|
|
7
7
|
scaled to fit) and `setup(page, { brand })`, which runs the app's e2e mocks
|
|
8
8
|
**unchanged** and lays the brand over the response that carries it.
|
|
9
9
|
Optional: `actions` (app steps such as a barcode scan), `idleTimeoutSeconds`,
|
|
10
|
-
`locale`, `timezone`, and `brandNeeds`: the `config` keys and asset slots
|
|
11
|
-
description (where it shows, what shape) or
|
|
12
|
-
brand without a need that isn't optional fails
|
|
10
|
+
`locale`, `timezone`, and `brandNeeds`: the `config` keys and asset slots
|
|
11
|
+
`setup` uses, each a description (where it shows, what shape) or
|
|
12
|
+
`{ what, optional: true }`. A brand without a need that isn't optional fails
|
|
13
|
+
`check`.
|
|
13
14
|
|
|
14
15
|
```ts
|
|
15
16
|
import { defineDemo, overlayResponse } from "@navipartner/demo-video";
|
|
@@ -42,30 +43,80 @@ export default defineDemo({
|
|
|
42
43
|
|
|
43
44
|
## Story (`<app>/demo/stories/<name>.json`)
|
|
44
45
|
|
|
45
|
-
`app`, `description`, optional `
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
46
|
+
`app`, `description`, optional `kind` (`showcase`, the default, or
|
|
47
|
+
`feature`), `primary` (a showcase), `title`, `closing`, `steps`.
|
|
48
|
+
|
|
49
|
+
| Step | Fields |
|
|
50
|
+
|---|---|
|
|
51
|
+
| `click` | `target`, `nth`, `zoom` (push in on it first, 1.3–2), `behindCard` |
|
|
52
|
+
| `type` | `target`, `nth`, `text`, `perCharMs` (≥ 40, default 45), `replace` (clear the field first; without it the text is added), `behindCard` |
|
|
53
|
+
| `press` | `key`, `behindCard` |
|
|
54
|
+
| `zoom` | `target`, `nth`, `scale` (1.3–2) |
|
|
55
|
+
| `frame` | `targets` (2–4 testids or `{ target, nth }`), `maxScale` (1.3–2, default 1.8) |
|
|
56
|
+
| `zoomOut` | `park` (rest the cursor too) |
|
|
57
|
+
| `park` | rests the cursor in empty space |
|
|
58
|
+
| `waitFor` | `target`, `nth`, `hidden`, `timeout` (s), `behindCard` |
|
|
59
|
+
| `expectText` | `target`, `nth`, `text`, `contains`, `timeout` (s) |
|
|
60
|
+
| `hold` | `seconds` (≤ 6) |
|
|
61
|
+
| `card` | see Cards |
|
|
62
|
+
|
|
63
|
+
Plus the adapter's actions as `{ "do": "<action>", …params }`. `target` is a
|
|
64
|
+
testid or any Playwright selector (`role=button[name=/pay/i]`); `nth` picks
|
|
65
|
+
among matches (-1 = last). Clicks wait until their target stops moving.
|
|
66
|
+
|
|
67
|
+
**Cards** (`card`, `title`, `closing`): `heading` (≤ 7 words, `*word*` in
|
|
68
|
+
italic, once), `sub` (≤ 16 words; a chapter card's benefit ≤ 10), `logo`,
|
|
69
|
+
`style` (`pale` | `brand`; chapter cards without one alternate, pale first),
|
|
70
|
+
`seconds` (a minimum: a card stays up long enough to read), and on `title`
|
|
71
|
+
and `closing` only, `eyebrow` (≤ 4 words). `title` may `show` an element
|
|
72
|
+
too: a snapshot of it as it last looks in the story, beside the logo. A `card` step may `show` an element
|
|
73
|
+
(a testid or `{ target, nth }`): a snapshot of it beside the words, as it
|
|
74
|
+
last looks in the chapter after the card (on a payoff, as the card comes up).
|
|
75
|
+
Cards that follow each other hand over directly. A number on a card must be
|
|
76
|
+
checked by an `expectText` in the story.
|
|
77
|
+
|
|
78
|
+
**Behind a card:** `behindCard` steps right after a card (or at the very
|
|
79
|
+
start, behind the title card) run while the card covers the app, with no
|
|
80
|
+
cursor and no camera. The chapter's first `zoom` or `frame` is set behind the
|
|
81
|
+
card too, so the chapter opens on it. A card stays up until what's behind it
|
|
82
|
+
is done.
|
|
83
|
+
|
|
84
|
+
**Camera rules** (`check` enforces them): at most two push-ins a chapter,
|
|
85
|
+
and a push-in needs something done or read in its shot. A click target must
|
|
86
|
+
be inside the current shot. What a zoomed click changes must be in the shot
|
|
87
|
+
or shown by the next step (a `zoomOut`, or a zoom that frames it). Clicks in
|
|
88
|
+
the wide shot whose controls and results would fit a push-in of 1.4 or more
|
|
89
|
+
need one.
|
|
90
|
+
|
|
91
|
+
**Timing:** the engine adds the beats around clicks, the camera's settle and
|
|
92
|
+
a linger before each card (look.md has the numbers). Holds may not add up
|
|
93
|
+
past the app's idle timeout. A passing `check` prints the story's estimated
|
|
94
|
+
length against its kind's range (`seconds` and `kind` in `--json`).
|
|
95
|
+
|
|
96
|
+
## What `check` says, and the fix
|
|
97
|
+
|
|
98
|
+
| It says | Fix |
|
|
99
|
+
|---|---|
|
|
100
|
+
| `"x" is outside the shot …` | The shot frames the wrong area: frame what this shot clicks, or `zoomOut` first |
|
|
101
|
+
| `clicking "x" changes y, which is outside the shot …` | Frame what the click changes, or `zoomOut` right after the click |
|
|
102
|
+
| `"x" is clicked in the wide shot, but … fit a push-in` | `frame` the controls and what they change; or, if it's setup, `behindCard` |
|
|
103
|
+
| `N camera push-ins in one chapter` | Push in once on the chapter's area and hold steady |
|
|
104
|
+
| `… only fit in the wide shot` | `frame` things that sit together, or stay wide |
|
|
105
|
+
| `a zoom with nothing in its shot` | Remove it, or act or read something in it |
|
|
106
|
+
| `zoom 2.4; use 1.3–2` | Zoom less: context reads better and stays sharp |
|
|
107
|
+
| `behindCard only right after a card` | Move the step to just after a card, or drop `behindCard` |
|
|
108
|
+
| `"x" (show) never appears in the chapter …` | Show an element the chapter ends on |
|
|
109
|
+
| `cards between chapters have no eyebrow` | Remove it: the statement and sub-line carry the chapter |
|
|
110
|
+
| `… shows the same snapshot` | Show each result once: on the open card or on a chapter card |
|
|
111
|
+
| `title.show: "x" never appears in the story` | Show an element the story reaches: its result, or the feature |
|
|
112
|
+
| `kind: a feature clip shows one feature, in one chapter` | Cut it to the feature's one chapter, or make it a showcase |
|
|
113
|
+
| `N chapters; a showcase has at most 4` | Make a second story |
|
|
114
|
+
| `kind: the primary story … is a showcase` | Drop `"kind": "feature"` from the primary story |
|
|
115
|
+
| `"…" looks like a testid-like name / barcode / code` | Cards are for people: say it in words |
|
|
116
|
+
| `"38" isn't shown by an expectText` | Quote only values an `expectText` checks |
|
|
117
|
+
| `the card announces a chapter in which nothing is done` | Follow it with the steps it describes (setup behind the card doesn't count) |
|
|
118
|
+
| `… names a brand or extends a story` | Remove it: a customer's branding is @Linear's, a translation is a story of its own |
|
|
119
|
+
| `…/demo/brands isn't used` | Delete the folder: repos keep no brands |
|
|
69
120
|
|
|
70
121
|
## Brand (the engine's `navipartner`, or one a pitch draft builds)
|
|
71
122
|
|
|
@@ -73,8 +124,8 @@ export default defineDemo({
|
|
|
73
124
|
- `config`: opaque to the engine, the keys the app's branding API reads
|
|
74
125
|
(`primaryColor`, …). An adapter may also read `config.demoData`: names
|
|
75
126
|
for the mock's products, keyed by the mock's barcodes (prices and flows
|
|
76
|
-
stay the mock's). It takes `demoData` out before it
|
|
77
|
-
|
|
127
|
+
stay the mock's). It takes `demoData` out before it overlays the
|
|
128
|
+
branding.
|
|
78
129
|
- `assets`: slot → file, e.g. `{ "logo": "navipartner/logo.svg" }`
|
|
79
130
|
- `video`: `primary`, `ink`, `accent`, `text`, `headingFont`, `bodyFont`,
|
|
80
131
|
optional `fontsUrl`, `logo` (asset slot)
|