efficient-easel 1.1.1 → 2.0.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 (70) hide show
  1. package/README.md +7 -3
  2. package/dist/chrome/index.js +1 -1
  3. package/dist/{chunk-ORR3Q4WV.js → chunk-2JIWFFXA.js} +1 -1
  4. package/dist/{chunk-MAEXP3KE.js → chunk-35Q5HMJZ.js} +1 -1
  5. package/dist/{chunk-THQB37AA.js → chunk-4CJP57AY.js} +1 -1
  6. package/dist/chunk-4VJATVVR.js +1 -0
  7. package/dist/{chunk-5LGAIELC.js → chunk-6AMS5BQH.js} +3 -3
  8. package/dist/chunk-6HHHBBSY.js +16 -0
  9. package/dist/{chunk-QR4DLZ3P.js → chunk-BSSKAEFF.js} +1 -1
  10. package/dist/chunk-E2L2XVRX.js +23 -0
  11. package/dist/chunk-HGTPLCTQ.js +1 -0
  12. package/dist/chunk-HMXIAMCU.js +1 -0
  13. package/dist/chunk-IJ3OOBDY.js +64 -0
  14. package/dist/chunk-IJGHMGG4.js +1 -0
  15. package/dist/chunk-LACBURK5.js +5 -0
  16. package/dist/{chunk-DCPFE4IO.js → chunk-LC7N3GZS.js} +1 -1
  17. package/dist/{chunk-P3GORPR4.js → chunk-LEGBBCOH.js} +1 -1
  18. package/dist/chunk-OSPUG6S6.js +1 -0
  19. package/dist/chunk-OXYGFK2B.js +21 -0
  20. package/dist/{chunk-EOUMA3QT.js → chunk-PBVC2VGH.js} +1 -1
  21. package/dist/chunk-PT6NPMWV.js +5 -0
  22. package/dist/chunk-V7U33NF2.js +1 -0
  23. package/dist/{chunk-SQTY6CJD.js → chunk-ZV6OYSZ7.js} +1 -1
  24. package/dist/copy/index.js +21 -21
  25. package/dist/drag/index.js +1 -1
  26. package/dist/fields/index.js +1 -1
  27. package/dist/icons/index.d.ts +2 -507
  28. package/dist/icons/index.js +1 -1
  29. package/dist/index.d.ts +1 -1
  30. package/dist/index.js +1 -1
  31. package/dist/node-ops/index.js +1 -1
  32. package/dist/panel/index.js +15 -15
  33. package/dist/rail/index.d.ts +1 -1
  34. package/dist/rail/index.js +1 -1
  35. package/dist/screen/components/AddBlockRow.js +1 -1
  36. package/dist/screen/components/AddSidePanel.js +1 -1
  37. package/dist/screen/components/MediaSidePanel.js +1 -1
  38. package/dist/screen/components/NodeContextMenu.js +1 -1
  39. package/dist/screen/components/PageEditGuardNotices.js +1 -1
  40. package/dist/screen/components/ScreenChrome.js +1 -1
  41. package/dist/screen/components/ScreenMount.js +1 -1
  42. package/dist/screen/components/ScreenStoreProvider.js +1 -1
  43. package/dist/screen/components/SectionScreenShell.js +16 -16
  44. package/dist/screen/components/SidePanelHead.js +1 -1
  45. package/dist/screen/components/UiIcon.js +2 -2
  46. package/dist/screen/components/panel-widths.js +1 -1
  47. package/dist/screen/components/usePartBridge.js +1 -1
  48. package/dist/screen/index.js +1 -1
  49. package/dist/screen/lib/puck/style-clipboard.js +1 -1
  50. package/dist/screen/lib/puck/use-section-ops.js +1 -1
  51. package/dist/screen/lib/screen-parts.js +1 -1
  52. package/dist/shell/index.d.ts +4 -4
  53. package/dist/shell/index.js +1 -1
  54. package/dist/shell/shell.css +11 -3
  55. package/dist/style-clipboard/index.js +1 -1
  56. package/dist/text-styles/index.js +23 -23
  57. package/package.json +5 -4
  58. package/dist/chunk-2LK54I4E.js +0 -1
  59. package/dist/chunk-57DJOKXT.js +0 -1
  60. package/dist/chunk-63GQKLJI.js +0 -5
  61. package/dist/chunk-CG4OPQQX.js +0 -64
  62. package/dist/chunk-FODNRCCO.js +0 -5
  63. package/dist/chunk-HMJS344F.js +0 -1
  64. package/dist/chunk-JLTZQ4US.js +0 -1
  65. package/dist/chunk-K6ELD7N5.js +0 -23
  66. package/dist/chunk-L5KW4HG5.js +0 -470
  67. package/dist/chunk-TJ7YIRWQ.js +0 -21
  68. package/dist/chunk-U4MJQAVH.js +0 -1
  69. package/dist/chunk-W3XX2CNW.js +0 -16
  70. package/dist/chunk-X6DQWK2C.js +0 -1
@@ -1,507 +1,2 @@
1
- import * as react from 'react';
2
- import { SVGProps } from 'react';
3
-
4
- type IconProps = Omit<SVGProps<SVGSVGElement>, 'children'> & {
5
- size?: number;
6
- };
7
- /** Every icon name in the set, with what it means. One meaning, one SVG. */
8
- declare const iconMeanings: {
9
- readonly trash: "Delete";
10
- readonly duplicate: "Duplicate — owner pick 08-20, two-pages form";
11
- readonly "copy-to-page": "Copy to another page";
12
- readonly close: "Close / dismiss";
13
- readonly add: "Add / plus";
14
- readonly check: "Checkmark / success";
15
- readonly undo: "Undo";
16
- readonly redo: "Redo";
17
- readonly rename: "Rename / edit";
18
- readonly search: "Search";
19
- readonly eye: "Show";
20
- readonly "eye-off": "Hide";
21
- readonly external: "Leaves this surface";
22
- readonly drag: "Drag handle";
23
- readonly lock: "Locked";
24
- readonly revert: "Revert to inherited";
25
- readonly chevron: "Disclosure — rotate for direction";
26
- readonly send: "Send";
27
- readonly page: "Page AND the Pages rail — owner ruling 08-20, one meaning";
28
- readonly layers: "Layers";
29
- readonly styles: "Styles";
30
- readonly media: "Media";
31
- readonly sitemap: "Sitemap";
32
- readonly image: "Image / photo";
33
- readonly grid: "Grid";
34
- readonly cart: "Cart";
35
- readonly desktop: "Desktop";
36
- readonly tablet: "Tablet";
37
- readonly phone: "Phone";
38
- readonly warning: "Warning";
39
- readonly type: "Text marker — the T";
40
- readonly wheel: "Wheel";
41
- readonly chat: "Chat";
42
- readonly bell: "Notification bell";
43
- readonly template: "Template / bookmark";
44
- readonly clock: "clock";
45
- readonly play: "play";
46
- readonly "align-left": "WHICH WAY content is aligned — worn by the `Alignment` row of the campaign editor's Text, Button, Badge, Divider and Social blocks, and by the storefront part panel's `align` row (efficient-shop PartSettingsPanel FIELD_ICONS). The row's own segments draw each answer; this names the question.";
47
- readonly "align-center": "align center";
48
- readonly opacity: "opacity";
49
- readonly "padding-top": "padding top";
50
- readonly "padding-bottom": "padding bottom";
51
- readonly "padding-x": "the room a page leaves at its left and right edge — the `Side space` row on the storefront's Site styles ▸ Basics tab, beside `Content width`. NOT the air between two cards, which is `gap` on that same tab, and NOT `width`, which is how wide the content column itself may grow";
52
- readonly width: "width";
53
- readonly anchor: "anchor";
54
- readonly hash: "a NUMBER or its unit — worn by the `Measure length in` row (px / %) of the campaign editor's Divider, which picks what the length beside it is counted in.";
55
- readonly columns: "columns";
56
- readonly list: "a list of entries a merchant orders — worn by the `Phone order` row of the campaign editor's Section settings and by the `Links` row of its Social block. …AND THE `Bulleted list` toolbar button of the campaign editor's Text block, and the `Bulleted list` item of its No list / Bulleted list / Numbered list menu (final design, 2026-10-06): lines set as a list. `numbered-list` is its pair, with figures in place of the dots.";
57
- readonly "text-lines": "text lines";
58
- readonly "text-size": "text size";
59
- readonly "text-small": "SMALL TYPE — an eyebrow, a caption, a label run. Worn by the `Eyebrow` row of the campaign editor's Text block and by the `Tagline` row of its Logo. The set's `text-size` is the SIZE control; this is the small-type kind itself.";
60
- readonly button: "a call-to-action on the page — the settings row for a button's own look. ⚠️ NAMED BY CARD 66310, 2026-09-01; it used to read \"button\", which is a SHAPE, and a shape claims nothing, so nothing stopped a second meaning attaching to this drawing. Measured the same day: `ButtonIcon` has no call site in efficient-shop, in efficient-admin, or in this repo — it is drawn and not yet wired to a row";
61
- readonly link: "link";
62
- readonly tag: "tag";
63
- readonly rotate: "rotate";
64
- readonly square: "square";
65
- readonly corner: "the `Which corners` row in a section's Style > Shape group, on the storefront editor";
66
- readonly drop: "a COLOUR, where the row is named for the colour itself rather than for the element it paints — worn by the `Divider` colour row of the campaign editor's Email styles and by its Divider block's `Color`. The set names a colour by its ELEMENT wherever it can (`text-color`, `ground`, `link`); this is the answer where there is no element to name.";
67
- readonly "plus-minus": "plus minus";
68
- readonly dollar: "dollar";
69
- readonly note: "a short note ABOUT a thing rather than the thing — worn by the `Alt text` row of the campaign editor's Image block, the words a reader gets when the picture does not load.";
70
- readonly weight: "HOW HEAVY A STROKE IS — a font's weight, and a rule's thickness. It was written as “font weight” alone until the storefront's `Thickness` row (a footer divider, 1-8px) needed it: both settings make a mark heavier, and that is what the drawing shows. ⚠️ NOT `line-style`, which is WHICH DASH a rule is drawn with — solid, dashed, dotted — a different question about the same rule. Extended on card [FIX] The 176 Settings Rows With No Picture, 2026-09-23";
71
- readonly "letter-spacing": "letter spacing";
72
- readonly case: "letter case";
73
- readonly layout: "page layout — the Layout settings bucket, not columns. …AND THE ROWS THAT ASK IT DIRECTLY: the `Layout`, `Arrangement` and `Card layout` rows of the storefront editor, which pick which arrangement a section draws. The bucket and the row are one idea at two scales — the bucket holds the questions about how a section is laid out, and these rows are that question asked directly. ⚠️ STILL NOT `columns`, which is a COUNT of them, and still not `grid`, which is equal cells: the distinction the sentence above draws is unchanged. Card [FIX] The 176 Settings Rows With No Picture, 2026-09-23";
74
- readonly settings: "site settings — a gear; heads the Basics tab of the Site styles panel";
75
- readonly contrast: "the Theme tab of the Site styles panel — where a site's one palette is set. ⚠️ THIS MEANING WAS REWRITTEN BY CARD 66310, 2026-09-01: it used to say the tab held light/dark pairs, and cards 66238/66239 deleted that — a theme is ONE FLAT palette now. The drawing did not move and does not need to; the filled half disc reads as TONE, which is what a palette sets. The fill is justified in `from` below and stays";
76
- readonly account: "a person — the account / sign-in row and the header's account icon";
77
- readonly globe: "a globe — the country / region selector row";
78
- readonly logo: "a brand mark — the Header panel's Logo tab";
79
- readonly "align-right": "align right";
80
- readonly "align-separate": "align separate — the rows pushed apart to both edges";
81
- readonly accent: "the ACCENT — the site's one emphasis, the phrase picked out inside a heading. Worn by `Accent` on the Text tab and by `Brand colour` on the Theme tab. ONE drawing for both, for two reasons that hold each other up. (1) `accent` is a NAMED ROLE on this site, not a coincidence of spelling: it is declared as a font role (`FONT_ROLES`) and as a colour role (`WORD_STYLE_COLOURS`). The Text tab's `Accent` sets that role's TYPEFACE; the Theme tab's `Brand colour` sets the colour it is painted in. One role, two halves — which is why one drawing serves both. (2) the Site styles Theme tab names every colour row by the ELEMENT it colours and never by a glyph meaning \"colour\" — `Text colour` wears `type`, `Label colour` wears `text-small`, `Page background` wears `page` (ThemeField ROW_ICON, card 66205). The glyph names the element; the row says what it sets. Card 66310, 2026-09-01. ⚠️ THIS CORRECTS TWO EARLIER GOES AT THIS SENTENCE, and the RULING survived both — one drawing still serves both rows and the drawing has not moved. 66310's own first entry said the two rows keep the key `accent` in one place, which is not so. es#36 replaced that with a NUMBER, and a number is the wrong shape here: counting what `accent` IS gives the role declarations above, while counting where an accent VALUE lives gives the typeface, the preset colour and — since card 66307 — the site brand colour. Both counts are true, of different things, so a figure that needs its counting rule carried beside it will be misread in a one-line entry. The structure is what does not move. Corrected on card 66315, 2026-09-01. Not \"a star\" — a star borrowed for any other row would be a second meaning on one SVG, which is the rule this set is written under";
82
- readonly shadow: "the depth a card sits at — the `Card shadow` row on the storefront's Site styles ▸ Basics tab, beside `Corners`";
83
- readonly gap: "the air between two cards — the `Card gap` row on the storefront's Site styles ▸ Basics tab, beside `Corners`. …and the Box's block-spacing row, which is the same air one tier down: the room between the BLOCKS a merchant stacks inside a box rather than between two cards in a grid. One idea — the space between siblings — at two scales, which is why one drawing serves both rather than the shop drawing a second. Card [FIX] The 176 Settings Rows With No Picture, 2026-09-23 …AND THE TICKER'S `Join` ROW, which makes THREE SCALES for one idea: between two cards, between the blocks inside a box, and between a section and the one above or below it. ⚠️ AND `Join` SETS THE SAME THING BY CLOSING IT. `Nothing` / `Section above` / `Section below` picks which seam disappears, which reads at first glance like a different question — it is not. The space between siblings is what is being set either way, and zero is one of its answers. Written down because somebody will otherwise read `Join` as adjacency or as a border and reach for another drawing. Card [FIX] The 176 Settings Rows With No Picture, 2026-09-23";
84
- readonly hover: "the pointer resting on a card — the `Hover effect` row on the storefront's Site styles ▸ Basics tab, beside `Corners`";
85
- readonly "product-field": "the words come from the catalogue record — the `From product` segment of the Card text control";
86
- readonly "own-text": "the words are the merchant's own, not the product's — the `My own text` segment of the Card text control";
87
- readonly theme: "one whole palette a section can be painted in — paper, ink, borders and accent together, not one colour. Worn by the `Theme` row of the section panel's `Colour` group (card 66313), the dropdown that says which of the site's themes this one section is on. NOT `contrast`, which names the Site styles Theme TAB — that is a PLACE, not the idea “a palette”. NOT `accent`, which is the site's ONE emphasis colour, one colour rather than a whole set. Card 66315, 2026-09-01";
88
- readonly background: "the BAND A SECTION LAYS DOWN — the section's own background, the thing other boxes sit on top of. Worn by `Section background` and `Backdrop` in the admin portal's email editor (src/components/email/puckConfig.tsx:784 and :2398), both of which inherit from the theme and reset with 'Back to the theme color', and by the four section-band `Background` rows in efficient-shop's `backgroundField`. ⚠️ ITS ORIGINAL REASON IS DEAD AND IS KEPT HERE ONLY SO NOBODY REVIVES IT. This entry used to read \"the `Background` row of the section panel's `Colour` group (card 66313), whose choices are Page / Dark / Accent\". That picker is gone: card 66510 removed the choice, `ss.section-theme-picker` stopped the renderer reading the stored value, and the last 62 stored keys were cleared on 2026-09-03. A glyph outliving its stated reason is the `contrast` case — right on screen, dead why — and here it cost a real decision: PR #1456 ruled against this glyph because of that sentence and put `ground` on the four shop rows instead. ⚠️ NOT `ground`, which is the fill of the BOX the content sits in and covers this band — the two sit one line apart in the email editor's section panel, and that pair is the definition. The test is not what colour is set but WHAT SURFACE: a section's own band is `background`; a box drawn on top of it, at any level, is `ground`. Card 66315, 2026-09-01; reason replaced with a live one 2026-09-23";
89
- readonly copy: "put this block on the clipboard so it can be pasted somewhere else — the `Copy` row (⌘C) of the block right-click menu the owner approved 2026-08-31. NOT `copy-to-page`, whose meaning is already \"Copy to another page\" and which names a DESTINATION rather than the clipboard. NOT `duplicate`, which sits two rows below this one in the same menu and makes a second block in place at once without ever touching the clipboard. Card 66400.a, 2026-09-02";
90
- readonly paste: "drop whatever is on the clipboard into here — the `Paste` row (⌘V) of the block right-click menu the owner approved 2026-08-31. The other half of `copy`, and the only entry in the set that means the clipboard's CONTENTS coming back out. NOT `add`, which opens a chooser for a new block rather than placing one already taken. Card 66400.a, 2026-09-02";
91
- readonly "move-up": "send this block one step earlier in its parent's order — the `Move up` row of the block right-click menu the owner approved 2026-08-31. It REORDERS: it does not scroll a view, sort a list or raise a number. NOT `chevron`, which is disclosure — a section opening, not a block moving — and is the first arrow-shaped thing a borrower meets in this set. Card 66400.a, 2026-09-02";
92
- readonly "move-down": "send this block one step later in its parent's order — the `Move down` row of the block right-click menu the owner approved 2026-08-31. The mirror of `move-up` and it reorders the same way: it does not scroll a view, sort a list or lower a number. NOT `chevron`, which is disclosure rather than movement. Card 66400.a, 2026-09-02";
93
- readonly ground: "the fill of the BOX THE CONTENT SITS IN — the ground under the content, at whatever level the box is. Worn at every level today, and they are one idea, not several: the `Background` row under `Surfaces` in a theme's colour sheet (the row card 66510 renamed from `Page background` when a theme stopped colouring a page and started colouring a SECTION); in the admin portal's email editor, `Card color` (puckConfig.tsx:684), `Content background` (:790, hinted \"Covers the section color, but not its image.\"), `Email body` (:2404), a button's `Fill color` and `Zebra rows`, and `Column background` (ColumnLookControls.tsx:193, a SwatchRow); and in the shop, `Image background`, the fill of the well behind a product card's picture — a box inside a card inside a section. `Card color` is the closest precedent for that last one: a CARD's own fill already wears this glyph in shipped code. Level is not meaning: a new glyph per level would name WHERE the box is rather than WHAT the row sets, which is the `drop` / `styles` fault in this file's own rule. ⚠️ NOT `background`, AND THE REASON PRINTED HERE UNTIL 2026-09-23 WAS A GHOST. It said `background` meant the section panel's Page / Dark / Accent picker — but card 66510 removed that choice, `ss.section-theme-picker` stopped the renderer reading it, and [FIX] Section Theme Colours cleared the last 62 stored keys on 2026-09-03. Nothing had worn that meaning for three weeks. Ruling against a control that no longer exists is how the same wrong decision gets made twice, and it was: PR #1456 read that sentence and put THIS glyph on the four section-band `Background` rows. The live distinction is in efficient-admin-portal's email editor, one line apart under a comment citing this file (src/components/email/puckConfig.tsx:781): `Section background` wears `background`, `Content background` wears `ground`, and the hint says why — \"Covers the section color, but not its image.\" `background` is the band a section lays down; `ground` is the fill of the box that covers it. NOT `page`, which carries an owner ruling (2026-08-20) pinning it to the page and the Pages rail — the meaning this row stopped having, which is the whole reason this glyph exists. NOT `layout` and NOT `square`, its two siblings in the same `Surfaces` group — `Panels & cards` and `Borders`. ⚠️ AND IT IS NOT CALLED `surface`, which is the obvious name and the wrong one: `surface` is already the shop's stored colour KEY for `Panels & cards`, the row directly below this one, so a glyph of that name would sit on the one row in the group it does not name — the same fault as `page` on this row, committed again one line down. Card 66511, 2026-09-02; wearers and the ghost corrected 2026-09-23";
94
- readonly "text-color": "the COLOUR one run of text is painted in — worn by the `Color` row of the storefront part panel's `Appearance` fold, the row that lets a merchant override the theme's ink on a single heading or paragraph. NOT `type`, which is the Site styles Theme tab's `Text colour` row AND the part panel's own `Font` row — that panel forbids two rows sharing a drawing (`scripts/test-part-field-icons.tsx` §4), so the element glyph the Theme tab's grammar would ask for is already spent one row up. NOT `accent`, which is one drawing already serving `Accent` (the type) and `Brand colour` (the colour) and may not take a third meaning. NOT `text-small`, which is `Label colour` on that same Theme tab. This is the one place in the set where a glyph names a COLOUR rather than the element it colours, and it does so because the element — a run of text — already has two drawings pointing at it. The letter says what is painted; the solid bar under it says a colour is being chosen, which is the swatch every design tool puts there. Card [ADD] A Run Of Text Can Take Its Own Color, 2026-09-09";
95
- readonly direction: "which way this thing travels — the heading a merchant picks for a section's own motion. ⚠️ DRAWN FOR the `Scroll direction` row on the Scrolling Bar section AND NOT WORN BY IT. efficient-shop's `doc/naming.md` N10.1 gives the `Direction` idea a DASH in its Glyph column, and names `Direction` itself as one of the two reasons a row gets that dash: it is a MODIFIER, not a thing, and a modifier takes no leading glyph. So that row ships with no mark beside its label, and that is CORRECT rather than an omission — which is the whole reason this sentence is here, so the next reader does not file a bug against a row that is drawn the way it was decided. The marks a merchant actually presses are `direction-left`, `direction-right`, `direction-up` and `direction-down`, inside the control, and those four ARE worn. This glyph therefore has the same standing as `button`: drawn, correct, and not wired to a row. SS seat, 2026-09-11, recording that its own canvas drew a leading glyph in the field head and the naming table is what governs. ⚠️ AND IT NEVER HEADED THE HERO'S OVERLAY ROW, though it was briefed as if it did. The SS seat settled that row as a PLACEMENT on 2026-09-11: a lit cell there means where the DARK SITS, which is one of nine positions, which is what this shell's 3×3 grid already means at every one of its call sites — so that row draws the ordinary dots and wants nothing from this set. Both withdrawn claims are recorded rather than deleted, because a glyph that was once said to head a row is the first thing a later reader puts back. NOT `move-up` and NOT `move-down`, which REORDER a block inside its parent's list — card 66400.a's entries already say in writing that they do not scroll a view, which is exactly the thing this idea DOES say, so those are the first two glyphs a borrower will reach for and the two that must be refused hardest. NOT `chevron`, which is disclosure: its own meaning reads \"rotate for direction\", and that sentence is the one a borrower will read as permission — a chevron is turned to point AT the thing it opens, it never says which way anything travels. NOT `width`, which is a SPAN — how wide the content column may grow — and is double-headed for exactly that reason; a span names an extent, this names a heading. Owner, 2026-09-11";
96
- readonly "direction-right": "the direction a marquee travels — the bar runs rightwards, so its content walks towards the right edge. Worn by the RIGHT cell of the `Scroll direction` control on the Scrolling Bar section, which is the shell's 3×3 placement grid with four live cells, each drawing an arrow in place of the grid's dot. One of a family of four, and the family is one drawing turned: `direction-right` rotated a quarter turn at a time. ⚠️ NOT `move-up` and NOT `move-down`, and that refusal is the reason this entry is long. Those two are arrows, they are already in this set, and they mean the one thing these four must never be read as — REORDERING a block inside its parent's list, which their own entries say does not scroll a view. An arrow here that did not refuse them by name would be borrowed by one within a release. NOT `chevron`, which is disclosure and is turned to point AT the thing it opens. NOT `direction`, which is the row's LEADING glyph — the mark beside the label saying the row is about travel at all — where these four are the ANSWERS inside the control. Owner, 2026-09-11";
97
- readonly "direction-down": "the direction a marquee travels — the bar runs downwards, so its content walks towards the bottom edge. Worn by the BOTTOM cell of the `Scroll direction` control on the Scrolling Bar section, which is the shell's 3×3 placement grid with four live cells, each drawing an arrow in place of the grid's dot. One of a family of four, and the family is one drawing turned: `direction-right` rotated a quarter turn at a time. ⚠️ NOT `move-up` and NOT `move-down`, and that refusal is the reason this entry is long. Those two are arrows, they are already in this set, and they mean the one thing these four must never be read as — REORDERING a block inside its parent's list, which their own entries say does not scroll a view. An arrow here that did not refuse them by name would be borrowed by one within a release. NOT `chevron`, which is disclosure and is turned to point AT the thing it opens. NOT `direction`, which is the row's LEADING glyph — the mark beside the label saying the row is about travel at all — where these four are the ANSWERS inside the control. Owner, 2026-09-11";
98
- readonly "direction-left": "the direction a marquee travels — the bar runs leftwards, so its content walks towards the left edge. Worn by the LEFT cell of the `Scroll direction` control on the Scrolling Bar section, which is the shell's 3×3 placement grid with four live cells, each drawing an arrow in place of the grid's dot. One of a family of four, and the family is one drawing turned: `direction-right` rotated a quarter turn at a time. ⚠️ NOT `move-up` and NOT `move-down`, and that refusal is the reason this entry is long. Those two are arrows, they are already in this set, and they mean the one thing these four must never be read as — REORDERING a block inside its parent's list, which their own entries say does not scroll a view. An arrow here that did not refuse them by name would be borrowed by one within a release. NOT `chevron`, which is disclosure and is turned to point AT the thing it opens. NOT `direction`, which is the row's LEADING glyph — the mark beside the label saying the row is about travel at all — where these four are the ANSWERS inside the control. Owner, 2026-09-11";
99
- readonly "direction-up": "the direction a marquee travels — the bar runs upwards, so its content walks towards the top edge. Worn by the TOP cell of the `Scroll direction` control on the Scrolling Bar section, which is the shell's 3×3 placement grid with four live cells, each drawing an arrow in place of the grid's dot. One of a family of four, and the family is one drawing turned: `direction-right` rotated a quarter turn at a time. ⚠️ NOT `move-up` and NOT `move-down`, and that refusal is the reason this entry is long. Those two are arrows, they are already in this set, and they mean the one thing these four must never be read as — REORDERING a block inside its parent's list, which their own entries say does not scroll a view. An arrow here that did not refuse them by name would be borrowed by one within a release. NOT `chevron`, which is disclosure and is turned to point AT the thing it opens. NOT `direction`, which is the row's LEADING glyph — the mark beside the label saying the row is about travel at all — where these four are the ANSWERS inside the control. Owner, 2026-09-11";
100
- readonly animation: "how a thing MOVES — the `Animation` settings bucket, the fourth and last tab of every section panel (`Content · Style · Layout · Animation`). Owner, 2026-09-11, asked for it himself: a FOURTH tab, like Wix's, so that every element can have a motion. He had considered it for a while before saying so, which is why it arrived as a decision rather than a question. The drawing is an object at the head of the path it has travelled, so it names MOVEMENT ITSELF rather than any one motion — the tab holds `Entrance` today (None / Fade / Rise / Scale) and the later moments are rows under it. NOT `play`, whose entry says only \"play\": a triangle is video PLAYBACK, which is the picture idea this tab was folded away from — `Media` merged into `Style` in the same breath as this tab arriving, so a tab drawn with a playback mark would point at the one bucket that had just stopped existing. NOT `rotate`, whose entry says only \"rotate\": it is the nearest curved drawing in the set and it means turning a thing in place, which is one motion out of many and not the idea of motion. NOT `direction`, which says WHICH WAY a thing travels — two same-way arrows heading a `Scroll direction` row (2026-09-11). A heading is a property OF a movement; this names that there is one at all. NOT `hover`, the pointer resting on a card: that is one MOMENT which can start a motion, never the motion. ⚠️ `play` and `rotate` are the standing trap here and the reason this entry is long: both were drawn for the 2026-08-20 settings-panel design, both are worn by NOTHING today, and both name their own shape — so nothing in either entry refuses a borrower looking for a motion mark.";
101
- readonly "block-section": "the SECTION block - one full-width band of an email that holds one to four columns of blocks. Worn by a Section row in the Layers tree and the Section tile. Decided 2026-09-17. NOT `layout` (the Layout settings tab) and NOT `columns` (three bars, a count of columns).";
102
- readonly "block-column": "one COLUMN of a Section block - the slot its blocks stand in. Worn by the `Column 1` / `Column 2` rows of the Layers tree. Decided 2026-09-17. NOT `columns`, which is three bars and answers HOW MANY columns, not which one.";
103
- readonly "block-text": "the TEXT block - a run of words a person types into an email. Worn by a Text row in the Layers tree and the Text tile. Decided 2026-09-17. NOT `text-lines`, which is WORN already by the body-text field row and the Content tab (efficient-shop FieldGlyph.tsx) - a block row wearing it would be one drawing with two meanings.";
104
- readonly "block-heading": "the HEADING block - the legacy heading kind older campaigns still hold (GTS-8 has six). Worn by its Layers row. Decided 2026-09-17. NOT `type`, the T that marks text settings, and NOT `text-size`.";
105
- readonly "block-button": "the BUTTON block - one call to action in an email. Worn by a Button row in the Layers tree and the Button tile. Decided 2026-09-17. NOT `button`, whose entry is the settings ROW for a button's own look - the row and the block are two ideas.";
106
- readonly "block-badge": "the BADGE block - a small word pinned on a product, like NEW. Worn by a Badge row in the Layers tree and the Badge tile. Decided 2026-09-17. NOT `tag`, which the owner ruled is the `label` field row (2026-09-05), not a badge.";
107
- readonly "block-included-list": "the INCLUDED LIST block - model names on the left, prices on the right, row by row. Worn by its Layers row and the Included list tile. Decided 2026-09-17. NOT `list`, which is worn by the Header panel's menu item.";
108
- readonly "block-layered-images": "the LAYERED IMAGES block - one picture laid over another. Worn by its Layers row and the Layered images tile. Decided 2026-09-17. NOT `image` (one picture) and NOT `copy` (two pages, a clipboard action).";
109
- readonly "block-video": "the VIDEO block - a video shown in an email as a poster with a play mark. Worn by its Layers row and the Video tile. Decided 2026-09-17. NOT `play`: a bare triangle is playback, and this is the block that holds a video.";
110
- readonly "block-product": "the PRODUCT block - one catalogue product quoted in an email, its price and its buttons (the Add tile that said `Price` becomes `Product`, Lewis 2026-09-17). Drawn as a PACKAGE: the thing sold. Worn by its Layers row and tile. NOT `dollar`, worn by the price field row, NOT `tag`, the label row, and NOT `cart`, which is buying.. ⚠️ AND IT IS ALREADY WORN IN THE SHOP, which this entry did not say until now. `GalleryProductBinding`, `GalleryShowcaseSource`, `ProductPicker` and `SpecTableSource` each draw a `Product` row with this glyph, and the storefront config's own `Product` picker joins them. One catalogue product, whether it is quoted in an email or picked in a panel. Recorded on card [FIX] The 176 Settings Rows With No Picture, 2026-09-23, because pre-existing silent reuse is still silent reuse and is worse undocumented than documented";
111
- readonly "block-coupon": "the COUPON CODE block - a ticket with the code each person gets. Worn by its Layers row and the Coupon code tile. Decided 2026-09-17. The dashed line is the tear line where the code sits.";
112
- readonly "block-divider": "the DIVIDER block - a rule between things, in an email and on a website page. Worn by a Divider row in the Layers tree and the Divider tile, in both editors. Decided 2026-09-17. NOT `plus-minus` or any settings row: it is the block itself.";
113
- readonly "block-spacer": "the SPACER block - empty room between blocks, in an email and on a website page. Worn by a Spacer row in the Layers tree and the Spacer tile, in both editors. Decided 2026-09-17. NOT `gap` (the air between cards, a settings row) and NOT `padding-top`.";
114
- readonly "block-footer": "the FOOTER block - the bottom of an email or of a website page, pinned last. Worn by the Footer row in the Layers tree, in both editors. Decided 2026-09-17. NOT `page` and NOT `layout`: it is the block, not the page or its settings.";
115
- readonly "block-banner": "the BANNER block - words laid over an image. Worn by a Banner row in the Layers tree and the Banner tile, in both editors. Decided 2026-09-17. NOT `image` (a picture alone) and NOT `button`.";
116
- readonly "block-social": "the SOCIAL block - links to whichever social platforms the business has, never one platform's mark. Worn by a Social row in the Layers tree and the Social tile, in both editors. Decided 2026-09-17. NOT `link` (one link) and NOT `share` actions.";
117
- readonly "block-box": "the BOX block - a container that holds blocks (N8.1: `Box`). The campaign editor called it Group until Lewis renamed it Box, 2026-09-17. Worn by a Box row in the Layers tree and the Box tile, in both editors. NOT `direction`, whose arrows say which way a thing travels.";
118
- readonly radius: "how ROUND a box's corners are — the `Corner radius` row of the campaign editor's Section and Column settings, and the image `Corner radius` row of Email styles. Decided 2026-09-17. A box with ONE strongly rounded corner. NOT `corner`, which is the storefront's `Which corners` row, and NOT `square`, which is the Borders row one line above.";
119
- readonly "column-widths": "how the width is SHARED between a section's columns — the `Column widths` row of the campaign editor's Section settings (a ratio at two columns, shares at three). Decided 2026-09-17. NOT `columns`, which answers HOW MANY, and NOT `block-column`, a block kind that never wears a settings row.. …and the storefront's `Positions` row, where a block in a grid says how many CELLS it spans (`Auto`, `1 position`, `2 positions`, …). A share and a span are two answers to ONE question — how much of a multi-column row this thing takes — and the arrow across the bars draws the question rather than either answer. ⚠️ NOT `columns`, which is a COUNT of them; the two are told apart at 16px by that arrow. Card [FIX] The 176 Settings Rows With No Picture, 2026-09-23";
120
- readonly "line-between": "a rule drawn BETWEEN two columns of content — the `Line between columns` row of the campaign editor's Section settings. Decided 2026-09-17. An upright rule with words on both sides. NOT `block-divider`, the Divider block kind, which is a flat line across.. …and the storefront's `Separator` row, which draws the same rule between ITEMS in a run rather than between columns. The picture is the rule itself, so what it divides is the row's business and not the glyph's. ⚠️ NOT `block-divider`, the divider BLOCK kind, which never heads a settings row — the refusal above stands. Card [FIX] The 176 Settings Rows With No Picture, 2026-09-23";
121
- readonly "column-gap": "the air between columns SIDE BY SIDE — the `Gap between columns` row of the campaign editor's Section settings. Decided 2026-09-17. The GAP is the subject: two short upright bars with an arrowed space between them, drawn like `width`'s arrows. NOT `gap`, which is the air between STACKED things (the `Space between items` row wears that), and NOT `block-column`, whose two boxes the first draft read as at 16px (GG, 2026-09-17).";
122
- readonly "v-align": "where content sits UP AND DOWN inside its box — the `Content position` row (top / middle / bottom) of the campaign editor's Column settings. Decided 2026-09-17. A block between a top and a bottom rule. NOT `padding-top`, which has one rule and says how much room is above.";
123
- readonly height: "how TALL a thing is — the `Min height` row of the campaign editor's Column settings. Decided 2026-09-17. `width` stood upright, so the pair reads as one family. NOT `width`, which is side to side.";
124
- readonly underline: "whether links are UNDERLINED — the `Underline links` row of the campaign editor's Email styles. Decided 2026-09-17. A U over a rule, the mark every word processor uses. NOT `type`, which is the text marker, the T. …AND THE `Underline` toolbar button of the campaign editor's Text block (final design, 2026-10-06): the mark that underlines the selected words. One idea, words with a rule under them, so the button wears this drawing rather than a second copy of it.";
125
- readonly "line-style": "WHICH DASH a rule is drawn with — the `Line style` row (Solid / Dashed / Dotted) of the campaign editor's Divider, and of every Border row. Decided 2026-09-17. Three rules stacked: solid, dashed, dotted, so the row's own choices are the drawing. NOT `block-divider`, the Divider BLOCK kind, which is one plain line and never wears a settings row.";
126
- readonly "full-width": "how far a picture REACHES — the `Width` row (Default / Full width) of the campaign editor's Image block. Decided 2026-09-17. A band running edge to edge between two end walls. NOT `width`, a plain measure with two arrowheads, which says how wide rather than how far it reaches.";
127
- readonly "copy-style": "take a component's LOOK so it can be put on another one — the `Copy style` row (⌥⌘C) of the right-click menu in both editors, the campaign editor's block menu and the website editor's node menu. Decided 2026-09-19 (card [ADD] Copy Style And Paste Style; GG: one meaning per glyph, so it is not `copy`). The brush is the style; the back sheet is `copy`'s own, so the pair reads as \"copy, but the look\". NOT `copy`, which takes the whole block, and NOT `styles`, which opens the site's Styles panel.";
128
- readonly "paste-style": "put a held look onto this component — the `Paste style from …` row (⌥⌘V) of the right-click menu in both editors. Decided 2026-09-19 (card [ADD] Copy Style And Paste Style). The other half of `copy-style`: the same brush, beside `paste`'s clipboard. NOT `paste`, which drops a whole block, and NOT `copy-style`, which takes the look rather than putting it down.";
129
- readonly finish: "THE FINISHES A PRODUCT IS OFFERED IN — the swatch row a shopper picks a colour from. Worn by the `Finishes` row of the `Show on a card` group, on the storefront editor's Product Listing and Product Grid sections, which says whether a card draws that row at all (card [ADD] Choose What A Product Card Shows, 2026-09-21). Three swatches, because the idea is a CHOICE between finishes and a single swatch is just a colour. ⚠️ IT IS NOT `drop`, which is one colour where the row is named for the colour itself; not `accent`, which is the site's ONE emphasis rather than a set to pick from; not `contrast`, which is the tone of a whole palette; and not `theme`. Those four all answer \"what colour is this thing\"; this answers \"which of these does the shopper choose\".. …and the Spec Table's `Finish` row, where a MERCHANT picks which of a linked product's finishes the table should describe. Same subject — the finishes a product is offered in — seen from the other side of the editor. ⚠️ AND DELIBERATELY NOT THE `Opening filter`'s `Finish`, one line away in the same vocabulary, which carries NO glyph at all by the owner's facet ruling of 2026-08-29: a facet's options grow out of the merchant's catalogue, so an icon-per-facet queue never empties. Two rows, one drawn and one bare, written here where somebody is standing rather than left to be discovered. Card [FIX] The 176 Settings Rows With No Picture, 2026-09-23";
130
- readonly "product-size": "THE SIZES A PRODUCT IS SOLD IN — the row of size chips on a product card, each one an orderable variant. Worn by the `Sizes` row of the `Show on a card` group, on the storefront editor's Product Listing and Product Grid sections, which says whether a card draws those chips (card [ADD] Choose What A Product Card Shows, 2026-09-21). Two upright boxes on one baseline, one plainly bigger, because the idea is SEVERAL sizes of one product; one box would be a shape and would claim nothing. The pair is drawn SIDE BY SIDE and never overlapping: overlapping rounded boxes are already `copy`, and the difference a reader must see here is the SIZE, which an overlap turns into \"two of them\" instead. Three ascending boxes were drawn and rejected the same way — beside `columns` they read as a bar chart. ⚠️ IT CARRIES THE `product-` QUALIFIER FOR A REASON, and `product-field` is the precedent. Bare `size` is a word three rows of this set already want: `text-size` is how big type is set, `width` and `height` are how big a section is. None of them is a product's own catalogue of sizes, and a bare name is what lets the next borrower attach a second meaning to one drawing. It is also not `square`, which is one box and a shape.";
131
- readonly breadcrumb: "the trail back up to where a shopper came from — the `Breadcrumb` row of the storefront Gallery panel's `Show / hide elements` group. NOT `sitemap`, which is the whole structure of a site rather than one path through it, and NOT `chevron`, which is a disclosure. Card [FIX] Panel Rows That Draw No Picture, 2026-09-22";
132
- readonly tabs: "one strip of choices where only one panel shows at a time — the `Tab switcher` row of the storefront Gallery panel. TWO tabs with the selected one drawn TALLER is what makes it a switcher — a single raised tab over a panel is a folder, which is what the first drawing read as and why it was thrown away rather than a `layout` or a plain panel; nothing else in this set draws a selected-of-several. Card [FIX] Panel Rows That Draw No Picture, 2026-09-22";
133
- readonly sort: "the order a SHOPPER puts a list in — the `Sort control` row of the Gallery panel and the `Sort + Clear all` row of the storefront's Catalog filter bar. ⚠️ NOT `list`, which is a list of entries the MERCHANT orders by hand (the campaign editor's `Phone order` and `Links` rows). The difference is who does the ordering, so the arrow is the whole point of this drawing. Card [FIX] Panel Rows That Draw No Picture, 2026-09-22";
134
- readonly "spec-table": "the table of a product's measured facts on its own page — the `Spec table` row of the storefront Product hero's `Show in the buy box` group. A header band over two name/value columns. NOT `grid`, which is a layout of equal cells, and NOT `line-between`, which is one rule drawn between two columns of CONTENT. Card [FIX] Panel Rows That Draw No Picture, 2026-09-22";
135
- readonly car: "the shopper's own vehicle, which a product either fits or does not — the `Ask for the car first` row of the storefront Alloy wheels listing and the `Vehicle fitment` row of the Product hero. ⚠️ NOT `wheel`, which is the PRODUCT this shop sells; this is the thing the product has to fit, and a panel that drew both rows with `wheel` would say the two questions are the same question. Card [FIX] Panel Rows That Draw No Picture, 2026-09-22";
136
- readonly diagram: "a measured drawing of a product rather than a photograph of it — the `Dimension diagram` row of the storefront Spec table. The object ruled on two sides. ⚠️ A CIRCLE OVER A DIMENSION LINE WAS DRAWN FIRST AND THROWN AWAY: at 16px a circle above a wide horizontal line is a head and shoulders, and the glyph read as a person. NOT `image`, which is a photograph, and NOT `width` or `height`, which are single settings a merchant TYPES; this is a picture the shopper is shown. Card [FIX] Panel Rows That Draw No Picture, 2026-09-22";
137
- readonly headquarters: "the one office of several that is the main one — the `HQ` row of each office in the storefront Footprint section. The star is what separates it from a plain building: this glyph never means \"an office\", it means \"THE office\". NOT `globe`, which is the country / region selector. Card [FIX] Panel Rows That Draw No Picture, 2026-09-22";
138
- readonly "black-and-white": "colour taken out of a picture on purpose — the `Black and white` row of the three storefront photography sections and `Black and white logos` on the Logos strip. `doc/naming.md` N10.1 fixes those words and forbids `Grayscale` (owner ruling 2026-08-28), so the glyph is named for the idea the shop says out loud. ⚠️ A HALF-FILLED CIRCLE WAS DRAWN FIRST AND REJECTED: that is what `contrast` already is, and `contrast` heads the Theme tab. This is a PICTURE with one half ruled out, which is the thing the row does. Hatched rather than filled, because the house standard for this set is stroke on currentColor and no baked plate. Card [FIX] Panel Rows That Draw No Picture, 2026-09-22";
139
- readonly "button-arrow": "the arrow a button carries after its words — the `Arrow` row of the storefront Button block. ⚠️ IT IS NEITHER OF THE TWO GLYPHS IT SITS BETWEEN. `button` is the settings row for a button's own look, and this row is one detail inside that; `direction-right` is which way a thing SCROLLS. Here the button and its arrow are drawn together because the row is about the pair. Card [FIX] Panel Rows That Draw No Picture, 2026-09-22";
140
- readonly sticky: "a thing that stays put while the page scrolls under it — the `Stick under header` row of the storefront Category bar and the `Scroll-over` row of Intro bleed. The bar is pinned and the content moves away from it, which is why the arrow points DOWN and away rather than up. Card [FIX] Panel Rows That Draw No Picture, 2026-09-22";
141
- readonly category: "the group of products a merchant files a thing under — the `Category` row of the storefront's Product picker, Gallery showcase, Spec table and Product hero source panels. A FOLDER: the drawer several products live in. ⚠️ NOT `tag`, which is the shell's luggage tag and already draws a storefront `Label` row — a tag is one name pinned on one thing, a category is the drawer it is filed in, and a panel that drew both with one picture would say those are the same question. NOT `layers`, which is the Layers panel and means stacking order, and NOT `grid`, which is a layout of equal cells. ALSO WORN BY THE `Collection` ROW, ON PURPOSE — see the note in that row's own panel: a collection is a curated group of products and a category is the catalogue's own, but both are \"the group this is filed under\", and four separate drawings for a collection were made and thrown away because none could be told from `grid`, `layers` or this folder at 16px. Card [FIX] The 28 Hand-Rolled Settings Rows, 2026-09-22. …and the `Product type` row of a dynamic page template, which says which KIND of product (`alloy-wheel`, `tyre`) the template is written for. A category is a grouping the merchant invents and a product type is one the catalogue already has, but both answer “which drawer does this belong in”, which is what the folder draws. ⚠️ NOT `product-field`, whose sentence is “the words come from the catalogue record” — that names where a VALUE is read from, never which KIND a thing is. Card [FIX] The 176 Settings Rows With No Picture, 2026-09-23";
142
- readonly "blog-post": "one written article of a series — the `Blog posts` and `Blog post source` rows of the storefront's blog panels. An article laid out: a picture block, its headline beside it, the body beneath. ⚠️ NOT `page`, and that is the whole reason this drawing exists: `page` means a PAGE of the site and the Pages rail, one meaning by the owner's ruling of 2026-08-20, so a blog row wearing it would say a post is a page. NOT `note`, which is a short note ABOUT a thing rather than the thing, and NOT `text-lines`, which is body copy with no article around it. ⚠️ IT IS THE DENSEST DRAWING IN THE SET AND THAT IS DELIBERATE: the block-beside-lines arrangement is what separates it from `page` at 16px, and a simpler page-with-a-heading was drawn first and thrown away because it WAS `page` with an extra stroke. Card [FIX] The 28 Hand-Rolled Settings Rows, 2026-09-22";
143
- readonly menu: "a navigation menu the merchant builds — the `Menu` row of the storefront's Menu picker. The bar a shopper reads along, with the menu dropped open beneath it. ⚠️ NOT `list`, which is a list of entries a merchant orders by hand (the campaign editor's `Phone order` row): every menu is a list, but not every list is the thing a shopper navigates by, and the bar is what says which one this is. NOT `sitemap`, which is the whole structure of a site rather than one menu in it, and NOT `tabs`, which is one strip where only one panel shows at a time. Card [FIX] The 28 Hand-Rolled Settings Rows, 2026-09-22";
144
- readonly placement: "WHERE A THING SITS inside its box, in two dimensions — the `Placement`, `Content position` and `Text position` rows of the storefront editor, and the Hero's `Overlay position`. Each is a 3×3 pad, and the drawing is one square resting in a corner of a frame. ⚠️ NOT `v-align`, and this is the whole reason the drawing exists: that entry says it means \"where content sits UP AND DOWN inside its box\" — one dimension, top / middle / bottom. A 3×3 pad is two, and borrowing a one-dimensional picture for it would be a second meaning on one drawing. NOT `grid`, which is a layout of equal cells, and NOT `columns`. ⚠️ `layout` IS THE CLOSE ONE, and the distinction is that `layout`'s inner marks TOUCH the frame — a header band across it, a divider down it — while this square FLOATS in a corner, because floating is what says it could sit somewhere else. They can appear in one panel, since a `Placement` row lives inside the Layout bucket. If this square is ever redrawn touching an edge it becomes `layout` and should go. Card [FIX] The 28 Hand-Rolled Settings Rows, 2026-09-22";
145
- readonly location: "A POINT ON THE EARTH, given as numbers — the `Coordinates`, `Latitude` and `Longitude` rows of the storefront's location editor, where a merchant types or fetches a place's figures. A map pin. ⚠️ NOT `drop`, which is the nearest shape in the set and means A COLOUR: that droplet's point is at the TOP and it is solid, this pin's point is at the BOTTOM and it is pierced. Rendered side by side at 16px before this was kept, because a teardrop beside a teardrop was the obvious way to lose. NOT `globe`, which is the country / region selector — a globe is which MARKET, a pin is which SPOT. NOT `headquarters`, which is one office of several and is a building with a star. Card [FIX] The 28 Hand-Rolled Settings Rows, 2026-09-22";
146
- readonly trigger: "WHAT MAKES THIS HAPPEN — the event a merchant picks to start something, not the thing that is started. Drawn for the `Trigger` row of the storefront's Subscribe popup, whose three answers are `Delay`, `Scroll` and `Exit`: a wait, a scroll position and a pointer leaving the page. Nothing they share is a picture, which is exactly why none of the five shipped candidates could take the row. ⚠️ NOT `clock`, and this is the drawing this one exists to replace: a clock face says TIME, which is true of `Delay` and FALSE of the other two — it shipped on that row in efficient-shop #1468 and is corrected in the card that adds this. ⚠️ NOT `hover`, a pointer resting on a card: that names the MOUSE specifically, and neither a scroll position nor an exit is a hover. ⚠️ NOT `animation`, an object at the head of the path it has travelled: that names MOVEMENT, and a trigger is not a motion — it is the moment one starts. ⚠️ NOT `sticky`, a bar with content moving away beneath it, which names a thing that STAYS PUT while the page scrolls; `Scroll` here is when the reader reaches a point, never what the bar does. ⚠️ NOT `play`, a triangle, which is video playback. The bolt is the one shape in this set that means a thing FIRING rather than a thing being or moving, and it is the only zigzag in 138 drawings, so it cannot be misread for a neighbour at 16px. Card [FIX] The 176 Settings Rows With No Picture, 2026-09-23";
147
- readonly wrap: "WHETHER A ROW'S ITEMS FLOW ONTO A NEW LINE when they run out of room — the `Wrap` row of a Box's layout (`Wrap` / `No wrap`). The drawing is the RESULT rather than the motion: three items on the first line and one that has fallen to the second, because an uneven second row is the only thing that says wrapping happened. ⚠️ NOT `revert`, and this is the drawing this one was nearly drawn as. A line running right, turning down and coming back left with an arrowhead is the obvious picture for `wrap` and it is ALREADY `revert` — the two would have been the same drawing at 16px. Caught on the sheet before it was drawn, which is what the sheet is for. ⚠️ NOT `direction`, two same-way arrows, which names WHICH WAY a container's children run — and which is itself ruled to head no row (doc/naming.md N10.1 calls it a modifier). Wrapping is not a heading. ⚠️ NOT `columns`, three upright bars, which is a COUNT of columns, and NOT `grid`, which is equal cells: both draw an even arrangement, and unevenness is the whole of what this one says. ⚠️ NOT `line-between`, an upright rule with content either side, which divides two columns rather than describing how one row behaves. ⚠️ `grid` IS THE CLOSE ONE, AND THIS IS WHY IT IS ALLOWED TO LIVE. Both are a cluster of small squares, and at 16px what separates them is SILHOUETTE: this drawing is ASYMMETRIC — three across the top, one at the bottom LEFT, so it is wider on top and visibly short on the bottom right — against `grid`'s even 2×2. That difference survives the size; it was checked at 16px and again at 6× before it was kept, and it was handed up as a coin-flip rather than decided quietly. GG looked at both sheets and approved it, 2026-09-23. ⚠️ ITS KILL CONDITION, in the shape the bolt carries: if `grid` is ever redrawn asymmetric, or if a SECOND cluster-of-squares drawing is added to this set, THIS is the one to question first. Counting squares is a weaker way to be told apart than a shape nothing else has, and this drawing knows it. Card [FIX] The 176 Settings Rows With No Picture, 2026-09-23";
148
- readonly state: "WHICH OF SEVERAL STATES a thing is in, where no one of them is the good one — the `State` row of a Mockup's result rows (`Match / done`, `In progress`, `No match`). A ring with its centre filled: one position chosen out of several, which is the idea, rather than any particular verdict. ⚠️ NOT `check`, and refusing it is the whole reason this entry exists. `check` means “checkmark / success”, which is TRUE OF ONE ANSWER IN THREE and false of the other two — a row wearing it would say `done` while a merchant is looking at `No match`. That is the same defect `clock` had on the `Trigger` row, found the same way and written here so the next person does not reach for `check` again. ⚠️ NOT `warning`, a triangle, which is wrong for the success case for the mirror-image reason. ⚠️ NOT `hash`, which is a NUMBER or its unit. ⚠️ NOT `contrast`, a circle with one HALF filled: that is a tone, and its hard straight edge is what tells the two apart at 16px — this one's fill is a centred dot. NOT `eye`, whose pupil sits inside a lens rather than a circle, and NOT `drag`, which is six dots in two columns. Card [FIX] The 176 Settings Rows With No Picture, 2026-09-23";
149
- readonly "padding-left": "THE ROOM ON ONE SIDE — THE LEFT — of a box, worn by the storefront's `Padding left` row and by the folded `Left` row of a section's padding group. Drawn in `padding-top`'s grammar exactly: a rule at that edge, and the box held off it. ⚠️ IT EXISTS BECAUSE THE FAMILY WAS ASYMMETRIC, which is the whole finding. The set drew top and bottom as SINGLE sides and left/right only as a PAIR, so a row about one horizontal side had nothing true to wear and the obvious reach was `padding-x`. ⚠️ NOT `padding-x`, and bending that entry was refused on purpose: its sentence is “the room a PAGE leaves at its left and right edge — the `Side space` row”, which is a different thing at a different scale, and it refuses other uses by name. An entry that has been stretched twice stops meaning anything. GG, 2026-09-23. Card [FIX] The 176 Settings Rows With No Picture";
150
- readonly "padding-right": "THE ROOM ON ONE SIDE — THE RIGHT — of a box. The mirror of `padding-left`, and it lands with it so the four sides are finally one family: top, bottom, left, right, each a rule at its own edge with the box held off it. ⚠️ NOT `padding-x`, which is the PAGE's side space — see `padding-left` for why that entry was not stretched. Card [FIX] The 176 Settings Rows With No Picture, 2026-09-23";
151
- readonly "padding-y": "THE ROOM ABOVE AND BELOW a box, as ONE setting — the storefront's `Space above and below` row. ⚠️ IT RETIRES A WORKAROUND THAT WAS ALREADY SHIPPING, KNOWINGLY. `efficient-shop`'s `components/PartSettingsPanel.tsx` FIELD_ICONS carries this comment against its own padding row: “The set draws `padding-top` and `padding-bottom` and has no glyph for the PAIR, which is what this one row moves. `PaddingTopIcon` is the nearer of the two … Flagged to the seat rather than solved quietly.” That flag is what this drawing answers; that row should move to this glyph. ⚠️ NOT `v-align`, AND THE PROPORTIONS ARE THE WHOLE REASON IT CAN LIVE. `v-align` is ALREADY two full-width rules with a narrow box between them — the obvious drawing for this idea is already taken, and drawing it again would have been a duplicate. This one INVERTS that: SHORT ticks and a WIDE box. `v-align` says which of three positions the content sits in; this says how much room is left. ⚠️ ITS KILL CONDITION follows from that: if `v-align` is ever redrawn with a wide box, or a second short-tick-and-wide-box drawing is added, THIS is the one to question first — it survives on proportion rather than on a shape nothing else has. ⚠️ NOT `gap`, which is the space BETWEEN siblings at three scales; this is room INSIDE one box. NOT `layout`, a frame with a band across it. Card [FIX] The 176 Settings Rows With No Picture, 2026-09-23";
152
- readonly nudge: "A FINE ADJUSTMENT FROM WHERE A THING ALREADY SITS — the storefront hero group's `Sideways` and `Up and down` rows, each a ±px offset. ⚠️ ONE DRAWING FOR BOTH ROWS, deliberately. They are one idea on two axes, and the ROW'S OWN LABEL says which axis — `Sideways` and `Up and down` are as plain as the panel gets. The padding family splits by side because WHICH EDGE changes what the setting means; an axis does not change what a nudge is. ⚠️ NOT `placement`, and refusing it is the point: that entry is WHERE A THING SITS among NINE POSITIONS in a 3×3 pad, and a nudge is not one of nine — it is a small move from wherever the thing already is. ⚠️ NOT `width` or `height`, which are a line with arrowheads at both ends: those MEASURE an extent, this MOVES a thing. NOT `direction-up`/`-down`/`-left`/`-right`, single arrows that say which way a marquee TRAVELS. NOT `drag`, six dots, which is a handle a person grabs. Card [FIX] The 176 Settings Rows With No Picture, 2026-09-23";
153
- readonly "scroll-point": "HOW FAR DOWN a reader has got before something happens — the Subscribe popup's `Scroll` row, a percentage of the page. An arrow travelling down to the line it must reach. ⚠️ ITS SIBLING ROW IS WHY IT HAD TO EXIST. One row up, `Delay` wears `clock`, honestly: a delay IS a time. This row is a POSITION, and wearing a clock beside it would make two different questions look like one. Same defect `clock` had on the `Trigger` row (corrected in 0.56.0), one row along. ⚠️ NOT `sticky`, which is the close one at 16px: both are a bar and a down arrow, and what separates them is WHICH END THE MASS IS AT — `sticky` is a thick pinned bar at the TOP with content moving away beneath it, this is a thin line at the BOTTOM with an arrow arriving at it. ⚠️ ITS KILL CONDITION: if `sticky` is ever redrawn with its bar at the bottom, these two collide and this is the one to question first. ⚠️ NOT `direction-down`, a plain arrow with nothing to arrive at — the line is the whole idea. Card [FIX] The 176 Settings Rows With No Picture, 2026-09-23";
154
- readonly "words-from": "WHICH SIDE A ROW'S WORDS COME FROM, as the question rather than either answer — worn by a settings row that asks it, where the merchant picks between their own copy and copy the catalogue already holds. Drawn for the storefront Feature Rows block's `Rows from` row (`Product story` | `Detail shots`).";
155
- readonly title: "THE HEADING OF ONE ITEM, not of the band around it — worn by a settings row that holds the loudest line on a single card. An H drawn INSIDE the item's frame, and the containment is the whole distinction. Drawn for the campaign editor's Coupon card, where every layout carries exactly one `title` place. Decided 2026-09-25.";
156
- readonly meta: "THE SMALL LINE OF FACTS ALONG THE BOTTOM of an item — a date, a code, a deadline, run together on one line. Worn by a settings row that holds that line. One full rule with three SHORT runs under it: the gaps are the drawing, because the gaps are what make it read as several facts instead of a paragraph. Decided 2026-09-25.";
157
- readonly bold: "the BOLD mark — the toolbar button that writes `**words**` (Strong, ⌘B) over the selection in the copy box's formatting bar. A capital B, the letter every word processor puts on this button. One idea: the mark, not a weight setting. Decided 2026-10-02.";
158
- readonly italic: "the ITALIC mark — the toolbar button that writes `_words_` (⌘I) over the selection in the copy box's formatting bar. A slanted capital I with its two serifs, the button every word processor draws. Decided 2026-10-02.";
159
- readonly strike: "the STRIKETHROUGH mark — the toolbar button that writes `~~words~~` over the selection in the copy box's formatting bar (a was-price beside a now-price). An S with a rule through its middle. Decided 2026-10-02.";
160
- readonly emphasis: "the EMPHASIS mark — the toolbar button that writes `==words==` over the selection in the copy box's formatting bar: the phrase painted in the brand accent colour. A diamond, the ◆ the bar has shown for this mark since the campaign designer first drew it. Decided 2026-10-02.";
161
- readonly quiet: "the QUIET mark — the toolbar button that writes `^^words^^` over the selection in the copy box's formatting bar: smaller, softer words, like the fine print under a price. A small one-storey a. It is drawn SMALL on purpose, under the set's 14–17.5 box: smaller is what the mark does, and the design (v5) draws this button's a smaller than the B beside it. Decided 2026-10-02.";
162
- readonly "clear-marks": "CLEAR MARKS — the toolbar button that takes every mark off the selection in the copy box's formatting bar (⌘⇧X), keeping the words and any link. A T with a small × at its foot: the text, with its marks crossed out. Decided 2026-10-02.";
163
- readonly superscript: "the SUPERSCRIPT mark — raised small text (®, ™, a footnote¹). Worn by the `Superscript` toolbar button of the campaign editor's Text block and the `Superscript` item of its Normal / Superscript / Subscript menu. A capital A with a small 2 at its top right (Lewis, 2026-10-06: the design's x, then a T, then, after seeing the T: use A for all). Decided 2026-10-06.";
164
- readonly subscript: "the SUBSCRIPT mark — lowered small text (H₂O). Worn by the `Subscript` toolbar button of the campaign editor's Text block and the `Subscript` item of its Normal / Superscript / Subscript menu. The same capital A as `superscript`, with the small 2 at its foot (Lewis, 2026-10-06: after seeing the T: use A for all). Decided 2026-10-06.";
165
- readonly "numbered-list": "a NUMBERED LIST — the lines the caret is on, written as 1. 2. 3. Worn by the `Numbered list` toolbar button of the campaign editor's Text block and the `Numbered list` item of its No list / Bulleted list / Numbered list menu. Three rules with 1, 2, 3 down the left. Decided 2026-10-06.";
166
- readonly "paragraph-spacing": "PARAGRAPH SPACING — the room between one paragraph and the next, in px. Worn by the fourth value of the campaign editor's Text block number row (`Paragraph spacing`, beside Font size, Line spacing and Letter spacing). Two short paragraphs with a small upright mark in the room between them. Decided 2026-10-06.";
167
- readonly "case-normal": "letter case LEFT AS TYPED — `Aa`, the `Normal` option of the Letter case buttons (Normal / Uppercase / Lowercase) on the campaign editor's Text block, and of the storefront part panel's Case strip. The plan calls it sentence case; it changes nothing the merchant typed. A capital A beside a one-storey a. Decided 2026-10-06.";
168
- readonly "case-upper": "letter case ALL CAPITALS — `AA`, the `Uppercase` option of the Letter case buttons on the campaign editor's Text block, and of the storefront part panel's Case strip. Two capital A's. Decided 2026-10-06.";
169
- readonly "case-lower": "letter case ALL SMALL LETTERS — `aa`, the `Lowercase` option of the Letter case buttons on the campaign editor's Text block, and of the storefront part panel's Case strip. Two one-storey a's. Decided 2026-10-06.";
170
- readonly "align-justify": "JUSTIFY — text whose rows run edge to edge. Worn by the Justify button on the final text box's second toolbar row, beside Left, Center and Right, and by the Justify chip of the alignment strip. Three full-width rows on the same three heights the other alignment glyphs use. Decided 2026-10-06 (the design was made final that day).";
171
- readonly "panel-left": "the LEFT SIDE PANEL itself — worn by the Hide panel button at the end of a left panel's head (`MediaPanelHead`, both editors' SidePanelHeads) and by the Show panel button in the strip a hidden left panel leaves. One control, so one drawing: hiding and showing the panel wear the same glyph. A frame with its left column ruled off. ⛔ NOT an ✕: an ✕ closes a dialog, and a panel head has none (owner, 2026-10-04).";
172
- readonly "panel-right": "the RIGHT SIDE PANEL itself — the twin of `panel-left` for the settings panel: its head's Hide panel button and the strip a hidden right panel leaves. A frame with its right column ruled off.";
173
- readonly braces: "INSERT A MERGE TAG — a word that fills in for each reader ({{first_name}}, a coupon code). Worn by the Insert button the campaign designer puts in the 9th cell of the final text box's first toolbar row (`CopyBox` `lastTool`), which opens its list of tags. Two curly braces, the shape a merge tag is written in. Decided 2026-10-07. ⛔ NOT `code` or a pair of angle brackets: nothing here is code, and the braces are the tag's own spelling.";
174
- };
175
- type IconName = keyof typeof iconMeanings;
176
- /** Delete · keep · efficient-shop · components/UiIcon.tsx:99 */
177
- declare function TrashIcon({ size, ...rest }: IconProps): react.JSX.Element;
178
- /** Duplicate — owner pick 08-20, two-pages form · picked · efficient-admin-portal · src/components/SalesOrderDetail.tsx:628 */
179
- declare function DuplicateIcon({ size, ...rest }: IconProps): react.JSX.Element;
180
- /** Copy to another page · keep · efficient-shop · components/DuplicateToPageMenu.tsx:56 */
181
- declare function CopyToPageIcon({ size, ...rest }: IconProps): react.JSX.Element;
182
- /** Close / dismiss · pick · efficient-shop · components/AddSectionPanel.tsx:212 */
183
- declare function CloseIcon({ size, ...rest }: IconProps): react.JSX.Element;
184
- /** Add / plus · keep · editor-shell · src/rail/icons.tsx:92 */
185
- declare function AddIcon({ size, ...rest }: IconProps): react.JSX.Element;
186
- /** Checkmark / success · pick · efficient-shop · components/wheels-plp/PlpNotifyMeDialog.tsx:143 */
187
- declare function CheckIcon({ size, ...rest }: IconProps): react.JSX.Element;
188
- /** Undo · keep · efficient-admin-portal · src/components/email/CampaignDesigner.tsx:195 */
189
- declare function UndoIcon({ size, ...rest }: IconProps): react.JSX.Element;
190
- /** Redo · keep · efficient-admin-portal · src/components/email/CampaignDesigner.tsx:208 */
191
- declare function RedoIcon({ size, ...rest }: IconProps): react.JSX.Element;
192
- /** Rename / edit · keep · efficient-shop · components/UiIcon.tsx:90 */
193
- declare function RenameIcon({ size, ...rest }: IconProps): react.JSX.Element;
194
- /** Search · keep · efficient-shop · components/UiIcon.tsx:74 */
195
- declare function SearchIcon({ size, ...rest }: IconProps): react.JSX.Element;
196
- /** Show · keep · efficient-shop · components/UiIcon.tsx:63 */
197
- declare function EyeIcon({ size, ...rest }: IconProps): react.JSX.Element;
198
- /** Hide · keep · efficient-shop · components/UiIcon.tsx:69 */
199
- declare function EyeOffIcon({ size, ...rest }: IconProps): react.JSX.Element;
200
- /** Leaves this surface · keep · efficient-shop · components/UiIcon.tsx:82 */
201
- declare function ExternalIcon({ size, ...rest }: IconProps): react.JSX.Element;
202
- /** Drag handle · keep · efficient-admin-portal · src/components/email/designerIcons.tsx:78 */
203
- declare function DragIcon({ size, ...rest }: IconProps): react.JSX.Element;
204
- /** Locked · keep · efficient-admin-portal · src/components/email/designerIcons.tsx:8 */
205
- declare function LockIcon({ size, ...rest }: IconProps): react.JSX.Element;
206
- /** Revert to inherited · keep · efficient-admin-portal · src/components/email/designerIcons.tsx:31 */
207
- declare function RevertIcon({ size, ...rest }: IconProps): react.JSX.Element;
208
- /** Disclosure — rotate for direction · keep · efficient-shop · components/UiIcon.tsx:107 */
209
- declare function ChevronIcon({ size, ...rest }: IconProps): react.JSX.Element;
210
- /** Send · keep · efficient-shop · components/wheels-plp/PlpNotifyMeDialog.tsx:293 */
211
- declare function SendIcon({ size, ...rest }: IconProps): react.JSX.Element;
212
- /** Page AND the Pages rail — owner ruling 08-20, one meaning · picked · editor-shell · src/rail/icons.tsx:36 */
213
- declare function PageIcon({ size, ...rest }: IconProps): react.JSX.Element;
214
- /** Layers · keep · editor-shell · src/rail/icons.tsx:47 */
215
- declare function LayersIcon({ size, ...rest }: IconProps): react.JSX.Element;
216
- /** Styles · keep · editor-shell · src/rail/icons.tsx:57 */
217
- declare function StylesIcon({ size, ...rest }: IconProps): react.JSX.Element;
218
- /** Media · keep · editor-shell · src/rail/icons.tsx:69 */
219
- declare function MediaIcon({ size, ...rest }: IconProps): react.JSX.Element;
220
- /** Sitemap · keep · editor-shell · src/rail/icons.tsx:80 */
221
- declare function SitemapIcon({ size, ...rest }: IconProps): react.JSX.Element;
222
- /** Image / photo · pick · efficient-shop · components/AddSectionPanel.tsx:151 */
223
- declare function ImageIcon({ size, ...rest }: IconProps): react.JSX.Element;
224
- /** Grid · pick · efficient-shop · components/SearchDialog.tsx:504 */
225
- declare function GridIcon({ size, ...rest }: IconProps): react.JSX.Element;
226
- /** Cart · pick · efficient-shop · components/Header.tsx:69 */
227
- declare function CartIcon({ size, ...rest }: IconProps): react.JSX.Element;
228
- /** Desktop · keep · efficient-shop · components/DeviceSwitch.tsx:18 */
229
- declare function DesktopIcon({ size, ...rest }: IconProps): react.JSX.Element;
230
- /** Tablet · keep · efficient-shop · components/DeviceSwitch.tsx:24 */
231
- declare function TabletIcon({ size, ...rest }: IconProps): react.JSX.Element;
232
- /** Phone · pick · efficient-shop · components/DeviceSwitch.tsx:30 */
233
- declare function PhoneIcon({ size, ...rest }: IconProps): react.JSX.Element;
234
- /** Warning · pick · efficient-admin-portal · src/components/CustomerDetail.tsx:235 */
235
- declare function WarningIcon({ size, ...rest }: IconProps): react.JSX.Element;
236
- /** Text marker — the T · pick · efficient-shop · lib/puck/controls.tsx:269 */
237
- declare function TypeIcon({ size, ...rest }: IconProps): react.JSX.Element;
238
- /** Wheel · pick · efficient-shop · components/SearchDialog.tsx:485 */
239
- declare function WheelIcon({ size, ...rest }: IconProps): react.JSX.Element;
240
- /** Chat · pick · efficient-shop · components/ChatWidget.tsx:108 */
241
- declare function ChatIcon({ size, ...rest }: IconProps): react.JSX.Element;
242
- /** Notification bell · keep · efficient-shop · components/wheels-plp/PlpNotifyMeDialog.tsx:183 */
243
- declare function BellIcon({ size, ...rest }: IconProps): react.JSX.Element;
244
- /** Template / bookmark · keep · efficient-shop · components/TemplateGlyph.tsx:20 */
245
- declare function TemplateIcon({ size, ...rest }: IconProps): react.JSX.Element;
246
- /** clock · new · drawn for the settings-panel design, 2026-08-20 */
247
- declare function ClockIcon({ size, ...rest }: IconProps): react.JSX.Element;
248
- /** play · new · drawn for the settings-panel design, 2026-08-20 */
249
- declare function PlayIcon({ size, ...rest }: IconProps): react.JSX.Element;
250
- /** WHICH WAY content is aligned — worn by the `Alignment` row of the campaign editor's Text, Button, Badge, Divider and Social blocks, and by the storefront part panel's `align` row (efficient-shop PartSettingsPanel FIELD_ICONS). The row's own segments draw each answer; this names the question. · new · drawn for the settings-panel design, 2026-08-20 Meaning written 2026-09-17 (0.46.0): the entry named its own shape until then, which is what lets a second meaning attach to a drawing. */
251
- declare function AlignLeftIcon({ size, ...rest }: IconProps): react.JSX.Element;
252
- /** align center · new · drawn for the settings-panel design, 2026-08-20 */
253
- declare function AlignCenterIcon({ size, ...rest }: IconProps): react.JSX.Element;
254
- /** opacity · new · drawn for the settings-panel design, 2026-08-20 */
255
- declare function OpacityIcon({ size, ...rest }: IconProps): react.JSX.Element;
256
- /** padding top · new · drawn for the settings-panel design, 2026-08-20 */
257
- declare function PaddingTopIcon({ size, ...rest }: IconProps): react.JSX.Element;
258
- /** padding bottom · new · drawn for the settings-panel design, 2026-08-20 */
259
- declare function PaddingBottomIcon({ size, ...rest }: IconProps): react.JSX.Element;
260
- /** the room a page leaves at its left and right edge — the `Side space` row on the storefront's Site styles ▸ Basics tab, beside `Content width`. NOT the air between two cards, which is `gap` on that same tab, and NOT `width`, which is how wide the content column itself may grow · new · drawn for ss.side-space.a, 2026-09-03, for the storefront's `Side space` row (owner approved the mockup that day). The HORIZONTAL member of a family that had only a vertical pair: `padding-top` / `padding-bottom` (2026-08-20) are one edge line plus an offset block, so this is that same drawing turned on its side — two edge lines with the content standing between them. TWO lines and not one, because a single line reads as an alignment rather than as a pair of margins */
261
- declare function PaddingXIcon({ size, ...rest }: IconProps): react.JSX.Element;
262
- /** width · new · drawn for the settings-panel design, 2026-08-20 */
263
- declare function WidthIcon({ size, ...rest }: IconProps): react.JSX.Element;
264
- /** anchor · new · drawn for the settings-panel design, 2026-08-20 */
265
- declare function AnchorIcon({ size, ...rest }: IconProps): react.JSX.Element;
266
- /** a NUMBER or its unit — worn by the `Measure length in` row (px / %) of the campaign editor's Divider, which picks what the length beside it is counted in. · new · drawn for the settings-panel design, 2026-08-20 Meaning written 2026-09-17 (0.46.0): the entry named its own shape until then, which is what lets a second meaning attach to a drawing. */
267
- declare function HashIcon({ size, ...rest }: IconProps): react.JSX.Element;
268
- /** columns · new · drawn for the settings-panel design, 2026-08-20 */
269
- declare function ColumnsIcon({ size, ...rest }: IconProps): react.JSX.Element;
270
- /** a list of entries a merchant orders — worn by the `Phone order` row of the campaign editor's Section settings and by the `Links` row of its Social block. …AND THE `Bulleted list` toolbar button of the campaign editor's Text block, and the `Bulleted list` item of its No list / Bulleted list / Numbered list menu (final design, 2026-10-06): lines set as a list. `numbered-list` is its pair, with figures in place of the dots. · new · drawn for the settings-panel design, 2026-08-20 Meaning written 2026-09-17 (0.46.0): the entry named its own shape until then, which is what lets a second meaning attach to a drawing. */
271
- declare function ListIcon({ size, ...rest }: IconProps): react.JSX.Element;
272
- /** text lines · new · drawn for the settings-panel design, 2026-08-20 */
273
- declare function TextLinesIcon({ size, ...rest }: IconProps): react.JSX.Element;
274
- /** text size · new · drawn for the settings-panel design, 2026-08-20 */
275
- declare function TextSizeIcon({ size, ...rest }: IconProps): react.JSX.Element;
276
- /** SMALL TYPE — an eyebrow, a caption, a label run. Worn by the `Eyebrow` row of the campaign editor's Text block and by the `Tagline` row of its Logo. The set's `text-size` is the SIZE control; this is the small-type kind itself. · new · drawn for the settings-panel design, 2026-08-20 Meaning written 2026-09-17 (0.46.0): the entry named its own shape until then, which is what lets a second meaning attach to a drawing. */
277
- declare function TextSmallIcon({ size, ...rest }: IconProps): react.JSX.Element;
278
- /** a call-to-action on the page — the settings row for a button's own look. ⚠️ NAMED BY CARD 66310, 2026-09-01; it used to read "button", which is a SHAPE, and a shape claims nothing, so nothing stopped a second meaning attaching to this drawing. Measured the same day: `ButtonIcon` has no call site in efficient-shop, in efficient-admin, or in this repo — it is drawn and not yet wired to a row · new · drawn for the settings-panel design, 2026-08-20 */
279
- declare function ButtonIcon({ size, ...rest }: IconProps): react.JSX.Element;
280
- /** link · new · drawn for the settings-panel design, 2026-08-20 */
281
- declare function LinkIcon({ size, ...rest }: IconProps): react.JSX.Element;
282
- /** tag · new · drawn for the settings-panel design, 2026-08-20 */
283
- declare function TagIcon({ size, ...rest }: IconProps): react.JSX.Element;
284
- /** rotate · new · drawn for the settings-panel design, 2026-08-20 */
285
- declare function RotateIcon({ size, ...rest }: IconProps): react.JSX.Element;
286
- /** square · new · drawn for the settings-panel design, 2026-08-20 */
287
- declare function SquareIcon({ size, ...rest }: IconProps): react.JSX.Element;
288
- /** the `Which corners` row in a section's Style > Shape group, on the storefront editor · new · drawn for the `Which corners` row, 2026-09-04. NOT the square: reused on that row at 12-18px an outlined rounded rect reads as an unchecked checkbox, and Lewis pressed it expecting it to tick. This draws ONE corner - an L turning through a radius - which is the thing the row edits and a shape no checkbox has. Open at both ends on purpose: a closed shape is a box, and the box is what `square` means. */
289
- declare function CornerIcon({ size, ...rest }: IconProps): react.JSX.Element;
290
- /** a COLOUR, where the row is named for the colour itself rather than for the element it paints — worn by the `Divider` colour row of the campaign editor's Email styles and by its Divider block's `Color`. The set names a colour by its ELEMENT wherever it can (`text-color`, `ground`, `link`); this is the answer where there is no element to name. · new · drawn for the settings-panel design, 2026-08-20 Meaning written 2026-09-17 (0.46.0): the entry named its own shape until then, which is what lets a second meaning attach to a drawing. */
291
- declare function DropIcon({ size, ...rest }: IconProps): react.JSX.Element;
292
- /** plus minus · new · drawn for the settings-panel design, 2026-08-20 */
293
- declare function PlusMinusIcon({ size, ...rest }: IconProps): react.JSX.Element;
294
- /** dollar · new · drawn for the settings-panel design, 2026-08-20 */
295
- declare function DollarIcon({ size, ...rest }: IconProps): react.JSX.Element;
296
- /** a short note ABOUT a thing rather than the thing — worn by the `Alt text` row of the campaign editor's Image block, the words a reader gets when the picture does not load. · new · drawn for the settings-panel design, 2026-08-20 Meaning written 2026-09-17 (0.46.0): the entry named its own shape until then, which is what lets a second meaning attach to a drawing. */
297
- declare function NoteIcon({ size, ...rest }: IconProps): react.JSX.Element;
298
- /** HOW HEAVY A STROKE IS — a font's weight, and a rule's thickness. It was written as “font weight” alone until the storefront's `Thickness` row (a footer divider, 1-8px) needed it: both settings make a mark heavier, and that is what the drawing shows. ⚠️ NOT `line-style`, which is WHICH DASH a rule is drawn with — solid, dashed, dotted — a different question about the same rule. Extended on card [FIX] The 176 Settings Rows With No Picture, 2026-09-23 · new · approved by Lewis from mockups/8802d-three-missing-icons-mockup.html */
299
- declare function WeightIcon({ size, ...rest }: IconProps): react.JSX.Element;
300
- /** letter spacing · new · approved by Lewis from mockups/8802d-three-missing-icons-mockup.html */
301
- declare function LetterSpacingIcon({ size, ...rest }: IconProps): react.JSX.Element;
302
- /** letter case · new · approved by Lewis from mockups/8802d-three-missing-icons-mockup.html */
303
- declare function CaseIcon({ size, ...rest }: IconProps): react.JSX.Element;
304
- /** page layout — the Layout settings bucket, not columns. …AND THE ROWS THAT ASK IT DIRECTLY: the `Layout`, `Arrangement` and `Card layout` rows of the storefront editor, which pick which arrangement a section draws. The bucket and the row are one idea at two scales — the bucket holds the questions about how a section is laid out, and these rows are that question asked directly. ⚠️ STILL NOT `columns`, which is a COUNT of them, and still not `grid`, which is equal cells: the distinction the sentence above draws is unchanged. Card [FIX] The 176 Settings Rows With No Picture, 2026-09-23 · new · drawn by Lewis for card 8806, 2026-08-22 */
305
- declare function LayoutIcon({ size, ...rest }: IconProps): react.JSX.Element;
306
- /** site settings — a gear; heads the Basics tab of the Site styles panel · new · drawn by Lewis, his own pick for card 66166, 2026-08-28 — nothing else in the set is a gear, so no collision */
307
- declare function SettingsIcon({ size, ...rest }: IconProps): react.JSX.Element;
308
- /** the Theme tab of the Site styles panel — where a site's one palette is set. ⚠️ THIS MEANING WAS REWRITTEN BY CARD 66310, 2026-09-01: it used to say the tab held light/dark pairs, and cards 66238/66239 deleted that — a theme is ONE FLAT palette now. The drawing did not move and does not need to; the filled half disc reads as TONE, which is what a palette sets. The fill is justified in `from` below and stays · new · drawn by Lewis, his own pick for card 66166, 2026-08-28 — the half disc is FILLED on purpose and stays filled: an outline can only draw a circle with a line down it, which reads as a divided circle, not as one light half beside one dark half. The fill IS the meaning here, not decoration ⚠️ Card 66310, 2026-09-01: cards 66238/66239 removed light/dark from the storefront, so the sentence above is kept as the RECORD OF WHY THE FILL EXISTS, not as a live description of what the tab holds. Do not outline it on the strength of that. */
309
- declare function ContrastIcon({ size, ...rest }: IconProps): react.JSX.Element;
310
- /** a person — the account / sign-in row and the header's account icon · new · drawn by SS for card 66190, 2026-08-28, approved by Lewis for card 66191 — the set had no person glyph. The shoulder is an OPEN arc, not a closed half-disc: closed, it silts up into a black lump at 16px. Head radius 3.6 to shoulder radius 7.2 is exactly 1:2, the same handling as the cart wheels */
311
- declare function AccountIcon({ size, ...rest }: IconProps): react.JSX.Element;
312
- /** a globe — the country / region selector row · new · drawn by SS for card 66190, 2026-08-28, approved by Lewis for card 66191 — the set had no globe or flag glyph. Three strokes only: ring, equator, one upright meridian. Latitude lines silt up at 16px, the same reason `search` is only two strokes */
313
- declare function GlobeIcon({ size, ...rest }: IconProps): react.JSX.Element;
314
- /** a brand mark — the Header panel's Logo tab · new · supplied by Lewis for card 66191, 2026-08-28, after he rejected `image` (picture frame + mountain) for the Logo tab — `image` means a picture you upload, the Logo tab means the brand mark, and the set had no glyph that said brand. Two overlapping circles with a pen drawn across them. The small circle is an ARC WITH A GAP, not a closed circle, so the pen crosses a break instead of a line; keep the gap */
315
- declare function LogoIcon({ size, ...rest }: IconProps): react.JSX.Element;
316
- /** align right · new · drawn for card 66241, 2026-08-31, for the header Alignment control (card 66242) — the set shipped `align-left` and `align-center` on 2026-08-20 and stopped there. Checked by SHAPE across all 68 icons before drawing: nothing in the set is a right-flush row stack (`text-lines` is left-flush, `list` is three equal rows from x9, `columns` is rects). This is `align-left` mirrored about x=12, so the pair reads as one drawing seen both ways round */
317
- declare function AlignRightIcon({ size, ...rest }: IconProps): react.JSX.Element;
318
- /** align separate — the rows pushed apart to both edges · new · drawn for card 66241, 2026-08-31, for the header Alignment control (card 66242). NOT `justify`: justify runs its rows edge to edge, this opens a channel down the middle. An ARROW version was drawn and dropped the same day — it was the shipped `width` glyph turned 90 degrees, and two glyphs that differ only by rotation misread inside one control. The channel is x9 -> x15 on ALL THREE rows, 6 units = 4.0px at 16px: the first draft opened 4 units on rows 1 and 3 and 6 on row 2, which is three unequal gaps and 2.7px of nothing. Lewis approved this even channel looking at mockups/separate-icon-gap.html — keep the three gaps equal */
319
- declare function AlignSeparateIcon({ size, ...rest }: IconProps): react.JSX.Element;
320
- /** the ACCENT — the site's one emphasis, the phrase picked out inside a heading. Worn by `Accent` on the Text tab and by `Brand colour` on the Theme tab. ONE drawing for both, for two reasons that hold each other up. (1) `accent` is a NAMED ROLE on this site, not a coincidence of spelling: it is declared as a font role (`FONT_ROLES`) and as a colour role (`WORD_STYLE_COLOURS`). The Text tab's `Accent` sets that role's TYPEFACE; the Theme tab's `Brand colour` sets the colour it is painted in. One role, two halves — which is why one drawing serves both. (2) the Site styles Theme tab names every colour row by the ELEMENT it colours and never by a glyph meaning "colour" — `Text colour` wears `type`, `Label colour` wears `text-small`, `Page background` wears `page` (ThemeField ROW_ICON, card 66205). The glyph names the element; the row says what it sets. Card 66310, 2026-09-01. ⚠️ THIS CORRECTS TWO EARLIER GOES AT THIS SENTENCE, and the RULING survived both — one drawing still serves both rows and the drawing has not moved. 66310's own first entry said the two rows keep the key `accent` in one place, which is not so. es#36 replaced that with a NUMBER, and a number is the wrong shape here: counting what `accent` IS gives the role declarations above, while counting where an accent VALUE lives gives the typeface, the preset colour and — since card 66307 — the site brand colour. Both counts are true, of different things, so a figure that needs its counting rule carried beside it will be misread in a one-line entry. The structure is what does not move. Corrected on card 66315, 2026-09-01. Not "a star" — a star borrowed for any other row would be a second meaning on one SVG, which is the rule this set is written under · new · drawn for card 66310, 2026-09-01, after the shortlist of existing glyphs came up empty — `contrast` heads the Theme tab this row sits on, `drop` is the Photography row one tab across, `styles` is the rail item that OPENS this panel, and `layers` means the Layers panel. A four-point spark ON A LINE OF TYPE, and the LINE IS LOAD-BEARING: a bare spark reads as AI in most products today, and the line under it moves the reading to "this part of the text is picked out", which is what an accent is. Keep the line. Every point is an explicit M/L so the optical box can be measured without a browser */
321
- declare function AccentIcon({ size, ...rest }: IconProps): react.JSX.Element;
322
- /** the depth a card sits at — the `Card shadow` row on the storefront's Site styles ▸ Basics tab, beside `Corners` · new · drawn for card 66331, 2026-09-01, for the `Card shadow` row (card 66332). Checked by SHAPE across all 71 before drawing, and the check found a trap: the set's one offset pair is `opacity`, which is TWO CLOSED same-size rounded rects overlapping — the naive shadow drawing is that same picture. This is ONE closed card plus an OPEN L behind it, bottom and right arms only, so the two can never collapse into each other: one rect and one open path, never two rects. Leaving the back shape open is the set's own habit for the same reason `account`'s shoulder and `logo`'s small circle are open. The offset is 5 units, 2.9px at 14px, and it was checked at 14px on light AND dark before it was committed ⚠️ CORRECTED on card 66371: this entry said the row sits inside a `Card appearance` GROUP. The design Lewis approved has these three rows FLAT on Site styles ▸ Basics beside `Corners`, with no group at all. An icon entry is what the next person reads when deciding where a glyph belongs, so a stated home that contradicts the shipped design is a false claim living in a shared library — the same shape as the `accent` entry corrected on 2026-09-01, where the ruling was right and its written reason was false. The DRAWING is unchanged and still correct */
323
- declare function ShadowIcon({ size, ...rest }: IconProps): react.JSX.Element;
324
- /** the air between two cards — the `Card gap` row on the storefront's Site styles ▸ Basics tab, beside `Corners`. …and the Box's block-spacing row, which is the same air one tier down: the room between the BLOCKS a merchant stacks inside a box rather than between two cards in a grid. One idea — the space between siblings — at two scales, which is why one drawing serves both rather than the shop drawing a second. Card [FIX] The 176 Settings Rows With No Picture, 2026-09-23 …AND THE TICKER'S `Join` ROW, which makes THREE SCALES for one idea: between two cards, between the blocks inside a box, and between a section and the one above or below it. ⚠️ AND `Join` SETS THE SAME THING BY CLOSING IT. `Nothing` / `Section above` / `Section below` picks which seam disappears, which reads at first glance like a different question — it is not. The space between siblings is what is being set either way, and zero is one of its answers. Written down because somebody will otherwise read `Join` as adjacency or as a border and reach for another drawing. Card [FIX] The 176 Settings Rows With No Picture, 2026-09-23 · new · drawn for card 66331, 2026-09-01, for the `Card gap` row (card 66332). The FIRST draft was two upright bars side by side and 14px killed it: two upright bars beside the three of `columns` is the same drawing with one bar taken away, and the channel came to 1.75px. Turned on its side instead — two wide cards STACKED, with a 7-unit channel, 4.1px at 14px and wider than the 6-unit channel Lewis approved for `align-separate` on 2026-08-31. Nothing else in the set is two stacked rounded bars: `columns` and `grid` are upright, `align-separate` and `text-lines` are hairlines. Nothing is drawn inside the channel on purpose — the air is the subject, and a tick or an arrow in there silts it up at 14px ⚠️ CORRECTED on card 66371: this entry said the row sits inside a `Card appearance` GROUP. The design Lewis approved has these three rows FLAT on Site styles ▸ Basics beside `Corners`, with no group at all. An icon entry is what the next person reads when deciding where a glyph belongs, so a stated home that contradicts the shipped design is a false claim living in a shared library — the same shape as the `accent` entry corrected on 2026-09-01, where the ruling was right and its written reason was false. The DRAWING is unchanged and still correct */
325
- declare function GapIcon({ size, ...rest }: IconProps): react.JSX.Element;
326
- /** the pointer resting on a card — the `Hover effect` row on the storefront's Site styles ▸ Basics tab, beside `Corners` · new · drawn for card 66331, 2026-09-01, for the `Hover effect` row (card 66332). The brief offered two readings, a shape lifting or a pointer over a shape, and the pointer was picked because a lift IS a shadow: `shadow` sits three rows above this one on the same tab, with `Shadow colour` and `Card gap` between them, and two glyphs that misread inside one control is exactly what card 66241 rejected an arrow for. The set had no pointer and no cursor at all (measured 2026-09-01). The arrow is TAIL-LESS on purpose — the classic seven-point cursor was drawn first and silts into a blob at 14px; four points survive. The residual read is click-versus-hover, which no motion-free glyph can fully settle ⚠️ CORRECTED on card 66371: this entry said the row sits inside a `Card appearance` GROUP. The design Lewis approved has these three rows FLAT on Site styles ▸ Basics beside `Corners`, with no group at all. An icon entry is what the next person reads when deciding where a glyph belongs, so a stated home that contradicts the shipped design is a false claim living in a shared library — the same shape as the `accent` entry corrected on 2026-09-01, where the ruling was right and its written reason was false. The DRAWING is unchanged and still correct */
327
- declare function HoverIcon({ size, ...rest }: IconProps): react.JSX.Element;
328
- /** the words come from the catalogue record — the `From product` segment of the Card text control · new · drawn for card 66331, 2026-09-01, for the Card text segmented control (card 66333). A cylinder, the convention for stored data; nothing in the set said data before this — no `database`, no `data`, no `field`, measured 2026-09-01. The bottom is an OPEN arc, not a second full ellipse: closed, it reads as a drum or a can, and the open form is what makes it a database. This is the only glyph in the set whose body is an elliptical arc, which is why spec (ad) reads arcs properly instead of refusing them the way (n) and (y) do — refused, the box would come back 3.4 units short, because the arc bulges below its own endpoints */
329
- declare function ProductFieldIcon({ size, ...rest }: IconProps): react.JSX.Element;
330
- /** the words are the merchant's own, not the product's — the `My own text` segment of the Card text control · new · drawn for card 66331 and REDRAWN for card 66371, 2026-09-01, for the Card text segmented control (card 66333). Lewis approved Q1 — two curved quotation marks — after seeing four candidates rendered at 16px on light and dark grounds. The obvious drawings are all spoken for, and this is the record so nobody pays for them twice: a PENCIL is the shipped `rename`, and 66331's first draft came out byte-for-byte that drawing; an I-BEAM is `type` with one bar removed, and `type` heads the Text tab of this same panel; a PEN NIB reads as a MAP PIN at 16px, because the slit and the vent are what make a nib a nib and they are exactly what silts at that size — drawn three ways, the same read three times. The 0.27.0 SCRAWL over a baseline shipped and had to go: it reads as a chart line, and 66331 had already tried making the zigzag irregular, which reduced the misread without removing it. A quotation mark survives because nothing else in the 76 is one, and because beside `product-field` it makes the pair the row is actually about: a machine record versus words a person chose. Q3 — the same quotes with a baseline ruled under them — was drawn and is WORSE: the line drags the weight down and off centre, and it is not to come back. The two marks are ONE mark twice, the right at a fixed +8.5 in x. The box is 14 × 11, short and wide and outside the set's usual 14–17.5, on the `align-` family's precedent (16 × 11, deliberate, card 66241) — measured in `tests/fixtures/icons-66331-optical-size.html` because Q1 is cubic and spec (ad) refuses curve commands on purpose. THE NAME `own-text` DID NOT CHANGE — two consumer cards already reference it */
331
- declare function OwnTextIcon({ size, ...rest }: IconProps): react.JSX.Element;
332
- /** one whole palette a section can be painted in — paper, ink, borders and accent together, not one colour. Worn by the `Theme` row of the section panel's `Colour` group (card 66313), the dropdown that says which of the site's themes this one section is on. NOT `contrast`, which names the Site styles Theme TAB — that is a PLACE, not the idea “a palette”. NOT `accent`, which is the site's ONE emphasis colour, one colour rather than a whole set. Card 66315, 2026-09-01 · new · drawn for card 66315, 2026-09-01, and picked by the owner at 16px in a real settings row — the size `.es-field-icon svg` actually renders — from a shortlist of four. A rounded square with its RIGHT HALF FILLED: paper and ink in one square, which is what a palette is. The fill IS the drawing and an outline cannot replace it — two empty boxes is the shipped `opacity`, and a stroke cannot show a tone at all. The filled half uses the square's OWN corner radius, so it is half of that square and not a rectangle laid over one. Rejected at 16px on the same sheet: three circles in a row read as radio buttons, a meaning already spoken for; a triangle of circles went muddy; a painter's palette survived the size but is a skeuomorphic object among 76 geometric ones and was louder than everything beside it in the row */
333
- declare function ThemeIcon({ size, ...rest }: IconProps): react.JSX.Element;
334
- /** the BAND A SECTION LAYS DOWN — the section's own background, the thing other boxes sit on top of. Worn by `Section background` and `Backdrop` in the admin portal's email editor (src/components/email/puckConfig.tsx:784 and :2398), both of which inherit from the theme and reset with 'Back to the theme color', and by the four section-band `Background` rows in efficient-shop's `backgroundField`. ⚠️ ITS ORIGINAL REASON IS DEAD AND IS KEPT HERE ONLY SO NOBODY REVIVES IT. This entry used to read "the `Background` row of the section panel's `Colour` group (card 66313), whose choices are Page / Dark / Accent". That picker is gone: card 66510 removed the choice, `ss.section-theme-picker` stopped the renderer reading the stored value, and the last 62 stored keys were cleared on 2026-09-03. A glyph outliving its stated reason is the `contrast` case — right on screen, dead why — and here it cost a real decision: PR #1456 ruled against this glyph because of that sentence and put `ground` on the four shop rows instead. ⚠️ NOT `ground`, which is the fill of the BOX the content sits in and covers this band — the two sit one line apart in the email editor's section panel, and that pair is the definition. The test is not what colour is set but WHAT SURFACE: a section's own band is `background`; a box drawn on top of it, at any level, is `ground`. Card 66315, 2026-09-01; reason replaced with a live one 2026-09-23 · new · drawn for card 66315, 2026-09-01, beside `theme` and picked by the owner at 16px in a real settings row. A rounded rect with ONE FILLED horizontal band edge to edge across its middle. Filled and full-width on purpose: a band is a solid area of colour, and an outlined strip at 16px reads as one more rule between two others — which is `list` and `text-lines`, both already in the set. It is wider than it is tall so it cannot be read as a column, which is `columns`, and it crosses the card edge to edge so it is a band rather than a bar floating inside one */
335
- declare function BackgroundIcon({ size, ...rest }: IconProps): react.JSX.Element;
336
- /** put this block on the clipboard so it can be pasted somewhere else — the `Copy` row (⌘C) of the block right-click menu the owner approved 2026-08-31. NOT `copy-to-page`, whose meaning is already "Copy to another page" and which names a DESTINATION rather than the clipboard. NOT `duplicate`, which sits two rows below this one in the same menu and makes a second block in place at once without ever touching the clipboard. Card 66400.a, 2026-09-02 · new · drawn for card 66400.a, 2026-09-02, for the block right-click menu Lewis approved on 2026-08-31 (`mockups/editor-add-and-context-v1.html`). Checked by SHAPE across all 78 entries before drawing, and the check found the trap this card was warned about: `copy-to-page` is a page with an arrow leaving it, and `duplicate` is the heroicons two-DOCUMENT pair — so the copy drawing may be neither. It is two overlapping PLAIN rounded squares, no page notch and no inner rule, which is the one silhouette in the copy family the set does not already own: beside `duplicate` at 16px one reads as two tiles and the other as two sheets of paper. The back square is an OPEN L, top and left arms only, on the same habit `shadow` gives for itself — one closed rect plus one open path can never collapse into two rects, which is what `opacity` already is. The 3-unit air between each stub and the front square is what makes the two read as separate at 14px */
337
- declare function CopyIcon({ size, ...rest }: IconProps): react.JSX.Element;
338
- /** drop whatever is on the clipboard into here — the `Paste` row (⌘V) of the block right-click menu the owner approved 2026-08-31. The other half of `copy`, and the only entry in the set that means the clipboard's CONTENTS coming back out. NOT `add`, which opens a chooser for a new block rather than placing one already taken. Card 66400.a, 2026-09-02 · new · drawn for card 66400.a, 2026-09-02, beside `copy` for the block right-click menu Lewis approved on 2026-08-31. A clipboard: board, clip and two content rules. The clipboard is what makes the pair legible — `copy` and `paste` are one mechanism read in both directions, and drawing paste as the OBJECT both actions pass through is what stops it being read as a third kind of duplicate. The board's top is left OPEN where the clip crosses it rather than drawing two rects through each other. The two content rules are not decoration: a bare board plus a tab is `lock` upside down — same 14-wide body, same small shape riding the edge — and the rules are what separate them at 14px. They are 4 units apart and the lower one is short, so the pair reads as text on a board and not as `text-lines` or `list`, both already in the set */
339
- declare function PasteIcon({ size, ...rest }: IconProps): react.JSX.Element;
340
- /** send this block one step earlier in its parent's order — the `Move up` row of the block right-click menu the owner approved 2026-08-31. It REORDERS: it does not scroll a view, sort a list or raise a number. NOT `chevron`, which is disclosure — a section opening, not a block moving — and is the first arrow-shaped thing a borrower meets in this set. Card 66400.a, 2026-09-02 · new · drawn for card 66400.a, 2026-09-02, for the block right-click menu Lewis approved on 2026-08-31, whose own row reads ↑. Measured 2026-09-02: the set had no plain arrow at all — every arrowhead in it is attached to something else (`undo`, `redo`, `revert` are curved returns, `send` is a paper plane, `external` leaves a frame, `chevron` is a single disclosure stroke). So a straight vertical arrow is free, and it is what the approved menu already shows. Feather's proportions: a full-height shaft with a 90° head, 14 × 14 and centred on 12,12, which puts it in the middle of the set's box beside `square` at 14 and `type` at 16. Nothing is drawn around it — a bar above the head would read as "move to top", which is a different row the menu does not have */
341
- declare function MoveUpIcon({ size, ...rest }: IconProps): react.JSX.Element;
342
- /** send this block one step later in its parent's order — the `Move down` row of the block right-click menu the owner approved 2026-08-31. The mirror of `move-up` and it reorders the same way: it does not scroll a view, sort a list or lower a number. NOT `chevron`, which is disclosure rather than movement. Card 66400.a, 2026-09-02 · new · drawn for card 66400.a, 2026-09-02, beside `move-up` and mirrored about the canvas's horizontal centre line, on the precedent card 66241 set for `align-right` being `align-left` mirrored: two rows that are one idea read in two directions get one drawing turned round, not two drawings. Same 14 × 14 box, same 90° head, same centre. The two are a matched pair on purpose — they sit directly above and below each other in the menu, and a head that changed weight between them is the thing a reviewer notices and cannot name */
343
- declare function MoveDownIcon({ size, ...rest }: IconProps): react.JSX.Element;
344
- /** the fill of the BOX THE CONTENT SITS IN — the ground under the content, at whatever level the box is. Worn at every level today, and they are one idea, not several: the `Background` row under `Surfaces` in a theme's colour sheet (the row card 66510 renamed from `Page background` when a theme stopped colouring a page and started colouring a SECTION); in the admin portal's email editor, `Card color` (puckConfig.tsx:684), `Content background` (:790, hinted "Covers the section color, but not its image."), `Email body` (:2404), a button's `Fill color` and `Zebra rows`, and `Column background` (ColumnLookControls.tsx:193, a SwatchRow); and in the shop, `Image background`, the fill of the well behind a product card's picture — a box inside a card inside a section. `Card color` is the closest precedent for that last one: a CARD's own fill already wears this glyph in shipped code. Level is not meaning: a new glyph per level would name WHERE the box is rather than WHAT the row sets, which is the `drop` / `styles` fault in this file's own rule. ⚠️ NOT `background`, AND THE REASON PRINTED HERE UNTIL 2026-09-23 WAS A GHOST. It said `background` meant the section panel's Page / Dark / Accent picker — but card 66510 removed that choice, `ss.section-theme-picker` stopped the renderer reading it, and [FIX] Section Theme Colours cleared the last 62 stored keys on 2026-09-03. Nothing had worn that meaning for three weeks. Ruling against a control that no longer exists is how the same wrong decision gets made twice, and it was: PR #1456 read that sentence and put THIS glyph on the four section-band `Background` rows. The live distinction is in efficient-admin-portal's email editor, one line apart under a comment citing this file (src/components/email/puckConfig.tsx:781): `Section background` wears `background`, `Content background` wears `ground`, and the hint says why — "Covers the section color, but not its image." `background` is the band a section lays down; `ground` is the fill of the box that covers it. NOT `page`, which carries an owner ruling (2026-08-20) pinning it to the page and the Pages rail — the meaning this row stopped having, which is the whole reason this glyph exists. NOT `layout` and NOT `square`, its two siblings in the same `Surfaces` group — `Panels & cards` and `Borders`. ⚠️ AND IT IS NOT CALLED `surface`, which is the obvious name and the wrong one: `surface` is already the shop's stored colour KEY for `Panels & cards`, the row directly below this one, so a glyph of that name would sit on the one row in the group it does not name — the same fault as `page` on this row, committed again one line down. Card 66511, 2026-09-02; wearers and the ghost corrected 2026-09-23 · new · drawn for card 66511, 2026-09-02, for the row card 66510 left wearing `page`. Named `ground` and not `surface` after reading the row list it joins: `THEME_COLOUR_ROWS` keys `Panels & cards` as `surface`, one row below this one, and the group heading above them both is `Surfaces`. ONE path with `fill-rule="evenodd"`: a FILLED rounded square with two content bars cut clean THROUGH it. The fill is the meaning and an outline cannot replace it — this row sets a COLOUR, and the set already accepts that argument for `theme` and `background`, both of which sit in colour rows and are filled for the same reason. The knockout is what makes it the GROUND rather than one more object: the content is not drawn on top of the surface, it is the hole the surface shows through, which is the only way one drawing says "behind" without a second offset shape — and a second offset shape is the shipped `shadow`. Checked by SHAPE against all 82 before drawing: `square` (Borders) is a bare outline and this is a solid; `layout` (Panels & cards) is an outline cut by two rules; `background` is the exact INVERSE — an outlined card with one filled band lying across it — and the inversion is the meaning, because there the band is the section lying on the page and here the whole surface is the colour; `theme` is one square half filled; `opacity` is two outlined rects offset. Sized 15 × 15 on the 24 canvas, centred on 12,12, so it sits inside the set's 14–17.5 optical box between `square` at 14 and `type` at 16 — it is deliberately NOT full bleed, because a solid at the set's top width would out-weigh the two outlines it stands directly beside. The two slots are 2 units tall with 1.8 between them — NOT the set's 1.7 stroke weight, which is what they were drawn at first. At the 16px `.es-field-icon svg` actually renders, 1.7 units is 1.13px of slot and 1.55px of gap, and the drawing goes back to being a blob; at 2 / 1.8 it is 1.33px and 1.2px and the two bars stay open. This is spec (h)'s precedent exactly — the owner widened the `columns` gap for the same reason, and that test pins the GAP and not the bar positions, as this note does */
345
- declare function GroundIcon({ size, ...rest }: IconProps): react.JSX.Element;
346
- /** the COLOUR one run of text is painted in — worn by the `Color` row of the storefront part panel's `Appearance` fold, the row that lets a merchant override the theme's ink on a single heading or paragraph. NOT `type`, which is the Site styles Theme tab's `Text colour` row AND the part panel's own `Font` row — that panel forbids two rows sharing a drawing (`scripts/test-part-field-icons.tsx` §4), so the element glyph the Theme tab's grammar would ask for is already spent one row up. NOT `accent`, which is one drawing already serving `Accent` (the type) and `Brand colour` (the colour) and may not take a third meaning. NOT `text-small`, which is `Label colour` on that same Theme tab. This is the one place in the set where a glyph names a COLOUR rather than the element it colours, and it does so because the element — a run of text — already has two drawings pointing at it. The letter says what is painted; the solid bar under it says a colour is being chosen, which is the swatch every design tool puts there. Card [ADD] A Run Of Text Can Take Its Own Color, 2026-09-09 · new · drawn for the storefront part panel's `Color` row, 2026-09-09. An `A` because every letterform already in the set is a `T` — `type` (serif T), `text-size` and `text-small` (a T twice at two sizes), `case` (T beside a lowercase o), `weight` (T beside a heavier T) — so a fifth T would have been the fourth drawing of one shape, sitting at 16px directly under the `Font` row that wears the first of them. Nothing in the 85 is an A, checked by shape before drawing. THE BAR IS FILLED, NOT STROKED, and that is the decision worth keeping: `accent` is a star over a 1.7 stroke line at y=20, so a stroked rule under a letter would have been that composition with the mark swapped — two glyphs differing only in their mark is what this set is written against. A solid 2.6-unit bar reads as a swatch rather than a baseline, which is also the truth of it: the bar IS the colour. At the 16px `.es-field-icon svg` actually renders, 2.6 units is 1.73px of solid, above the 1.2px the `ground` entry measured as the floor for a bar that has to stay open. Optical box 16 x 15.1, inside the set's 14–17.5 */
347
- declare function TextColorIcon({ size, ...rest }: IconProps): react.JSX.Element;
348
- /** which way this thing travels — the heading a merchant picks for a section's own motion. ⚠️ DRAWN FOR the `Scroll direction` row on the Scrolling Bar section AND NOT WORN BY IT. efficient-shop's `doc/naming.md` N10.1 gives the `Direction` idea a DASH in its Glyph column, and names `Direction` itself as one of the two reasons a row gets that dash: it is a MODIFIER, not a thing, and a modifier takes no leading glyph. So that row ships with no mark beside its label, and that is CORRECT rather than an omission — which is the whole reason this sentence is here, so the next reader does not file a bug against a row that is drawn the way it was decided. The marks a merchant actually presses are `direction-left`, `direction-right`, `direction-up` and `direction-down`, inside the control, and those four ARE worn. This glyph therefore has the same standing as `button`: drawn, correct, and not wired to a row. SS seat, 2026-09-11, recording that its own canvas drew a leading glyph in the field head and the naming table is what governs. ⚠️ AND IT NEVER HEADED THE HERO'S OVERLAY ROW, though it was briefed as if it did. The SS seat settled that row as a PLACEMENT on 2026-09-11: a lit cell there means where the DARK SITS, which is one of nine positions, which is what this shell's 3×3 grid already means at every one of its call sites — so that row draws the ordinary dots and wants nothing from this set. Both withdrawn claims are recorded rather than deleted, because a glyph that was once said to head a row is the first thing a later reader puts back. NOT `move-up` and NOT `move-down`, which REORDER a block inside its parent's list — card 66400.a's entries already say in writing that they do not scroll a view, which is exactly the thing this idea DOES say, so those are the first two glyphs a borrower will reach for and the two that must be refused hardest. NOT `chevron`, which is disclosure: its own meaning reads "rotate for direction", and that sentence is the one a borrower will read as permission — a chevron is turned to point AT the thing it opens, it never says which way anything travels. NOT `width`, which is a SPAN — how wide the content column may grow — and is double-headed for exactly that reason; a span names an extent, this names a heading. Owner, 2026-09-11 · new · drawn for the `Scroll direction` and `Overlay direction` rows, 2026-09-11. Checked by MEANING against all 86 first: none of them means a direction of travel. Checked by SHAPE against the arrow family, which is the most crowded corner of the set — `move-up` and `move-down` (one vertical shaft, one head), `chevron` (a bare head, no shaft), `width` (one horizontal shaft, TWO heads facing out), `undo` / `redo` / `revert` / `rotate` (curved), `copy-to-page` and `external` (an arrow plus a box). Nothing in the set is two parallel same-way arrows. TWO ARROWS, NOT ONE, and both pointing the SAME way: one arrow alone on the centre line is `width` with a head removed, and two arrows facing OPPOSITE ways is the universal swap mark, which would name the AXIS when the row names the heading. THE TWO SHAFTS ARE UNEQUAL — 15 units and 8.5 — so the pair reads as one current rather than as two rows of a list; the set already holds six drawings that are nothing but stacked horizontal rules (`align-left`, `align-right`, `align-center`, `align-separate`, `text-lines`, `list`) and equal shafts would have been a seventh wearing arrowheads. CHANGED FROM THE PROPOSAL on the design canvas, which was two short rules with a head leaving one end and entering the other: that return is a curved arrow going back into a line, which is `undo`, `redo` AND `revert` — three shipped drawings — and the proposal was also FLAT, about 7 units tall like `width`, where the set's guard wants 14–17.5 in both axes. So it grew to fill the box. MEASUREMENTS at the 16px `.es-field-icon svg` actually renders: the two shafts sit 8 units apart, which is 5.33px, wider than the 5.5-unit row pitch `align-separate` ships at, so they never close; each head is 3.5 units from tip to shoulder, the same as the heads on `width`, so this glyph is no bolder than the arrow it stands nearest. Optical box 15 x 15, centred on 12,12, inside the set's 14–17.5 */
349
- declare function DirectionIcon({ size, ...rest }: IconProps): react.JSX.Element;
350
- /** the direction a marquee travels — the bar runs rightwards, so its content walks towards the right edge. Worn by the RIGHT cell of the `Scroll direction` control on the Scrolling Bar section, which is the shell's 3×3 placement grid with four live cells, each drawing an arrow in place of the grid's dot. One of a family of four, and the family is one drawing turned: `direction-right` rotated a quarter turn at a time. ⚠️ NOT `move-up` and NOT `move-down`, and that refusal is the reason this entry is long. Those two are arrows, they are already in this set, and they mean the one thing these four must never be read as — REORDERING a block inside its parent's list, which their own entries say does not scroll a view. An arrow here that did not refuse them by name would be borrowed by one within a release. NOT `chevron`, which is disclosure and is turned to point AT the thing it opens. NOT `direction`, which is the row's LEADING glyph — the mark beside the label saying the row is about travel at all — where these four are the ANSWERS inside the control. Owner, 2026-09-11 · new · drawn for the `Scroll direction` control, 2026-09-11. ONE DRAWING TURNED FOUR TIMES, not four arrows drawn by hand: `direction-right` is the original and each of the others is the previous one rotated a quarter turn clockwise about the canvas centre, 12,12, with the cycle closing back on the original. Four hand-drawn arrows drift — one head a half-unit wider, one shaft a unit longer — and a 3×3 grid then reads as four different controls rather than one question asked four ways; spec (bg) pins the rotation exactly, and pins the closure too, because a roughly rotated member passes three pairwise checks and fails the fourth. Written with explicit L commands and no H or V precisely so that comparison is possible at all. THE SHAFT IS 14 UNITS and the head 4.5 from tip to shoulder, sized against the cell rather than against the icon column: a placement cell is 26.67px across (`.es-placement` is a 96px box, 3×3, gap 4, padding 4) and the dot it replaces is 7px, so the arrow renders at 13px — big enough to read as a direction and not so big it crowds the 6px cell radius. It is deliberately NOT in the set's 14–17.5 square optical box, which is the rule for a glyph standing in a COLUMN of settings rows beside its siblings; this one stands in a nine-square beside eight identical cells, and being square there would mean a fat arrow. It does NOT scale on the chosen cell the way the dot does: the dot grows to 1.5 because a dot has no other way to say chosen, and an arrow that grew would crowd the cell and change its apparent weight against its three siblings */
351
- declare function DirectionRightIcon({ size, ...rest }: IconProps): react.JSX.Element;
352
- /** the direction a marquee travels — the bar runs downwards, so its content walks towards the bottom edge. Worn by the BOTTOM cell of the `Scroll direction` control on the Scrolling Bar section, which is the shell's 3×3 placement grid with four live cells, each drawing an arrow in place of the grid's dot. One of a family of four, and the family is one drawing turned: `direction-right` rotated a quarter turn at a time. ⚠️ NOT `move-up` and NOT `move-down`, and that refusal is the reason this entry is long. Those two are arrows, they are already in this set, and they mean the one thing these four must never be read as — REORDERING a block inside its parent's list, which their own entries say does not scroll a view. An arrow here that did not refuse them by name would be borrowed by one within a release. NOT `chevron`, which is disclosure and is turned to point AT the thing it opens. NOT `direction`, which is the row's LEADING glyph — the mark beside the label saying the row is about travel at all — where these four are the ANSWERS inside the control. Owner, 2026-09-11 · new · drawn for the `Scroll direction` control, 2026-09-11. ONE DRAWING TURNED FOUR TIMES, not four arrows drawn by hand: `direction-right` is the original and each of the others is the previous one rotated a quarter turn clockwise about the canvas centre, 12,12, with the cycle closing back on the original. Four hand-drawn arrows drift — one head a half-unit wider, one shaft a unit longer — and a 3×3 grid then reads as four different controls rather than one question asked four ways; spec (bg) pins the rotation exactly, and pins the closure too, because a roughly rotated member passes three pairwise checks and fails the fourth. Written with explicit L commands and no H or V precisely so that comparison is possible at all. THE SHAFT IS 14 UNITS and the head 4.5 from tip to shoulder, sized against the cell rather than against the icon column: a placement cell is 26.67px across (`.es-placement` is a 96px box, 3×3, gap 4, padding 4) and the dot it replaces is 7px, so the arrow renders at 13px — big enough to read as a direction and not so big it crowds the 6px cell radius. It is deliberately NOT in the set's 14–17.5 square optical box, which is the rule for a glyph standing in a COLUMN of settings rows beside its siblings; this one stands in a nine-square beside eight identical cells, and being square there would mean a fat arrow. It does NOT scale on the chosen cell the way the dot does: the dot grows to 1.5 because a dot has no other way to say chosen, and an arrow that grew would crowd the cell and change its apparent weight against its three siblings. This member is the original turned 1 quarter turn clockwise */
353
- declare function DirectionDownIcon({ size, ...rest }: IconProps): react.JSX.Element;
354
- /** the direction a marquee travels — the bar runs leftwards, so its content walks towards the left edge. Worn by the LEFT cell of the `Scroll direction` control on the Scrolling Bar section, which is the shell's 3×3 placement grid with four live cells, each drawing an arrow in place of the grid's dot. One of a family of four, and the family is one drawing turned: `direction-right` rotated a quarter turn at a time. ⚠️ NOT `move-up` and NOT `move-down`, and that refusal is the reason this entry is long. Those two are arrows, they are already in this set, and they mean the one thing these four must never be read as — REORDERING a block inside its parent's list, which their own entries say does not scroll a view. An arrow here that did not refuse them by name would be borrowed by one within a release. NOT `chevron`, which is disclosure and is turned to point AT the thing it opens. NOT `direction`, which is the row's LEADING glyph — the mark beside the label saying the row is about travel at all — where these four are the ANSWERS inside the control. Owner, 2026-09-11 · new · drawn for the `Scroll direction` control, 2026-09-11. ONE DRAWING TURNED FOUR TIMES, not four arrows drawn by hand: `direction-right` is the original and each of the others is the previous one rotated a quarter turn clockwise about the canvas centre, 12,12, with the cycle closing back on the original. Four hand-drawn arrows drift — one head a half-unit wider, one shaft a unit longer — and a 3×3 grid then reads as four different controls rather than one question asked four ways; spec (bg) pins the rotation exactly, and pins the closure too, because a roughly rotated member passes three pairwise checks and fails the fourth. Written with explicit L commands and no H or V precisely so that comparison is possible at all. THE SHAFT IS 14 UNITS and the head 4.5 from tip to shoulder, sized against the cell rather than against the icon column: a placement cell is 26.67px across (`.es-placement` is a 96px box, 3×3, gap 4, padding 4) and the dot it replaces is 7px, so the arrow renders at 13px — big enough to read as a direction and not so big it crowds the 6px cell radius. It is deliberately NOT in the set's 14–17.5 square optical box, which is the rule for a glyph standing in a COLUMN of settings rows beside its siblings; this one stands in a nine-square beside eight identical cells, and being square there would mean a fat arrow. It does NOT scale on the chosen cell the way the dot does: the dot grows to 1.5 because a dot has no other way to say chosen, and an arrow that grew would crowd the cell and change its apparent weight against its three siblings. This member is the original turned 2 quarter turns clockwise */
355
- declare function DirectionLeftIcon({ size, ...rest }: IconProps): react.JSX.Element;
356
- /** the direction a marquee travels — the bar runs upwards, so its content walks towards the top edge. Worn by the TOP cell of the `Scroll direction` control on the Scrolling Bar section, which is the shell's 3×3 placement grid with four live cells, each drawing an arrow in place of the grid's dot. One of a family of four, and the family is one drawing turned: `direction-right` rotated a quarter turn at a time. ⚠️ NOT `move-up` and NOT `move-down`, and that refusal is the reason this entry is long. Those two are arrows, they are already in this set, and they mean the one thing these four must never be read as — REORDERING a block inside its parent's list, which their own entries say does not scroll a view. An arrow here that did not refuse them by name would be borrowed by one within a release. NOT `chevron`, which is disclosure and is turned to point AT the thing it opens. NOT `direction`, which is the row's LEADING glyph — the mark beside the label saying the row is about travel at all — where these four are the ANSWERS inside the control. Owner, 2026-09-11 · new · drawn for the `Scroll direction` control, 2026-09-11. ONE DRAWING TURNED FOUR TIMES, not four arrows drawn by hand: `direction-right` is the original and each of the others is the previous one rotated a quarter turn clockwise about the canvas centre, 12,12, with the cycle closing back on the original. Four hand-drawn arrows drift — one head a half-unit wider, one shaft a unit longer — and a 3×3 grid then reads as four different controls rather than one question asked four ways; spec (bg) pins the rotation exactly, and pins the closure too, because a roughly rotated member passes three pairwise checks and fails the fourth. Written with explicit L commands and no H or V precisely so that comparison is possible at all. THE SHAFT IS 14 UNITS and the head 4.5 from tip to shoulder, sized against the cell rather than against the icon column: a placement cell is 26.67px across (`.es-placement` is a 96px box, 3×3, gap 4, padding 4) and the dot it replaces is 7px, so the arrow renders at 13px — big enough to read as a direction and not so big it crowds the 6px cell radius. It is deliberately NOT in the set's 14–17.5 square optical box, which is the rule for a glyph standing in a COLUMN of settings rows beside its siblings; this one stands in a nine-square beside eight identical cells, and being square there would mean a fat arrow. It does NOT scale on the chosen cell the way the dot does: the dot grows to 1.5 because a dot has no other way to say chosen, and an arrow that grew would crowd the cell and change its apparent weight against its three siblings. This member is the original turned 3 quarter turns clockwise */
357
- declare function DirectionUpIcon({ size, ...rest }: IconProps): react.JSX.Element;
358
- /** how a thing MOVES — the `Animation` settings bucket, the fourth and last tab of every section panel (`Content · Style · Layout · Animation`). Owner, 2026-09-11, asked for it himself: a FOURTH tab, like Wix's, so that every element can have a motion. He had considered it for a while before saying so, which is why it arrived as a decision rather than a question. The drawing is an object at the head of the path it has travelled, so it names MOVEMENT ITSELF rather than any one motion — the tab holds `Entrance` today (None / Fade / Rise / Scale) and the later moments are rows under it. NOT `play`, whose entry says only "play": a triangle is video PLAYBACK, which is the picture idea this tab was folded away from — `Media` merged into `Style` in the same breath as this tab arriving, so a tab drawn with a playback mark would point at the one bucket that had just stopped existing. NOT `rotate`, whose entry says only "rotate": it is the nearest curved drawing in the set and it means turning a thing in place, which is one motion out of many and not the idea of motion. NOT `direction`, which says WHICH WAY a thing travels — two same-way arrows heading a `Scroll direction` row (2026-09-11). A heading is a property OF a movement; this names that there is one at all. NOT `hover`, the pointer resting on a card: that is one MOMENT which can start a motion, never the motion. ⚠️ `play` and `rotate` are the standing trap here and the reason this entry is long: both were drawn for the 2026-08-20 settings-panel design, both are worn by NOTHING today, and both name their own shape — so nothing in either entry refuses a borrower looking for a motion mark. · new · drawn for the `Animation` settings bucket, card `[MOVE] The Settings Panel Gets Its Animation Tab`, 2026-09-14, after the owner asked for the tab on 2026-09-11. A ROUNDED SQUARE AT THE TOP OF A RISING ARC — the object, and the path it came along. Two shapes and no arrowhead. NO ARROWHEAD ON PURPOSE: a head on a curve is `rotate`, `undo`, `redo` AND `revert` — four shipped drawings — and it would also say a DIRECTION, which is `direction`, a fifth. The trail is open at its tail so it reads as where the object has been, not as an instruction. Checked by MEANING against all 91 first: none of them means that a thing moves. Checked by SHAPE against the rect family, which is the most crowded corner of the set — 24 entries carry a `<rect>`, and only four pair one with an arc (`lock`, `theme`, `copy`, `paste`), none of them an OPEN arc leading INTO the rect from outside it. REJECTED ON THE SHEET at 110px and again at 16px: an object with two straight speed-lines behind it read as a power plug, and with a wider gap as `align-right` wearing a box; a pair of swooshes collapsed into a chevron beside a bar; a lone S-curve (the easing-curve mark every motion tool draws) survived every size and was dropped because it is a DESIGNER'S mark — this tab is pressed by merchants, and a curve on its own reads as a graph. MEASUREMENTS at the 16px the tab strip actually renders: optical box 17 × 15, centred on 12,12, inside the set's 14–17.5 in both axes — it stands in a strip of FOUR beside `text-lines`, `styles` (both 16-ish) and `layout` (16), so it answers to those three before it answers to the set. The square is 8 units, which is 5.33px at 16, wide enough to stay an object rather than a blob; the arc drops 10.3 units below it so the trail is never mistaken for the square's own shadow, which is the shipped `shadow`. */
359
- declare function AnimationIcon({ size, ...rest }: IconProps): react.JSX.Element;
360
- /** the SECTION block - one full-width band of an email that holds one to four columns of blocks. Worn by a Section row in the Layers tree and the Section tile. Decided 2026-09-17. NOT `layout` (the Layout settings tab) and NOT `columns` (three bars, a count of columns). · new · Added for the campaign editor redesign approved 2026-09-17 (GG ruling within the plan: a block kind gets its OWN entry, never a settings-row glyph). lifted from the campaign editor, efficient-admin-portal `src/components/email/emailBlockIcons.tsx` key `EmailSection`, brought to stroke 1.7, to M/L/H/V/A/Z commands, and into the set's centred 14-17.5 optical box. */
361
- declare function BlockSectionIcon({ size, ...rest }: IconProps): react.JSX.Element;
362
- /** one COLUMN of a Section block - the slot its blocks stand in. Worn by the `Column 1` / `Column 2` rows of the Layers tree. Decided 2026-09-17. NOT `columns`, which is three bars and answers HOW MANY columns, not which one. · new · Added for the campaign editor redesign approved 2026-09-17 (GG ruling within the plan: a block kind gets its OWN entry, never a settings-row glyph). lifted from the campaign editor, efficient-admin-portal `src/components/email/emailBlockIcons.tsx` key `EmailColumns`, brought to stroke 1.7, to M/L/H/V/A/Z commands, and into the set's centred 14-17.5 optical box. */
363
- declare function BlockColumnIcon({ size, ...rest }: IconProps): react.JSX.Element;
364
- /** the TEXT block - a run of words a person types into an email. Worn by a Text row in the Layers tree and the Text tile. Decided 2026-09-17. NOT `text-lines`, which is WORN already by the body-text field row and the Content tab (efficient-shop FieldGlyph.tsx) - a block row wearing it would be one drawing with two meanings. · new · Added for the campaign editor redesign approved 2026-09-17 (GG ruling within the plan: a block kind gets its OWN entry, never a settings-row glyph). lifted from the campaign editor, efficient-admin-portal `src/components/email/emailBlockIcons.tsx` key `EmailText`, brought to stroke 1.7, to M/L/H/V/A/Z commands, and into the set's centred 14-17.5 optical box. */
365
- declare function BlockTextIcon({ size, ...rest }: IconProps): react.JSX.Element;
366
- /** the HEADING block - the legacy heading kind older campaigns still hold (GTS-8 has six). Worn by its Layers row. Decided 2026-09-17. NOT `type`, the T that marks text settings, and NOT `text-size`. · new · Added for the campaign editor redesign approved 2026-09-17 (GG ruling within the plan: a block kind gets its OWN entry, never a settings-row glyph). lifted from the campaign editor, efficient-admin-portal `src/components/email/emailBlockIcons.tsx` key `EmailHeading`, brought to stroke 1.7, to M/L/H/V/A/Z commands, and into the set's centred 14-17.5 optical box. */
367
- declare function BlockHeadingIcon({ size, ...rest }: IconProps): react.JSX.Element;
368
- /** the BUTTON block - one call to action in an email. Worn by a Button row in the Layers tree and the Button tile. Decided 2026-09-17. NOT `button`, whose entry is the settings ROW for a button's own look - the row and the block are two ideas. · new · Added for the campaign editor redesign approved 2026-09-17 (GG ruling within the plan: a block kind gets its OWN entry, never a settings-row glyph). Starts from the campaign editor, efficient-admin-portal `src/components/email/emailBlockIcons.tsx` key `EmailButton` (a pill with a bar), with an ARROW in place of the bar: the bare pill-and-bar is, at 16px, the same picture as the shipped `button` field-row glyph, and two meanings must not share a picture. Stroke 1.7, centred, 16 x 8. */
369
- declare function BlockButtonIcon({ size, ...rest }: IconProps): react.JSX.Element;
370
- /** the BADGE block - a small word pinned on a product, like NEW. Worn by a Badge row in the Layers tree and the Badge tile. Decided 2026-09-17. NOT `tag`, which the owner ruled is the `label` field row (2026-09-05), not a badge. · new · Added for the campaign editor redesign approved 2026-09-17 (GG ruling within the plan: a block kind gets its OWN entry, never a settings-row glyph). lifted from the campaign editor, efficient-admin-portal `src/components/email/emailBlockIcons.tsx` key `EmailProductBadge`, brought to stroke 1.7, to M/L/H/V/A/Z commands, and into the set's centred 14-17.5 optical box. */
371
- declare function BlockBadgeIcon({ size, ...rest }: IconProps): react.JSX.Element;
372
- /** the INCLUDED LIST block - model names on the left, prices on the right, row by row. Worn by its Layers row and the Included list tile. Decided 2026-09-17. NOT `list`, which is worn by the Header panel's menu item. · new · Added for the campaign editor redesign approved 2026-09-17 (GG ruling within the plan: a block kind gets its OWN entry, never a settings-row glyph). lifted from the campaign editor, efficient-admin-portal `src/components/email/emailBlockIcons.tsx` key `EmailIncludedTable`, brought to stroke 1.7, to M/L/H/V/A/Z commands, and into the set's centred 14-17.5 optical box. */
373
- declare function BlockIncludedListIcon({ size, ...rest }: IconProps): react.JSX.Element;
374
- /** the LAYERED IMAGES block - one picture laid over another. Worn by its Layers row and the Layered images tile. Decided 2026-09-17. NOT `image` (one picture) and NOT `copy` (two pages, a clipboard action). · new · Added for the campaign editor redesign approved 2026-09-17 (GG ruling within the plan: a block kind gets its OWN entry, never a settings-row glyph). lifted from the campaign editor, efficient-admin-portal `src/components/email/emailBlockIcons.tsx` key `EmailLayeredImages`, brought to stroke 1.7, to M/L/H/V/A/Z commands, and into the set's centred 14-17.5 optical box. The back frame is drawn only where the front one does not cover it, so the glyph needs no fill. */
375
- declare function BlockLayeredImagesIcon({ size, ...rest }: IconProps): react.JSX.Element;
376
- /** the VIDEO block - a video shown in an email as a poster with a play mark. Worn by its Layers row and the Video tile. Decided 2026-09-17. NOT `play`: a bare triangle is playback, and this is the block that holds a video. · new · Added for the campaign editor redesign approved 2026-09-17 (GG ruling within the plan: a block kind gets its OWN entry, never a settings-row glyph). lifted from the campaign editor, efficient-admin-portal `src/components/email/emailBlockIcons.tsx` key `EmailVideo`, brought to stroke 1.7, to M/L/H/V/A/Z commands, and into the set's centred 14-17.5 optical box. The triangle is outlined, not filled. */
377
- declare function BlockVideoIcon({ size, ...rest }: IconProps): react.JSX.Element;
378
- /** the PRODUCT block - one catalogue product quoted in an email, its price and its buttons (the Add tile that said `Price` becomes `Product`, Lewis 2026-09-17). Drawn as a PACKAGE: the thing sold. Worn by its Layers row and tile. NOT `dollar`, worn by the price field row, NOT `tag`, the label row, and NOT `cart`, which is buying.. ⚠️ AND IT IS ALREADY WORN IN THE SHOP, which this entry did not say until now. `GalleryProductBinding`, `GalleryShowcaseSource`, `ProductPicker` and `SpecTableSource` each draw a `Product` row with this glyph, and the storefront config's own `Product` picker joins them. One catalogue product, whether it is quoted in an email or picked in a panel. Recorded on card [FIX] The 176 Settings Rows With No Picture, 2026-09-23, because pre-existing silent reuse is still silent reuse and is worse undocumented than documented · new · Added for the campaign editor redesign approved 2026-09-17 (GG ruling within the plan: a block kind gets its OWN entry, never a settings-row glyph). Replaces the price tag of efficient-admin-portal `src/components/email/emailBlockIcons.tsx` key `EmailProduct`: at 16px that tag is the shipped `tag` glyph, which the owner ruled is the `label` field row (2026-09-05). A package names the product itself. Stroke 1.7, M/L/V/Z only, centred, 15 x 17. */
379
- declare function BlockProductIcon({ size, ...rest }: IconProps): react.JSX.Element;
380
- /** the COUPON CODE block - a ticket with the code each person gets. Worn by its Layers row and the Coupon code tile. Decided 2026-09-17. The dashed line is the tear line where the code sits. · new · Added for the campaign editor redesign approved 2026-09-17 (GG ruling within the plan: a block kind gets its OWN entry, never a settings-row glyph). lifted from the campaign editor, efficient-admin-portal `src/components/email/emailBlockIcons.tsx` key `EmailCoupon`, brought to stroke 1.7, to M/L/H/V/A/Z commands, and into the set's centred 14-17.5 optical box. */
381
- declare function BlockCouponIcon({ size, ...rest }: IconProps): react.JSX.Element;
382
- /** the DIVIDER block - a rule between things, in an email and on a website page. Worn by a Divider row in the Layers tree and the Divider tile, in both editors. Decided 2026-09-17. NOT `plus-minus` or any settings row: it is the block itself. · new · Added for the campaign editor redesign approved 2026-09-17 (GG ruling within the plan: a block kind gets its OWN entry, never a settings-row glyph). lifted unchanged from the website editor, efficient-shop `components/SectionIcon.tsx` key `Divider` at origin/main 14.24.0, so the shop can point that key here with no visual change (rule zero, the website wins). Keeps the website's own 18-unit reach. */
383
- declare function BlockDividerIcon({ size, ...rest }: IconProps): react.JSX.Element;
384
- /** the SPACER block - empty room between blocks, in an email and on a website page. Worn by a Spacer row in the Layers tree and the Spacer tile, in both editors. Decided 2026-09-17. NOT `gap` (the air between cards, a settings row) and NOT `padding-top`. · new · Added for the campaign editor redesign approved 2026-09-17 (GG ruling within the plan: a block kind gets its OWN entry, never a settings-row glyph). lifted unchanged from the website editor, efficient-shop `components/SectionIcon.tsx` key `Spacer` at origin/main 14.24.0, so the shop can point that key here with no visual change (rule zero, the website wins). Keeps the website's own 18-unit reach. */
385
- declare function BlockSpacerIcon({ size, ...rest }: IconProps): react.JSX.Element;
386
- /** the FOOTER block - the bottom of an email or of a website page, pinned last. Worn by the Footer row in the Layers tree, in both editors. Decided 2026-09-17. NOT `page` and NOT `layout`: it is the block, not the page or its settings. · new · Added for the campaign editor redesign approved 2026-09-17 (GG ruling within the plan: a block kind gets its OWN entry, never a settings-row glyph). lifted unchanged from the website editor, efficient-shop `components/SectionIcon.tsx` key `Footer` at origin/main 14.24.0, so the shop can point that key here with no visual change (rule zero, the website wins). Keeps the website's own 18-unit reach. */
387
- declare function BlockFooterIcon({ size, ...rest }: IconProps): react.JSX.Element;
388
- /** the BANNER block - words laid over an image. Worn by a Banner row in the Layers tree and the Banner tile, in both editors. Decided 2026-09-17. NOT `image` (a picture alone) and NOT `button`. · new · Added for the campaign editor redesign approved 2026-09-17 (GG ruling within the plan: a block kind gets its OWN entry, never a settings-row glyph). lifted unchanged from the website editor, efficient-shop `components/SectionIcon.tsx` key `Banner` at origin/main 14.24.0, so the shop can point that key here with no visual change (rule zero, the website wins). Keeps the website's own 18-unit reach. */
389
- declare function BlockBannerIcon({ size, ...rest }: IconProps): react.JSX.Element;
390
- /** the SOCIAL block - links to whichever social platforms the business has, never one platform's mark. Worn by a Social row in the Layers tree and the Social tile, in both editors. Decided 2026-09-17. NOT `link` (one link) and NOT `share` actions. · new · Added for the campaign editor redesign approved 2026-09-17 (GG ruling within the plan: a block kind gets its OWN entry, never a settings-row glyph). lifted unchanged from the website editor, efficient-shop `components/SectionIcon.tsx` key `FooterSocial / social` at origin/main 14.24.0, so the shop can point that key here with no visual change (rule zero, the website wins). Keeps the website's own 18-unit reach. */
391
- declare function BlockSocialIcon({ size, ...rest }: IconProps): react.JSX.Element;
392
- /** the BOX block - a container that holds blocks (N8.1: `Box`). The campaign editor called it Group until Lewis renamed it Box, 2026-09-17. Worn by a Box row in the Layers tree and the Box tile, in both editors. NOT `direction`, whose arrows say which way a thing travels. · new · Added for the campaign editor redesign approved 2026-09-17 (GG ruling within the plan: a block kind gets its OWN entry, never a settings-row glyph). lifted unchanged from the website editor, efficient-shop `components/SectionIcon.tsx` key `Flex` at origin/main 14.24.0, so the shop can point that key here with no visual change (rule zero, the website wins). Keeps the website's own 18-unit reach. */
393
- declare function BlockBoxIcon({ size, ...rest }: IconProps): react.JSX.Element;
394
- /** how ROUND a box's corners are — the `Corner radius` row of the campaign editor's Section and Column settings, and the image `Corner radius` row of Email styles. Decided 2026-09-17. A box with ONE strongly rounded corner. NOT `corner`, which is the storefront's `Which corners` row, and NOT `square`, which is the Borders row one line above. · new · drawn for the campaign editor redesign approved 2026-09-17 (admin PR 8: the Section, Column and Email styles rows move onto SettingsField, and every row carries a glyph). Checked at 16px beside the glyphs it must not be read as. */
395
- declare function RadiusIcon({ size, ...rest }: IconProps): react.JSX.Element;
396
- /** how the width is SHARED between a section's columns — the `Column widths` row of the campaign editor's Section settings (a ratio at two columns, shares at three). Decided 2026-09-17. NOT `columns`, which answers HOW MANY, and NOT `block-column`, a block kind that never wears a settings row.. …and the storefront's `Positions` row, where a block in a grid says how many CELLS it spans (`Auto`, `1 position`, `2 positions`, …). A share and a span are two answers to ONE question — how much of a multi-column row this thing takes — and the arrow across the bars draws the question rather than either answer. ⚠️ NOT `columns`, which is a COUNT of them; the two are told apart at 16px by that arrow. Card [FIX] The 176 Settings Rows With No Picture, 2026-09-23 · new · drawn for the campaign editor redesign approved 2026-09-17 (admin PR 8: the Section, Column and Email styles rows move onto SettingsField, and every row carries a glyph). Checked at 16px beside the glyphs it must not be read as. */
397
- declare function ColumnWidthsIcon({ size, ...rest }: IconProps): react.JSX.Element;
398
- /** a rule drawn BETWEEN two columns of content — the `Line between columns` row of the campaign editor's Section settings. Decided 2026-09-17. An upright rule with words on both sides. NOT `block-divider`, the Divider block kind, which is a flat line across.. …and the storefront's `Separator` row, which draws the same rule between ITEMS in a run rather than between columns. The picture is the rule itself, so what it divides is the row's business and not the glyph's. ⚠️ NOT `block-divider`, the divider BLOCK kind, which never heads a settings row — the refusal above stands. Card [FIX] The 176 Settings Rows With No Picture, 2026-09-23 · new · drawn for the campaign editor redesign approved 2026-09-17 (admin PR 8: the Section, Column and Email styles rows move onto SettingsField, and every row carries a glyph). Checked at 16px beside the glyphs it must not be read as. */
399
- declare function LineBetweenIcon({ size, ...rest }: IconProps): react.JSX.Element;
400
- /** the air between columns SIDE BY SIDE — the `Gap between columns` row of the campaign editor's Section settings. Decided 2026-09-17. The GAP is the subject: two short upright bars with an arrowed space between them, drawn like `width`'s arrows. NOT `gap`, which is the air between STACKED things (the `Space between items` row wears that), and NOT `block-column`, whose two boxes the first draft read as at 16px (GG, 2026-09-17). · new · drawn for the campaign editor redesign approved 2026-09-17 (admin PR 8: the Section, Column and Email styles rows move onto SettingsField, and every row carries a glyph). Checked at 16px beside the glyphs it must not be read as. */
401
- declare function ColumnGapIcon({ size, ...rest }: IconProps): react.JSX.Element;
402
- /** where content sits UP AND DOWN inside its box — the `Content position` row (top / middle / bottom) of the campaign editor's Column settings. Decided 2026-09-17. A block between a top and a bottom rule. NOT `padding-top`, which has one rule and says how much room is above. · new · drawn for the campaign editor redesign approved 2026-09-17 (admin PR 8: the Section, Column and Email styles rows move onto SettingsField, and every row carries a glyph). Checked at 16px beside the glyphs it must not be read as. */
403
- declare function VAlignIcon({ size, ...rest }: IconProps): react.JSX.Element;
404
- /** how TALL a thing is — the `Min height` row of the campaign editor's Column settings. Decided 2026-09-17. `width` stood upright, so the pair reads as one family. NOT `width`, which is side to side. · new · drawn for the campaign editor redesign approved 2026-09-17 (admin PR 8: the Section, Column and Email styles rows move onto SettingsField, and every row carries a glyph). Checked at 16px beside the glyphs it must not be read as. */
405
- declare function HeightIcon({ size, ...rest }: IconProps): react.JSX.Element;
406
- /** whether links are UNDERLINED — the `Underline links` row of the campaign editor's Email styles. Decided 2026-09-17. A U over a rule, the mark every word processor uses. NOT `type`, which is the text marker, the T. …AND THE `Underline` toolbar button of the campaign editor's Text block (final design, 2026-10-06): the mark that underlines the selected words. One idea, words with a rule under them, so the button wears this drawing rather than a second copy of it. · new · drawn for the campaign editor redesign approved 2026-09-17 (admin PR 8: the Section, Column and Email styles rows move onto SettingsField, and every row carries a glyph). Checked at 16px beside the glyphs it must not be read as. */
407
- declare function UnderlineIcon({ size, ...rest }: IconProps): react.JSX.Element;
408
- /** WHICH DASH a rule is drawn with — the `Line style` row (Solid / Dashed / Dotted) of the campaign editor's Divider, and of every Border row. Decided 2026-09-17. Three rules stacked: solid, dashed, dotted, so the row's own choices are the drawing. NOT `block-divider`, the Divider BLOCK kind, which is one plain line and never wears a settings row. · new · drawn for the campaign editor redesign approved 2026-09-17 (admin PR 9: the content and media blocks' rows move onto SettingsField). Checked at 16px beside the glyphs it must not be read as. */
409
- declare function LineStyleIcon({ size, ...rest }: IconProps): react.JSX.Element;
410
- /** how far a picture REACHES — the `Width` row (Default / Full width) of the campaign editor's Image block. Decided 2026-09-17. A band running edge to edge between two end walls. NOT `width`, a plain measure with two arrowheads, which says how wide rather than how far it reaches. · new · drawn for the campaign editor redesign approved 2026-09-17 (admin PR 9: the content and media blocks' rows move onto SettingsField). Checked at 16px beside the glyphs it must not be read as. */
411
- declare function FullWidthIcon({ size, ...rest }: IconProps): react.JSX.Element;
412
- /** take a component's LOOK so it can be put on another one — the `Copy style` row (⌥⌘C) of the right-click menu in both editors, the campaign editor's block menu and the website editor's node menu. Decided 2026-09-19 (card [ADD] Copy Style And Paste Style; GG: one meaning per glyph, so it is not `copy`). The brush is the style; the back sheet is `copy`'s own, so the pair reads as "copy, but the look". NOT `copy`, which takes the whole block, and NOT `styles`, which opens the site's Styles panel. · new · drawn for card [ADD] Copy Style And Paste Style, 2026-09-19. A flat paint brush beside `copy`'s back sheet. Lines, rects and arcs only, so the set's optical-box reader can measure it. Checked at 16px in a menu beside `copy` and `paste`. */
413
- declare function CopyStyleIcon({ size, ...rest }: IconProps): react.JSX.Element;
414
- /** put a held look onto this component — the `Paste style from …` row (⌥⌘V) of the right-click menu in both editors. Decided 2026-09-19 (card [ADD] Copy Style And Paste Style). The other half of `copy-style`: the same brush, beside `paste`'s clipboard. NOT `paste`, which drops a whole block, and NOT `copy-style`, which takes the look rather than putting it down. · new · drawn for card [ADD] Copy Style And Paste Style, 2026-09-19, beside `copy-style`. The brush is the same drawing in both; only the companion changes, the way `copy` and `paste` differ by the object and not the action. Checked at 16px in a menu beside `copy` and `paste`. */
415
- declare function PasteStyleIcon({ size, ...rest }: IconProps): react.JSX.Element;
416
- /** THE FINISHES A PRODUCT IS OFFERED IN — the swatch row a shopper picks a colour from. Worn by the `Finishes` row of the `Show on a card` group, on the storefront editor's Product Listing and Product Grid sections, which says whether a card draws that row at all (card [ADD] Choose What A Product Card Shows, 2026-09-21). Three swatches, because the idea is a CHOICE between finishes and a single swatch is just a colour. ⚠️ IT IS NOT `drop`, which is one colour where the row is named for the colour itself; not `accent`, which is the site's ONE emphasis rather than a set to pick from; not `contrast`, which is the tone of a whole palette; and not `theme`. Those four all answer "what colour is this thing"; this answers "which of these does the shopper choose".. …and the Spec Table's `Finish` row, where a MERCHANT picks which of a linked product's finishes the table should describe. Same subject — the finishes a product is offered in — seen from the other side of the editor. ⚠️ AND DELIBERATELY NOT THE `Opening filter`'s `Finish`, one line away in the same vocabulary, which carries NO glyph at all by the owner's facet ruling of 2026-08-29: a facet's options grow out of the merchant's catalogue, so an icon-per-facet queue never empties. Two rows, one drawn and one bare, written here where somebody is standing rather than left to be discovered. Card [FIX] The 176 Settings Rows With No Picture, 2026-09-23 · new · drawn for [ADD] Choose What A Product Card Shows, 2026-09-21 */
417
- declare function FinishIcon({ size, ...rest }: IconProps): react.JSX.Element;
418
- /** THE SIZES A PRODUCT IS SOLD IN — the row of size chips on a product card, each one an orderable variant. Worn by the `Sizes` row of the `Show on a card` group, on the storefront editor's Product Listing and Product Grid sections, which says whether a card draws those chips (card [ADD] Choose What A Product Card Shows, 2026-09-21). Two upright boxes on one baseline, one plainly bigger, because the idea is SEVERAL sizes of one product; one box would be a shape and would claim nothing. The pair is drawn SIDE BY SIDE and never overlapping: overlapping rounded boxes are already `copy`, and the difference a reader must see here is the SIZE, which an overlap turns into "two of them" instead. Three ascending boxes were drawn and rejected the same way — beside `columns` they read as a bar chart. ⚠️ IT CARRIES THE `product-` QUALIFIER FOR A REASON, and `product-field` is the precedent. Bare `size` is a word three rows of this set already want: `text-size` is how big type is set, `width` and `height` are how big a section is. None of them is a product's own catalogue of sizes, and a bare name is what lets the next borrower attach a second meaning to one drawing. It is also not `square`, which is one box and a shape. · new · drawn for [ADD] Choose What A Product Card Shows, 2026-09-21 */
419
- declare function ProductSizeIcon({ size, ...rest }: IconProps): react.JSX.Element;
420
- /** the trail back up to where a shopper came from — the `Breadcrumb` row of the storefront Gallery panel's `Show / hide elements` group. NOT `sitemap`, which is the whole structure of a site rather than one path through it, and NOT `chevron`, which is a disclosure. Card [FIX] Panel Rows That Draw No Picture, 2026-09-22 · picked · efficient-shop · [FIX] Panel Rows That Draw No Picture, 2026-09-22 */
421
- declare function BreadcrumbIcon({ size, ...rest }: IconProps): react.JSX.Element;
422
- /** one strip of choices where only one panel shows at a time — the `Tab switcher` row of the storefront Gallery panel. TWO tabs with the selected one drawn TALLER is what makes it a switcher — a single raised tab over a panel is a folder, which is what the first drawing read as and why it was thrown away rather than a `layout` or a plain panel; nothing else in this set draws a selected-of-several. Card [FIX] Panel Rows That Draw No Picture, 2026-09-22 · picked · efficient-shop · [FIX] Panel Rows That Draw No Picture, 2026-09-22 */
423
- declare function TabsIcon({ size, ...rest }: IconProps): react.JSX.Element;
424
- /** the order a SHOPPER puts a list in — the `Sort control` row of the Gallery panel and the `Sort + Clear all` row of the storefront's Catalog filter bar. ⚠️ NOT `list`, which is a list of entries the MERCHANT orders by hand (the campaign editor's `Phone order` and `Links` rows). The difference is who does the ordering, so the arrow is the whole point of this drawing. Card [FIX] Panel Rows That Draw No Picture, 2026-09-22 · picked · efficient-shop · [FIX] Panel Rows That Draw No Picture, 2026-09-22 */
425
- declare function SortIcon({ size, ...rest }: IconProps): react.JSX.Element;
426
- /** the table of a product's measured facts on its own page — the `Spec table` row of the storefront Product hero's `Show in the buy box` group. A header band over two name/value columns. NOT `grid`, which is a layout of equal cells, and NOT `line-between`, which is one rule drawn between two columns of CONTENT. Card [FIX] Panel Rows That Draw No Picture, 2026-09-22 · picked · efficient-shop · [FIX] Panel Rows That Draw No Picture, 2026-09-22 */
427
- declare function SpecTableIcon({ size, ...rest }: IconProps): react.JSX.Element;
428
- /** the shopper's own vehicle, which a product either fits or does not — the `Ask for the car first` row of the storefront Alloy wheels listing and the `Vehicle fitment` row of the Product hero. ⚠️ NOT `wheel`, which is the PRODUCT this shop sells; this is the thing the product has to fit, and a panel that drew both rows with `wheel` would say the two questions are the same question. Card [FIX] Panel Rows That Draw No Picture, 2026-09-22 · picked · efficient-shop · [FIX] Panel Rows That Draw No Picture, 2026-09-22 */
429
- declare function CarIcon({ size, ...rest }: IconProps): react.JSX.Element;
430
- /** a measured drawing of a product rather than a photograph of it — the `Dimension diagram` row of the storefront Spec table. The object ruled on two sides. ⚠️ A CIRCLE OVER A DIMENSION LINE WAS DRAWN FIRST AND THROWN AWAY: at 16px a circle above a wide horizontal line is a head and shoulders, and the glyph read as a person. NOT `image`, which is a photograph, and NOT `width` or `height`, which are single settings a merchant TYPES; this is a picture the shopper is shown. Card [FIX] Panel Rows That Draw No Picture, 2026-09-22 · picked · efficient-shop · [FIX] Panel Rows That Draw No Picture, 2026-09-22 */
431
- declare function DiagramIcon({ size, ...rest }: IconProps): react.JSX.Element;
432
- /** the one office of several that is the main one — the `HQ` row of each office in the storefront Footprint section. The star is what separates it from a plain building: this glyph never means "an office", it means "THE office". NOT `globe`, which is the country / region selector. Card [FIX] Panel Rows That Draw No Picture, 2026-09-22 · picked · efficient-shop · [FIX] Panel Rows That Draw No Picture, 2026-09-22 */
433
- declare function HeadquartersIcon({ size, ...rest }: IconProps): react.JSX.Element;
434
- /** colour taken out of a picture on purpose — the `Black and white` row of the three storefront photography sections and `Black and white logos` on the Logos strip. `doc/naming.md` N10.1 fixes those words and forbids `Grayscale` (owner ruling 2026-08-28), so the glyph is named for the idea the shop says out loud. ⚠️ A HALF-FILLED CIRCLE WAS DRAWN FIRST AND REJECTED: that is what `contrast` already is, and `contrast` heads the Theme tab. This is a PICTURE with one half ruled out, which is the thing the row does. Hatched rather than filled, because the house standard for this set is stroke on currentColor and no baked plate. Card [FIX] Panel Rows That Draw No Picture, 2026-09-22 · picked · efficient-shop · [FIX] Panel Rows That Draw No Picture, 2026-09-22 */
435
- declare function BlackAndWhiteIcon({ size, ...rest }: IconProps): react.JSX.Element;
436
- /** the arrow a button carries after its words — the `Arrow` row of the storefront Button block. ⚠️ IT IS NEITHER OF THE TWO GLYPHS IT SITS BETWEEN. `button` is the settings row for a button's own look, and this row is one detail inside that; `direction-right` is which way a thing SCROLLS. Here the button and its arrow are drawn together because the row is about the pair. Card [FIX] Panel Rows That Draw No Picture, 2026-09-22 · picked · efficient-shop · [FIX] Panel Rows That Draw No Picture, 2026-09-22 */
437
- declare function ButtonArrowIcon({ size, ...rest }: IconProps): react.JSX.Element;
438
- /** a thing that stays put while the page scrolls under it — the `Stick under header` row of the storefront Category bar and the `Scroll-over` row of Intro bleed. The bar is pinned and the content moves away from it, which is why the arrow points DOWN and away rather than up. Card [FIX] Panel Rows That Draw No Picture, 2026-09-22 · picked · efficient-shop · [FIX] Panel Rows That Draw No Picture, 2026-09-22 */
439
- declare function StickyIcon({ size, ...rest }: IconProps): react.JSX.Element;
440
- /** the group of products a merchant files a thing under — the `Category` row of the storefront's Product picker, Gallery showcase, Spec table and Product hero source panels. A FOLDER: the drawer several products live in. ⚠️ NOT `tag`, which is the shell's luggage tag and already draws a storefront `Label` row — a tag is one name pinned on one thing, a category is the drawer it is filed in, and a panel that drew both with one picture would say those are the same question. NOT `layers`, which is the Layers panel and means stacking order, and NOT `grid`, which is a layout of equal cells. ALSO WORN BY THE `Collection` ROW, ON PURPOSE — see the note in that row's own panel: a collection is a curated group of products and a category is the catalogue's own, but both are "the group this is filed under", and four separate drawings for a collection were made and thrown away because none could be told from `grid`, `layers` or this folder at 16px. Card [FIX] The 28 Hand-Rolled Settings Rows, 2026-09-22. …and the `Product type` row of a dynamic page template, which says which KIND of product (`alloy-wheel`, `tyre`) the template is written for. A category is a grouping the merchant invents and a product type is one the catalogue already has, but both answer “which drawer does this belong in”, which is what the folder draws. ⚠️ NOT `product-field`, whose sentence is “the words come from the catalogue record” — that names where a VALUE is read from, never which KIND a thing is. Card [FIX] The 176 Settings Rows With No Picture, 2026-09-23 · picked · efficient-shop · [FIX] The 28 Hand-Rolled Settings Rows, 2026-09-22 */
441
- declare function CategoryIcon({ size, ...rest }: IconProps): react.JSX.Element;
442
- /** one written article of a series — the `Blog posts` and `Blog post source` rows of the storefront's blog panels. An article laid out: a picture block, its headline beside it, the body beneath. ⚠️ NOT `page`, and that is the whole reason this drawing exists: `page` means a PAGE of the site and the Pages rail, one meaning by the owner's ruling of 2026-08-20, so a blog row wearing it would say a post is a page. NOT `note`, which is a short note ABOUT a thing rather than the thing, and NOT `text-lines`, which is body copy with no article around it. ⚠️ IT IS THE DENSEST DRAWING IN THE SET AND THAT IS DELIBERATE: the block-beside-lines arrangement is what separates it from `page` at 16px, and a simpler page-with-a-heading was drawn first and thrown away because it WAS `page` with an extra stroke. Card [FIX] The 28 Hand-Rolled Settings Rows, 2026-09-22 · picked · efficient-shop · [FIX] The 28 Hand-Rolled Settings Rows, 2026-09-22 */
443
- declare function BlogPostIcon({ size, ...rest }: IconProps): react.JSX.Element;
444
- /** a navigation menu the merchant builds — the `Menu` row of the storefront's Menu picker. The bar a shopper reads along, with the menu dropped open beneath it. ⚠️ NOT `list`, which is a list of entries a merchant orders by hand (the campaign editor's `Phone order` row): every menu is a list, but not every list is the thing a shopper navigates by, and the bar is what says which one this is. NOT `sitemap`, which is the whole structure of a site rather than one menu in it, and NOT `tabs`, which is one strip where only one panel shows at a time. Card [FIX] The 28 Hand-Rolled Settings Rows, 2026-09-22 · picked · efficient-shop · [FIX] The 28 Hand-Rolled Settings Rows, 2026-09-22 */
445
- declare function MenuIcon({ size, ...rest }: IconProps): react.JSX.Element;
446
- /** WHERE A THING SITS inside its box, in two dimensions — the `Placement`, `Content position` and `Text position` rows of the storefront editor, and the Hero's `Overlay position`. Each is a 3×3 pad, and the drawing is one square resting in a corner of a frame. ⚠️ NOT `v-align`, and this is the whole reason the drawing exists: that entry says it means "where content sits UP AND DOWN inside its box" — one dimension, top / middle / bottom. A 3×3 pad is two, and borrowing a one-dimensional picture for it would be a second meaning on one drawing. NOT `grid`, which is a layout of equal cells, and NOT `columns`. ⚠️ `layout` IS THE CLOSE ONE, and the distinction is that `layout`'s inner marks TOUCH the frame — a header band across it, a divider down it — while this square FLOATS in a corner, because floating is what says it could sit somewhere else. They can appear in one panel, since a `Placement` row lives inside the Layout bucket. If this square is ever redrawn touching an edge it becomes `layout` and should go. Card [FIX] The 28 Hand-Rolled Settings Rows, 2026-09-22 · picked · efficient-shop · [FIX] The 28 Hand-Rolled Settings Rows, 2026-09-22 */
447
- declare function PlacementIcon({ size, ...rest }: IconProps): react.JSX.Element;
448
- /** A POINT ON THE EARTH, given as numbers — the `Coordinates`, `Latitude` and `Longitude` rows of the storefront's location editor, where a merchant types or fetches a place's figures. A map pin. ⚠️ NOT `drop`, which is the nearest shape in the set and means A COLOUR: that droplet's point is at the TOP and it is solid, this pin's point is at the BOTTOM and it is pierced. Rendered side by side at 16px before this was kept, because a teardrop beside a teardrop was the obvious way to lose. NOT `globe`, which is the country / region selector — a globe is which MARKET, a pin is which SPOT. NOT `headquarters`, which is one office of several and is a building with a star. Card [FIX] The 28 Hand-Rolled Settings Rows, 2026-09-22 · picked · efficient-shop · [FIX] The 28 Hand-Rolled Settings Rows, 2026-09-22 */
449
- declare function LocationIcon({ size, ...rest }: IconProps): react.JSX.Element;
450
- /** WHAT MAKES THIS HAPPEN — the event a merchant picks to start something, not the thing that is started. Drawn for the `Trigger` row of the storefront's Subscribe popup, whose three answers are `Delay`, `Scroll` and `Exit`: a wait, a scroll position and a pointer leaving the page. Nothing they share is a picture, which is exactly why none of the five shipped candidates could take the row. ⚠️ NOT `clock`, and this is the drawing this one exists to replace: a clock face says TIME, which is true of `Delay` and FALSE of the other two — it shipped on that row in efficient-shop #1468 and is corrected in the card that adds this. ⚠️ NOT `hover`, a pointer resting on a card: that names the MOUSE specifically, and neither a scroll position nor an exit is a hover. ⚠️ NOT `animation`, an object at the head of the path it has travelled: that names MOVEMENT, and a trigger is not a motion — it is the moment one starts. ⚠️ NOT `sticky`, a bar with content moving away beneath it, which names a thing that STAYS PUT while the page scrolls; `Scroll` here is when the reader reaches a point, never what the bar does. ⚠️ NOT `play`, a triangle, which is video playback. The bolt is the one shape in this set that means a thing FIRING rather than a thing being or moving, and it is the only zigzag in 138 drawings, so it cannot be misread for a neighbour at 16px. Card [FIX] The 176 Settings Rows With No Picture, 2026-09-23 · picked · efficient-shop · [FIX] The 176 Settings Rows With No Picture, 2026-09-23 */
451
- declare function TriggerIcon({ size, ...rest }: IconProps): react.JSX.Element;
452
- /** WHETHER A ROW'S ITEMS FLOW ONTO A NEW LINE when they run out of room — the `Wrap` row of a Box's layout (`Wrap` / `No wrap`). The drawing is the RESULT rather than the motion: three items on the first line and one that has fallen to the second, because an uneven second row is the only thing that says wrapping happened. ⚠️ NOT `revert`, and this is the drawing this one was nearly drawn as. A line running right, turning down and coming back left with an arrowhead is the obvious picture for `wrap` and it is ALREADY `revert` — the two would have been the same drawing at 16px. Caught on the sheet before it was drawn, which is what the sheet is for. ⚠️ NOT `direction`, two same-way arrows, which names WHICH WAY a container's children run — and which is itself ruled to head no row (doc/naming.md N10.1 calls it a modifier). Wrapping is not a heading. ⚠️ NOT `columns`, three upright bars, which is a COUNT of columns, and NOT `grid`, which is equal cells: both draw an even arrangement, and unevenness is the whole of what this one says. ⚠️ NOT `line-between`, an upright rule with content either side, which divides two columns rather than describing how one row behaves. ⚠️ `grid` IS THE CLOSE ONE, AND THIS IS WHY IT IS ALLOWED TO LIVE. Both are a cluster of small squares, and at 16px what separates them is SILHOUETTE: this drawing is ASYMMETRIC — three across the top, one at the bottom LEFT, so it is wider on top and visibly short on the bottom right — against `grid`'s even 2×2. That difference survives the size; it was checked at 16px and again at 6× before it was kept, and it was handed up as a coin-flip rather than decided quietly. GG looked at both sheets and approved it, 2026-09-23. ⚠️ ITS KILL CONDITION, in the shape the bolt carries: if `grid` is ever redrawn asymmetric, or if a SECOND cluster-of-squares drawing is added to this set, THIS is the one to question first. Counting squares is a weaker way to be told apart than a shape nothing else has, and this drawing knows it. Card [FIX] The 176 Settings Rows With No Picture, 2026-09-23 · picked · efficient-shop · [FIX] The 176 Settings Rows With No Picture, 2026-09-23 */
453
- declare function WrapIcon({ size, ...rest }: IconProps): react.JSX.Element;
454
- /** WHICH OF SEVERAL STATES a thing is in, where no one of them is the good one — the `State` row of a Mockup's result rows (`Match / done`, `In progress`, `No match`). A ring with its centre filled: one position chosen out of several, which is the idea, rather than any particular verdict. ⚠️ NOT `check`, and refusing it is the whole reason this entry exists. `check` means “checkmark / success”, which is TRUE OF ONE ANSWER IN THREE and false of the other two — a row wearing it would say `done` while a merchant is looking at `No match`. That is the same defect `clock` had on the `Trigger` row, found the same way and written here so the next person does not reach for `check` again. ⚠️ NOT `warning`, a triangle, which is wrong for the success case for the mirror-image reason. ⚠️ NOT `hash`, which is a NUMBER or its unit. ⚠️ NOT `contrast`, a circle with one HALF filled: that is a tone, and its hard straight edge is what tells the two apart at 16px — this one's fill is a centred dot. NOT `eye`, whose pupil sits inside a lens rather than a circle, and NOT `drag`, which is six dots in two columns. Card [FIX] The 176 Settings Rows With No Picture, 2026-09-23 · picked · efficient-shop · [FIX] The 176 Settings Rows With No Picture, 2026-09-23 */
455
- declare function StateIcon({ size, ...rest }: IconProps): react.JSX.Element;
456
- /** THE ROOM ON ONE SIDE — THE LEFT — of a box, worn by the storefront's `Padding left` row and by the folded `Left` row of a section's padding group. Drawn in `padding-top`'s grammar exactly: a rule at that edge, and the box held off it. ⚠️ IT EXISTS BECAUSE THE FAMILY WAS ASYMMETRIC, which is the whole finding. The set drew top and bottom as SINGLE sides and left/right only as a PAIR, so a row about one horizontal side had nothing true to wear and the obvious reach was `padding-x`. ⚠️ NOT `padding-x`, and bending that entry was refused on purpose: its sentence is “the room a PAGE leaves at its left and right edge — the `Side space` row”, which is a different thing at a different scale, and it refuses other uses by name. An entry that has been stretched twice stops meaning anything. GG, 2026-09-23. Card [FIX] The 176 Settings Rows With No Picture · picked · efficient-shop · [FIX] The 176 Settings Rows With No Picture, 2026-09-23 */
457
- declare function PaddingLeftIcon({ size, ...rest }: IconProps): react.JSX.Element;
458
- /** THE ROOM ON ONE SIDE — THE RIGHT — of a box. The mirror of `padding-left`, and it lands with it so the four sides are finally one family: top, bottom, left, right, each a rule at its own edge with the box held off it. ⚠️ NOT `padding-x`, which is the PAGE's side space — see `padding-left` for why that entry was not stretched. Card [FIX] The 176 Settings Rows With No Picture, 2026-09-23 · picked · efficient-shop · [FIX] The 176 Settings Rows With No Picture, 2026-09-23 */
459
- declare function PaddingRightIcon({ size, ...rest }: IconProps): react.JSX.Element;
460
- /** THE ROOM ABOVE AND BELOW a box, as ONE setting — the storefront's `Space above and below` row. ⚠️ IT RETIRES A WORKAROUND THAT WAS ALREADY SHIPPING, KNOWINGLY. `efficient-shop`'s `components/PartSettingsPanel.tsx` FIELD_ICONS carries this comment against its own padding row: “The set draws `padding-top` and `padding-bottom` and has no glyph for the PAIR, which is what this one row moves. `PaddingTopIcon` is the nearer of the two … Flagged to the seat rather than solved quietly.” That flag is what this drawing answers; that row should move to this glyph. ⚠️ NOT `v-align`, AND THE PROPORTIONS ARE THE WHOLE REASON IT CAN LIVE. `v-align` is ALREADY two full-width rules with a narrow box between them — the obvious drawing for this idea is already taken, and drawing it again would have been a duplicate. This one INVERTS that: SHORT ticks and a WIDE box. `v-align` says which of three positions the content sits in; this says how much room is left. ⚠️ ITS KILL CONDITION follows from that: if `v-align` is ever redrawn with a wide box, or a second short-tick-and-wide-box drawing is added, THIS is the one to question first — it survives on proportion rather than on a shape nothing else has. ⚠️ NOT `gap`, which is the space BETWEEN siblings at three scales; this is room INSIDE one box. NOT `layout`, a frame with a band across it. Card [FIX] The 176 Settings Rows With No Picture, 2026-09-23 · picked · efficient-shop · [FIX] The 176 Settings Rows With No Picture, 2026-09-23 */
461
- declare function PaddingYIcon({ size, ...rest }: IconProps): react.JSX.Element;
462
- /** A FINE ADJUSTMENT FROM WHERE A THING ALREADY SITS — the storefront hero group's `Sideways` and `Up and down` rows, each a ±px offset. ⚠️ ONE DRAWING FOR BOTH ROWS, deliberately. They are one idea on two axes, and the ROW'S OWN LABEL says which axis — `Sideways` and `Up and down` are as plain as the panel gets. The padding family splits by side because WHICH EDGE changes what the setting means; an axis does not change what a nudge is. ⚠️ NOT `placement`, and refusing it is the point: that entry is WHERE A THING SITS among NINE POSITIONS in a 3×3 pad, and a nudge is not one of nine — it is a small move from wherever the thing already is. ⚠️ NOT `width` or `height`, which are a line with arrowheads at both ends: those MEASURE an extent, this MOVES a thing. NOT `direction-up`/`-down`/`-left`/`-right`, single arrows that say which way a marquee TRAVELS. NOT `drag`, six dots, which is a handle a person grabs. Card [FIX] The 176 Settings Rows With No Picture, 2026-09-23 · picked · efficient-shop · [FIX] The 176 Settings Rows With No Picture, 2026-09-23 */
463
- declare function NudgeIcon({ size, ...rest }: IconProps): react.JSX.Element;
464
- /** HOW FAR DOWN a reader has got before something happens — the Subscribe popup's `Scroll` row, a percentage of the page. An arrow travelling down to the line it must reach. ⚠️ ITS SIBLING ROW IS WHY IT HAD TO EXIST. One row up, `Delay` wears `clock`, honestly: a delay IS a time. This row is a POSITION, and wearing a clock beside it would make two different questions look like one. Same defect `clock` had on the `Trigger` row (corrected in 0.56.0), one row along. ⚠️ NOT `sticky`, which is the close one at 16px: both are a bar and a down arrow, and what separates them is WHICH END THE MASS IS AT — `sticky` is a thick pinned bar at the TOP with content moving away beneath it, this is a thin line at the BOTTOM with an arrow arriving at it. ⚠️ ITS KILL CONDITION: if `sticky` is ever redrawn with its bar at the bottom, these two collide and this is the one to question first. ⚠️ NOT `direction-down`, a plain arrow with nothing to arrive at — the line is the whole idea. Card [FIX] The 176 Settings Rows With No Picture, 2026-09-23 · picked · efficient-shop · [FIX] The 176 Settings Rows With No Picture, 2026-09-23 */
465
- declare function ScrollPointIcon({ size, ...rest }: IconProps): react.JSX.Element;
466
- /** WHICH SIDE A ROW'S WORDS COME FROM, as the question rather than either answer — worn by a settings row that asks it, where the merchant picks between their own copy and copy the catalogue already holds. Drawn for the storefront Feature Rows block's `Rows from` row (`Product story` | `Detail shots`). · new · efficient-shop · [ADD] Detail Shots Write Their Own Section, 2026-09-23. ⚠️ IT COMPLETES A FAMILY BY NAMING ITS AXIS, and that is the whole reason it exists rather than a third side being borrowed. `product-field` means "the words come from the catalogue record" and `own-text` means "the words are the merchant's own, not the product's" — one SEGMENT each of the Card text control. A ROW that asks which of the two has no glyph in that pair, and putting either on it is false in both directions: `product-field` would claim the row means "from the product", `own-text` would claim the opposite, and the row asks. ⛔ NOT `state`, and refusing it is recorded here so nobody re-opens it. `state` is structurally this drawing's question — one position chosen out of several — but its stated idea is WHICH STATE a thing is IN, and where words come from is not a state. Borrowing a glyph whose entry claims a different idea is how `ground` ended up on three. ⛔ AND NOT `product-field` FOR A SECOND REASON, independent of the half-truth: it is already worn by `dynamic: toggle("Connect to product data")`, the row directly above this one in the same panel. Two sibling rows wearing one picture, one line apart, is the heading/row echo in pictures. THE DRAWING: two branches entering from the left and joining one trunk that leaves to the right — two possible origins, one destination. Checked against the set before it was drawn: no junction or fork existed. `sitemap` is the nearest shape and is top-down with three rectangles; `direction` is two separate arrows; `breadcrumb` is dots on one line. */
467
- declare function WordsFromIcon({ size, ...rest }: IconProps): react.JSX.Element;
468
- /** THE HEADING OF ONE ITEM, not of the band around it — worn by a settings row that holds the loudest line on a single card. An H drawn INSIDE the item's frame, and the containment is the whole distinction. Drawn for the campaign editor's Coupon card, where every layout carries exactly one `title` place. Decided 2026-09-25. · new · efficient-admin-portal · [ADD] The Coupon Card Reaches Six Looks, 2026-09-25. ⚠️ THIS IS A DRAWING THAT ALREADY EXISTS, BROUGHT TO THE SHELL RATHER THAN INVENTED. efficient-shop drew it in `components/FieldGlyph.tsx` on 2026-09-05 *because the shell had nothing for it*, and its stated refusal travels with it — `SHELL_VERDICT.title`: "Layout — a frame with a header bar and a column split, not an H inside a box". ⛔ NOT `layout`, for exactly that reason and unchanged: `layout` is a frame with a header BAND and a column split, and it means WHICH ARRANGEMENT a section draws — one scale above the heading of a single item. ⛔ NOT `block-heading`, the bare H, and refusing it is a rule the set already carries rather than a preference: that entry is a BLOCK KIND, and 0.53.0's ruling is that a block kind gets its own entry and never a settings-row glyph. It also has no frame, which is the idea here. ⛔ NOT `text-size`, the big/small pair, which is a SIZE control and not a place; NOT `type`, the bare T that marks text settings; NOT `square`, an empty rect with nothing written in it; NOT `spec-table`, a header band over two name/value columns. THE DRAWING: an H centred inside a rounded rect. Rendered by the repo's own `scripts/glyph-sheet.mjs` at 16px — the size `.es-field-icon` actually draws a settings-row glyph at — and at 26px, beside those six, and looked at before it was committed. ⚠️ ITS KILL CONDITION: it survives on CONTAINMENT, not on a shape nothing else has. If a second letterform-inside-a-frame is ever drawn, or `layout` is ever redrawn without its band, this is the one to question first. */
469
- declare function TitleIcon({ size, ...rest }: IconProps): react.JSX.Element;
470
- /** THE SMALL LINE OF FACTS ALONG THE BOTTOM of an item — a date, a code, a deadline, run together on one line. Worn by a settings row that holds that line. One full rule with three SHORT runs under it: the gaps are the drawing, because the gaps are what make it read as several facts instead of a paragraph. Decided 2026-09-25. · new · efficient-admin-portal · [ADD] The Coupon Card Reaches Six Looks, 2026-09-25. ⚠️ ALREADY DRAWN IN efficient-shop (`components/FieldGlyph.tsx`, 2026-09-05), brought here rather than invented, and its own stated reason comes with it — `SHELL_VERDICT.meta`: "TextLines — this is that with the gaps that make it read as several facts". ⛔ NOT `text-lines`, three full-width rules, which is a paragraph of body copy and is already worn by every body-text row in the product — including the shop's own `body`, which IMPORTS it rather than drawing one. This is that drawing with its lower row BROKEN, and the break is the meaning. ⛔ NOT `list`, dots against rules, which is entries a merchant orders. ⛔ NOT `align-separate`, three pairs of equal rules pushed to both edges, which says WHERE rows sit rather than what one holds. ⛔ NOT `breadcrumb`, three dots joined along one line, which is the trail back up to where a shopper came from. THE DRAWING: one rule edge to edge, and under it three short runs with two even gaps. Rendered by the repo's own `scripts/glyph-sheet.mjs` at 16px — the size `.es-field-icon` actually draws a settings-row glyph at — and at 26px, beside those four plus `sort`, and looked at before it was committed. ⚠️ THE SHOP'S GEOMETRY WAS RE-CENTRED, NOT REDRAWN: the storefront copy sits at y 7 and 14, which is 10.5 down a 24 canvas, and this set centres every drawing on 12. The rows moved to 8 and 16 and the runs were evened; the picture is the same picture. */
471
- declare function MetaIcon({ size, ...rest }: IconProps): react.JSX.Element;
472
- /** the BOLD mark — the toolbar button that writes `**words**` (Strong, ⌘B) over the selection in the copy box's formatting bar. A capital B, the letter every word processor puts on this button. One idea: the mark, not a weight setting. Decided 2026-10-02. · new · efficient-editor · [FINISH] Markdown Text Box To The Approved Design, 2026-10-02. Lewis approved the box's toolbar on 2026-10-02 (design v5, https://claude.ai/artifact/SZDRnLuGot2tmnduhKgfVs): ONE glyph button per mark, B (**) · I (_) · S (~~) · ◆ (==) · a (^^) · link · clear, and no words on the buttons — the names live only in the tooltip and the aria-label. ⛔ NOT `weight`, a T beside a heavier T, which is the font-WEIGHT row of a text style: a setting for every word of a style, where this button marks a phrase. ⛔ NOT `type`, the T that marks a text setting. Drawn with only M/H/A/Z, so the set's optical-box guard reads it. */
473
- declare function BoldIcon({ size, ...rest }: IconProps): react.JSX.Element;
474
- /** the ITALIC mark — the toolbar button that writes `_words_` (⌘I) over the selection in the copy box's formatting bar. A slanted capital I with its two serifs, the button every word processor draws. Decided 2026-10-02. · new · efficient-editor · [FINISH] Markdown Text Box To The Approved Design, 2026-10-02. Lewis approved the box's toolbar on 2026-10-02 (design v5, https://claude.ai/artifact/SZDRnLuGot2tmnduhKgfVs): ONE glyph button per mark, B (**) · I (_) · S (~~) · ◆ (==) · a (^^) · link · clear, and no words on the buttons — the names live only in the tooltip and the aria-label. ⛔ NOT `type` or `text-small`, upright T's that mark text settings: this is a mark on a phrase. ⛔ NOT `rename`, the pencil. The slant is the drawing — an upright I would be a cursor. */
475
- declare function ItalicIcon({ size, ...rest }: IconProps): react.JSX.Element;
476
- /** the STRIKETHROUGH mark — the toolbar button that writes `~~words~~` over the selection in the copy box's formatting bar (a was-price beside a now-price). An S with a rule through its middle. Decided 2026-10-02. · new · efficient-editor · [FINISH] Markdown Text Box To The Approved Design, 2026-10-02. Lewis approved the box's toolbar on 2026-10-02 (design v5, https://claude.ai/artifact/SZDRnLuGot2tmnduhKgfVs): ONE glyph button per mark, B (**) · I (_) · S (~~) · ◆ (==) · a (^^) · link · clear, and no words on the buttons — the names live only in the tooltip and the aria-label. ⛔ NOT `line-style`, three rules solid, dashed and dotted, which is how a DIVIDER is drawn. ⛔ NOT `underline`, a U over a rule, which is whether links are underlined. The rule crosses the letter at its spine; that crossing is the meaning. */
477
- declare function StrikeIcon({ size, ...rest }: IconProps): react.JSX.Element;
478
- /** the EMPHASIS mark — the toolbar button that writes `==words==` over the selection in the copy box's formatting bar: the phrase painted in the brand accent colour. A diamond, the ◆ the bar has shown for this mark since the campaign designer first drew it. Decided 2026-10-02. · new · efficient-editor · [FINISH] Markdown Text Box To The Approved Design, 2026-10-02. Lewis approved the box's toolbar on 2026-10-02 (design v5, https://claude.ai/artifact/SZDRnLuGot2tmnduhKgfVs): ONE glyph button per mark, B (**) · I (_) · S (~~) · ◆ (==) · a (^^) · link · clear, and no words on the buttons — the names live only in the tooltip and the aria-label. ⛔ NOT `accent`, a spark on a line of type, which is the Accent ROLE on the Text and Theme tabs — what the accent IS, set once for the site. This button only says WHICH words wear it. Two meanings may not share one drawing, so the button keeps its own ◆. ⛔ NOT `state`, a dot in a ring. */
479
- declare function EmphasisIcon({ size, ...rest }: IconProps): react.JSX.Element;
480
- /** the QUIET mark — the toolbar button that writes `^^words^^` over the selection in the copy box's formatting bar: smaller, softer words, like the fine print under a price. A small one-storey a. It is drawn SMALL on purpose, under the set's 14–17.5 box: smaller is what the mark does, and the design (v5) draws this button's a smaller than the B beside it. Decided 2026-10-02. · new · efficient-editor · [FINISH] Markdown Text Box To The Approved Design, 2026-10-02. Lewis approved the box's toolbar on 2026-10-02 (design v5, https://claude.ai/artifact/SZDRnLuGot2tmnduhKgfVs): ONE glyph button per mark, B (**) · I (_) · S (~~) · ◆ (==) · a (^^) · link · clear, and no words on the buttons — the names live only in the tooltip and the aria-label. ⛔ NOT `case`, which is a T BESIDE this same small a: there the a is half of a pair that means upper versus lower case; alone it is the quiet words. ⛔ NOT `text-small`, a small T, which is the small-TYPE kind (an eyebrow), a style for a whole line. ⛔ NOT `text-size`, the big/small pair of the size control. */
481
- declare function QuietIcon({ size, ...rest }: IconProps): react.JSX.Element;
482
- /** CLEAR MARKS — the toolbar button that takes every mark off the selection in the copy box's formatting bar (⌘⇧X), keeping the words and any link. A T with a small × at its foot: the text, with its marks crossed out. Decided 2026-10-02. · new · efficient-editor · [FINISH] Markdown Text Box To The Approved Design, 2026-10-02. Lewis approved the box's toolbar on 2026-10-02 (design v5, https://claude.ai/artifact/SZDRnLuGot2tmnduhKgfVs): ONE glyph button per mark, B (**) · I (_) · S (~~) · ◆ (==) · a (^^) · link · clear, and no words on the buttons — the names live only in the tooltip and the aria-label. ⛔ NOT `close`, the bare ×, which closes a window. ⛔ NOT `type`, the bare T that marks a text setting. ⛔ NOT `revert`, the hooked arrow that puts a setting back to what it inherits — clear takes marks off words, it does not reset a setting. ⛔ NOT `trash`, which deletes. */
483
- declare function ClearMarksIcon({ size, ...rest }: IconProps): react.JSX.Element;
484
- /** the SUPERSCRIPT mark — raised small text (®, ™, a footnote¹). Worn by the `Superscript` toolbar button of the campaign editor's Text block and the `Superscript` item of its Normal / Superscript / Subscript menu. A capital A with a small 2 at its top right (Lewis, 2026-10-06: the design's x, then a T, then, after seeing the T: use A for all). Decided 2026-10-06. · picked · efficient-easel · [ADD] Text Box Icons For The Final Design, 2026-10-06 (step E2 of the campaign-editor plan Lewis approved that day). Final design: https://claude.ai/artifact/Mpzgvi2sZmTCmciZW36w5H. The Text block's toolbar is two rows of 32px glyph buttons with the names only in the tooltip and the aria-label; the number row is Font size · Line spacing · Letter spacing · Paragraph spacing. Checked at 16px beside every neighbour named here before it was committed. ⛔ NOT `subscript`, the same A with the 2 at its FOOT: the pair differs only in where the 2 sits, and that is the meaning. ⛔ NOT `case-normal` (A beside a small a) or `case-upper` (two A's): here the small thing beside the A is a figure, raised. ⛔ NOT `clear-marks`, a T with a small × at its foot. The 2 is the design's path; the drawing sits 1 right and 0.7 down of the design so it is centred. The letter went x → T → A on Lewis's word, 2026-10-06: the Ts did not look right beside Aa / AA / aa. */
485
- declare function SuperscriptIcon({ size, ...rest }: IconProps): react.JSX.Element;
486
- /** the SUBSCRIPT mark — lowered small text (H₂O). Worn by the `Subscript` toolbar button of the campaign editor's Text block and the `Subscript` item of its Normal / Superscript / Subscript menu. The same capital A as `superscript`, with the small 2 at its foot (Lewis, 2026-10-06: after seeing the T: use A for all). Decided 2026-10-06. · picked · efficient-easel · [ADD] Text Box Icons For The Final Design, 2026-10-06 (step E2 of the campaign-editor plan Lewis approved that day). Final design: https://claude.ai/artifact/Mpzgvi2sZmTCmciZW36w5H. The Text block's toolbar is two rows of 32px glyph buttons with the names only in the tooltip and the aria-label; the number row is Font size · Line spacing · Letter spacing · Paragraph spacing. Checked at 16px beside every neighbour named here before it was committed. ⛔ NOT `superscript`, the same A with the 2 at its TOP. ⛔ NOT `case-normal` (A beside a small a) or `case-upper` (two A's): here the small thing at the A's foot is a figure. ⛔ NOT `clear-marks`, a T with a small × at its foot. The 2 is the design's path; the drawing sits 1 right and 1 up of the design so it is centred. The letter went x → T → A on Lewis's word, 2026-10-06. */
487
- declare function SubscriptIcon({ size, ...rest }: IconProps): react.JSX.Element;
488
- /** a NUMBERED LIST — the lines the caret is on, written as 1. 2. 3. Worn by the `Numbered list` toolbar button of the campaign editor's Text block and the `Numbered list` item of its No list / Bulleted list / Numbered list menu. Three rules with 1, 2, 3 down the left. Decided 2026-10-06. · picked · efficient-easel · [ADD] Text Box Icons For The Final Design, 2026-10-06 (step E2 of the campaign-editor plan Lewis approved that day). Final design: https://claude.ai/artifact/Mpzgvi2sZmTCmciZW36w5H. The Text block's toolbar is two rows of 32px glyph buttons with the names only in the tooltip and the aria-label; the number row is Font size · Line spacing · Letter spacing · Paragraph spacing. Checked at 16px beside every neighbour named here before it was committed. ⛔ NOT `list`, the same three rules with DOTS, which is the bulleted list (and the orderable-entries rows): dots against figures is the whole difference, and at 16px the figures still read as figures. ⛔ NOT `text-lines`, plain rules with nothing at the edge. ⛔ NOT `hash`, a number as a VALUE. Paths from the design; the 3 lifted 0.1 so the drawing is centred. */
489
- declare function NumberedListIcon({ size, ...rest }: IconProps): react.JSX.Element;
490
- /** PARAGRAPH SPACING — the room between one paragraph and the next, in px. Worn by the fourth value of the campaign editor's Text block number row (`Paragraph spacing`, beside Font size, Line spacing and Letter spacing). Two short paragraphs with a small upright mark in the room between them. Decided 2026-10-06. · picked · efficient-easel · [ADD] Text Box Icons For The Final Design, 2026-10-06 (step E2 of the campaign-editor plan Lewis approved that day). Final design: https://claude.ai/artifact/Mpzgvi2sZmTCmciZW36w5H. The Text block's toolbar is two rows of 32px glyph buttons with the names only in the tooltip and the aria-label; the number row is Font size · Line spacing · Letter spacing · Paragraph spacing. Checked at 16px beside every neighbour named here before it was committed. ⛔ NOT `text-lines`, three rules evenly spaced, which is LINE spacing inside a paragraph: here the rules come in two pairs and the gap between the pairs is the subject. ⛔ NOT `gap`, two stacked cards, the room between BLOCKS. ⛔ NOT `padding-y`, the room inside a box. ⛔ NOT `align-left`, ragged rules. Paths from the design, unchanged. */
491
- declare function ParagraphSpacingIcon({ size, ...rest }: IconProps): react.JSX.Element;
492
- /** letter case LEFT AS TYPED — `Aa`, the `Normal` option of the Letter case buttons (Normal / Uppercase / Lowercase) on the campaign editor's Text block, and of the storefront part panel's Case strip. The plan calls it sentence case; it changes nothing the merchant typed. A capital A beside a one-storey a. Decided 2026-10-06. · picked · efficient-easel · [ADD] Text Box Icons For The Final Design, 2026-10-06 (step E2 of the campaign-editor plan Lewis approved that day). Final design: https://claude.ai/artifact/Mpzgvi2sZmTCmciZW36w5H. The Text block's toolbar is two rows of 32px glyph buttons with the names only in the tooltip and the aria-label; the number row is Font size · Line spacing · Letter spacing · Paragraph spacing. Checked at 16px beside every neighbour named here before it was committed. MOVED FROM THE STOREFRONT: efficient-storefront `components/PartGlyphs.tsx` `CaseGlyph` drew Aa / AA / aa as live text at weight 600; the plan makes the set the one source, so these are strokes now, and the storefront should import them instead. ⛔ NOT `case`, a T beside an a, which is the Letter case ROW (the question); this is one ANSWER. ⛔ NOT `quiet`, the small a alone. ⛔ NOT `type`, the T. */
493
- declare function CaseNormalIcon({ size, ...rest }: IconProps): react.JSX.Element;
494
- /** letter case ALL CAPITALS — `AA`, the `Uppercase` option of the Letter case buttons on the campaign editor's Text block, and of the storefront part panel's Case strip. Two capital A's. Decided 2026-10-06. · picked · efficient-easel · [ADD] Text Box Icons For The Final Design, 2026-10-06 (step E2 of the campaign-editor plan Lewis approved that day). Final design: https://claude.ai/artifact/Mpzgvi2sZmTCmciZW36w5H. The Text block's toolbar is two rows of 32px glyph buttons with the names only in the tooltip and the aria-label; the number row is Font size · Line spacing · Letter spacing · Paragraph spacing. Checked at 16px beside every neighbour named here before it was committed. MOVED FROM THE STOREFRONT: efficient-storefront `components/PartGlyphs.tsx` `CaseGlyph` (`AA`, live text); the set is the one source now. ⛔ NOT `case-normal`, which is A beside a SMALL a. ⛔ NOT `case`, the row's T + a. ⛔ NOT `bold`: this is which letters, not how heavy. The two A's are drawn narrow with a 3.5-unit channel between their feet, so they stay two letters at 16px. */
495
- declare function CaseUpperIcon({ size, ...rest }: IconProps): react.JSX.Element;
496
- /** letter case ALL SMALL LETTERS — `aa`, the `Lowercase` option of the Letter case buttons on the campaign editor's Text block, and of the storefront part panel's Case strip. Two one-storey a's. Decided 2026-10-06. · picked · efficient-easel · [ADD] Text Box Icons For The Final Design, 2026-10-06 (step E2 of the campaign-editor plan Lewis approved that day). Final design: https://claude.ai/artifact/Mpzgvi2sZmTCmciZW36w5H. The Text block's toolbar is two rows of 32px glyph buttons with the names only in the tooltip and the aria-label; the number row is Font size · Line spacing · Letter spacing · Paragraph spacing. Checked at 16px beside every neighbour named here before it was committed. MOVED FROM THE STOREFRONT: efficient-storefront `components/PartGlyphs.tsx` `CaseGlyph` (`aa`, live text); the set is the one source now. ⛔ NOT `case-normal`, a capital A beside the a. ⛔ NOT `quiet`, ONE small a drawn under the set's box, which is the quiet mark on a phrase. ⛔ NOT `case`, the row's T + a. A 3-unit channel between the first stem and the second bowl keeps them two letters at 16px. */
497
- declare function CaseLowerIcon({ size, ...rest }: IconProps): react.JSX.Element;
498
- /** JUSTIFY — text whose rows run edge to edge. Worn by the Justify button on the final text box's second toolbar row, beside Left, Center and Right, and by the Justify chip of the alignment strip. Three full-width rows on the same three heights the other alignment glyphs use. Decided 2026-10-06 (the design was made final that day). · new · efficient-easel · E5b, the final text box, design final 2026-10-06: https://claude.ai/artifact/Mpzgvi2sZmTCmciZW36w5H — its toolbar draws Justify as `M4 6.5h16M4 12h16M4 17.5h16`, and this is that drawing. ⛔ NOT `align-separate`, whose own entry says "NOT `justify`": it opens a channel down the middle of each row, which is where rows SIT, not how text runs. The package drew Justify with it until now; that was a borrowed meaning. ⛔ NOT `text-lines`, three rules with a short last one, which is a paragraph of body copy. ⛔ NOT `align-left`, whose rows are of three lengths. */
499
- declare function AlignJustifyIcon({ size, ...rest }: IconProps): react.JSX.Element;
500
- /** the LEFT SIDE PANEL itself — worn by the Hide panel button at the end of a left panel's head (`MediaPanelHead`, both editors' SidePanelHeads) and by the Show panel button in the strip a hidden left panel leaves. One control, so one drawing: hiding and showing the panel wear the same glyph. A frame with its left column ruled off. ⛔ NOT an ✕: an ✕ closes a dialog, and a panel head has none (owner, 2026-10-04). · new · efficient-easel · card [MERGE] One Media Panel Head For Both Editors, 2026-10-06 — the drawing both editors already carried twice: efficient-storefront components/PanelToggleIcon.tsx and efficient-admin-portal src/components/email/CampaignTopBar.tsx `PanelToggleGlyph`. */
501
- declare function PanelLeftIcon({ size, ...rest }: IconProps): react.JSX.Element;
502
- /** the RIGHT SIDE PANEL itself — the twin of `panel-left` for the settings panel: its head's Hide panel button and the strip a hidden right panel leaves. A frame with its right column ruled off. · new · efficient-easel · card [MERGE] One Media Panel Head For Both Editors, 2026-10-06 — the drawing both editors already carried twice: efficient-storefront components/PanelToggleIcon.tsx and efficient-admin-portal src/components/email/CampaignTopBar.tsx `PanelToggleGlyph`. */
503
- declare function PanelRightIcon({ size, ...rest }: IconProps): react.JSX.Element;
504
- /** INSERT A MERGE TAG — a word that fills in for each reader ({{first_name}}, a coupon code). Worn by the Insert button the campaign designer puts in the 9th cell of the final text box's first toolbar row (`CopyBox` `lastTool`), which opens its list of tags. Two curly braces, the shape a merge tag is written in. Decided 2026-10-07. ⛔ NOT `code` or a pair of angle brackets: nothing here is code, and the braces are the tag's own spelling. · new · efficient-easel · card [CHANGE] Undo Button Becomes Clear Style, 2026-10-07 — Lewis's ruling on mockup v2 https://claude.ai/artifact/GiyeV3xazepzArKGVkFM8T, which draws Insert with this path; asked for by GG for the admin card [CHANGE] Email Insert Moves Into The Toolbar (icons come from easel). */
505
- declare function BracesIcon({ size, ...rest }: IconProps): react.JSX.Element;
506
-
507
- export { AccentIcon, AccountIcon, AddIcon, AlignCenterIcon, AlignJustifyIcon, AlignLeftIcon, AlignRightIcon, AlignSeparateIcon, AnchorIcon, AnimationIcon, BackgroundIcon, BellIcon, BlackAndWhiteIcon, BlockBadgeIcon, BlockBannerIcon, BlockBoxIcon, BlockButtonIcon, BlockColumnIcon, BlockCouponIcon, BlockDividerIcon, BlockFooterIcon, BlockHeadingIcon, BlockIncludedListIcon, BlockLayeredImagesIcon, BlockProductIcon, BlockSectionIcon, BlockSocialIcon, BlockSpacerIcon, BlockTextIcon, BlockVideoIcon, BlogPostIcon, BoldIcon, BracesIcon, BreadcrumbIcon, ButtonArrowIcon, ButtonIcon, CarIcon, CartIcon, CaseIcon, CaseLowerIcon, CaseNormalIcon, CaseUpperIcon, CategoryIcon, ChatIcon, CheckIcon, ChevronIcon, ClearMarksIcon, ClockIcon, CloseIcon, ColumnGapIcon, ColumnWidthsIcon, ColumnsIcon, ContrastIcon, CopyIcon, CopyStyleIcon, CopyToPageIcon, CornerIcon, DesktopIcon, DiagramIcon, DirectionDownIcon, DirectionIcon, DirectionLeftIcon, DirectionRightIcon, DirectionUpIcon, DollarIcon, DragIcon, DropIcon, DuplicateIcon, EmphasisIcon, ExternalIcon, EyeIcon, EyeOffIcon, FinishIcon, FullWidthIcon, GapIcon, GlobeIcon, GridIcon, GroundIcon, HashIcon, HeadquartersIcon, HeightIcon, HoverIcon, type IconName, type IconProps, ImageIcon, ItalicIcon, LayersIcon, LayoutIcon, LetterSpacingIcon, LineBetweenIcon, LineStyleIcon, LinkIcon, ListIcon, LocationIcon, LockIcon, LogoIcon, MediaIcon, MenuIcon, MetaIcon, MoveDownIcon, MoveUpIcon, NoteIcon, NudgeIcon, NumberedListIcon, OpacityIcon, OwnTextIcon, PaddingBottomIcon, PaddingLeftIcon, PaddingRightIcon, PaddingTopIcon, PaddingXIcon, PaddingYIcon, PageIcon, PanelLeftIcon, PanelRightIcon, ParagraphSpacingIcon, PasteIcon, PasteStyleIcon, PhoneIcon, PlacementIcon, PlayIcon, PlusMinusIcon, ProductFieldIcon, ProductSizeIcon, QuietIcon, RadiusIcon, RedoIcon, RenameIcon, RevertIcon, RotateIcon, ScrollPointIcon, SearchIcon, SendIcon, SettingsIcon, ShadowIcon, SitemapIcon, SortIcon, SpecTableIcon, SquareIcon, StateIcon, StickyIcon, StrikeIcon, StylesIcon, SubscriptIcon, SuperscriptIcon, TabletIcon, TabsIcon, TagIcon, TemplateIcon, TextColorIcon, TextLinesIcon, TextSizeIcon, TextSmallIcon, ThemeIcon, TitleIcon, TrashIcon, TriggerIcon, TypeIcon, UnderlineIcon, UndoIcon, VAlignIcon, WarningIcon, WeightIcon, WheelIcon, WidthIcon, WordsFromIcon, WrapIcon, iconMeanings };
1
+ export * from 'efficient-shell/icons/efficient';
2
+ export { EfficientIconName as IconName, EfficientIconProps as IconProps, efficientIconMeanings as iconMeanings } from 'efficient-shell/icons/efficient';