@mthanh/vespercli 2.2.1 → 2.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (157) hide show
  1. package/README.md +3 -2
  2. package/assets/CATALOG.md +9 -2
  3. package/assets/claude/.claude-plugin/marketplace.json +9 -9
  4. package/assets/claude/.claude-plugin/plugin.json +1 -1
  5. package/assets/claude/agents/code-planner.md +1 -1
  6. package/assets/claude/agents/code-reviewer.md +1 -1
  7. package/assets/claude/agents/code-tester.md +1 -1
  8. package/assets/claude/agents/copywriter.md +1 -1
  9. package/assets/claude/agents/feature-wrap-document.md +1 -1
  10. package/assets/claude/agents/janitor.md +1 -1
  11. package/assets/claude/agents/modernization.md +1 -1
  12. package/assets/claude/agents/principal-software-engineer.md +1 -1
  13. package/assets/claude/agents/refine-issue.md +1 -1
  14. package/assets/claude/agents/se-system-architecture-reviewer.md +1 -1
  15. package/assets/claude/agents/se-technical-writer.md +1 -1
  16. package/assets/claude/agents/skill-creator.md +1 -1
  17. package/assets/claude/agents/task-researcher.md +1 -1
  18. package/assets/claude/agents/technical-product-manager.md +1 -1
  19. package/assets/claude/agents/vision-analyst.md +1 -1
  20. package/assets/claude/agents/vitest.md +1 -1
  21. package/assets/claude/agents/workspace-learner.md +2 -2
  22. package/assets/claude/packs/backend/.claude-plugin/plugin.json +1 -1
  23. package/assets/claude/packs/backend/agents/firebase-developer.md +1 -1
  24. package/assets/claude/packs/backend/agents/nodejs-express-developer.md +1 -1
  25. package/assets/claude/packs/docs/.claude-plugin/plugin.json +1 -1
  26. package/assets/claude/packs/frontend/.claude-plugin/plugin.json +1 -1
  27. package/assets/claude/packs/frontend/agents/expert-nextjs-developer.md +1 -1
  28. package/assets/claude/packs/frontend/agents/expert-react-frontend-engineer.md +1 -1
  29. package/assets/claude/packs/frontend/agents/jest-react-component-analyzer.md +1 -1
  30. package/assets/claude/packs/frontend/agents/jest-react-scenario-scanner.md +1 -1
  31. package/assets/claude/packs/frontend/agents/jest-react-test-generator.md +1 -1
  32. package/assets/claude/packs/frontend/agents/jest-react-test-planner.md +1 -1
  33. package/assets/claude/packs/frontend/skills/design-taste-frontend/LICENSE +21 -0
  34. package/assets/claude/packs/frontend/skills/design-taste-frontend/SKILL.md +529 -0
  35. package/assets/claude/packs/frontend/skills/design-taste-frontend/UPSTREAM.json +7 -0
  36. package/assets/claude/packs/frontend/skills/design-taste-frontend/assets/app.css +216 -0
  37. package/assets/claude/packs/frontend/skills/design-taste-frontend/assets/base.css +105 -0
  38. package/assets/claude/packs/frontend/skills/design-taste-frontend/assets/base.js +37 -0
  39. package/assets/claude/packs/frontend/skills/design-taste-frontend/assets/charts.js +617 -0
  40. package/assets/claude/packs/frontend/skills/design-taste-frontend/assets/scenes/stage.css +28 -0
  41. package/assets/claude/packs/frontend/skills/design-taste-frontend/assets/scenes/stage.js +133 -0
  42. package/assets/claude/packs/frontend/skills/design-taste-frontend/evals/evals.json +76 -0
  43. package/assets/claude/packs/frontend/skills/design-taste-frontend/library/app.json +1327 -0
  44. package/assets/claude/packs/frontend/skills/design-taste-frontend/library/directions.json +1078 -0
  45. package/assets/claude/packs/frontend/skills/design-taste-frontend/library/heroes.json +1086 -0
  46. package/assets/claude/packs/frontend/skills/design-taste-frontend/library/motions.json +92 -0
  47. package/assets/claude/packs/frontend/skills/design-taste-frontend/library/palettes.json +1485 -0
  48. package/assets/claude/packs/frontend/skills/design-taste-frontend/library/photos.json +7240 -0
  49. package/assets/claude/packs/frontend/skills/design-taste-frontend/library/sections.json +4429 -0
  50. package/assets/claude/packs/frontend/skills/design-taste-frontend/library/sites.json +8350 -0
  51. package/assets/claude/packs/frontend/skills/design-taste-frontend/library/type.json +2024 -0
  52. package/assets/claude/packs/frontend/skills/design-taste-frontend/references/app-screens.md +1199 -0
  53. package/assets/claude/packs/frontend/skills/design-taste-frontend/references/colour.md +141 -0
  54. package/assets/claude/packs/frontend/skills/design-taste-frontend/references/copy.md +177 -0
  55. package/assets/claude/packs/frontend/skills/design-taste-frontend/references/critique.md +182 -0
  56. package/assets/claude/packs/frontend/skills/design-taste-frontend/references/imagery.md +791 -0
  57. package/assets/claude/packs/frontend/skills/design-taste-frontend/references/layout.md +292 -0
  58. package/assets/claude/packs/frontend/skills/design-taste-frontend/references/motion.md +980 -0
  59. package/assets/claude/packs/frontend/skills/design-taste-frontend/references/research.md +356 -0
  60. package/assets/claude/packs/frontend/skills/design-taste-frontend/references/scenes.md +174 -0
  61. package/assets/claude/packs/frontend/skills/design-taste-frontend/references/tells.md +115 -0
  62. package/assets/claude/packs/frontend/skills/design-taste-frontend/references/type.md +170 -0
  63. package/assets/claude/packs/frontend/skills/design-taste-frontend/scripts/assets.mjs +865 -0
  64. package/assets/claude/packs/frontend/skills/design-taste-frontend/scripts/draw.mjs +584 -0
  65. package/assets/claude/packs/frontend/skills/design-taste-frontend/scripts/inspect.mjs +303 -0
  66. package/assets/claude/packs/frontend/skills/design-taste-frontend/scripts/lib/app-draw.mjs +203 -0
  67. package/assets/claude/packs/frontend/skills/design-taste-frontend/scripts/lib/cdp.mjs +248 -0
  68. package/assets/claude/packs/frontend/skills/design-taste-frontend/scripts/lib/probe.mjs +909 -0
  69. package/assets/claude/packs/frontend/skills/design-taste-frontend/scripts/lib/rules.mjs +243 -0
  70. package/assets/claude/packs/frontend/skills/design-taste-frontend/scripts/lint.mjs +119 -0
  71. package/assets/claude/packs/frontend/skills/design-taste-frontend/scripts/scenes.mjs +124 -0
  72. package/assets/claude/packs/graphify/.claude-plugin/plugin.json +1 -1
  73. package/assets/claude/packs/integrations/.claude-plugin/plugin.json +1 -1
  74. package/assets/claude/packs/playwright/.claude-plugin/plugin.json +1 -1
  75. package/assets/claude/packs/playwright/agents/playwright-component-analyzer.md +1 -1
  76. package/assets/claude/packs/playwright/agents/playwright-scenario-scanner.md +1 -1
  77. package/assets/claude/packs/playwright/agents/playwright-test-generator.md +1 -1
  78. package/assets/claude/packs/playwright/agents/playwright-test-planner.md +1 -1
  79. package/assets/claude/packs/playwright/agents/playwright-tester.md +1 -1
  80. package/assets/claude/packs/polyglot/.claude-plugin/plugin.json +1 -1
  81. package/assets/claude/packs/styles/.claude-plugin/plugin.json +1 -1
  82. package/assets/copilot/agents/code-planner.agent.md +1 -1
  83. package/assets/copilot/agents/code-reviewer.agent.md +1 -1
  84. package/assets/copilot/agents/code-tester.agent.md +1 -1
  85. package/assets/copilot/agents/copywriter.agent.md +1 -1
  86. package/assets/copilot/agents/feature-wrap-document.agent.md +1 -1
  87. package/assets/copilot/agents/janitor.agent.md +1 -1
  88. package/assets/copilot/agents/modernization.agent.md +1 -1
  89. package/assets/copilot/agents/principal-software-engineer.agent.md +1 -1
  90. package/assets/copilot/agents/refine-issue.agent.md +1 -1
  91. package/assets/copilot/agents/se-system-architecture-reviewer.agent.md +1 -1
  92. package/assets/copilot/agents/se-technical-writer.agent.md +1 -1
  93. package/assets/copilot/agents/skill-creator.agent.md +1 -1
  94. package/assets/copilot/agents/task-researcher.agent.md +1 -1
  95. package/assets/copilot/agents/technical-product-manager.agent.md +1 -1
  96. package/assets/copilot/agents/vision-analyst.agent.md +1 -1
  97. package/assets/copilot/agents/vitest.agent.md +1 -1
  98. package/assets/copilot/agents/workspace-learner.agent.md +2 -2
  99. package/assets/copilot/packs/backend/agents/firebase-developer.agent.md +1 -1
  100. package/assets/copilot/packs/backend/agents/nodejs-express-developer.agent.md +1 -1
  101. package/assets/copilot/packs/frontend/agents/expert-nextjs-developer.agent.md +1 -1
  102. package/assets/copilot/packs/frontend/agents/expert-react-frontend-engineer.agent.md +1 -1
  103. package/assets/copilot/packs/frontend/agents/jest-react-component-analyzer.agent.md +1 -1
  104. package/assets/copilot/packs/frontend/agents/jest-react-scenario-scanner.agent.md +1 -1
  105. package/assets/copilot/packs/frontend/agents/jest-react-test-generator.agent.md +1 -1
  106. package/assets/copilot/packs/frontend/agents/jest-react-test-planner.agent.md +1 -1
  107. package/assets/copilot/packs/frontend/skills/design-taste-frontend/LICENSE +21 -0
  108. package/assets/copilot/packs/frontend/skills/design-taste-frontend/SKILL.md +529 -0
  109. package/assets/copilot/packs/frontend/skills/design-taste-frontend/UPSTREAM.json +7 -0
  110. package/assets/copilot/packs/frontend/skills/design-taste-frontend/assets/app.css +216 -0
  111. package/assets/copilot/packs/frontend/skills/design-taste-frontend/assets/base.css +105 -0
  112. package/assets/copilot/packs/frontend/skills/design-taste-frontend/assets/base.js +37 -0
  113. package/assets/copilot/packs/frontend/skills/design-taste-frontend/assets/charts.js +617 -0
  114. package/assets/copilot/packs/frontend/skills/design-taste-frontend/assets/scenes/stage.css +28 -0
  115. package/assets/copilot/packs/frontend/skills/design-taste-frontend/assets/scenes/stage.js +133 -0
  116. package/assets/copilot/packs/frontend/skills/design-taste-frontend/evals/evals.json +76 -0
  117. package/assets/copilot/packs/frontend/skills/design-taste-frontend/library/app.json +1327 -0
  118. package/assets/copilot/packs/frontend/skills/design-taste-frontend/library/directions.json +1078 -0
  119. package/assets/copilot/packs/frontend/skills/design-taste-frontend/library/heroes.json +1086 -0
  120. package/assets/copilot/packs/frontend/skills/design-taste-frontend/library/motions.json +92 -0
  121. package/assets/copilot/packs/frontend/skills/design-taste-frontend/library/palettes.json +1485 -0
  122. package/assets/copilot/packs/frontend/skills/design-taste-frontend/library/photos.json +7240 -0
  123. package/assets/copilot/packs/frontend/skills/design-taste-frontend/library/sections.json +4429 -0
  124. package/assets/copilot/packs/frontend/skills/design-taste-frontend/library/sites.json +8350 -0
  125. package/assets/copilot/packs/frontend/skills/design-taste-frontend/library/type.json +2024 -0
  126. package/assets/copilot/packs/frontend/skills/design-taste-frontend/references/app-screens.md +1199 -0
  127. package/assets/copilot/packs/frontend/skills/design-taste-frontend/references/colour.md +141 -0
  128. package/assets/copilot/packs/frontend/skills/design-taste-frontend/references/copy.md +177 -0
  129. package/assets/copilot/packs/frontend/skills/design-taste-frontend/references/critique.md +182 -0
  130. package/assets/copilot/packs/frontend/skills/design-taste-frontend/references/imagery.md +791 -0
  131. package/assets/copilot/packs/frontend/skills/design-taste-frontend/references/layout.md +292 -0
  132. package/assets/copilot/packs/frontend/skills/design-taste-frontend/references/motion.md +980 -0
  133. package/assets/copilot/packs/frontend/skills/design-taste-frontend/references/research.md +356 -0
  134. package/assets/copilot/packs/frontend/skills/design-taste-frontend/references/scenes.md +174 -0
  135. package/assets/copilot/packs/frontend/skills/design-taste-frontend/references/tells.md +115 -0
  136. package/assets/copilot/packs/frontend/skills/design-taste-frontend/references/type.md +170 -0
  137. package/assets/copilot/packs/frontend/skills/design-taste-frontend/scripts/assets.mjs +865 -0
  138. package/assets/copilot/packs/frontend/skills/design-taste-frontend/scripts/draw.mjs +584 -0
  139. package/assets/copilot/packs/frontend/skills/design-taste-frontend/scripts/inspect.mjs +303 -0
  140. package/assets/copilot/packs/frontend/skills/design-taste-frontend/scripts/lib/app-draw.mjs +203 -0
  141. package/assets/copilot/packs/frontend/skills/design-taste-frontend/scripts/lib/cdp.mjs +248 -0
  142. package/assets/copilot/packs/frontend/skills/design-taste-frontend/scripts/lib/probe.mjs +909 -0
  143. package/assets/copilot/packs/frontend/skills/design-taste-frontend/scripts/lib/rules.mjs +243 -0
  144. package/assets/copilot/packs/frontend/skills/design-taste-frontend/scripts/lint.mjs +119 -0
  145. package/assets/copilot/packs/frontend/skills/design-taste-frontend/scripts/scenes.mjs +124 -0
  146. package/assets/copilot/packs/playwright/agents/playwright-component-analyzer.agent.md +1 -1
  147. package/assets/copilot/packs/playwright/agents/playwright-scenario-scanner.agent.md +1 -1
  148. package/assets/copilot/packs/playwright/agents/playwright-test-generator.agent.md +1 -1
  149. package/assets/copilot/packs/playwright/agents/playwright-test-planner.agent.md +1 -1
  150. package/assets/copilot/packs/playwright/agents/playwright-tester.agent.md +1 -1
  151. package/assets/manifest.json +2 -0
  152. package/dist/cli.min.js +102 -102
  153. package/package.json +1 -1
  154. package/scripts/__snapshots__/generate-claude-assets.test.js.snap +1 -1
  155. package/scripts/generate-claude-assets.strict.test.js +1 -1
  156. package/scripts/generate-claude-assets.test.js +6 -6
  157. package/scripts/packs-layout.test.js +2 -1
@@ -0,0 +1,791 @@
1
+ # Imagery
2
+
3
+ Pictures are where generated pages most obviously give up: a grey box, an icon in a square, a fake
4
+ dashboard, an abstract blob. This file is how to decide what the pictures are, where to find real ones,
5
+ how to crop and place them, and what to do when there are none.
6
+
7
+ ## Contents
8
+
9
+ 1. What the study measured
10
+ 2. Decide what imagery exists
11
+ 3. Real pictures from the open collections
12
+ 4. The dealt photographs
13
+ 5. Cropping and placing
14
+ 6. Treatment
15
+ 7. Showing software
16
+ 8. Drawing the subject
17
+ 9. Type and colour alone
18
+ 10. Markup and credits
19
+ 11. Video
20
+ 12. Where pictures and footage go
21
+
22
+ ## 1. What the study measured
23
+
24
+ - On 60% of the studied sites one piece of media covers at least half of the first screen; on half of
25
+ them it covers nearly all of it. Top-scored sites: 68% and 56%. Weak sites: 48% and 39%.
26
+ - Only 15% of heroes have no media at all, and those are deliberate typographic statements.
27
+ - Media has square corners on 73% of sites. Where corners are rounded the usual radius is about 12px,
28
+ applied to every image alike.
29
+ - Top-scored pages carry far more imagery (a median of 37 images against 5 on weak pages): the strong
30
+ sites show, the weak ones tell.
31
+ - What the imagery is, by the panel's classification: a mix of kinds 32%, photography 14%, generative
32
+ or WebGL scenes 13%, real product interface 12%, 3D renders 11%, illustration 9%, video 6%, type only
33
+ 3%.
34
+ - Among the 54 sites the panel scored under 6.8, legibility (text lost over a busy image, or too
35
+ little contrast) was named as a weakness in 13.
36
+ - In the October 2026 study of 91 Awwwards Sites of the Day (section 12), the median page carries 7
37
+ pictures (top sites 8, the lowest 2) and footage appears on 42% of sites (half of the top ones, one
38
+ of the 16 lowest).
39
+ - Pictures come in whole screens: 42% of scrolled screens hold none and 19% are 90% picture or more.
40
+ - 94% of pictures have square corners, and on a typical site two ratios hold three-quarters of them.
41
+
42
+ ## 2. Decide what imagery exists
43
+
44
+ In order of preference:
45
+
46
+ 1. **The project's own images.** Product shots, the place, the people, the work. Even ordinary
47
+ photographs of the real thing beat beautiful photographs of something else. Ask what exists; look in
48
+ the repository.
49
+ 2. **Images you can generate** with an image tool in this session. Write prompts as a photographer's
50
+ brief: subject, angle, light, background, crop ratio, and "no text". Generate the hero first and
51
+ make the rest match its light.
52
+ 3. **Real pictures of the subject's world from the open collections** (section 3). Archives,
53
+ museums and photographers have published millions of pictures anyone may use with a credit: the
54
+ client's city and street in old postcards, maps of its neighbourhood, its materials, its trade in
55
+ engravings, museum objects of its kind. Whenever an honest one exists, it beats a drawing of the
56
+ same thing: it is real, it has detail no drawing in a page's budget reaches, and it carries history.
57
+ Honest means nobody could take it for the client's own product, room, dish, person or team.
58
+ 4. **Pictures you draw in code from the subject itself** (section 8), for what no honest picture
59
+ exists of: the product's own objects as flat shapes, the place's tiles and windows, a map of its
60
+ streets, the document a tool produces, the interface of a piece of software. In testing, pages that
61
+ drew their subject with care beat pages that borrowed unrelated photographs every time, and beat
62
+ pages that showed nothing.
63
+ 5. **The photographs dealt on the direction sheet.** Real photographs of places, light, texture and
64
+ weather. Use them only where an honestly generic picture fits (the open sea for a house on the sea,
65
+ fog for a quiet retreat). They cannot stand in for a specific product, dish, room, person or
66
+ screen: a foggy motorway on a restaurant page reads as stock at once, and jurors notice.
67
+ 6. **Type and colour alone,** done on purpose (section 9).
68
+
69
+ Tell `draw.mjs` the truth with `--have`. If you have no product photographs and no image tool, do not
70
+ pass `product-photo`; the draw will avoid the directions that depend on showing the object. Pictures
71
+ found in the open collections are not the project's own: do not pass `photography` for them.
72
+
73
+ ## 3. Real pictures from the open collections
74
+
75
+ `scripts/assets.mjs` searches four open sources without keys and prints, for each find, a direct image
76
+ URL, the page it comes from, its size, its creator, its licence and a credit line:
77
+
78
+ - **Openverse**: one index over Flickr, Wikimedia Commons, museums and libraries.
79
+ - **Wikimedia Commons**: archival photographs, old maps, scans of prints and books, places as they
80
+ look now.
81
+ - **The Art Institute of Chicago** and **The Metropolitan Museum of Art**: public-domain paintings,
82
+ prints, drawings, photographs, textiles and objects, in large scans.
83
+
84
+ ```bash
85
+ node <skill>/scripts/assets.mjs "ghent postcard"
86
+ node <skill>/scripts/assets.mjs "fig" --source museums --orientation portrait
87
+ node <skill>/scripts/assets.mjs "basalt texture" --min-width 2400 --source openverse,commons
88
+ node <skill>/scripts/assets.mjs --get commons:36649959,met:707892 # download, record the credits
89
+ node <skill>/scripts/assets.mjs --credits # footer line and report list
90
+ ```
91
+
92
+ By default it keeps only licences that allow commercial use (CC0, public domain, CC BY, CC BY-SA) and
93
+ pictures at least 1000 pixels wide, and checks that every image it prints actually loads.
94
+ `--license pd` keeps only pictures that need no credit; `--orientation`, `--min-width` and `--limit`
95
+ narrow the list; `--source` picks the sources; `--json` gives the raw results. Each result has a ref
96
+ (`commons:36649959`) that `--get` takes.
97
+
98
+ **What to search for.** The inventory (SKILL.md step 1), not the category: "bakery" finds other
99
+ people's bakeries. The subject's world is specific:
100
+
101
+ - **Its place:** the city, the street, the harbour, the valley, in old postcards and photographs
102
+ ("ghent postcard", "rotterdam harbour 1920") and as it looks today ("gent korenmarkt").
103
+ - **Its maps:** the street plan, the chart of its bay, the geology of its valley ("ghent old map",
104
+ "nautical chart lisbon").
105
+ - **Its materials,** close enough to read as a surface: the stone of its quay, the grain of its oak,
106
+ its glaze, its tiles ("azulejo tiles", "basalt cobblestones", "oak grain").
107
+ - **Its trade's history:** the old tools, the craft in engravings and trade catalogues, patent
108
+ drawings ("bread oven engraving", "potter's wheel", "bicycle patent drawing").
109
+ - **Museum objects of its kind,** with `--source museums`: a coffee set from about 1810 for a studio
110
+ that makes coffee sets, a woodblock print of a wave for a surf school, a porcelain plate painted
111
+ with figs for a fig orchard.
112
+ - **Scientific imagery:** botanical and zoological plates ("botanical engraving fig"), star charts,
113
+ microscope photographs, satellite views of its coast, geological sections.
114
+
115
+ Search in the place's own words (azulejo, not "blue tile"; Korenmarkt, not "market square"), add a
116
+ medium (postcard, engraving, old map, lithograph, aerial photograph) or a decade, and try two or three
117
+ queries per idea. The museum sources match best on one or two words ("fig", "harbour", "teapot").
118
+
119
+ **What makes a good find.**
120
+
121
+ - It belongs to this subject's world and would not fit the nearest competitor's page.
122
+ - It still reads at the crop the slot needs. Look at it before deciding: `--get` downloads it, then
123
+ open the file. A title is not a picture.
124
+ - It is large enough: twice the width it is shown at for anything full-bleed (the script prints the
125
+ largest size available). A 1024-pixel Flickr photograph is a half-width picture at most.
126
+ - It belongs to one family with the others on the page: all engravings, or all photographs from one
127
+ era, or all close surfaces in one light. A 1900 postcard beside a modern stock photograph beside a
128
+ botanical plate reads as a scrapbook.
129
+ - No watermark, no burned-in text or logo, no frame or scanner edge you cannot crop away, and no
130
+ recognisable living person who could be taken for the client's staff or customers.
131
+
132
+ **Use it creatively.** Found pictures are material, not decoration:
133
+
134
+ - **One archival photograph as the hero,** full-bleed: the street as it was a century ago, behind the
135
+ name of the business that stands in it today, with the year in the caption.
136
+ - **A museum engraving enlarged until its line becomes texture,** cropped tight and returning at
137
+ different scales as the page's one motif (the whole fig plate in the hero, a single leaf of it
138
+ beside the menu).
139
+ - **An engraving or a map on white paper set with `mix-blend-mode: multiply` on the page's colour
140
+ field,** so the ink sits on the ground (section 6).
141
+ - **The real map of the street as the contact section,** the door marked, the north and the scale
142
+ taken from the original.
143
+ - **A material close-up as a whole field:** the quay's stone behind the opening hours.
144
+ - **A run of old postcards or plates as the gallery,** one size, one treatment.
145
+
146
+ Treatments stay within section 6: untouched, greyscale for the whole set, or multiply on a field.
147
+
148
+ **Stay honest.**
149
+
150
+ - **A found picture is never the client's own.** It may show the client's city, its materials, its
151
+ history, the kind of thing it makes; it may never stand in for the client's product, room, dish,
152
+ person, team or customers. If a visitor could take it for the client's own (a bakery counter, a
153
+ plate of pasta, a smiling barista, a guest room), do not use it.
154
+ - **Caption from the source** when a caption helps: what it is and when, as the archive describes it
155
+ ("Gand, unloading a steamer, 1905"). Never write a caption that ties it to the client.
156
+ - **Record and credit every picture.** `--get` writes the source, creator, licence and page of each
157
+ download to `assets/credits.json`. CC BY and CC BY-SA require a credit with the title, the creator,
158
+ a link to the source and a link to the licence; `--credits` prints them as one line of HTML for
159
+ the footer (section 10). Public-domain pictures need no credit; give one anyway.
160
+ - **Respect the licence.** CC BY-SA: an altered version (recoloured, combined with other pictures)
161
+ must be shared under the same licence. Non-commercial (NC) and no-derivatives (ND) licences are out
162
+ for a client's site, which is why the script leaves them out unless asked. Read the `note` lines:
163
+ some pictures carry personality rights or a trademark, are public domain only in the United States,
164
+ or come with an archive's statement instead of a licence.
165
+ - **Download, do not hotlink.** Save what you use into the project: `--get` puts it in `assets/` at
166
+ 1920 pixels wide (pass `--width 1280` for a picture shown at half the screen, `--width 3840` for a
167
+ very large hero where the source has it). The page then works offline, does not break when an
168
+ archive moves a file, and does not load from someone else's server. Every licence the script
169
+ allows by default permits copying.
170
+ - **List them in the report:** file, title, creator, licence, source page, and where the credit sits.
171
+ `--credits` prints that list too.
172
+
173
+ If two or three honest queries per idea find nothing that fits, draw (section 8). A drawing made for
174
+ the subject is better than a found picture that is merely nearby. If the script cannot reach any
175
+ source (no network), draw, and say so in the report. For moving pictures, the same script searches
176
+ real footage with `--video` (section 11).
177
+
178
+ ## 4. The dealt photographs
179
+
180
+ - The sheet lists eight from one set so they share a subject and a light. Use three to six.
181
+ - Each line says where the calm area is. Put text there or keep text off the image.
182
+ - More from the same or another set: `node scripts/draw.mjs --photos list`, `--photos <set>`, or
183
+ `--photos "fog coast"` to search descriptions.
184
+ - URLs have the form `https://picsum.photos/id/<id>/<width>/<height>`. Request the exact pixel size you
185
+ render at twice the CSS size for sharpness, capped around 2400 wide. Add `?grayscale` for
186
+ black-and-white.
187
+ - These are photographs from Unsplash served by Lorem Picsum under the Unsplash licence. List the ids
188
+ you used in your report; they are meant to be replaced by the project's own pictures.
189
+
190
+ ## 5. Cropping and placing
191
+
192
+ - **Choose a small set of ratios and stick to them:** for example 4:5 for portraits, 16:10 for
193
+ landscapes and 1:1 for details. Random ratios look like a stock dump.
194
+ - **Go large.** A photograph at full width, or at half the screen and full height, has presence. Six
195
+ small ones in a grid have none. If the image is good, give it the room; if it is not, cut it.
196
+ - **Crop with intent.** Use `object-fit: cover` with an `object-position` chosen per image so the
197
+ subject sits where the composition needs it (off-centre, on a third, against the text side).
198
+ - **Let images touch edges.** Full-bleed, or bleeding off one side, reads as designed. An image
199
+ floating with equal margins on all sides reads as placed by default.
200
+ - **Overlap sparingly and on purpose:** a headline whose last line runs over the top edge of the
201
+ picture, a small image overlapping a large one by a fixed 40–80px. One overlap per screen at most.
202
+ - **Square corners** unless the direction or the one-motif shape says otherwise. If rounded, one radius
203
+ for every image on the page.
204
+ - **No frames:** no borders, no shadows, no device mock-ups, no browser chrome around pictures.
205
+ - **Captions** are one short line in the small size and soft ink under the image, left-aligned to its
206
+ edge. Most images need none.
207
+ - Where each picture goes on the page, how large, and what the phone does with it: section 12.
208
+
209
+ ## 6. Treatment
210
+
211
+ One treatment for the whole page:
212
+
213
+ - **Untouched.** The default. Pick images whose light already agrees.
214
+ - **Greyscale.** `filter: grayscale(1) contrast(1.05)`, or `?grayscale` on the URL. Unifies a mixed
215
+ set instantly and suits editorial and typographic directions. Apply to every image or none.
216
+ - **Multiply on a field.** On a light flat ground, `mix-blend-mode: multiply` makes a white studio
217
+ background vanish so a product sits directly on the colour.
218
+ - **Darkened for a dark page.** `filter: brightness(0.85) contrast(1.05)` so the image edges sink into
219
+ the ground.
220
+
221
+ Not treatments: colour washes over photographs, duotone overlays, blur, grain overlays, vignettes,
222
+ tilted "polaroid" frames with shadows.
223
+
224
+ For text on a photograph, a neutral scrim covering only the text area: a solid block at 40–55% black,
225
+ or a fade from 55% black to transparent over the lower third. Never a coloured overlay.
226
+
227
+ ## 7. Showing software
228
+
229
+ - Build a real fragment of the interface in HTML at its true size, with believable content, instead of
230
+ a shrunken screenshot or a decorative mock-up. Crop to the part that makes the point: one control,
231
+ one row, one panel.
232
+ - Believable means real labels, real numbers that add up, one item hovered or selected, proper
233
+ alignment. Grey bars standing in for text are worse than no image.
234
+ - Put the fragment directly on the page or on one flat stage colour. No laptop, no phone frame unless
235
+ the product is a phone app and the frame is a plain rounded rectangle.
236
+ - Inside a fragment the product's own interface conventions apply (its small radii, its 1px control
237
+ borders, a shadow on its open menu). Put the attribute `data-ui` on the fragment's root element: the
238
+ inspector and the linter then leave what is inside alone, and hold the page around it to the house
239
+ rules. `data-ui` is for cropped fragments only; wrapping a heading or a whole section in it fails.
240
+ Write the fragment's CSS under a `[data-ui]` selector (`[data-ui] .row { … }`) so the linter can
241
+ tell it apart from page styles.
242
+ - If the user supplies real screenshots, show them large and uncropped at least once.
243
+
244
+ ## 8. Drawing the subject
245
+
246
+ When nothing real can be photographed and the open collections hold no honest picture of it, draw it,
247
+ and draw it well. Inline SVG and CSS are enough. Drawings and found pictures can share a page: the
248
+ found ones show the world around the client, the drawings show the client's own things.
249
+
250
+ - **Draw the subject's own things,** not decoration: the stool's three legs and the grain of its seat,
251
+ the enamel sign over the bakery door, the hut's two windows and its stove pipe, the street plan, the
252
+ invoice the tool produces, the festival's stage. If you cannot name what a drawing depicts in the subject's world, it is decoration.
253
+ - **One graphic language for the whole page:** flat filled shapes, no outlines or one consistent
254
+ stroke weight, the same corner and curve vocabulary everywhere, drawn in the palette's real colours
255
+ (fields and accent at full strength, not greys). A set of drawings that obviously belong together
256
+ reads as an identity; a mix of styles reads as clip art.
257
+ - **Colour is the material.** A product sold on its finish is drawn in that finish's colours; a sea house in the
258
+ sea's blues and the sand; never a page of grey placeholders.
259
+ - **Draw with three levels of detail.** Jurors called simple drawings "basic" every time. Give each
260
+ drawing big shapes that read at a glance, middle shapes that describe the thing (the handle, the
261
+ window frame, the step), and small details that reward a second look (the maker's mark, the house
262
+ number, the chipped tile, the hinge, a bird on the roof). Make light with flat tone steps (a lit face
263
+ and a shaded face of each volume), not gradients. A drawing that would pass as a placeholder icon at
264
+ full size is not finished.
265
+ - **Draw large and let it work:** the drawing is the hero's dominant element, a full-width band, a set
266
+ of tiles, the footer mark. Small doodles scattered around read as filler.
267
+ - **Let it carry the idea through the page,** the way a motif does: the same drawn object returns at
268
+ different scales, the tile grid becomes the opening hours, the map becomes the booking section.
269
+ - **Honesty:** say plainly, in small text near the first drawing or in the footer, that the pictures
270
+ are drawn until photographs exist, if the client might otherwise be taken to be showing real
271
+ products. In your report, list which drawings are placeholders for photography.
272
+ - **Not this:** gradient-shaded 3D-looking blobs, isometric clip art, generic line illustrations of
273
+ people at laptops, abstract floating shapes, icons in squares. Those are the generated look.
274
+
275
+ ## 9. Type and colour alone
276
+
277
+ This is a legitimate design, not a gap to disguise. Only 7 of the studied sites use no imagery at all,
278
+ and they hold their own: a median panel score of 7.5 against 7.2 for the whole set.
279
+
280
+ - Make the typography the image: one statement at 10–14vw, a list set at 5vw, numerals at display size.
281
+ - Use colour at scale: a full field, an inverted section, a two-field split.
282
+ - Use the subject's own shape as one flat motif if the direction calls for it (a circle, an arc, a
283
+ notch), drawn in CSS, cropped by the viewport.
284
+ - Do not add: icons in squares, abstract gradients, dot grids, wave dividers, floating shapes, emoji,
285
+ generic line illustrations, or an empty box where a picture "will go".
286
+
287
+ ## 10. Markup and credits
288
+
289
+ A found picture, downloaded into the project with `--get`, used as the hero:
290
+
291
+ ```html
292
+ <img src="assets/fig-engraving.jpg" width="1920" height="2807" fetchpriority="high" decoding="async"
293
+ alt="Hand-coloured engraving of a fig cut open, with its flowers and seeds, in black, pink and green">
294
+ ```
295
+
296
+ A dealt photograph further down the page:
297
+
298
+ ```html
299
+ <img src="https://picsum.photos/id/626/2400/1500" width="2400" height="1500"
300
+ alt="Red and white lighthouse in a turquoise sea below a chalk cliff" loading="lazy" decoding="async">
301
+ ```
302
+
303
+ The credits, as `--credits` prints them, in the footer:
304
+
305
+ ```html
306
+ <p class="credits">Pictures: <a href="https://commons.wikimedia.org/wiki/File:Fig_(Ficus_carica_L.);_57_segments_of_flowers_and_fruits_at_Wellcome_V0043000.jpg">“Fig (Ficus carica L.): 57 segments of flowers and fruits”</a>, <a href="https://creativecommons.org/publicdomain/mark/1.0/">public domain</a>, via Wikimedia Commons.</p>
307
+ ```
308
+
309
+ - Always `width` and `height` (or `aspect-ratio` in CSS) so nothing jumps while loading.
310
+ - `loading="lazy"` on everything except the hero image, which gets `fetchpriority="high"`.
311
+ - `alt` describes the picture in plain words. Decorative repeats get `alt=""`. The script's suggested
312
+ alt is the archive's title; rewrite it to say what the picture shows.
313
+ - A coloured `background-color` on the image container (the ground or surface tone) so the layout is
314
+ whole before the image arrives.
315
+ - The credit line is part of the footer's design, at full contrast, with its links. Set it at the body
316
+ size; one step smaller only on a page with plenty of running text, because a long credit line in
317
+ small type can become the page's most common text size and fail the inspector's body-size check.
318
+ One line for all pictures; no credit captions laid over the pictures themselves. Credit only the
319
+ pictures the page still uses.
320
+ - A broken image fails the inspector. Check every picture in the screenshots.
321
+
322
+ ## 11. Video
323
+
324
+ A moving picture of the subject's world can carry a section the way a photograph does: the river at
325
+ the end of the street, the roaster's drum turning, a timber frame going up. `assets.mjs --video`
326
+ searches real footage without keys: Wikimedia Commons (every video there comes with web-sized
327
+ transcodes; the best source for short clips), the Internet Archive's Prelinger Archives (industrial,
328
+ educational, city and home films from the 1920s to the 1970s, mostly public domain and mostly long)
329
+ and NASA (the Earth from orbit, launches, aircraft, laboratories). The rest of the Internet Archive is
330
+ left out: anyone can upload there, and the licence claims are unchecked.
331
+
332
+ ```bash
333
+ node <skill>/scripts/assets.mjs "coffee roasting" --video
334
+ node <skill>/scripts/assets.mjs "river" --video --source commons,nasa --orientation landscape
335
+ node <skill>/scripts/assets.mjs --get commons:49769620 # the clip, a poster frame, the credit
336
+ ```
337
+
338
+ It takes a rendition of 720p or smaller (`--res` changes that), lists short clips first, prints each
339
+ clip's length and file size, and flags anything over 25 MB or longer than a minute. `--get` refuses a
340
+ clip over 25 MB unless you pass `--max-mb`, and saves the source's still frame beside it as the
341
+ poster (Commons and NASA; the archive's own stills are too small). An archive film of ten minutes is
342
+ too heavy as it stands: trim a few seconds from it with ffmpeg if it is installed, or choose a
343
+ shorter clip. Licences, credits and honesty work exactly as for pictures (section 3).
344
+
345
+ **Choosing a clip.**
346
+
347
+ - **Short:** 5 to 20 seconds that loop without a visible jump: water, smoke, a turning drum, traffic,
348
+ leaves, a crowd from far away. Watch it to the end before choosing.
349
+ - **Light:** under about 5 MB for a section and 10 MB for a hero. In the study sources are 1920×1080
350
+ (the commonest) or 1280×720, median length 10 s; 720p is plenty behind type. For a full-bleed hero,
351
+ cut a tall 720×1280 version for the phone, or set `object-position` on the subject.
352
+ - **Clean:** no slate, title card, logo, watermark or burned-in caption. NASA and archive films often
353
+ open with a slate, and the source's poster frame may be that slate. No recognisable person who could
354
+ be taken for the client's staff or customers.
355
+ - **Never the client's own:** a found clip of a roastery is not this roastery.
356
+ - **Found clips: one per page, two at most.** A found clip shows the world around the client; a
357
+ third makes a theme of it. The project's own footage can carry more: in the study a site with
358
+ footage carries a median of three or four clips. Either way, **one moving picture per screen**;
359
+ two loops running side by side are noise.
360
+
361
+ **On the page.**
362
+
363
+ - Muted, looping, inline, with a poster and a fixed size, as `--get` prints it:
364
+ `<video autoplay muted loop playsinline preload="metadata" poster="assets/river-poster.jpg"
365
+ width="854" height="480" aria-hidden="true"><source src="assets/river.webm" type="video/webm"></video>`.
366
+ No sound and no controls on a decorative loop. `aria-hidden` because it is decoration: whatever the
367
+ clip says that matters belongs in the text beside it.
368
+ - The poster shows before the clip plays, on slow connections and under reduced motion, so it must
369
+ work as a picture on its own. If the source's still is a slate or a blur, take a frame from the clip
370
+ yourself or use a found picture.
371
+ - In the study only 31% of clips had a poster, and the panel recorded the blank and grey boxes
372
+ before they played as faults. Here every clip has one.
373
+ - Play a clip only while it is in view, and none under `prefers-reduced-motion: reduce`, where the
374
+ poster shows instead:
375
+
376
+ ```html
377
+ <script>
378
+ const calm = matchMedia('(prefers-reduced-motion: reduce)');
379
+ const clips = [...document.querySelectorAll('video[autoplay]')];
380
+ const inView = new Set();
381
+ const sync = (v) => {
382
+ if (calm.matches) return;
383
+ if (inView.has(v)) v.play().catch(() => {}); else v.pause();
384
+ };
385
+ const settle = () => {
386
+ for (const v of clips) {
387
+ if (calm.matches) { v.removeAttribute('autoplay'); v.pause(); v.load(); }
388
+ else if (inView.has(v)) v.play().catch(() => {});
389
+ }
390
+ };
391
+ const watch = new IntersectionObserver((entries) => {
392
+ for (const e of entries) {
393
+ if (e.isIntersecting) inView.add(e.target); else inView.delete(e.target);
394
+ sync(e.target);
395
+ }
396
+ }, { threshold: 0.2 });
397
+ clips.forEach((v) => watch.observe(v));
398
+ settle();
399
+ calm.addEventListener('change', settle);
400
+ </script>
401
+ ```
402
+
403
+ - Crop and place it like a photograph (sections 5 and 6): `object-fit: cover`, one ratio, square
404
+ corners, no frame, a ground-coloured `background-color` while it loads.
405
+ - Never under body text. On a clip put a headline, one line and one action at most, and check the
406
+ contrast where they sit across the whole loop, not only on the poster: footage that is dark at
407
+ one second can be bright at the next. If any frame drops below 4.5:1 (3:1 for 24px and up), use the
408
+ scrim in section 6 or move the text off the clip. Nothing lies on top of a headline or a statement.
409
+ - It is motion: let it be the page's one moving thing, or sit in a section where nothing else moves.
410
+ - Credit it with the pictures: `--credits` prints one footer line for both ("Pictures and footage:")
411
+ and the list for the report, with each clip's length.
412
+ - Where footage goes (hero background, inline loop, the frame that grows, a docked card), and what
413
+ the study measured about it: section 12. Nothing that matters plays on hover only, and a full film
414
+ with sound sits behind a play button that opens a player with controls.
415
+
416
+ ## 12. Where pictures and footage go
417
+
418
+ What strong pages do with their pictures, measured on the latest 100 Awwwards Sites of the Day
419
+ (10 July to 17 October 2026, captured at 1440×900 and 390×844). 91 were usable. A panel described where
420
+ every picture sat and scored each site the Awwwards way, and a script measured how much of each screen
421
+ is picture. "Top" means a panel score of 7.5 or more (36 sites), "lowest" under 7.3 (16 sites). The
422
+ scores sit close together (6.7 to 7.9) and a single score carries about half a point of noise, so read
423
+ the links between a placement and the score as leanings, not laws.
424
+
425
+ ### How much of each screen is picture
426
+
427
+ - **All or nothing.** Counting photographs, footage and picture backgrounds (not canvases), the median
428
+ scrolled screen in the study is 16% picture, but few screens sit near it: 42% hold no picture and
429
+ 19% are 90% picture or more. Only 19% fall between 20% and 60%. A picture either leads its screen or
430
+ stays out of it.
431
+ - **About a third, with rests.** On the 67 sites that put pictures in the page, the average screen is
432
+ 36% picture (middle half 18–69%). Top sites sit at 30% and leave 28% of their screens with no picture
433
+ at all: screens of type are the rests between picture screens.
434
+ - **The first screen.** A picture covers at least half of it on 41% of the sites and nearly all of it
435
+ on 32%. A full-bleed photograph or film is the whole first screen on 29%; footage is the main hero
436
+ picture on about a quarter.
437
+ - **A scene is not a picture.** 66 of the 91 keep a WebGL canvas over at least 30% of the screen, so
438
+ counting canvases the median screen is entirely covered. On the lowest-scored sites that canvas is
439
+ often all there is: the five lowest usable sites (6.7 to 7.0) draw everything in it and put two
440
+ pictures at most in the page.
441
+ - **Text is small in area.** The median screen is 8% text. Type is set large and sparse around the
442
+ pictures, not packed beside them.
443
+ - **Off-centre.** Measured per section across the crawled sites, pictures sit to the left or right
444
+ 939 times, centred 273 times, and full-bleed or behind text 269 times.
445
+ - **The phone carries more picture,** not less: 19% of a phone screen at the median, and 27% of the
446
+ first phone screen against 17% on desktop. Full-bleed pictures re-crop to portrait and fill the
447
+ screen; splits put the picture first at full width.
448
+
449
+ ### How many
450
+
451
+ - **Seven pictures per page** at the median (middle half 1–25). Top sites 8 (middle half 4–27), lowest
452
+ 2 (0–4). The floor in SKILL.md step 6, four and usually six to twelve, is the strong half of the
453
+ study.
454
+ - **Footage on 42% of sites:** on half of the top sites and half of the middle band, and on one of the
455
+ 16 lowest. A site with footage carries a median of three or four clips.
456
+ - **Three to five placements.** Sites that use two or fewer of the placements below average 7.31;
457
+ sites that use three or more average about 7.5. The median top site uses four, the median lowest
458
+ site one. Where the pictures go changes from section to section on a designed page.
459
+
460
+ ### The placements, ranked
461
+
462
+ | Placement | Sites (of 91) | Top (of 36) | Lowest (of 16) | Mean score with / without |
463
+ | --- | --- | --- | --- | --- |
464
+ | Split: picture in a half or two-thirds | 32 | 17 | 2 | 7.50 / 7.38 |
465
+ | Horizontal gallery | 32 | 13 | 4 | 7.44 / 7.41 |
466
+ | Full-bleed band between sections | 31 | 14 | 3 | 7.48 / 7.40 |
467
+ | Full-bleed picture or film as the first screen | 26 | 10 | 3 | 7.45 / 7.41 |
468
+ | Uneven mosaic | 25 | 11 | 1 | 7.49 / 7.40 |
469
+ | Picture held while text scrolls | 23 | 12 | 1 | 7.52 / 7.39 |
470
+ | Footage behind text | 22 | 8 | 2 | 7.46 / 7.41 |
471
+ | Even grid | 20 | 11 | 2 | 7.48 / 7.41 |
472
+ | Scattered collage | 19 | 6 | 3 | 7.47 / 7.41 |
473
+ | Panel sliding over a held picture | 19 | 8 | 2 | 7.48 / 7.41 |
474
+ | Inset frame that grows | 17 | 7 | 1 | 7.52 / 7.40 |
475
+ | One picture centred on a field | 14 | 5 | 3 | 7.38 / 7.43 |
476
+ | Cut-out object on a flat field | 13 | 7 | 1 | 7.57 / 7.40 |
477
+ | Index with hover preview | 12 | 6 | 1 | 7.49 / 7.41 |
478
+ | 3D gallery | 12 | 4 | 4 | 7.30 / 7.44 |
479
+ | Small card docked in a corner | 11 | 5 | 1 | 7.47 / 7.42 |
480
+ | Picture inside or in front of display type | 11 | 7 | 1 | 7.50 / 7.41 |
481
+ | One small picture beside a statement | 8 | 5 | 0 | 7.56 / 7.41 |
482
+ | Small pictures between words | 6 | 4 | 0 | 7.52 / 7.42 |
483
+
484
+ - Found on top pages more than their share and almost never on the lowest: the split, the picture held
485
+ while text scrolls, the uneven mosaic, the inset frame that grows, the cut-out on a flat field, and
486
+ pictures set with the type (the last three rows together: 24 sites, 16 of them top, 1 lowest).
487
+ - The horizontal gallery is common in every band and lifts nothing. Use it where browsing is the point.
488
+ - The 3D gallery is the one placement that goes with lower scores, and with the lowest usability in the
489
+ table (5.9 against 6.35 for all sites).
490
+
491
+ ### Each placement
492
+
493
+ Each entry gives when to use it, the geometry at 1440×900, the phone version and how it fails.
494
+
495
+ **Split: picture in a half or two-thirds**
496
+
497
+ - *When.* A claim and the picture that proves it. The commonest way strong pages pair words and a
498
+ picture.
499
+ - *Geometry.* The picture takes 42% of the width at the median (middle half 33–49%), up to two-thirds,
500
+ at the full height of its section: 680×850 and 720×900 are typical. 38% of these pictures are
501
+ portrait, mostly 4:5 or 3:4. The text starts on the 50% line (x = 720) or on the line where the
502
+ picture ends, top-aligned or docked low, not centred in its half. Let the picture touch the viewport
503
+ on its outer side: only about 30% do in the study, and the ones with margin on every side read as
504
+ placed by default (section 5). Alternate sides only across three or more rows.
505
+ - *Phone.* Picture first at full width (4:5, or 4:3 for a landscape), text under it.
506
+ - *Fails.* The same split in three sections running; a picture floating in the middle of its half; a
507
+ text column narrower than about 30 characters.
508
+
509
+ **Full-bleed band**
510
+
511
+ - *When.* One picture carries a whole screen between type screens: the place, the work, the object at
512
+ full size. One every three or four screens at most.
513
+ - *Geometry.* 100% wide and one to one and a half screens tall (median 900px at 1440×900, middle half
514
+ 890–1,170px; ratios 1.4 to 1.9). For a slow parallax the picture is oversized in its frame by 4–10%
515
+ (32–72px a side in the study) and travels no further than that. Text is a headline and one line, or
516
+ nothing, docked 32–64px in from a corner over the calm part of the picture.
517
+ - *Phone.* A portrait re-crop that fills the screen, with `object-position` set on the subject; the
518
+ text moves to the bottom quarter.
519
+ - *Fails.* 11–14px white text over a bright area; three bands with nothing between them; a band that
520
+ only decorates.
521
+
522
+ **Picture held while text scrolls**
523
+
524
+ - *When.* A list, steps or a long paragraph that all belong to one picture. If the picture changes for
525
+ each item, it is the index with a preview, below.
526
+ - *Geometry.* A 100vh sticky stage inside a section two to six screens long (runways of 1,800–5,400px
527
+ are typical in the study). The picture holds one half (685×880 is a typical portrait), two-thirds, or
528
+ the whole screen with the text passing over it on a solid panel. Text rows about 150px apart, so two
529
+ or three are in view at once.
530
+ - *Phone.* Release the stick: picture first, text under it. If the picture swaps per item, keep it as
531
+ a band in the top 40% of the screen.
532
+ - *Fails.* Long runways where the text has faded out and the held picture is all that is left (the
533
+ panel recorded several empty stages on phones); body copy set on the held picture.
534
+
535
+ **Inset frame that grows**
536
+
537
+ - *When.* Once per page, for the film or picture the page is about, as the move from type into
538
+ picture.
539
+ - *Geometry.* The frame starts centred at 35–50% of the width (549×366, 710×480 and 864×540 in the
540
+ study) or as a 16px inset round a full screen, and grows to the full width and height over
541
+ 720–2,700px of scroll. Any corner radius goes to 0 as it reaches the edges. A headline sits above it
542
+ before it starts; nothing else on the screen moves while it grows.
543
+ - *Phone.* Start at full width inside the 16px margins and grow to a full-bleed portrait, or skip the
544
+ growth.
545
+ - *Fails.* The growth is the only thing on screen for three scrolls; a loading spinner or a blank box
546
+ in the first frame (give it a poster, start loading before it enters); used twice.
547
+
548
+ **Uneven mosaic**
549
+
550
+ - *When.* A body of work, or one place seen several ways: five to twelve pictures.
551
+ - *Geometry.* Two columns, or rows of three on a 24-column grid. Two or three picture widths (for
552
+ example 32%, 48% and 65% of the width, or 5, 7 and 12 columns), neighbours offset vertically by
553
+ 120–190px, 130–450px between rows, one or two ratios, a caption under each.
554
+ - *Phone.* One column alternating full width and about 70% width, or two columns of 120–180px tiles
555
+ that keep the offsets.
556
+ - *Fails.* Random ratios with random offsets, which read as a stock dump. Captions in 9–12px mono with
557
+ index numbers, the award-site habit: here the caption is one line in the text face at body size, with
558
+ no number.
559
+
560
+ **Horizontal gallery**
561
+
562
+ - *When.* A set people browse in any order: products, rooms, events, a team.
563
+ - *Geometry.* Cards 25–35% of the width (435×326 with 20px gaps at 1440: three in full and a fourth
564
+ cut by the edge), or a strip at one fixed height with mixed widths (576px tall in the study), or a
565
+ slider whose centre slide is about 73% of the width with 170–180px of each neighbour showing. Always
566
+ cut by the right edge so it reads as more. A marquee of pictures moves slowly: 60–120s per loop.
567
+ - *Phone.* One card at 75–80% of the width (290–300px of 390) with the next one showing; swipe.
568
+ - *Fails.* Arrows and no drag or swipe; a marquee of things people need to read; a carousel holding the
569
+ page's one important picture.
570
+
571
+ **Panel sliding over a held picture**
572
+
573
+ - *When.* A change of chapter: the picture holds, and the next section rises over it.
574
+ - *Geometry.* The picture is sticky at 100vh; the next section's ground slides up over it at full width,
575
+ its top edge straight or shaped from the subject (the study has the arch of a building's windows).
576
+ Here it is a solid panel with square corners: no rounded sheet tops, no frosted glass.
577
+ - *Phone.* Unchanged.
578
+ - *Fails.* Decks of five or six cards whose earlier cards linger as slivers; stacking for its own sake.
579
+
580
+ **Even grid**
581
+
582
+ - *When.* An archive only (layout.md §5): a shop range, the team, a menu, the full list of work.
583
+ - *Geometry.* Two, three or four across, equal cells, 8–16px gaps, one ratio (4:5 is the commonest),
584
+ the caption under each picture.
585
+ - *Phone.* Two across for products, one for work and people.
586
+ - *Fails.* Three equal cards as "features". Cards with a dark gradient at the foot so the label can sit
587
+ on the picture, common in the study: here the label goes under the picture.
588
+
589
+ **Index with hover preview**
590
+
591
+ - *When.* A list of eight or more projects or clients where the names matter as much as the pictures.
592
+ - *Geometry.* Rows on a 45–80px pitch, names at 30–60px. One picture at a time, about a third of the
593
+ width at 16:9 or a portrait 300–450px tall, at a fixed place (the right half from the 50% line, or
594
+ the centre), swapped within 0.3s. A version that needs no mouse: the names scroll across a picture
595
+ fixed at the centre and the picture shows whichever name is crossing it. In the study the picture
596
+ sits on top of the names; here nothing lies on top of large type, so the names pass in front of it.
597
+ - *Phone.* No hover. Give each row a thumbnail about 100px wide, or use the scroll version.
598
+ - *Fails.* Pictures that never appear on a touch screen. Rows divided by hairlines, the award-site
599
+ habit: here rows are separated by space, and the active row by ink or a change of ground.
600
+
601
+ **One picture on a field, or one small picture beside a statement**
602
+
603
+ - *When.* A pause in the page: a single portrait or object. Or a small picture that gives a statement
604
+ a face.
605
+ - *Geometry.* A single centred picture at 3:4 and 75% of the viewport height, on a ground taken from
606
+ the picture. Or a small picture 7–26% of the width (108–374px) beside, above or between the lines
607
+ of a 48–136px statement, aligned to one of its lines.
608
+ - *Phone.* The picture above the statement at 60–100% of the width.
609
+ - *Fails.* Used as the default for every picture: a picture with equal margins on all sides reads as
610
+ placed by default (section 5).
611
+
612
+ **Small pictures between words**
613
+
614
+ - *When.* A statement about the things themselves (materials, people, products), on a screen of its
615
+ own.
616
+ - *Geometry.* Two to four chips in the statement, from the cap height to three-quarters of the type
617
+ size tall and one to one and a half times as wide (50×46px in a 60px line; 113×75px between the two
618
+ words of a 150px name), all from one shoot, square corners. Give them a width and height so the lines
619
+ do not jump while they load.
620
+ - *Phone.* Keep them inline at the height of the text.
621
+ - *Fails.* More than four; chips from different shoots; a chip that carries information the words do
622
+ not.
623
+
624
+ **Picture inside or behind display type**
625
+
626
+ - *When.* The object is the subject: a product, a building, a person.
627
+ - *Geometry.* A small picture window sits inside a block of 150–200px display type and later opens
628
+ into the next screen; or the object stands behind the type, showing between and around the letters;
629
+ or it touches the edge of the word without covering a letter. In the study the object more often
630
+ stands in front and covers one or two letters, or a line of type runs behind a square picture; here
631
+ nothing lies on top of a headline (the inspector fails large text a fifth or more hidden), so the
632
+ type stays in front.
633
+ - *Phone.* Keep it, with the type at about 15vw, and check the word still reads.
634
+ - *Fails.* An object over the letters; type displaced or glitched by the picture.
635
+
636
+ **Cut-out object on a flat field**
637
+
638
+ - *When.* Products and objects. The highest mean score in the table, on 7 of the 36 top sites.
639
+ - *Geometry.* The object at 35–60% of the width on a flat ground taken from its own colours, standing
640
+ on the bottom edge or running off one side, with the type behind or beside it.
641
+ - *Phone.* The object at 80–90% of the width under the headline.
642
+ - *Fails.* A render floating in a void with no ground; a drop shadow added to a cut-out (no resting
643
+ shadows here; keep a contact shadow only if it was photographed).
644
+
645
+ **Scattered collage**
646
+
647
+ - *When.* Archives, ephemera, a festival of many small things. Sparingly: it is about as common on the
648
+ lowest pages as on the top ones.
649
+ - *Geometry.* Six to sixteen pictures of 100–300px at a few sizes around a centred heading, never over
650
+ it.
651
+ - *Phone.* Re-stack as overlapping pairs in one column.
652
+ - *Fails.* Tilted prints and stickers with offset shadows, common in the study and not a treatment
653
+ here (section 6); pictures crossing the text.
654
+
655
+ **Small card docked in a corner**
656
+
657
+ - *When.* A standing pointer to the reel or to the next thing.
658
+ - *Geometry.* About 216×144 to 240×140, 30–43px from the corner; one per page.
659
+ - *Phone.* Drop it, or move it into the flow.
660
+ - *Fails.* Content scrolling under it; a second one.
661
+
662
+ **3D gallery**
663
+
664
+ - *What.* Pictures on a ring, sphere, helix or tunnel in a WebGL scene, turned by the wheel or by
665
+ dragging.
666
+ - *In the study.* 12 sites, 4 of them among the 16 lowest; mean score 7.30 against 7.44, usability 5.9
667
+ against 6.35.
668
+ - *Here.* Do not build one. Show the same pictures as an index with previews or a horizontal gallery.
669
+
670
+ ### Footage
671
+
672
+ **What the study measured.**
673
+
674
+ - Footage on 38 of 91 sites (42%): 18 of the 36 top sites, 19 of the 39 in the middle, 1 of the 16
675
+ lowest. A site with footage carries a median of three or four clips (middle half 1–8).
676
+ - Footage covers at least half of the first screen on about a quarter of the sites, and is full-bleed
677
+ on nearly all of them.
678
+ - Clips are short: median 10s, middle half 5–14s; 61% run 10s or less and 88% 20s or less.
679
+ - Every decorative clip is muted, loops, plays inline and has no controls. The autoplay attribute is on
680
+ 44% of clips; the rest are started by script, mostly as they come into view.
681
+ - Only 31% of clips have a poster (13 of the 38 sites). The rest show a blank or grey box until they
682
+ play, and the panel recorded those as blank first paints. Here a poster is required (section 11).
683
+ - Sources: 1920×1080 is the commonest, then 1280×720; tall clips at 450×800 or 540×960 for phones and
684
+ portrait tiles. Median source width 1,080px.
685
+ - On the page: 16:9 41%, square 19%, portrait (4:5 to 9:16) 25%, 4:3 or 3:2 12%. Corners square on 75%
686
+ (the rest 8px or less, or 20–32px). `object-fit: cover` on 84%, contain on 16% (product strips, letterboxed
687
+ films).
688
+
689
+ **Where it goes.**
690
+
691
+ - **Hero background:** full-bleed, cover, often oversized by 1–25% so a drift or zoom never shows an
692
+ edge. Either one slow take or a montage cutting every second or two.
693
+ - **Inline, as a picture:** in splits, tiles and cards, at about a third of the width (median 33%,
694
+ middle half 24–45%); a third of these clips are under a quarter of the width and fewer than one in
695
+ ten is full width. Slow, near-still subjects (water, skin, light, a turning object) read as living
696
+ photographs and sit well among stills.
697
+ - **The frame that grows** (above), for a reel.
698
+ - **A docked card** (above): one small clip in a corner.
699
+ - **On hover:** only two or three sites play clips on hover, all of them in an index or list. Nothing
700
+ that matters should play on hover only; phones have no hover.
701
+ - **Full films:** about ten sites offer a full film behind a play button that opens a player with
702
+ controls. None autoplays it.
703
+ - **Sound:** six sites offer sound behind a toggle; no clip starts with sound.
704
+
705
+ **How text sits on it.**
706
+
707
+ - Of about 30 sites with a full-bleed picture or film behind text on the first screen, about 14 set the
708
+ type straight on it and rely on the footage being graded dark where the type sits; about 10 dim it
709
+ (to half brightness, under a 30–40% dark layer, or with a dark fade along the bottom 180–590px);
710
+ about 6 keep the text off the picture, above it or on a solid card.
711
+ - What goes on footage in the study is the name or a headline at 47–136px and one short line, docked
712
+ bottom-left or centred. Where body text at 11–14px went on footage or a busy photograph, the panel
713
+ named it as a fault, on top-scored sites too.
714
+ - Here: one headline, one line and one action on footage at most, and never body text. Check contrast
715
+ where the type sits across the whole loop, not only on the poster; if any frame drops below 4.5:1
716
+ (3:1 for type of 24px and up), use the scrim in section 6 or a solid band.
717
+
718
+ **On the phone.** Footage re-crops to a full-screen portrait (a separate tall source, or
719
+ `object-position` on the subject); inset frames go full-bleed. One site in the study adds a 40% scrim
720
+ on the phone only, where the type covers more of the picture.
721
+
722
+ ### Crops and treatment
723
+
724
+ - **Ratios.** Of 1,356 pictures and clips measured: 4:5 21%, 16:9 19%, 1:1 16%, 16:10 10%, 3:2 7%, 2:3
725
+ 5%, 4:3 5%, 5:4 4%, 3:4 3%, wider than 2:1 6%, 9:16 or taller 3%. Landscape 52%, portrait 33%,
726
+ square 15%.
727
+ - **Two ratios do most of the work.** On sites with four pictures or more, the two commonest ratios
728
+ hold 76% of the pictures. The others (five ratios in all at the median) are exceptions with a reason:
729
+ one tall portrait in a run of landscapes, one wide band.
730
+ - **Square corners** on 94% of pictures; 62 of the 68 sites with pictures in the page keep at least 80%
731
+ of them square. Where corners are rounded, it is 5px or less on two-thirds of them, or 20–32px on
732
+ card interfaces, one value per site.
733
+ - **Cover.** `object-fit: cover` on 78%, contain on 10% (a product on a tile, a letterboxed film).
734
+ - **Untouched.** CSS filters touch pictures on only 9 sites, mostly for hover states. A handful use
735
+ black-and-white photography as a set; two multiply scanned paper onto the ground. Several keep the
736
+ interface black, white and grey and let the photographs carry all the colour.
737
+ - **Common in the study, not treatments here** (section 6): a fixed grain layer over the whole page
738
+ (about a third of the sites), duotone or tinted photographs, blurred copies behind a picture as a
739
+ glow, tilted prints and stickers with offset shadows.
740
+ - **Oversize only by the distance it moves.** 22 sites move pictures with the scroll, oversizing them by
741
+ 1–25%. Oversize by the travel and no more, on one picture per screen.
742
+ - **Resolution.** The study serves pictures at a median 1.9 times their CSS width, but 17% are served
743
+ smaller than they are shown and full-width pictures at a median of only 1,440px. Here: twice the CSS
744
+ width, capped at about 2,400px (section 4).
745
+
746
+ ### Text over pictures
747
+
748
+ - In the study, text sits on pictures often and is checked rarely: about 28 notes record text set
749
+ straight on a picture with no scrim, and the faults of 16 sites include text lost over pictures: 8–14px
750
+ labels and body over photographs, and navigation in a difference blend or with no backing passing
751
+ over them.
752
+ - Where it works, the text is display size and sits over the calm part (sky, a dark wall, the shadow
753
+ side), docked in a corner or along one edge. Two other forms in the study: a solid card in the
754
+ ground colour inset over the photograph and carrying the heading, and text on the white of a picture
755
+ that fades into the page.
756
+ - Here: on a picture put only display text, one short line and one action. Body text, captions and
757
+ labels go beside or under it. Measure contrast at the text's own position (4.5:1, or 3:1 for 24px and
758
+ up). If it fails, move the text to a calmer part, put it on a solid card in the ground colour, or use
759
+ the scrim in section 6. A fixed navigation that passes over pictures gets a solid band, or hides
760
+ while scrolling down.
761
+
762
+ ### Rules for a generator
763
+
764
+ 1. **About a third of the page is picture.** Across the scrolled screens, pictures fill 30–40% of the
765
+ area, and at least one screen in four carries no picture (top sites: 30% and 28%).
766
+ 2. **A picture leads its screen or stays small.** A leading picture takes at least 60% of its screen;
767
+ an accent stays under 10% of it. Avoid screen after screen of pictures at 20–40%: in the study 42% of
768
+ screens are 0% and 19% are 90% or more.
769
+ 3. **Three to five placements per page,** and no two neighbouring sections with the same one. Sites
770
+ with two or fewer average 7.31, sites with three or more about 7.5.
771
+ 4. **Six to twelve pictures, never fewer than four.** Study median 7; top sites 4–27; lowest 2.
772
+ 5. **Two ratios for at least 75% of the pictures** (76% in the study), a third only for a deliberate
773
+ exception. Defaults: 4:5 for portraits, 16:9 or 3:2 for landscapes.
774
+ 6. **Square corners on every picture** (94% in the study). If the direction rounds them, one radius of
775
+ 4px for every picture and clip.
776
+ 7. **Split pictures take 42–50% of the width, or two-thirds,** at the full height of the section and
777
+ touching the viewport on their outer side; the text starts on the 50% line. On the phone the
778
+ picture goes first, full width.
779
+ 8. **Full-bleed bands are 100% wide and 100–150vh tall,** one every three or four screens, oversized by
780
+ 10% at most for parallax, with text only in one corner at least 32px in. On the phone, re-crop to a
781
+ full-screen portrait.
782
+ 9. **One inset frame that grows per page,** from 35–50% of the width to the full screen over
783
+ 720–2,700px of scroll, with nothing else moving on that screen.
784
+ 10. **Horizontal galleries show three cards and a cut fourth:** cards 25–35% of the width with 16–20px
785
+ gaps; on the phone one card at 75–80% of the width with the next one showing.
786
+ 11. **One moving picture per screen.** Clips of 5–15s (median 10s), muted, looped, inline, with a
787
+ poster, paused out of view; a hero source of 1920×1080 under 10MB, inline clips at 1280×720 or
788
+ smaller under 5MB.
789
+ 12. **Only display text on a picture:** a headline, one line and one action at most, with contrast
790
+ measured at the text's position across the whole loop. Body text, 16px or more, goes beside or
791
+ under the picture, never on it.